瀏覽代碼

feat(background alpha) Set background transparency

master
hmuresan 4 年之前
父節點
當前提交
f7c0d4f1fe

+ 3
- 0
config.js 查看文件

677
     */
677
     */
678
     // dynamicBrandingUrl: '',
678
     // dynamicBrandingUrl: '',
679
 
679
 
680
+    // Sets the background transparency level. '0' is fully transparent, '1' is opaque.
681
+    // backgroundAlpha: 1,
682
+
680
     // The URL of the moderated rooms microservice, if available. If it
683
     // The URL of the moderated rooms microservice, if available. If it
681
     // is present, a link to the service will be rendered on the welcome page,
684
     // is present, a link to the service will be rendered on the welcome page,
682
     // otherwise the app doesn't render it.
685
     // otherwise the app doesn't render it.

+ 8
- 0
modules/UI/UI.js 查看文件

7
 import Logger from 'jitsi-meet-logger';
7
 import Logger from 'jitsi-meet-logger';
8
 
8
 
9
 import { isMobileBrowser } from '../../react/features/base/environment/utils';
9
 import { isMobileBrowser } from '../../react/features/base/environment/utils';
10
+import { setColorAlpha } from '../../react/features/base/util';
10
 import { toggleChat } from '../../react/features/chat';
11
 import { toggleChat } from '../../react/features/chat';
11
 import { setDocumentUrl } from '../../react/features/etherpad';
12
 import { setDocumentUrl } from '../../react/features/etherpad';
12
 import { setFilmstripVisible } from '../../react/features/filmstrip';
13
 import { setFilmstripVisible } from '../../react/features/filmstrip';
129
         $('body').addClass('mobile-browser');
130
         $('body').addClass('mobile-browser');
130
     } else {
131
     } else {
131
         $('body').addClass('desktop-browser');
132
         $('body').addClass('desktop-browser');
133
+
134
+        if (config.backgroundAlpha !== undefined) {
135
+            const backgroundColor = $('body').css('background-color');
136
+            const alphaColor = setColorAlpha(backgroundColor, config.backgroundAlpha);
137
+
138
+            $('body').css('background-color', alphaColor);
139
+        }
132
     }
140
     }
133
 
141
 
