Переглянути джерело

fix(subtitles): Styles.

 - Move the styles from css to tss-react ones
 - Dynamic fontSize based on the visible area of the page
 - Remove the gaps in the background when a line is wrapped.
 - Change the text color to white.
 - Remove transparency.
factor2
Hristo Terezov 1 рік тому
джерело
коміт
2d56dbe249

+ 0
- 26
css/_transcription-subtitles.scss Переглянути файл

@@ -1,26 +0,0 @@
1
-.transcription-subtitles {
2
-    bottom: $newToolbarSize + 40px;
3
-    font-size: 16px;
4
-    font-weight: 1000;
5
-    left: 50%;
6
-    max-width: 50vw;
7
-    opacity: 0.80;
8
-    overflow-wrap: break-word;
9
-    pointer-events: none;
10
-    position: absolute;
11
-    text-shadow: 0px 0px 1px rgba(0,0,0,0.3),
12
-    0px 1px 1px rgba(0,0,0,0.3),
13
-    1px 0px 1px rgba(0,0,0,0.3),
14
-    0px 0px 1px rgba(0,0,0,0.3);
15
-    transform: translateX(-50%);
16
-    z-index: 7;
17
-
18
-    &.lifted {
19
-        // Lift subtitle above toolbar+dominant speaker box.
20
-        bottom: $newToolbarSize + 36px + 40px;
21
-    }
22
-
23
-    span {
24
-        background: black;
25
-    }
26
-}

+ 0
- 1
css/main.scss Переглянути файл

@@ -61,7 +61,6 @@ $flagsImagePath: "../images/";
61 61
 @import 'filmstrip/vertical_filmstrip_overrides';
62 62
 @import 'unsupported-browser/main';
63 63
 @import 'deep-linking/main';
64
-@import 'transcription-subtitles';
65 64
 @import '_meetings_list.scss';
66 65
 @import 'navigate_section_list';
67 66
 @import 'third-party-branding/google';

+ 12
- 1
react/features/base/ui/functions.web.ts Переглянути файл

@@ -1,5 +1,5 @@
1 1
 /* eslint-disable @typescript-eslint/naming-convention */
2
-import { adaptV4Theme, createTheme } from '@mui/material/styles';
2
+import { Theme, adaptV4Theme, createTheme } from '@mui/material/styles';
3 3
 
4 4
 import { ITypography, IPalette as Palette1 } from '../ui/types';
5 5
 
@@ -107,3 +107,14 @@ export function operatesWithEnterKey(element: Element): boolean {
107 107
 
108 108
     return false;
109 109
 }
110
+
111
+/**
112
+ * Returns a common spacing from the bottom of the page for floating elements over the video space.
113
+ *
114
+ * @param {Theme} theme - The current theme.
115
+ * @param {boolean} isToolbarVisible - Whether the toolbar is visible or not.
116
+ * @returns {number}
117
+ */
118
+export function getVideospaceFloatingElementsBottomSpacing(theme: Theme, isToolbarVisible: boolean) {
119
+    return parseInt(isToolbarVisible ? theme.spacing(12) : theme.spacing(6), 10);
120
+}

+ 3
- 1
react/features/display-name/components/web/DisplayNameBadge.tsx Переглянути файл

@@ -1,6 +1,8 @@
1 1
 import React from 'react';
2 2
 import { makeStyles } from 'tss-react/mui';
3 3
 
