浏览代码

ref(TS) Convert always-on-top to TS (#13332)

factor2
Robert Pintilii 2 年前
父节点
当前提交
ae0669fa07
没有帐户链接到提交者的电子邮件

+ 1
- 0
globals.d.ts 查看文件

21
         JitsiMeetElectron?: any;
21
         JitsiMeetElectron?: any;
22
         // selenium tests handler
22
         // selenium tests handler
23
         _sharedVideoPlayer: any;
23
         _sharedVideoPlayer: any;
24
+        alwaysOnTop: { api: any };
24
     }
25
     }
25
 
26
 
26
     interface Document {
27
     interface Document {

react/features/always-on-top/AlwaysOnTop.js → react/features/always-on-top/AlwaysOnTop.tsx 查看文件

1
-// @flow
2
-
3
 import React, { Component } from 'react';
1
 import React, { Component } from 'react';
4
 
2
 
5
 // We need to reference these files directly to avoid loading things that are not available
3
 // We need to reference these files directly to avoid loading things that are not available
19
 /**
17
 /**
20
  * The type of the React {@code Component} state of {@link AlwaysOnTop}.
18
  * The type of the React {@code Component} state of {@link AlwaysOnTop}.
21
  */
19
  */
22
-type State = {
23
-    avatarURL: string,
24
-    customAvatarBackgrounds: Array<string>,
25
-    displayName: string,
26
-    formattedDisplayName: string,
27
-    isVideoDisplayed: boolean,
28
-    userID: string,
29
-    visible: boolean
30
-};
20
+interface IState {
21
+    avatarURL: string;
22
+    customAvatarBackgrounds: Array<string>;
23
+    displayName: string;
24
+    formattedDisplayName: string;
25
+    isVideoDisplayed: boolean;
26
+    userID: string;
27
+    visible: boolean;
28
+}
31
 
29
 
32
 /**
30
 /**
33
  * Represents the always on top page.
31
  * Represents the always on top page.
35
  * @class AlwaysOnTop
33
  * @class AlwaysOnTop
36
  * @augments Component
34
  * @augments Component
37
  */
35
  */
38
-export default class AlwaysOnTop extends Component<*, State> {
36
+export default class AlwaysOnTop extends Component<any, IState> {
39
     _hovered: boolean;
37
     _hovered: boolean;
40
 
38
 
41
     /**
39
     /**
44
      * @param {*} props - The read-only properties with which the new instance
42
      * @param {*} props - The read-only properties with which the new instance
45
      * is to be initialized.
43
      * is to be initialized.
46
      */
44
      */
47
-    constructor(props: *) {
45
+    constructor(props: any) {
48
         super(props);
46
         super(props);
49
 
47
 
50
         this.state = {
48
         this.state = {
68
         this._onMouseOver = this._onMouseOver.bind(this);
66
         this._onMouseOver = this._onMouseOver.bind(this);
69
     }
67
     }
70
 
68
 
71
-    _avatarChangedListener: () => void;
72
-
73
     /**
69
     /**
74
      * Handles avatar changed api events.
70
      * Handles avatar changed api events.
75
      *
71
      *
76
      * @returns {void}
72
      * @returns {void}
77
      */
73
      */
78
-    _avatarChangedListener({ avatarURL, id }) {
74
+    _avatarChangedListener({ avatarURL, id }: { avatarURL: string; id: string; }) {
79
         if (api._getOnStageParticipant() === id
75
         if (api._getOnStageParticipant() === id
80
                 && avatarURL !== this.state.avatarURL) {
76
                 && avatarURL !== this.state.avatarURL) {
81
             this.setState({ avatarURL });
77
             this.setState({ avatarURL });
82
         }
78
         }
83
     }
79
     }
84
 
80
 
85
-    _displayNameChangedListener: () => void;
86
-
87
     /**
81
     /**
88
      * Handles display name changed api events.
82
      * Handles display name changed api events.
89
      *
83
      *
90
      * @returns {void}
84
      * @returns {void}
91
      */
85
      */
92
-    _displayNameChangedListener({ displayname, formattedDisplayName, id }) {
86
+    _displayNameChangedListener({ displayname, formattedDisplayName, id }: { displayname: string;
87
+        formattedDisplayName: string; id: string; }) {
93
         if (api._getOnStageParticipant() === id
88
         if (api._getOnStageParticipant() === id
94
                 && (formattedDisplayName !== this.state.formattedDisplayName
89
                 && (formattedDisplayName !== this.state.formattedDisplayName
95
                     || displayname !== this.state.displayName)) {
90
                     || displayname !== this.state.displayName)) {
118
             TOOLBAR_TIMEOUT);
113
             TOOLBAR_TIMEOUT);
119
     }
114
     }
120
 
115
 
121
-    _videoChangedListener: () => void;
122
-
123
     /**
116
     /**
124
      * Handles large video changed api events.
117
      * Handles large video changed api events.
125
      *
118
      *
141
         });
134
         });
142
     }
135
     }
143
 
136
 
144
-    _mouseMove: () => void;
145
-
146
     /**
137
     /**
147
      * Handles mouse move events.
138
      * Handles mouse move events.
148
      *
139
      *
152
         this.state.visible || this.setState({ visible: true });
143
         this.state.visible || this.setState({ visible: true });
153
     }
144
     }
154
 
145
 
155
-    _onMouseOut: () => void;
156
-
157
     /**
146
     /**
158
      * Toolbar mouse out handler.
147
      * Toolbar mouse out handler.
159
      *
148
      *
163
         this._hovered = false;
152
         this._hovered = false;
164
     }
153
     }
165
 
154
 
166
-    _onMouseOver: () => void;
167
-
168
     /**
155
     /**
169
      * Toolbar mouse over handler.
156
      * Toolbar mouse over handler.
170
      *
157
      *
229
 
216
 
230
         this._hideToolbarAfterTimeout();
217
         this._hideToolbarAfterTimeout();
231
         api.getCustomAvatarBackgrounds()
218
         api.getCustomAvatarBackgrounds()
232
-            .then(res =>
219
+            .then((res: { avatarBackgrounds?: string[]; }) =>
233
                 this.setState({
220
                 this.setState({
234
                     customAvatarBackgrounds: res.avatarBackgrounds || []
221
                     customAvatarBackgrounds: res.avatarBackgrounds || []
235
                 }))
222
                 }))
242
      * @inheritdoc
229
      * @inheritdoc
243
      * @returns {void}
230
      * @returns {void}
244
      */
231
      */
245
-    componentDidUpdate(prevProps: *, prevState: State) {
232
+    componentDidUpdate(_prevProps: any, prevState: IState) {
246
         if (!prevState.visible && this.state.visible) {
233
         if (!prevState.visible && this.state.visible) {
247
             this._hideToolbarAfterTimeout();
234
             this._hideToolbarAfterTimeout();
248
         }
235
         }

react/features/always-on-top/AudioMuteButton.js → react/features/always-on-top/AudioMuteButton.tsx 查看文件

1
-// @flow
2
-
3
 import React, { Component } from 'react';
1
 import React, { Component } from 'react';
4
 
2
 
5
 // We need to reference these files directly to avoid loading things that are not available
3
 // We need to reference these files directly to avoid loading things that are not available
6
 // in this environment (e.g. JitsiMeetJS or interfaceConfig)
4
 // in this environment (e.g. JitsiMeetJS or interfaceConfig)
7
 import { IconMic, IconMicSlash } from '../base/icons/svg';
5
 import { IconMic, IconMicSlash } from '../base/icons/svg';
8
-import type { Props } from '../base/toolbox/components/AbstractButton';
6
+import { IProps } from '../base/toolbox/components/AbstractButton';
9
 
7
 
10
 import ToolbarButton from './ToolbarButton';
8
 import ToolbarButton from './ToolbarButton';
11
 
9
 
14
 /**
12
 /**
15
  * The type of the React {@code Component} state of {@link AudioMuteButton}.
13
  * The type of the React {@code Component} state of {@link AudioMuteButton}.
16
  */
14
  */
17
-type State = {
15
+interface IState {
18
 
16
 
19
     /**
17
     /**
20
      * Whether audio is available is not.
18
      * Whether audio is available is not.
21
      */
19
      */
22
-    audioAvailable: boolean,
20
+    audioAvailable: boolean;
23
 
21
 
24
     /**
22
     /**
25
      * Whether audio is muted or not.
23
      * Whether audio is muted or not.
26
      */
24
      */
27
-    audioMuted: boolean
28
-};
25
+    audioMuted: boolean;
26
+}
27
+
28
+type Props = Partial<IProps>;
29
 
29
 
30
 /**
30
 /**
31
  * Stateless "mute/unmute audio" button for the Always-on-Top windows.
31
  * Stateless "mute/unmute audio" button for the Always-on-Top windows.
32
  */
32
  */
33
-export default class AudioMuteButton extends Component<Props, State> {
33
+export default class AudioMuteButton extends Component<Props, IState> {
34
     icon = IconMic;
34
     icon = IconMic;
35
     toggledIcon = IconMicSlash;
35
     toggledIcon = IconMicSlash;
36
     accessibilityLabel = 'Audio mute';
36
     accessibilityLabel = 'Audio mute';
38
     /**
38
     /**
39
      * Initializes a new {@code AudioMuteButton} instance.
39
      * Initializes a new {@code AudioMuteButton} instance.
40
      *
40
      *
41
-     * @param {Props} props - The React {@code Component} props to initialize
41
+     * @param {IProps} props - The React {@code Component} props to initialize
42
      * the new {@code AudioMuteButton} instance with.
42
      * the new {@code AudioMuteButton} instance with.
43
      */
43
      */
44
     constructor(props: Props) {
44
     constructor(props: Props) {
94
             this._audioMutedListener);
94
             this._audioMutedListener);
95
     }
95
     }
96
 
96
 
97
-    _audioAvailabilityListener: ({ available: boolean }) => void;
98
-
99
     /**
97
     /**
100
      * Handles audio available api events.
98
      * Handles audio available api events.
101
      *
99
      *
102
      * @param {{ available: boolean }} status - The new available status.
100
      * @param {{ available: boolean }} status - The new available status.
103
      * @returns {void}
101
      * @returns {void}
104
      */
102
      */
105
-    _audioAvailabilityListener({ available }) {
103
+    _audioAvailabilityListener({ available }: { available: boolean; }) {
106
         this.setState({ audioAvailable: available });
104
         this.setState({ audioAvailable: available });
107
     }
105
     }
108
 
106
 
109
-    _audioMutedListener: ({ muted: boolean }) => void;
110
-
111
     /**
107
     /**
112
      * Handles audio muted api events.
108
      * Handles audio muted api events.
113
      *
109
      *
114
      * @param {{ muted: boolean }} status - The new muted status.
110
      * @param {{ muted: boolean }} status - The new muted status.
115
      * @returns {void}
111
      * @returns {void}
116
      */
112
      */
117
-    _audioMutedListener({ muted }) {
113
+    _audioMutedListener({ muted }: { muted: boolean; }) {
118
         this.setState({ audioMuted: muted });
114
         this.setState({ audioMuted: muted });
119
     }
115
     }
120
 
116
 
144
      * Changes the muted state.
140
      * Changes the muted state.
145
      *
141
      *
146
      * @override
142
      * @override
147
-     * @param {boolean} audioMuted - Whether audio should be muted or not.
143
+     * @param {boolean} _audioMuted - Whether audio should be muted or not.
148
      * @protected
144
      * @protected
149
      * @returns {void}
145
      * @returns {void}
150
      */
146
      */
151
-    _setAudioMuted(audioMuted: boolean) { // eslint-disable-line no-unused-vars
147
+    _setAudioMuted(_audioMuted: boolean) {
152
         this.state.audioAvailable && api.executeCommand('toggleAudio');
148
         this.state.audioAvailable && api.executeCommand('toggleAudio');
153
     }
149
     }
154
 
150
 
155
-    _onClick: () => {};
156
-
157
     /**
151
     /**
158
      * Handles clicking / pressing the button, and toggles the audio mute state
152
      * Handles clicking / pressing the button, and toggles the audio mute state
159
      * accordingly.
153
      * accordingly.

react/features/always-on-top/HangupButton.js → react/features/always-on-top/HangupButton.tsx 查看文件

1
-// @flow
2
 import React, { Component } from 'react';
1
 import React, { Component } from 'react';
3
 
2
 
4
 // We need to reference these files directly to avoid loading things that are not available
3
 // We need to reference these files directly to avoid loading things that are not available
5
 // in this environment (e.g. JitsiMeetJS or interfaceConfig)
4
 // in this environment (e.g. JitsiMeetJS or interfaceConfig)
6
 import { IconHangup } from '../base/icons/svg';
5
 import { IconHangup } from '../base/icons/svg';
7
-import type { Props } from '../base/toolbox/components/AbstractButton';
6
+import { IProps } from '../base/toolbox/components/AbstractButton';
8
 
7
 
9
 import ToolbarButton from './ToolbarButton';
8
 import ToolbarButton from './ToolbarButton';
10
 
9
 
11
 const { api } = window.alwaysOnTop;
10
 const { api } = window.alwaysOnTop;
12
 
11
 
12
+type Props = Partial<IProps>;
13
+
13
 /**
14
 /**
14
  * Stateless hangup button for the Always-on-Top windows.
15
  * Stateless hangup button for the Always-on-Top windows.
15
  */
16
  */
16
-export default class HangupButton extends Component<Props, *> {
17
+export default class HangupButton extends Component<Props> {
17
 
18
 
18
     accessibilityLabel = 'Hangup';
19
     accessibilityLabel = 'Hangup';
19
     icon = IconHangup;
20
     icon = IconHangup;
21
     /**
22
     /**
22
      * Initializes a new {@code HangupButton} instance.
23
      * Initializes a new {@code HangupButton} instance.
23
      *
24
      *
24
-     * @param {Props} props - The React {@code Component} props to initialize
25
+     * @param {IProps} props - The React {@code Component} props to initialize
25
      * the new {@code HangupButton} instance with.
26
      * the new {@code HangupButton} instance with.
26
      */
27
      */
27
     constructor(props: Props) {
28
     constructor(props: Props) {
31
         this._onClick = this._onClick.bind(this);
32
         this._onClick = this._onClick.bind(this);
32
     }
33
     }
33
 
34
 
34
-    _onClick: () => {};
35
-
36
     /**
35
     /**
37
      * Handles clicking / pressing the button, and disconnects the conference.
36
      * Handles clicking / pressing the button, and disconnects the conference.
38
      *
37
      *

react/features/always-on-top/Toolbar.js → react/features/always-on-top/Toolbar.tsx 查看文件

1
-// @flow
2
-
3
 import React, { Component } from 'react';
1
 import React, { Component } from 'react';
4
 
2
 
5
 import AudioMuteButton from './AudioMuteButton';
3
 import AudioMuteButton from './AudioMuteButton';
9
 /**
7
 /**
10
  * The type of the React {@code Component} props of {@link Toolbar}.
8
  * The type of the React {@code Component} props of {@link Toolbar}.
11
  */
9
  */
12
-type Props = {
10
+interface IProps {
13
 
11
 
14
     /**
12
     /**
15
      * Additional CSS class names to add to the root of the toolbar.
13
      * Additional CSS class names to add to the root of the toolbar.
16
      */
14
      */
17
-    className: string,
15
+    className: string;
18
 
16
 
19
     /**
17
     /**
20
      * Callback invoked when no longer moused over the toolbar.
18
      * Callback invoked when no longer moused over the toolbar.
21
      */
19
      */
22
-    onMouseOut: Function,
20
+    onMouseOut: (e?: React.MouseEvent) => void;
23
 
21
 
24
     /**
22
     /**
25
      * Callback invoked when the mouse has moved over the toolbar.
23
      * Callback invoked when the mouse has moved over the toolbar.
26
      */
24
      */
27
-    onMouseOver: Function
28
-};
25
+    onMouseOver: (e?: React.MouseEvent) => void;
26
+}
29
 
27
 
30
 /**
28
 /**
31
  * Represents the toolbar in the Always On Top window.
29
  * Represents the toolbar in the Always On Top window.
32
  *
30
  *
33
  * @augments Component
31
  * @augments Component
34
  */
32
  */
35
-export default class Toolbar extends Component<Props> {
33
+export default class Toolbar extends Component<IProps> {
36
     /**
34
     /**
37
      * Implements React's {@link Component#render()}.
35
      * Implements React's {@link Component#render()}.
38
      *
36
      *

react/features/always-on-top/ToolbarButton.js → react/features/always-on-top/ToolbarButton.tsx 查看文件

2
 
2
 
3
 import Icon from '../base/icons/components/Icon';
3
 import Icon from '../base/icons/components/Icon';
4
 
4
 
5
-type Props = {
5
+interface IProps {
6
 
6
 
7
     /**
7
     /**
8
      * Accessibility label for button.
8
      * Accessibility label for button.
9
      */
9
      */
10
-    accessibilityLabel: string,
10
+    accessibilityLabel: string;
11
 
11
 
12
     /**
12
     /**
13
      * An extra class name to be added at the end of the element's class name
13
      * An extra class name to be added at the end of the element's class name
14
      * in order to enable custom styling.
14
      * in order to enable custom styling.
15
      */
15
      */
16
-    customClass?: string,
16
+    customClass?: string;
17
 
17
 
18
     /**
18
     /**
19
      * Whether or not the button is disabled.
19
      * Whether or not the button is disabled.
20
      */
20
      */
21
-    disabled?: boolean,
21
+    disabled?: boolean;
22
 
22
 
23
     /**
23
     /**
24
-     * Click handler.
24
+     * Button icon.
25
      */
25
      */
26
-    onClick: Function,
26
+    icon: Function;
27
 
27
 
28
     /**
28
     /**
29
-     * Button icon.
29
+     * Click handler.
30
      */
30
      */
31
-    icon: Object,
31
+    onClick: (e?: React.MouseEvent) => void;
32
 
32
 
33
     /**
33
     /**
34
      * Whether or not the button is toggled.
34
      * Whether or not the button is toggled.
35
      */
35
      */
36
-    toggled?: boolean
36
+    toggled?: boolean;
37
 }
37
 }
38
 
38
 
39
 const ToolbarButton = ({
39
 const ToolbarButton = ({
43
     onClick,
43
     onClick,
44
     icon,
44
     icon,
45
     toggled = false
45
     toggled = false
46
-}: Props) => {
46
+}: IProps) => {
47
     const onKeyPress = useCallback(event => {
47
     const onKeyPress = useCallback(event => {
48
         if (event.key === 'Enter' || event.key === ' ') {
48
         if (event.key === 'Enter' || event.key === ' ') {
49
             event.preventDefault();
49
             event.preventDefault();

react/features/always-on-top/VideoMuteButton.js → react/features/always-on-top/VideoMuteButton.tsx 查看文件

1
-// @flow
2
 import React, { Component } from 'react';
1
 import React, { Component } from 'react';
3
 
2
 
4
 // We need to reference these files directly to avoid loading things that are not available
3
 // We need to reference these files directly to avoid loading things that are not available
5
 // in this environment (e.g. JitsiMeetJS or interfaceConfig)
4
 // in this environment (e.g. JitsiMeetJS or interfaceConfig)
6
 import { IconVideo, IconVideoOff } from '../base/icons/svg';
5
 import { IconVideo, IconVideoOff } from '../base/icons/svg';
7
-import type { Props } from '../base/toolbox/components/AbstractButton';
6
+import { IProps } from '../base/toolbox/components/AbstractButton';
8
 
7
 
9
 import ToolbarButton from './ToolbarButton';
8
 import ToolbarButton from './ToolbarButton';
10
 
9
 
11
 const { api } = window.alwaysOnTop;
10
 const { api } = window.alwaysOnTop;
12
 
11
 
12
+type Props = Partial<IProps>;
13
+
13
 /**
14
 /**
14
  * The type of the React {@code Component} state of {@link VideoMuteButton}.
15
  * The type of the React {@code Component} state of {@link VideoMuteButton}.
15
  */
16
  */
18
     /**
19
     /**
19
      * Whether video is available is not.
20
      * Whether video is available is not.
20
      */
21
      */
21
-    videoAvailable: boolean,
22
+    videoAvailable: boolean;
22
 
23
 
23
     /**
24
     /**
24
      * Whether video is muted or not.
25
      * Whether video is muted or not.
25
      */
26
      */
26
-    videoMuted: boolean
27
+    videoMuted: boolean;
27
 };
28
 };
28
 
29
 
29
 /**
30
 /**
119
      * Changes the muted state.
120
      * Changes the muted state.
120
      *
121
      *
121
      * @override
122
      * @override
122
-     * @param {boolean} videoMuted - Whether video should be muted or not.
123
+     * @param {boolean} _videoMuted - Whether video should be muted or not.
123
      * @protected
124
      * @protected
124
      * @returns {void}
125
      * @returns {void}
125
      */
126
      */
126
-    _setVideoMuted(videoMuted: boolean) { // eslint-disable-line no-unused-vars
127
+    _setVideoMuted(_videoMuted: boolean) {
127
         this.state.videoAvailable && api.executeCommand('toggleVideo', false, true);
128
         this.state.videoAvailable && api.executeCommand('toggleVideo', false, true);
128
     }
129
     }
129
 
130
 
130
-    _videoAvailabilityListener: ({ available: boolean }) => void;
131
-
132
     /**
131
     /**
133
      * Handles video available api events.
132
      * Handles video available api events.
134
      *
133
      *
135
      * @param {{ available: boolean }} status - The new available status.
134
      * @param {{ available: boolean }} status - The new available status.
136
      * @returns {void}
135
      * @returns {void}
137
      */
136
      */
138
-    _videoAvailabilityListener({ available }) {
137
+    _videoAvailabilityListener({ available }: { available: boolean; }) {
139
         this.setState({ videoAvailable: available });
138
         this.setState({ videoAvailable: available });
140
     }
139
     }
141
 
140
 
142
-    _videoMutedListener: ({ muted: boolean }) => void;
143
-
144
     /**
141
     /**
145
      * Handles video muted api events.
142
      * Handles video muted api events.
146
      *
143
      *
147
      * @param {{ muted: boolean }} status - The new muted status.
144
      * @param {{ muted: boolean }} status - The new muted status.
148
      * @returns {void}
145
      * @returns {void}
149
      */
146
      */
150
-    _videoMutedListener({ muted }) {
147
+    _videoMutedListener({ muted }: { muted: boolean; }) {
151
         this.setState({ videoMuted: muted });
148
         this.setState({ videoMuted: muted });
152
     }
149
     }
153
 
150
 
154
-    _onClick: () => {};
155
-
156
     /**
151
     /**
157
      * Handles clicking / pressing the button, and toggles the video mute state
152
      * Handles clicking / pressing the button, and toggles the video mute state
158
      * accordingly.
153
      * accordingly.

react/features/always-on-top/index.js → react/features/always-on-top/index.tsx 查看文件

1
-// @flow
2
-
3
 import React from 'react';
1
 import React from 'react';
4
 import ReactDOM from 'react-dom';
2
 import ReactDOM from 'react-dom';
5
 
3
 
6
 import AlwaysOnTop from './AlwaysOnTop';
4
 import AlwaysOnTop from './AlwaysOnTop';
7
 
5
 
8
 // Render the main/root Component.
6
 // Render the main/root Component.
9
-// $FlowExpectedError
10
 ReactDOM.render(<AlwaysOnTop />, document.getElementById('react'));
7
 ReactDOM.render(<AlwaysOnTop />, document.getElementById('react'));
11
 
8
 
12
 window.addEventListener(
9
 window.addEventListener(
13
     'beforeunload',
10
     'beforeunload',
14
-    () => ReactDOM.unmountComponentAtNode(document.getElementById('react')));
11
+    () => ReactDOM.unmountComponentAtNode(document.getElementById('react') ?? document.body));

+ 1
- 0
tsconfig.native.json 查看文件

16
     },
16
     },
17
     "exclude": [
17
     "exclude": [
18
         "node_modules",
18
         "node_modules",
19
+        "react/features/always-on-top",
19
         "react/features/analytics/handlers/GoogleAnalyticsHandler.ts",
20
         "react/features/analytics/handlers/GoogleAnalyticsHandler.ts",
20
         "react/features/base/components/participants-pane-list",
21
         "react/features/base/components/participants-pane-list",
21
         "react/features/base/tooltip",
22
         "react/features/base/tooltip",

+ 1
- 1
webpack.config.js 查看文件

299
         }),
299
         }),
300
         Object.assign({}, config, {
300
         Object.assign({}, config, {
301
             entry: {
301
             entry: {
302
-                'alwaysontop': './react/features/always-on-top/index.js'
302
+                'alwaysontop': './react/features/always-on-top/index.tsx'
303
             },
303
             },
304
             plugins: [
304
             plugins: [
305
                 ...config.plugins,
305
                 ...config.plugins,

正在加载...
取消
保存