134
     if (config.iAmRecorder) {
142
     if (config.iAmRecorder) {

+ 1
- 0
react/features/base/config/configWhitelist.js 查看文件

17
     'audioLevelsInterval',
17
     'audioLevelsInterval',
18
     'apiLogLevels',
18
     'apiLogLevels',
19
     'avgRtpStatsN',
19
     'avgRtpStatsN',
20
+    'backgroundAlpha',
20
 
21
 
21
     /**
22
     /**
22
      * The display name of the CallKit call representing the conference/meeting
23
      * The display name of the CallKit call representing the conference/meeting

+ 59
- 0
react/features/base/util/helpers.js 查看文件

126
     console.error(msg, e);
126
     console.error(msg, e);
127
     window.onerror && window.onerror(msg, null, null, null, e);
127
     window.onerror && window.onerror(msg, null, null, null, e);
128
 }
128
 }
129
+
130
+/**
131
+ * Adds alpha to a color css string.
132
+ *
133
+ * @param {string} color - The color string either in rgb... Or #... Format.
134
+ * @param {number} opacity -The opacity(alpha) to apply to the color. Can take a value between 0 and 1, including.
135
+ * @returns {string} - The color with applied alpha.
136
+ */
137
+export function setColorAlpha(color: string, opacity: number) {
138
+    if (!color) {
139
+        return `rgba(0, 0, 0, ${opacity})`;
140
+    }
141
+
142
+    let b, g, r;
143
+
144
+    try {
145
+        if (color.startsWith('rgb')) {
146
+            [ r, g, b ] = color.split('(')[1].split(')')[0].split(',').map(c => c.trim());
147
+        } else if (color.startsWith('#')) {
148
+            if (color.length === 4) {
149
+                [ r, g, b ] = parseShorthandColor(color);
150
+            } else {
151
+                r = parseInt(color.substring(1, 3), 16);
152
+                g = parseInt(color.substring(3, 5), 16);
153
+                b = parseInt(color.substring(5, 7), 16);
154
+            }
155
+        } else {
156
+            return color;
157
+        }
158
+
159
+        return `rgba(${r}, ${g}, ${b}, ${opacity})`;
160
+    } catch {
161
+        return color;
162
+    }
163
+}
164
+
165
+/**
166
+ * Gets the hexa rgb values for a shorthand css color.
167
+ *
168
+ * @param {string} color -
169
+ * @returns {Array<number>} - Array containing parsed r, g, b values of the color.
170
+ */
171
+function parseShorthandColor(color) {
172
+    let b, g, r;
173
+
174
+    r = color.substring(1, 2);
175
+    r += r;
176
+    r = parseInt(r, 16);
177
+
178
+    g = color.substring(2, 3);
179
+    g += g;
180
+    g = parseInt(g, 16);
181
+
182
+    b = color.substring(3, 4);
183
+    b += b;
184
+    b = parseInt(b, 16);
185
+
186
+    return [ r, g, b ];
187
+}

+ 40
- 1
react/features/conference/components/web/Conference.js 查看文件

8
 import { connect, disconnect } from '../../../base/connection';
8
 import { connect, disconnect } from '../../../base/connection';
9
 import { translate } from '../../../base/i18n';
9
 import { translate } from '../../../base/i18n';
10
 import { connect as reactReduxConnect } from '../../../base/redux';
10
 import { connect as reactReduxConnect } from '../../../base/redux';
11
+import { setColorAlpha } from '../../../base/util';
11
 import { Chat } from '../../../chat';
12
 import { Chat } from '../../../chat';
12
 import { Filmstrip } from '../../../filmstrip';
13
 import { Filmstrip } from '../../../filmstrip';
13
 import { CalleeInfoContainer } from '../../../invite';
14
 import { CalleeInfoContainer } from '../../../invite';
61
  */
62
  */
62
 type Props = AbstractProps & {
63
 type Props = AbstractProps & {
63
 
64
 
65
+    /**
66
+     * The alpha(opacity) of the background
67
+     */
68
+    _backgroundAlpha: number,
69
+
64
     /**
70
     /**
65
      * Whether the local participant is recording the conference.
71
      * Whether the local participant is recording the conference.
66
      */
72
      */
98
     _onFullScreenChange: Function;
104
     _onFullScreenChange: Function;
99
     _onShowToolbar: Function;
105
     _onShowToolbar: Function;
100
     _originalOnShowToolbar: Function;
106
     _originalOnShowToolbar: Function;
107
+    _setBackground: Function;
101
 
108
 
102
     /**
109
     /**
103
      * Initializes a new Conference instance.
110
      * Initializes a new Conference instance.
121
 
128
 
122
         // Bind event handler so it is only bound once for every instance.
129
         // Bind event handler so it is only bound once for every instance.
123
         this._onFullScreenChange = this._onFullScreenChange.bind(this);
130
         this._onFullScreenChange = this._onFullScreenChange.bind(this);
131
+        this._setBackground = this._setBackground.bind(this);
124
     }
132
     }
125
 
133
 
126
     /**
134
     /**
186
             <div
194
             <div
187
                 className = { _layoutClassName }
195
                 className = { _layoutClassName }
188
                 id = 'videoconference_page'
196
                 id = 'videoconference_page'
189
-                onMouseMove = { this._onShowToolbar }>
197
+                onMouseMove = { this._onShowToolbar }
198
+                ref = { this._setBackground }>
190
 
199
 
191
                 <Notice />
200
                 <Notice />
192
                 <div id = 'videospace'>
201
                 <div id = 'videospace'>
208
         );
217
         );
209
     }
218
     }
210
 
219
 
220
+    /**
221
+     * Sets custom background opacity based on config. It also applies the
222
+     * opacity on parent element, as the parent element is not accessible directly,
223
+     * only though it's child.
224
+     *
225
+     * @param {Object} element - The DOM element for which to apply opacity.
226
+     *
227
+     * @private
228
+     * @returns {void}
229
+     */
230
+    _setBackground(element) {
231
+        if (!element) {
232
+            return;
233
+        }
234
+
235
+        if (this.props._backgroundAlpha !== undefined) {
236
+            const elemColor = element.style.background;
237
+            const alphaElemColor = setColorAlpha(elemColor, this.props._backgroundAlpha);
238
+
239
+            element.style.background = alphaElemColor;
240
+            if (element.parentElement) {
241
+                const parentColor = element.parentElement.style.background;
242
+                const alphaParentColor = setColorAlpha(parentColor, this.props._backgroundAlpha);
243
+
244
+                element.parentElement.style.background = alphaParentColor;
245
+            }
246
+        }
247
+    }
248
+
211
     /**
249
     /**
212
      * Updates the Redux state when full screen mode has been enabled or
250
      * Updates the Redux state when full screen mode has been enabled or
213
      * disabled.
251
      * disabled.
265
     return {
303
     return {
266
         ...abstractMapStateToProps(state),
304
         ...abstractMapStateToProps(state),
267
         _iAmRecorder: state['features/base/config'].iAmRecorder,
305
         _iAmRecorder: state['features/base/config'].iAmRecorder,
306
+        _backgroundAlpha: state['features/base/config'].backgroundAlpha,
268
         _isLobbyScreenVisible: state['features/base/dialog']?.component === LobbyScreen,
307
         _isLobbyScreenVisible: state['features/base/dialog']?.component === LobbyScreen,
269
         _layoutClassName: LAYOUT_CLASSNAMES[getCurrentLayout(state)],
308
         _layoutClassName: LAYOUT_CLASSNAMES[getCurrentLayout(state)],
270
         _roomName: getConferenceNameForTitle(state),
309
         _roomName: getConferenceNameForTitle(state),

+ 13
- 0
react/features/large-video/components/LargeVideo.web.js 查看文件

4
 
4
 
5
 import { Watermarks } from '../../base/react';
5
 import { Watermarks } from '../../base/react';
6
 import { connect } from '../../base/redux';
6
 import { connect } from '../../base/redux';
7
+import { setColorAlpha } from '../../base/util';
7
 import { Subject } from '../../conference';
8
 import { Subject } from '../../conference';
8
 import { fetchCustomBrandingData } from '../../dynamic-branding';
9
 import { fetchCustomBrandingData } from '../../dynamic-branding';
9
 import { Captions } from '../../subtitles/';
10
 import { Captions } from '../../subtitles/';
12
 
13
 
13
 type Props = {
14
 type Props = {
14
 
15
 
16
+    /**
17
+     * The alpha(opacity) of the background
18
+     */
19
+    _backgroundAlpha: number,
20
+
15
     /**
21
     /**
16
      * The user selected background color.
22
      * The user selected background color.
17
      */
23
      */
121
 
127
 
122
         styles.backgroundColor = _customBackgroundColor || interfaceConfig.DEFAULT_BACKGROUND;
128
         styles.backgroundColor = _customBackgroundColor || interfaceConfig.DEFAULT_BACKGROUND;
123
 
129
 
130
+        if (this.props._backgroundAlpha !== undefined) {
131
+            const alphaColor = setColorAlpha(styles.backgroundColor, this.props._backgroundAlpha);
132
+
133
+            styles.backgroundColor = alphaColor;
134
+        }
135
+
124
         if (_customBackgroundImageUrl) {
136
         if (_customBackgroundImageUrl) {
125
             styles.backgroundImage = `url(${_customBackgroundImageUrl})`;
137
             styles.backgroundImage = `url(${_customBackgroundImageUrl})`;
126
             styles.backgroundSize = 'cover';
138
             styles.backgroundSize = 'cover';
144
     const { isOpen: isChatOpen } = state['features/chat'];
156
     const { isOpen: isChatOpen } = state['features/chat'];
145
 
157
 
146
     return {
158
     return {
159
+        _backgroundAlpha: state['features/base/config'].backgroundAlpha,
147
         _customBackgroundColor: backgroundColor,
160
         _customBackgroundColor: backgroundColor,
148
         _customBackgroundImageUrl: backgroundImageUrl,
161
         _customBackgroundImageUrl: backgroundImageUrl,
149
         _isChatOpen: isChatOpen,
162
         _isChatOpen: isChatOpen,

Loading…
取消
儲存