4
+import { DISPLAY_NAME_VERTICAL_PADDING } from './styles';
5
+
4 6
 const useStyles = makeStyles()(theme => {
5 7
     const { text01 } = theme.palette;
6 8
 
@@ -11,7 +13,7 @@ const useStyles = makeStyles()(theme => {
11 13
             color: text01,
12 14
             maxWidth: '50%',
13 15
             overflow: 'hidden',
14
-            padding: '2px 16px',
16
+            padding: `${DISPLAY_NAME_VERTICAL_PADDING / 2}px 16px`,
15 17
             textOverflow: 'ellipsis',
16 18
             whiteSpace: 'nowrap'
17 19
         }

+ 5
- 3
react/features/display-name/components/web/StageParticipantNameLabel.tsx Переглянути файл

@@ -10,20 +10,22 @@ import {
10 10
     isWhiteboardParticipant
11 11
 } from '../../../base/participants/functions';
12 12
 import { withPixelLineHeight } from '../../../base/styles/functions.web';
13
+import { getVideospaceFloatingElementsBottomSpacing } from '../../../base/ui/functions.web';
13 14
 import { getLargeVideoParticipant } from '../../../large-video/functions';
14 15
 import { isToolboxVisible } from '../../../toolbox/functions.web';
15 16
 import { isLayoutTileView } from '../../../video-layout/functions.web';
16 17
 
17 18
 import DisplayNameBadge from './DisplayNameBadge';
19
+import { getStageParticipantTypography } from './styles';
18 20
 
19 21
 const useStyles = makeStyles()(theme => {
20 22
     return {
21 23
         badgeContainer: {
22
-            ...withPixelLineHeight(theme.typography.bodyShortRegularLarge),
24
+            ...withPixelLineHeight(getStageParticipantTypography(theme)),
23 25
             alignItems: 'center',
24 26
             display: 'inline-flex',
25 27
             justifyContent: 'center',
26
-            marginBottom: theme.spacing(7),
28
+            marginBottom: getVideospaceFloatingElementsBottomSpacing(theme, false),
27 29
             transition: 'margin-bottom 0.3s',
28 30
             pointerEvents: 'none',
29 31
             position: 'absolute',
@@ -33,7 +35,7 @@ const useStyles = makeStyles()(theme => {
33 35
             zIndex: 1
34 36
         },
35 37
         containerElevated: {
36
-            marginBottom: theme.spacing(12)
38
+            marginBottom: getVideospaceFloatingElementsBottomSpacing(theme, true)
37 39
         }
38 40
     };
39 41
 });

+ 26
- 0
react/features/display-name/components/web/styles.ts Переглянути файл

@@ -0,0 +1,26 @@
1
+import { Theme } from '@mui/material';
2
+
3
+/**
4
+ * The vertical padding for the display name.
5
+ */
6
+export const DISPLAY_NAME_VERTICAL_PADDING = 4;
7
+
8
+/**
9
+ * Returns the typography for stage participant display name badge.
10
+ *
11
+ * @param {Theme} theme - The current theme.
12
+ * @returns {ITypographyType}
13
+ */
14
+export function getStageParticipantTypography(theme: Theme) {
15
+    return theme.typography.bodyShortRegularLarge;
16
+}
17
+
18
+/**
19
+ * Returns the height + padding for stage participant display name badge.
20
+ *
21
+ * @param {Theme} theme - The current theme.
22
+ * @returns {number}
23
+ */
24
+export function getStageParticipantNameLabelHeight(theme: Theme) {
25
+    return getStageParticipantTypography(theme).lineHeight ?? 0 + DISPLAY_NAME_VERTICAL_PADDING;
26
+}

+ 67
- 7
react/features/subtitles/components/web/Captions.tsx Переглянути файл

@@ -1,25 +1,85 @@
1
+import { Theme } from '@mui/material';
1 2
 import React, { ReactElement } from 'react';
2 3
 import { connect } from 'react-redux';
4
+import { withStyles } from 'tss-react/mui';
3 5
 
4 6
 import { IReduxState } from '../../../app/types';
5 7
 import { getLocalParticipant } from '../../../base/participants/functions';
8
+import { getVideospaceFloatingElementsBottomSpacing } from '../../../base/ui/functions.web';
9
+import { getStageParticipantNameLabelHeight } from '../../../display-name/components/web/styles';
6 10
 import { getLargeVideoParticipant } from '../../../large-video/functions';
7 11
 import { isLayoutTileView } from '../../../video-layout/functions.web';
12
+import { calculateSubtitlesFontSize } from '../../functions.web';
8 13
 import {
9 14
     AbstractCaptions,
10 15
     type IAbstractCaptionsProps,
11 16
     _abstractMapStateToProps
12 17
 } from '../AbstractCaptions';
13 18
 
14
-
15 19
 interface IProps extends IAbstractCaptionsProps {
16 20
 
21
+    /**
22
+     * The height of the visible area.
23
+     */
24
+    _clientHeight?: number;
25
+
17 26
     /**
18 27
      * Whether the subtitles container is lifted above the invite box.
19 28
      */
20 29
     _isLifted: boolean | undefined;
30
+
31
+    /**
32
+     * An object containing the CSS classes.
33
+     */
34
+    classes?: Partial<Record<keyof ReturnType<typeof styles>, string>>;
21 35
 }
22 36
 
37
+
38
+const styles = (theme: Theme, props: IProps) => {
39
+    const { _isLifted = false, _clientHeight } = props;
40
+    const fontSize = calculateSubtitlesFontSize(_clientHeight);
41
+    const padding = Math.ceil(0.2 * fontSize);
42
+
43
+    // Currently the subtitles position are not affected by the toolbar visibility.
44
+    let bottom = getVideospaceFloatingElementsBottomSpacing(theme, true);
45
+
46
+    // This is the case where we display the onstage participant display name
47
+    // below the subtitles.
48
+    if (_isLifted) {
49
+        // 10px is the space between the onstage participant display name label and subtitles. We also need
50
+        // to add the padding of the subtitles because it will decrease the gap between the label and subtitles.
51
+        bottom += getStageParticipantNameLabelHeight(theme) + 10 + padding;
52
+    }
53
+
54
+    return {
55
+        transcriptionSubtitles: {
56
+            bottom,
57
+            fontSize: `${fontSize}px`,
58
+            left: '50%',
59
+            maxWidth: '50vw',
60
+            overflowWrap: 'break-word' as const,
61
+            pointerEvents: 'none' as const,
62
+            position: 'absolute' as const,
63
+            textShadow: `
64
+                0px 0px 1px rgba(0,0,0,0.3),
65
+                0px 1px 1px rgba(0,0,0,0.3),
66
+                1px 0px 1px rgba(0,0,0,0.3),
67
+                0px 0px 1px rgba(0,0,0,0.3)`,
68
+            transform: 'translateX(-50%)',
69
+            zIndex: 7, // The popups are with z-index 8. This z-index has to be lower.
70
+            lineHeight: 1.2,
71
+
72
+            span: {
73
+                color: '#fff',
74
+                background: 'black',
75
+
76
+                // without this when the text is wrapped on 2+ lines there will be a gap in the background:
77
+                padding: `${padding}px 0px`
78
+            }
79
+        }
80
+    };
81
+};
82
+
23 83
 /**
24 84
  * React {@code Component} which can display speech-to-text results from
25 85
  * Jigasi as subtitles.
@@ -53,12 +113,10 @@ class Captions extends AbstractCaptions<IProps> {
53 113
      * @returns {ReactElement} - The subtitles container.
54 114
      */
55 115
     _renderSubtitlesContainer(paragraphs: Array<ReactElement>): ReactElement {
56
-        const className = this.props._isLifted
57
-            ? 'transcription-subtitles lifted'
58
-            : 'transcription-subtitles';
116
+        const classes = withStyles.getClasses(this.props);
59 117
 
60 118
         return (
61
-            <div className = { className } >
119
+            <div className = { classes.transcriptionSubtitles } >
62 120
                 { paragraphs }
63 121
             </div>
64 122
         );
@@ -77,11 +135,13 @@ function mapStateToProps(state: IReduxState) {
77 135
     const isTileView = isLayoutTileView(state);
78 136
     const largeVideoParticipant = getLargeVideoParticipant(state);
79 137
     const localParticipant = getLocalParticipant(state);
138
+    const { clientHeight } = state['features/base/responsive-ui'];
80 139
 
81 140
     return {
82 141
         ..._abstractMapStateToProps(state),
83
-        _isLifted: Boolean(largeVideoParticipant && largeVideoParticipant?.id !== localParticipant?.id && !isTileView)
142
+        _isLifted: Boolean(largeVideoParticipant && largeVideoParticipant?.id !== localParticipant?.id && !isTileView),
143
+        _clientHeight: clientHeight
84 144
     };
85 145
 }
86 146
 
87
-export default connect(mapStateToProps)(Captions);
147
+export default connect(mapStateToProps)(withStyles(Captions, styles));

+ 4
- 0
react/features/subtitles/constants.ts Переглянути файл

@@ -0,0 +1,4 @@
1
+/**
2
+ * The minimum font size for subtitles.
3
+ */
4
+export const MIN_SUBTITLES_FONT_SIZE = 16;

+ 16
- 0
react/features/subtitles/functions.web.ts Переглянути файл

@@ -1,5 +1,7 @@
1 1
 /* eslint-disable max-params, max-len */
2 2
 
3
+import { MIN_SUBTITLES_FONT_SIZE } from './constants';
4
+
3 5
 /**
4 6
  * Logs when about the received transcription chunk.
5 7
  *
@@ -17,3 +19,17 @@ export const notifyTranscriptionChunkReceived = (transcriptMessageID: string, la
17 19
         participant,
18 20
         ...text
19 21
     });
22
+
23
+/**
24
+ * Calculates the font size for the subtitles.
25
+ *
26
+ * @param {number} clientHeight - The height of the visible area of the window.
27
+ * @returns {number}
28
+ */
29
+export function calculateSubtitlesFontSize(clientHeight?: number) {
30
+    if (typeof clientHeight === 'undefined') {
31
+        return MIN_SUBTITLES_FONT_SIZE;
32
+    }
33
+
34
+    return Math.max(Math.floor(clientHeight * 0.04), MIN_SUBTITLES_FONT_SIZE);
35
+}

+ 0
- 1
react/features/toolbox/constants.ts Переглянути файл

@@ -84,7 +84,6 @@ export const ZINDEX_DIALOG_PORTAL = 302;
84 84
  */
85 85
 export const SPINNER_COLOR = '#929292';
86 86
 
87
-
88 87
 /**
89 88
  * The list of all possible UI buttons.
90 89
  *

Завантаження…
Відмінити
Зберегти