ref(TS) Convert some Abstract classes to TS (#13117)

pull/13127/head jitsi-meet_8476
Robert Pintilii 2 years ago committed by GitHub
parent 1bf0bd6bca
commit b942ce9378
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 57
      react/features/connection-indicator/components/AbstractConnectionIndicator.ts
  2. 3
      react/features/connection-indicator/components/native/ConnectionIndicator.tsx
  3. 63
      react/features/connection-indicator/components/web/ConnectionIndicator.tsx
  4. 4
      react/features/dropbox/functions.native.ts
  5. 27
      react/features/filmstrip/components/AbstractRaisedHandIndicator.ts
  6. 4
      react/features/filmstrip/components/web/ThumbnailTopIndicators.tsx
  7. 79
      react/features/overlay/components/web/AbstractPageReloadOverlay.tsx
  8. 15
      react/features/overlay/components/web/AbstractSuspendedOverlay.ts
  9. 22
      react/features/overlay/components/web/AbstractUserMediaPermissionsOverlay.ts
  10. 6
      react/features/overlay/reducer.ts
  11. 2
      react/features/recording/actions.any.ts
  12. 123
      react/features/recording/components/Recording/AbstractStartRecordingDialog.ts

@ -1,7 +1,6 @@
// @flow
import { Component } from 'react';
import { IReduxState } from '../../app/types';
import { getVirtualScreenshareParticipantOwnerId } from '../../base/participants/functions';
import statsEmitter from '../statsEmitter';
@ -18,49 +17,51 @@ export const INDICATOR_DISPLAY_THRESHOLD = 30;
/**
* The type of the React {@code Component} props of {@link ConnectionIndicator}.
*/
export type Props = {
export interface IProps {
/**
* How long the connection indicator should remain displayed before hiding.
*/
_autoHideTimeout: number,
_autoHideTimeout: number;
/**
* Whether or not the statistics are for screen share.
*/
_isVirtualScreenshareParticipant: boolean,
_isVirtualScreenshareParticipant: boolean;
/**
* The ID of the participant associated with the displayed connection indication and
* stats.
* Custom icon style.
*/
participantId: string,
iconStyle?: Object;
/**
* Custom icon style.
* The ID of the participant associated with the displayed connection indication and
* stats.
*/
iconStyle?: Object
};
participantId: string;
}
/**
* The type of the React {@code Component} state of {@link ConnectionIndicator}.
*/
export type State = {
export interface IState {
/**
* Whether or not a CSS class should be applied to the root for hiding the
* connection indicator. By default the indicator should start out hidden
* because the current connection status is not known at mount.
*/
showIndicator: boolean,
showIndicator: boolean;
/**
* Cache of the stats received from subscribing to stats emitting. The keys
* should be the name of the stat. With each stat update, updates stats are
* mixed in with cached stats and a new stats object is set in state.
*/
stats: Object
};
stats: {
percent?: number;
};
}
/**
* Implements a React {@link Component} which displays the current connection
@ -68,11 +69,11 @@ export type State = {
*
* @augments {Component}
*/
class AbstractConnectionIndicator<P: Props, S: State> extends Component<P, S> {
class AbstractConnectionIndicator<P extends IProps, S extends IState> extends Component<P, S> {
/**
* The timeout for automatically hiding the indicator.
*/
autoHideTimeout: ?TimeoutID;
autoHideTimeout: number | undefined;
/**
* Initializes a new {@code ConnectionIndicator} instance.
@ -103,7 +104,7 @@ class AbstractConnectionIndicator<P: Props, S: State> extends Component<P, S> {
* @inheritdoc
* returns {void}
*/
componentDidUpdate(prevProps: Props) {
componentDidUpdate(prevProps: IProps) {
const prevParticipantId = this._getRealParticipantId(prevProps);
const participantId = this._getRealParticipantId(this.props);
@ -123,7 +124,7 @@ class AbstractConnectionIndicator<P: Props, S: State> extends Component<P, S> {
componentWillUnmount() {
statsEmitter.unsubscribeToClientStats(this._getRealParticipantId(this.props), this._onStatsUpdated);
clearTimeout(this.autoHideTimeout);
clearTimeout(this.autoHideTimeout ?? 0);
}
/**
@ -132,7 +133,7 @@ class AbstractConnectionIndicator<P: Props, S: State> extends Component<P, S> {
* @param {Props} props - The props where to extract the data from.
* @returns {string | undefined } The resolved participant ID.
*/
_getRealParticipantId(props: Props) {
_getRealParticipantId(props: IProps) {
if (props._isVirtualScreenshareParticipant) {
return getVirtualScreenshareParticipantOwnerId(props.participantId);
}
@ -140,8 +141,6 @@ class AbstractConnectionIndicator<P: Props, S: State> extends Component<P, S> {
return props.participantId;
}
_onStatsUpdated: (Object) => void;
/**
* Callback invoked when new connection stats associated with the passed in
* user ID are available. Will update the component's display of current
@ -151,7 +150,7 @@ class AbstractConnectionIndicator<P: Props, S: State> extends Component<P, S> {
* @private
* @returns {void}
*/
_onStatsUpdated(stats = {}) {
_onStatsUpdated(stats = { connectionQuality: undefined }) {
// Rely on React to batch setState actions.
const { connectionQuality } = stats;
const newPercentageState = typeof connectionQuality === 'undefined'
@ -166,7 +165,7 @@ class AbstractConnectionIndicator<P: Props, S: State> extends Component<P, S> {
stats: newStats
});
this._updateIndicatorAutoHide(newStats.percent);
this._updateIndicatorAutoHide(newStats.percent ?? 0);
}
/**
@ -177,9 +176,9 @@ class AbstractConnectionIndicator<P: Props, S: State> extends Component<P, S> {
* @private
* @returns {void}
*/
_updateIndicatorAutoHide(percent) {
_updateIndicatorAutoHide(percent: number) {
if (percent < INDICATOR_DISPLAY_THRESHOLD) {
clearTimeout(this.autoHideTimeout);
clearTimeout(this.autoHideTimeout ?? 0);
this.autoHideTimeout = undefined;
this.setState({
@ -190,7 +189,7 @@ class AbstractConnectionIndicator<P: Props, S: State> extends Component<P, S> {
// is needed if the percent is below the threshold and there is an
// autoHideTimeout set.
} else {
this.autoHideTimeout = setTimeout(() => {
this.autoHideTimeout = window.setTimeout(() => {
this.setState({
showIndicator: false
});
@ -205,9 +204,9 @@ class AbstractConnectionIndicator<P: Props, S: State> extends Component<P, S> {
*
* @param {Object} state - The Redux state.
* @private
* @returns {Props}
* @returns {IProps}
*/
export function mapStateToProps(state: Object) {
export function mapStateToProps(state: IReduxState) {
return {
_autoHideTimeout: state['features/base/config'].connectionIndicators?.autoHideTimeout ?? defaultAutoHideTimeout
};

@ -24,9 +24,8 @@ import {
isTrackStreamingStatusInterrupted
} from '../../functions';
import AbstractConnectionIndicator, {
type Props as AbstractProps,
IProps as AbstractProps,
mapStateToProps as _abstractMapStateToProps
// @ts-ignore
} from '../AbstractConnectionIndicator';
import {

@ -18,17 +18,16 @@ import {
getTrackByMediaTypeAndParticipant,
getVirtualScreenshareParticipantTrack
} from '../../../base/tracks/functions';
import { ITrack } from '../../../base/tracks/types';
import {
isTrackStreamingStatusInactive,
isTrackStreamingStatusInterrupted
} from '../../functions';
import AbstractConnectionIndicator, {
type Props as AbstractProps,
type State as AbstractState,
IProps as AbstractProps,
IState as AbstractState,
INDICATOR_DISPLAY_THRESHOLD,
mapStateToProps as _abstractMapStateToProps
// @ts-ignore
} from '../AbstractConnectionIndicator';
// @ts-ignore
@ -77,18 +76,33 @@ const QUALITY_TO_WIDTH: Array<{
/**
* The type of the React {@code Component} props of {@link ConnectionIndicator}.
*/
type Props = AbstractProps & WithTranslation & {
interface IProps extends AbstractProps, WithTranslation {
/**
* Disable/enable inactive indicator.
*/
_connectionIndicatorInactiveDisabled: boolean;
/**
* Whether the connection status is inactive.
*/
_isConnectionStatusInactive: boolean;
/**
* Whether the connection status is interrupted.
*/
_isConnectionStatusInterrupted?: boolean;
/**
* Whether the indicator popover is disabled.
*/
_popoverDisabled: boolean;
/**
* The participant's video track;.
*/
_videoTrack?: ITrack;
/**
* Whether or not the component should ignore setting a visibility class for
* hiding the component when the connection quality is not strong.
@ -98,7 +112,7 @@ type Props = AbstractProps & WithTranslation & {
/**
* The audio SSRC of this client.
*/
audioSsrc: number;
audioSsrc?: number;
/**
* An object containing the CSS classes.
@ -126,12 +140,12 @@ type Props = AbstractProps & WithTranslation & {
* should display.
*/
statsPopoverPosition: string;
};
}
interface IState extends AbstractState {
/**
* Whether popover is ivisible or not.
* Whether popover is visible or not.
*/
popoverVisible: boolean;
}
@ -188,17 +202,16 @@ const styles = (theme: Theme) => {
*
* @augments {Component}
*/
class ConnectionIndicator extends AbstractConnectionIndicator<Props, IState> {
class ConnectionIndicator extends AbstractConnectionIndicator<IProps, IState> {
/**
* Initializes a new {@code ConnectionIndicator} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props: Props) {
constructor(props: IProps) {
super(props);
// @ts-ignore
this.state = {
showIndicator: false,
stats: {},
@ -215,11 +228,9 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, IState> {
* @returns {ReactElement}
*/
render() {
// @ts-ignore
const { enableStatsDisplay, participantId, statsPopoverPosition, classes, t } = this.props;
const visibilityClass = this._getVisibilityClass();
// @ts-ignore
if (this.props._popoverDisabled) {
return this._renderIndicator();
}
@ -228,8 +239,6 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, IState> {
<Popover
className = { clsx(classes.container, visibilityClass) }
content = { <ConnectionIndicatorContent
// @ts-ignore
inheritedStats = { this.state.stats }
participantId = { participantId } /> }
disablePopover = { !enableStatsDisplay }
@ -255,15 +264,12 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, IState> {
*/
_getConnectionColorClass() {
// TODO We currently do not have logic to emit and handle stats changes for tracks.
// @ts-ignore
const { percent } = this.state.stats;
const {
_isConnectionStatusInactive,
_isConnectionStatusInterrupted,
_connectionIndicatorInactiveDisabled
// @ts-ignore
} = this.props;
if (_isConnectionStatusInactive) {
@ -304,13 +310,9 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, IState> {
* @returns {string}
*/
_getVisibilityClass() {
// @ts-ignore
const { _isConnectionStatusInactive, _isConnectionStatusInterrupted, classes } = this.props;
// @ts-ignore
return this.state.showIndicator
// @ts-ignore
|| this.props.alwaysVisible
|| _isConnectionStatusInterrupted
|| _isConnectionStatusInactive
@ -324,7 +326,6 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, IState> {
* @returns {void}
*/
_onHidePopover() {
// @ts-ignore
this.setState({ popoverVisible: false });
}
@ -335,7 +336,6 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, IState> {
* @returns {void}
*/
_onShowPopover() {
// @ts-ignore
this.setState({ popoverVisible: true });
}
@ -353,8 +353,6 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, IState> {
_videoTrack,
classes,
iconSize
// @ts-ignore
} = this.props;
return (
@ -376,10 +374,10 @@ class ConnectionIndicator extends AbstractConnectionIndicator<Props, IState> {
* Maps part of the Redux state to the props of this component.
*
* @param {Object} state - The Redux state.
* @param {Props} ownProps - The own props of the component.
* @returns {Props}
* @param {IProps} ownProps - The own props of the component.
* @returns {IProps}
*/
export function _mapStateToProps(state: IReduxState, ownProps: Props) {
export function _mapStateToProps(state: IReduxState, ownProps: IProps) {
const { participantId } = ownProps;
const tracks = state['features/base/tracks'];
const participant = participantId ? getParticipantById(state, participantId) : getLocalParticipant(state);
@ -397,14 +395,11 @@ export function _mapStateToProps(state: IReduxState, ownProps: Props) {
_connectionIndicatorInactiveDisabled:
Boolean(state['features/base/config'].connectionIndicators?.inactiveDisabled),
_isVirtualScreenshareParticipant: isScreenShareParticipant(participant),
_popoverDisabled: state['features/base/config'].connectionIndicators?.disableDetails,
_popoverDisabled: Boolean(state['features/base/config'].connectionIndicators?.disableDetails),
_isConnectionStatusInactive,
_isConnectionStatusInterrupted,
_videoTrack
};
}
export default translate(connect(_mapStateToProps)(
// @ts-ignore
withStyles(styles)(ConnectionIndicator)));
export default connect(_mapStateToProps)(translate(withStyles(styles)(ConnectionIndicator)));

@ -28,9 +28,11 @@ export async function _authorizeDropbox(_appKey?: any, _redirectURI?: any): Prom
/**
* Gets a new access token based on the refresh token.
*
* @param {string} _appKey - The dropbox appKey.
* @param {string} _rToken - The refresh token.
* @returns {Promise}
*/
export function getNewAccessToken() {
export function getNewAccessToken(_appKey: string, _rToken: string) {
return _authorizeDropbox();
}

@ -1,27 +1,26 @@
// @flow
import React, { Component } from 'react';
import { Component } from 'react';
import { IReduxState } from '../../app/types';
import { getParticipantById, hasRaisedHand } from '../../base/participants/functions';
import { getParticipantById, hasRaisedHand } from '../../base/participants';
export type Props = {
export interface IProps {
/**
* The participant id who we want to render the raised hand indicator
* for.
* True if the hand is raised for this participant.
*/
participantId: string,
_raisedHand?: boolean;
/**
* True if the hand is raised for this participant.
* The participant id who we want to render the raised hand indicator
* for.
*/
_raisedHand?: boolean
participantId: string;
}
/**
* Implements an abstract class for the RaisedHandIndicator component.
*/
export default class AbstractRaisedHandIndicator<P: Props>
export default class AbstractRaisedHandIndicator<P extends IProps>
extends Component<P> {
/**
@ -42,7 +41,7 @@ export default class AbstractRaisedHandIndicator<P: Props>
*
* @returns {React$Element<*>}
*/
_renderIndicator: () => React$Element<*>;
_renderIndicator: () => React.ReactElement;
}
@ -50,10 +49,10 @@ export default class AbstractRaisedHandIndicator<P: Props>
* Maps part of the Redux state to the props of this component.
*
* @param {Object} state - The Redux state.
* @param {Props} ownProps - The own props of the component.
* @param {IProps} ownProps - The own props of the component.
* @returns {Object}
*/
export function _mapStateToProps(state: Object, ownProps: Props): Object {
export function _mapStateToProps(state: IReduxState, ownProps: IProps) {
const participant = getParticipantById(state, ownProps.participantId);
return {

@ -104,7 +104,7 @@ const ThumbnailTopIndicators = ({
if (isVirtualScreenshareParticipant) {
return (
<div className = { styles.container }>
{!_connectionIndicatorDisabled
{!_connectionIndicatorDisabled // @ts-ignore
&& <ConnectionIndicator
alwaysVisible = { showConnectionIndicator }
enableStatsDisplay = { true }
@ -124,7 +124,7 @@ const ThumbnailTopIndicators = ({
iconSize = { _indicatorIconSize }
participantId = { participantId }
tooltipPosition = { tooltipPosition } />
{!_connectionIndicatorDisabled
{!_connectionIndicatorDisabled // @ts-ignore
&& <ConnectionIndicator
alwaysVisible = { showConnectionIndicator }
enableStatsDisplay = { true }

@ -1,96 +1,91 @@
// @flow
// @ts-ignore
import { randomInt } from '@jitsi/js-utils/random';
import React, { Component } from 'react';
import type { Dispatch } from 'redux';
import { WithTranslation } from 'react-i18next';
import {
createPageReloadScheduledEvent,
sendAnalytics
} from '../../../analytics';
import { reloadNow } from '../../../app/actions';
import { createPageReloadScheduledEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { reloadNow } from '../../../app/actions.web';
import { IReduxState, IStore } from '../../../app/types';
import {
isFatalJitsiConferenceError,
isFatalJitsiConnectionError
} from '../../../base/lib-jitsi-meet/functions';
} from '../../../base/lib-jitsi-meet/functions.web';
import logger from '../../logger';
// @ts-ignore
import ReloadButton from './ReloadButton';
declare var APP: Object;
/**
* The type of the React {@code Component} props of
* {@link AbstractPageReloadOverlay}.
*/
export type Props = {
export interface IProps extends WithTranslation {
/**
* The details is an object containing more information about the connection
* failed (shard changes, was the computer suspended, etc.).
*/
details: Object,
details: Object;
dispatch: Dispatch<any>,
/**
* Redux dispatch function.
*/
dispatch: IStore['dispatch'];
/**
* The error that caused the display of the overlay.
*/
error: Error,
error: Error;
/**
* The indicator which determines whether the reload was caused by network
* failure.
*/
isNetworkFailure: boolean,
isNetworkFailure: boolean;
/**
* The reason for the error that will cause the reload.
* NOTE: Used by PageReloadOverlay only.
*/
reason: string,
/**
* The function to translate human-readable text.
*/
t: Function
};
reason: string;
}
/**
* The type of the React {@code Component} state of
* {@link AbstractPageReloadOverlay}.
*/
type State = {
interface IState {
/**
* The translation key for the title of the overlay.
*/
message: string,
message: string;
/**
* Current value(time) of the timer.
*/
timeLeft: number,
timeLeft: number;
/**
* How long the overlay dialog will be displayed before the conference will
* be reloaded.
*/
timeoutSeconds: number,
timeoutSeconds: number;
/**
* The translation key for the title of the overlay.
*/
title: string
};
title: string;
}
/**
* Implements an abstract React {@link Component} for the page reload overlays.
*
* FIXME: This is not really an abstract class as some components and functions are very web specific.
*/
export default class AbstractPageReloadOverlay<P: Props>
extends Component<P, State> {
export default class AbstractPageReloadOverlay<P extends IProps>
extends Component<P, IState> {
/**
* Determines whether this overlay needs to be rendered (according to a
@ -100,7 +95,7 @@ export default class AbstractPageReloadOverlay<P: Props>
* @returns {boolean} - If this overlay needs to be rendered, {@code true};
* {@code false}, otherwise.
*/
static needsRender(state: Object) {
static needsRender(state: IReduxState) {
const { error: conferenceError } = state['features/base/conference'];
const { error: configError } = state['features/base/config'];
const { error: connectionError } = state['features/base/connection'];
@ -115,7 +110,7 @@ export default class AbstractPageReloadOverlay<P: Props>
return jitsiConnectionError || jitsiConferenceError || configError;
}
_interval: ?IntervalID;
_interval: number | undefined;
/**
* Initializes a new AbstractPageReloadOverlay instance.
@ -164,13 +159,11 @@ export default class AbstractPageReloadOverlay<P: Props>
// because the log queue is not flushed before "fabric terminated" is
// sent to the backed.
// FIXME: We should dispatch action for this.
if (typeof APP !== 'undefined') {
if (APP.conference && APP.conference._room) {
APP.conference._room.sendApplicationLog(JSON.stringify({
name: 'page.reload',
label: this.props.reason
}));
}
if (typeof APP !== 'undefined' && APP.conference?._room) {
APP.conference._room.sendApplicationLog(JSON.stringify({
name: 'page.reload',
label: this.props.reason
}));
}
sendAnalytics(createPageReloadScheduledEvent(
@ -183,7 +176,7 @@ export default class AbstractPageReloadOverlay<P: Props>
this.state.timeoutSeconds} seconds.`);
this._interval
= setInterval(
= window.setInterval(
() => {
if (this.state.timeLeft === 0) {
if (this._interval) {
@ -268,7 +261,7 @@ export default class AbstractPageReloadOverlay<P: Props>
* reason: string
* }}
*/
export function abstractMapStateToProps(state: Object) {
export function abstractMapStateToProps(state: IReduxState) {
const { error: configError } = state['features/base/config'];
const { error: connectionError } = state['features/base/connection'];
const { fatalError } = state['features/overlay'];
@ -290,7 +283,7 @@ export function abstractMapStateToProps(state: Object) {
}
return {
details: fatalError && fatalError.details,
details: fatalError?.details,
error: fatalError,
isNetworkFailure:
fatalError === configError || fatalError === connectionError,

@ -1,18 +1,13 @@
// @flow
import { Component } from 'react';
import { WithTranslation } from 'react-i18next';
import { IReduxState } from '../../../app/types';
/**
* The type of the React {@code Component} props of
* {@link AbstractSuspendedOverlay}.
*/
type Props = {
/**
* The function to translate human-readable text.
*/
t: Function
};
type Props = WithTranslation;
/**
* Implements a React {@link Component} for suspended overlay. Shown when a
@ -27,7 +22,7 @@ export default class AbstractSuspendedOverlay extends Component<Props> {
* @returns {boolean} - If this overlay needs to be rendered, {@code true};
* {@code false}, otherwise.
*/
static needsRender(state: Object) {
static needsRender(state: IReduxState) {
return state['features/power-monitor']?.suspendDetected;
}
}

@ -1,31 +1,27 @@
// @flow
import { Component } from 'react';
import { WithTranslation } from 'react-i18next';
import { IReduxState } from '../../../app/types';
/**
* The type of the React {@code Component} props of
* {@link AbstractUserMediaPermissionsOverlay}.
*/
type Props = {
interface IProps extends WithTranslation {
/**
* The browser which is used currently. The text is different for every
* browser.
*/
browser: string,
/**
* The function to translate human-readable text.
*/
t: Function
};
browser: string;
}
/**
* Implements a React {@link Component} for overlay with guidance how to proceed
* with gUM prompt.
*/
export default class AbstractUserMediaPermissionsOverlay
extends Component<Props> {
extends Component<IProps> {
/**
* Determines whether this overlay needs to be rendered (according to a
* specific redux state). Called by {@link OverlayContainer}.
@ -34,7 +30,7 @@ export default class AbstractUserMediaPermissionsOverlay
* @returns {boolean} - If this overlay needs to be rendered, {@code true};
* {@code false}, otherwise.
*/
static needsRender(state: Object) {
static needsRender(state: IReduxState) {
return state['features/overlay'].isMediaPermissionPromptVisible;
}
}
@ -48,7 +44,7 @@ export default class AbstractUserMediaPermissionsOverlay
* browser: string
* }}
*/
export function abstractMapStateToProps(state: Object) {
export function abstractMapStateToProps(state: IReduxState) {
const { browser } = state['features/overlay'];
return {

@ -6,7 +6,11 @@ import { MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED } from './actionTypes';
export interface IOverlayState {
browser?: string;
fatalError?: Error;
fatalError?: {
details: Object;
message?: string;
name?: string;
};
isMediaPermissionPromptVisible?: boolean;
}

@ -350,7 +350,7 @@ function _setPendingRecordingNotificationUid(uid: string | undefined, streamType
* @param {boolean} onlySelf - Whether to only record the local streams.
* @returns {Object}
*/
export function startLocalVideoRecording(onlySelf: boolean) {
export function startLocalVideoRecording(onlySelf?: boolean) {
return {
type: START_LOCAL_RECORDING,
onlySelf

@ -1,142 +1,138 @@
// @flow
import { Component } from 'react';
import { WithTranslation } from 'react-i18next';
import {
createRecordingDialogEvent,
sendAnalytics
} from '../../../analytics';
import { createRecordingDialogEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState, IStore } from '../../../app/types';
import { IJitsiConference } from '../../../base/conference/reducer';
import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
import {
getDropboxData,
getNewAccessToken,
isEnabled as isDropboxEnabled,
updateDropboxToken
} from '../../../dropbox';
import { NOTIFICATION_TIMEOUT_TYPE, showErrorNotification } from '../../../notifications';
import { toggleRequestingSubtitles } from '../../../subtitles';
import { updateDropboxToken } from '../../../dropbox/actions';
import { getDropboxData, getNewAccessToken, isEnabled as isDropboxEnabled } from '../../../dropbox/functions.any';
import { showErrorNotification } from '../../../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../../../notifications/constants';
import { toggleRequestingSubtitles } from '../../../subtitles/actions';
import { setSelectedRecordingService, startLocalVideoRecording } from '../../actions';
import { RECORDING_TYPES } from '../../constants';
import { supportsLocalRecording } from '../../functions';
export type Props = {
export interface IProps extends WithTranslation {
/**
* Requests subtitles when recording is turned on.
* The app key for the dropbox authentication.
*/
_autoCaptionOnRecord: boolean,
_appKey: string;
/**
* The {@code JitsiConference} for the current conference.
* Requests subtitles when recording is turned on.
*/
_conference: Object,
_autoCaptionOnRecord: boolean;
/**
* The app key for the dropbox authentication.
* The {@code JitsiConference} for the current conference.
*/
_appKey: string,
_conference: IJitsiConference;
/**
* Whether to show file recordings service, even if integrations
* are enabled.
*/
_fileRecordingsServiceEnabled: boolean,
_fileRecordingsServiceEnabled: boolean;
/**
* Whether to show the possibility to share file recording with other people (e.g. Meeting participants), based on
* the actual implementation on the backend.
*/
_fileRecordingsServiceSharingEnabled: boolean,
_fileRecordingsServiceSharingEnabled: boolean;
/**
* If true the dropbox integration is enabled, otherwise - disabled.
*/
_isDropboxEnabled: boolean,
_isDropboxEnabled: boolean;
/**
* Whether or not local recording is enabled.
*/
_localRecordingEnabled: boolean,
_localRecordingEnabled: boolean;
/**
* The dropbox refresh token.
*/
_rToken: string,
_rToken: string;
/**
* Whether or not the local participant is screensharing.
*/
_screensharing: boolean,
_screensharing: boolean;
/**
* Whether or not the screenshot capture feature is enabled.
*/
_screenshotCaptureEnabled: boolean,
/**
* Access token's expiration date as UNIX timestamp.
*/
_tokenExpireDate?: number,
_screenshotCaptureEnabled: boolean;
/**
* The dropbox access token.
*/
_token: string,
_token: string;
/**
* The redux dispatch function.
* Access token's expiration date as UNIX timestamp.
*/
dispatch: Function,
_tokenExpireDate?: number;
/**
* Invoked to obtain translated strings.
* The redux dispatch function.
*/
t: Function
dispatch: IStore['dispatch'];
}
type State = {
interface IState {
/**
* <tt>true</tt> if we have valid oauth token.
*/
isTokenValid: boolean,
isTokenValid: boolean;
/**
* <tt>true</tt> if we are in process of validating the oauth token.
*/
isValidating: boolean,
isValidating: boolean;
/**
* Whether the local recording should record just the local user streams.
*/
localRecordingOnlySelf?: boolean;
/**
* The currently selected recording service of type: RECORDING_TYPES.
*/
selectedRecordingService: ?string,
selectedRecordingService?: string;
/**
* True if the user requested the service to share the recording with others.
*/
sharingEnabled: boolean,
sharingEnabled: boolean;
/**
* Number of MiB of available space in user's Dropbox account.
*/
spaceLeft: ?number,
spaceLeft?: number;
/**
* The display name of the user's Dropbox account.
*/
userName: ?string
};
userName?: string;
}
/**
* Component for the recording start dialog.
*/
class AbstractStartRecordingDialog extends Component<Props, State> {
class AbstractStartRecordingDialog extends Component<IProps, IState> {
/**
* Initializes a new {@code StartRecordingDialog} instance.
*
* @inheritdoc
*/
constructor(props: Props) {
constructor(props: IProps) {
super(props);
// Bind event handler so it is only bound once for every instance.
@ -191,14 +187,12 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
* @inheritdoc
* @returns {void}
*/
componentDidUpdate(prevProps: Props) {
componentDidUpdate(prevProps: IProps) {
if (this.props._token !== prevProps._token) {
this._onTokenUpdated();
}
}
_areIntegrationsEnabled: () => boolean;
/**
* Returns true if the integrations with third party services are enabled
* and false otherwise.
@ -210,8 +204,6 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
return this.props._isDropboxEnabled;
}
_onSharingSettingChanged: () => void;
/**
* Callback to handle sharing setting change from the dialog.
*
@ -223,8 +215,6 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
});
}
_onLocalRecordingSelfChange: () => void;
/**
* Callback to handle local recording only self setting change.
*
@ -236,8 +226,6 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
});
}
_onSelectedRecordingServiceChanged: (string) => void;
/**
* Handles selected recording service changes.
*
@ -245,7 +233,7 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
* service.
* @returns {void}
*/
_onSelectedRecordingServiceChanged(selectedRecordingService) {
_onSelectedRecordingServiceChanged(selectedRecordingService: string) {
this.setState({ selectedRecordingService }, () => {
this.props.dispatch(setSelectedRecordingService(selectedRecordingService));
});
@ -268,10 +256,11 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
isTokenValid: false,
isValidating: false
});
} else {
} else { // @ts-ignore
if (_tokenExpireDate && Date.now() > new Date(_tokenExpireDate)) {
getNewAccessToken(_appKey, _rToken)
.then(resp => dispatch(updateDropboxToken(resp.token, resp.rToken, resp.expireDate)));
.then((resp: { expireDate: number; rToken: string; token: string; }) =>
dispatch(updateDropboxToken(resp.token, resp.rToken, resp.expireDate)));
return;
}
@ -297,8 +286,6 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
}
}
_onSubmit: () => boolean;
/**
* Starts a file recording session.
*
@ -316,7 +303,9 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
dispatch
} = this.props;
let appData;
const attributes = {};
const attributes: {
type?: string;
} = {};
switch (this.state.selectedRecordingService) {
case RECORDING_TYPES.DROPBOX: {
@ -374,8 +363,6 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
return true;
}
_toggleScreenshotCapture:() => void;
/**
* Toggles screenshot capture feature.
*
@ -391,7 +378,7 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
* @protected
* @returns {React$Component}
*/
_renderDialogContent: () => React$Component<*>;
_renderDialogContent: () => React.Component;
}
/**
@ -412,11 +399,11 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
* _token: string
* }}
*/
export function mapStateToProps(state: Object) {
export function mapStateToProps(state: IReduxState) {
const {
transcription,
recordingService,
dropbox = {},
dropbox = { appKey: undefined },
localRecording
} = state['features/base/config'];
Loading…
Cancel
Save