Compare commits
55 Commits
4757
...
rn-fix-and
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d69584ce17 | ||
|
|
b2d271a679 | ||
|
|
7046785ca3 | ||
|
|
b817bd19d5 | ||
|
|
817d54b0b9 | ||
|
|
3f0bb6818c | ||
|
|
4fa47c8070 | ||
|
|
0dcb8a025b | ||
|
|
8defaa9aec | ||
|
|
d214079148 | ||
|
|
096ee3cb53 | ||
|
|
fd606896b8 | ||
|
|
226581a81a | ||
|
|
e1c5b1e626 | ||
|
|
831c5ba59d | ||
|
|
bad1bc91cf | ||
|
|
30d0aabaca | ||
|
|
22b6d32174 | ||
|
|
31ace267ce | ||
|
|
194d357005 | ||
|
|
c2ad06c5e6 | ||
|
|
e40b02ab3c | ||
|
|
2587eefefc | ||
|
|
b87c433e99 | ||
|
|
751644db16 | ||
|
|
c508572cc5 | ||
|
|
b86c271a80 | ||
|
|
5efbe5f0ec | ||
|
|
2784c43a1b | ||
|
|
f5a34183e9 | ||
|
|
29f5d87d77 | ||
|
|
ab6790bdaa | ||
|
|
2e308d67d8 | ||
|
|
91ba835f78 | ||
|
|
2643029ac8 | ||
|
|
e40e078a29 | ||
|
|
6df5a4cf31 | ||
|
|
c7c7d7a155 | ||
|
|
8f06866646 | ||
|
|
b559cb8ec6 | ||
|
|
30a2e84da1 | ||
|
|
3122983000 | ||
|
|
407021e258 | ||
|
|
1a62a7b1cc | ||
|
|
0ee03f1538 | ||
|
|
572beb8382 | ||
|
|
d0d32b8a19 | ||
|
|
82ff988c18 | ||
|
|
8fa5d09612 | ||
|
|
508f1e0da9 | ||
|
|
dcda89012e | ||
|
|
d93a402cc2 | ||
|
|
b7b260f4c9 | ||
|
|
4db3f04c0c | ||
|
|
126a2bd0d7 |
@@ -6,7 +6,7 @@ build/*
|
||||
flow-typed/*
|
||||
libs/*
|
||||
resources/*
|
||||
react/features/stream-effects/blur/vendor/*
|
||||
react/features/stream-effects/virtual-background/vendor/*
|
||||
|
||||
# ESLint will by default ignore its own configuration file. However, there does
|
||||
# not seem to be a reason why we will want to risk being inconsistent with our
|
||||
|
||||
1
.github/workflows/ci.yml
vendored
@@ -12,5 +12,6 @@ jobs:
|
||||
with:
|
||||
node-version: '12.x'
|
||||
- run: npm install
|
||||
- run: git status -s --untracked-files=no
|
||||
- run: npm run lint
|
||||
- run: make
|
||||
|
||||
8
Makefile
@@ -5,8 +5,8 @@ LIBJITSIMEET_DIR = node_modules/lib-jitsi-meet/
|
||||
LIBFLAC_DIR = node_modules/libflacjs/dist/min/
|
||||
OLM_DIR = node_modules/olm
|
||||
RNNOISE_WASM_DIR = node_modules/rnnoise-wasm/dist/
|
||||
TFLITE_WASM = react/features/stream-effects/blur/vendor/tflite
|
||||
MEET_MODELS_DIR = react/features/stream-effects/blur/vendor/models/
|
||||
TFLITE_WASM = react/features/stream-effects/virtual-background/vendor/tflite
|
||||
MEET_MODELS_DIR = react/features/stream-effects/virtual-background/vendor/models/
|
||||
NODE_SASS = ./node_modules/.bin/sass
|
||||
NPM = npm
|
||||
OUTPUT_DIR = .
|
||||
@@ -51,10 +51,6 @@ deploy-appbundle:
|
||||
$(OUTPUT_DIR)/analytics-ga.js \
|
||||
$(BUILD_DIR)/analytics-ga.min.js \
|
||||
$(BUILD_DIR)/analytics-ga.min.map \
|
||||
$(BUILD_DIR)/video-blur-effect.min.js \
|
||||
$(BUILD_DIR)/video-blur-effect.min.map \
|
||||
$(BUILD_DIR)/rnnoise-processor.min.js \
|
||||
$(BUILD_DIR)/rnnoise-processor.min.map \
|
||||
$(BUILD_DIR)/close3.min.js \
|
||||
$(BUILD_DIR)/close3.min.map \
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
@@ -122,13 +122,17 @@ gradle.projectsEvaluated {
|
||||
android.applicationVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
output.getProcessManifestProvider().get().doLast {
|
||||
def outputDir = manifestOutputDirectory.get().asFile
|
||||
def manifestPath = new File(outputDir, 'AndroidManifest.xml')
|
||||
def charset = 'UTF-8'
|
||||
def text
|
||||
text = manifestPath.getText(charset)
|
||||
def outputDir = manifestOutputDirectory
|
||||
File directory
|
||||
if (outputDir instanceof File) {
|
||||
directory = outputDir
|
||||
} else {
|
||||
directory = outputDir.get().asFile
|
||||
}
|
||||
String manifestPath = directory.toString() + "/AndroidManifest.xml"
|
||||
def text = file(manifestPath).getText('UTF-8')
|
||||
text = text.replace('</application>', "${dropboxActivity}</application>")
|
||||
manifestPath.write(text, charset)
|
||||
file(manifestPath).write(text, 'UTF-8')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +132,7 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
public void onCurrentConferenceChanged(String conferenceUrl) {
|
||||
if (conferenceUrl == null) {
|
||||
stopSelf();
|
||||
OngoingNotification.resetStartingtime();
|
||||
JitsiMeetLogger.i(TAG + "Service stopped");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ class OngoingNotification {
|
||||
private static final String CHANNEL_NAME = "Ongoing Conference Notifications";
|
||||
|
||||
static final int NOTIFICATION_ID = new Random().nextInt(99999) + 10000;
|
||||
private static long startingTime = 0;
|
||||
|
||||
static void createOngoingConferenceNotificationChannel() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
@@ -85,6 +86,10 @@ class OngoingNotification {
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID);
|
||||
|
||||
if (startingTime == 0) {
|
||||
startingTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
builder
|
||||
.setCategory(NotificationCompat.CATEGORY_CALL)
|
||||
.setContentTitle(context.getString(R.string.ongoing_notification_title))
|
||||
@@ -92,6 +97,8 @@ class OngoingNotification {
|
||||
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setOngoing(true)
|
||||
.setWhen(startingTime)
|
||||
.setUsesChronometer(true)
|
||||
.setAutoCancel(false)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
.setOnlyAlertOnce(true)
|
||||
@@ -110,6 +117,10 @@ class OngoingNotification {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
static void resetStartingtime() {
|
||||
startingTime = 0;
|
||||
}
|
||||
|
||||
private static NotificationCompat.Action createAction(Context context, JitsiMeetOngoingConferenceService.Action action, @StringRes int titleId) {
|
||||
Intent intent = new Intent(context, JitsiMeetOngoingConferenceService.class);
|
||||
intent.setAction(action.getName());
|
||||
|
||||
114
conference.js
@@ -99,6 +99,7 @@ import {
|
||||
destroyLocalTracks,
|
||||
getLocalJitsiAudioTrack,
|
||||
getLocalJitsiVideoTrack,
|
||||
getLocalTracks,
|
||||
isLocalCameraTrackMuted,
|
||||
isLocalTrackMuted,
|
||||
isUserInteractionRequiredForUnmute,
|
||||
@@ -473,18 +474,13 @@ export default {
|
||||
*/
|
||||
createInitialLocalTracks(options = {}) {
|
||||
const errors = {};
|
||||
|
||||
// Always get a handle on the audio input device so that we have statistics (such as "No audio input" or
|
||||
// "Are you trying to speak?" ) even if the user joins the conference muted.
|
||||
const initialDevices = config.disableInitialGUM ? [] : [ 'audio' ];
|
||||
const requestedAudio = !config.disableInitialGUM;
|
||||
let requestedVideo = false;
|
||||
|
||||
// Always get a handle on the audio input device so that we have statistics even if the user joins the
|
||||
// conference muted. Previous implementation would only acquire the handle when the user first unmuted,
|
||||
// which would results in statistics ( such as "No audio input" or "Are you trying to speak?") being available
|
||||
// only after that point.
|
||||
if (options.startWithAudioMuted) {
|
||||
this.muteAudio(true, true);
|
||||
}
|
||||
|
||||
if (!config.disableInitialGUM
|
||||
&& !options.startWithVideoMuted
|
||||
&& !options.startAudioOnly
|
||||
@@ -824,12 +820,16 @@ export default {
|
||||
return this._setLocalAudioVideoStreams(tracks);
|
||||
}
|
||||
|
||||
const [ tracks, con ] = await this.createInitialLocalTracksAndConnect(
|
||||
roomName, initialOptions);
|
||||
const [ tracks, con ] = await this.createInitialLocalTracksAndConnect(roomName, initialOptions);
|
||||
let localTracks = tracks;
|
||||
|
||||
this._initDeviceList(true);
|
||||
|
||||
return this.startConference(con, tracks);
|
||||
if (initialOptions.startWithAudioMuted) {
|
||||
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.AUDIO);
|
||||
}
|
||||
|
||||
return this.startConference(con, localTracks);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1020,7 +1020,11 @@ export default {
|
||||
// Rollback the video muted status by using null track
|
||||
return null;
|
||||
})
|
||||
.then(videoTrack => this.useVideoStream(videoTrack));
|
||||
.then(videoTrack => {
|
||||
logger.debug(`muteVideo: calling useVideoStream for track: ${videoTrack}`);
|
||||
|
||||
return this.useVideoStream(videoTrack);
|
||||
});
|
||||
} else {
|
||||
// FIXME show error dialog if it fails (should be handled by react)
|
||||
muteLocalVideo(mute);
|
||||
@@ -1320,7 +1324,11 @@ export default {
|
||||
this._getConferenceOptions());
|
||||
|
||||
APP.store.dispatch(conferenceWillJoin(room));
|
||||
this._setLocalAudioVideoStreams(localTracks);
|
||||
|
||||
// Filter out the tracks that are muted.
|
||||
const tracks = localTracks.filter(track => !track.isMuted());
|
||||
|
||||
this._setLocalAudioVideoStreams(tracks);
|
||||
this._room = room; // FIXME do not use this
|
||||
|
||||
sendLocalParticipant(APP.store, room);
|
||||
@@ -1339,8 +1347,11 @@ export default {
|
||||
if (track.isAudioTrack()) {
|
||||
return this.useAudioStream(track);
|
||||
} else if (track.isVideoTrack()) {
|
||||
logger.debug(`_setLocalAudioVideoStreams is calling useVideoStream with track: ${track}`);
|
||||
|
||||
return this.useVideoStream(track);
|
||||
}
|
||||
|
||||
logger.error(
|
||||
'Ignored not an audio nor a video track: ', track);
|
||||
|
||||
@@ -1360,6 +1371,8 @@ export default {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
useVideoStream(newTrack) {
|
||||
logger.debug(`useVideoStream: ${newTrack}`);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
_replaceLocalVideoTrackQueue.enqueue(onFinish => {
|
||||
const state = APP.store.getState();
|
||||
@@ -1369,14 +1382,20 @@ export default {
|
||||
if (isPrejoinPageVisible(state)) {
|
||||
const oldTrack = getLocalJitsiVideoTrack(state);
|
||||
|
||||
logger.debug(`useVideoStream on the prejoin screen: Replacing ${oldTrack} with ${newTrack}`);
|
||||
|
||||
return APP.store.dispatch(replaceLocalTrack(oldTrack, newTrack))
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
.catch(error => {
|
||||
logger.error(`useVideoStream failed on the prejoin screen: ${error}`);
|
||||
reject(error);
|
||||
})
|
||||
.then(onFinish);
|
||||
}
|
||||
|
||||
logger.debug(`useVideoStream: Replacing ${this.localVideo} with ${newTrack}`);
|
||||
APP.store.dispatch(
|
||||
replaceLocalTrack(this.localVideo, newTrack, room))
|
||||
replaceLocalTrack(this.localVideo, newTrack, room))
|
||||
.then(() => {
|
||||
this.localVideo = newTrack;
|
||||
this._setSharingScreen(newTrack);
|
||||
@@ -1386,7 +1405,10 @@ export default {
|
||||
this.setVideoMuteStatus(this.isLocalVideoMuted());
|
||||
})
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
.catch(error => {
|
||||
logger.error(`useVideoStream failed: ${error}`);
|
||||
reject(error);
|
||||
})
|
||||
.then(onFinish);
|
||||
});
|
||||
});
|
||||
@@ -1533,7 +1555,11 @@ export default {
|
||||
|
||||
if (didHaveVideo) {
|
||||
promise = promise.then(() => createLocalTracksF({ devices: [ 'video' ] }))
|
||||
.then(([ stream ]) => this.useVideoStream(stream))
|
||||
.then(([ stream ]) => {
|
||||
logger.debug(`_turnScreenSharingOff using ${stream} for useVideoStream`);
|
||||
|
||||
return this.useVideoStream(stream);
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error('failed to switch back to local video', error);
|
||||
|
||||
@@ -1544,7 +1570,11 @@ export default {
|
||||
);
|
||||
});
|
||||
} else {
|
||||
promise = promise.then(() => this.useVideoStream(null));
|
||||
promise = promise.then(() => {
|
||||
logger.debug('_turnScreenSharingOff using null for useVideoStream');
|
||||
|
||||
return this.useVideoStream(null);
|
||||
});
|
||||
}
|
||||
|
||||
return promise.then(
|
||||
@@ -1555,6 +1585,8 @@ export default {
|
||||
},
|
||||
error => {
|
||||
this.videoSwitchInProgress = false;
|
||||
logger.error(`_turnScreenSharingOff failed: ${error}`);
|
||||
|
||||
throw error;
|
||||
});
|
||||
},
|
||||
@@ -1575,6 +1607,7 @@ export default {
|
||||
* @return {Promise.<T>}
|
||||
*/
|
||||
async toggleScreenSharing(toggle = !this._untoggleScreenSharing, options = {}) {
|
||||
logger.debug(`toggleScreenSharing: ${toggle}`);
|
||||
if (this.videoSwitchInProgress) {
|
||||
return Promise.reject('Switch in progress.');
|
||||
}
|
||||
@@ -1641,6 +1674,8 @@ export default {
|
||||
desktopVideoStream.on(
|
||||
JitsiTrackEvents.LOCAL_TRACK_STOPPED,
|
||||
() => {
|
||||
logger.debug(`Local screensharing track stopped. ${this.isSharingScreen}`);
|
||||
|
||||
// If the stream was stopped during screen sharing
|
||||
// session then we should switch back to video.
|
||||
this.isSharingScreen
|
||||
@@ -1805,6 +1840,7 @@ export default {
|
||||
const desktopVideoStream = streams.find(stream => stream.getType() === MEDIA_TYPE.VIDEO);
|
||||
|
||||
if (desktopVideoStream) {
|
||||
logger.debug(`_switchToScreenSharing is using ${desktopVideoStream} for useVideoStream`);
|
||||
await this.useVideoStream(desktopVideoStream);
|
||||
}
|
||||
|
||||
@@ -2010,6 +2046,7 @@ export default {
|
||||
if (participantThatMutedUs) {
|
||||
APP.store.dispatch(participantMutedUs(participantThatMutedUs, track));
|
||||
if (this.isSharingScreen && track.isVideoTrack()) {
|
||||
logger.debug('TRACK_MUTE_CHANGED while screen sharing');
|
||||
this._turnScreenSharingOff(false);
|
||||
}
|
||||
}
|
||||
@@ -2163,8 +2200,26 @@ export default {
|
||||
}
|
||||
);
|
||||
room.on(JitsiConferenceEvents.STARTED_MUTED, () => {
|
||||
(room.isStartAudioMuted() || room.isStartVideoMuted())
|
||||
&& APP.UI.notifyInitiallyMuted();
|
||||
const audioMuted = room.isStartAudioMuted();
|
||||
const videoMuted = room.isStartVideoMuted();
|
||||
const localTracks = getLocalTracks(APP.store.getState()['features/base/tracks']);
|
||||
const promises = [];
|
||||
|
||||
APP.store.dispatch(setAudioMuted(audioMuted));
|
||||
APP.store.dispatch(setVideoMuted(videoMuted));
|
||||
|
||||
// Remove the tracks from the peerconnection.
|
||||
for (const track of localTracks) {
|
||||
if (audioMuted && track.jitsiTrack?.getType() === MEDIA_TYPE.AUDIO) {
|
||||
promises.push(this.useAudioStream(null));
|
||||
}
|
||||
if (videoMuted && track.jitsiTrack?.getType() === MEDIA_TYPE.VIDEO) {
|
||||
promises.push(this.useVideoStream(null));
|
||||
}
|
||||
}
|
||||
|
||||
Promise.allSettled(promises)
|
||||
.then(() => APP.UI.notifyInitiallyMuted());
|
||||
});
|
||||
|
||||
room.on(
|
||||
@@ -2215,7 +2270,7 @@ export default {
|
||||
.then(effect => this.localVideo.setEffect(effect))
|
||||
.then(() => {
|
||||
this.setVideoMuteStatus(false);
|
||||
logger.log('switched local video device');
|
||||
logger.log('Switched local video device while screen sharing and the video is unmuted');
|
||||
this._updateVideoDeviceId();
|
||||
})
|
||||
.catch(err => APP.store.dispatch(notifyCameraError(err)));
|
||||
@@ -2224,7 +2279,7 @@ export default {
|
||||
// id for video, dispose the existing presenter track and create a new effect
|
||||
// that can be applied on un-mute.
|
||||
} else if (this.isSharingScreen && videoWasMuted) {
|
||||
logger.log('switched local video device');
|
||||
logger.log('Switched local video device: while screen sharing and the video is muted');
|
||||
const { height } = this.localVideo.track.getSettings();
|
||||
|
||||
this._updateVideoDeviceId();
|
||||
@@ -2251,12 +2306,20 @@ export default {
|
||||
|
||||
return stream;
|
||||
})
|
||||
.then(stream => this.useVideoStream(stream))
|
||||
.then(stream => {
|
||||
logger.log('Switching the local video device.');
|
||||
|
||||
return this.useVideoStream(stream);
|
||||
})
|
||||
.then(() => {
|
||||
logger.log('switched local video device');
|
||||
logger.log('Switched local video device.');
|
||||
this._updateVideoDeviceId();
|
||||
})
|
||||
.catch(err => APP.store.dispatch(notifyCameraError(err)));
|
||||
.catch(error => {
|
||||
logger.error(`Switching the local video device failed: ${error}`);
|
||||
|
||||
return APP.store.dispatch(notifyCameraError(error));
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -2608,6 +2671,7 @@ export default {
|
||||
delete newDevices.videoinput;
|
||||
|
||||
// Removing the current video track in order to force the unmute to select the preferred device.
|
||||
logger.debug('_onDeviceListChanged: Removing the current video track.');
|
||||
this.useVideoStream(null);
|
||||
|
||||
}
|
||||
|
||||
26
config.js
@@ -412,7 +412,26 @@ var config = {
|
||||
// enableAutomaticUrlCopy: false,
|
||||
|
||||
// Base URL for a Gravatar-compatible service. Defaults to libravatar.
|
||||
// gravatarBaseURL: 'https://seccdn.libravatar.org/avatar/';
|
||||
// gravatarBaseURL: 'https://seccdn.libravatar.org/avatar/',
|
||||
|
||||
// Moved from interfaceConfig(TOOLBAR_BUTTONS).
|
||||
// The name of the toolbar buttons to display in the toolbar, including the
|
||||
// "More actions" menu. If present, the button will display. Exceptions are
|
||||
// "livestreaming" and "recording" which also require being a moderator and
|
||||
// some other values in config.js to be enabled. Also, the "profile" button will
|
||||
// not display for users with a JWT.
|
||||
// Notes:
|
||||
// - it's impossible to choose which buttons go in the "More actions" menu
|
||||
// - it's impossible to control the placement of buttons
|
||||
// - 'desktop' controls the "Share your screen" button
|
||||
// - if `toolbarButtons` is undefined, we fallback to enabling all buttons on the UI
|
||||
// toolbarButtons: [
|
||||
// 'microphone', 'camera', 'closedcaptions', 'desktop', 'embedmeeting', 'fullscreen',
|
||||
// 'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
|
||||
// 'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
|
||||
// 'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
|
||||
// 'tileview', 'select-background', 'download', 'help', 'mute-everyone', 'mute-video-everyone', 'security'
|
||||
// ],
|
||||
|
||||
// Stats
|
||||
//
|
||||
@@ -666,6 +685,11 @@ var config = {
|
||||
// Sets the conference subject
|
||||
// subject: 'Conference Subject',
|
||||
|
||||
// This property is related to the use case when jitsi-meet is used via the IFrame API. When the property is true
|
||||
// jitsi-meet will use the local storage of the host page instead of its own. This option is useful if the browser
|
||||
// is not persisting the local storage inside the iframe.
|
||||
// useHostPageLocalStorage: true,
|
||||
|
||||
// List of undocumented settings used in jitsi-meet
|
||||
/**
|
||||
_immediateReloadThreshold
|
||||
|
||||
@@ -73,9 +73,17 @@
|
||||
*/
|
||||
.toolbox-button-wth-dialog > div:nth-child(2) {
|
||||
max-height: calc(100vh - #{$newToolbarSizeWithPadding} - 46px);
|
||||
margin-bottom: 4px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.audio-preview > div:nth-child(2),
|
||||
.video-preview > div:nth-child(2) {
|
||||
margin-bottom: 4px;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The following selectors keep the chat modal full-size anywhere between 100px
|
||||
* and 580px for desktop or 680px for mobile.
|
||||
@@ -114,3 +122,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.Tooltip {
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
@@ -1,26 +1,37 @@
|
||||
.audio-preview {
|
||||
display: inline-block;
|
||||
|
||||
&-content {
|
||||
background: #2A3A4B;
|
||||
font-size: 15px;
|
||||
background: $menuBG;
|
||||
border-radius: 3px;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
max-height: 456px;
|
||||
overflow: auto;
|
||||
width: 328px;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
&-header {
|
||||
color: #fff;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
padding: 16px;
|
||||
margin-top: 8px;
|
||||
padding: 8px 16px;
|
||||
|
||||
&-icon {
|
||||
color: #A4B8D1;
|
||||
display: inline-block;
|
||||
|
||||
svg {
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&--bordered {
|
||||
border-bottom: 1px solid #4C4D50;
|
||||
}
|
||||
|
||||
&-text {
|
||||
font-weight: bold;
|
||||
margin-left: 8px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,19 +40,18 @@
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
padding: 12px 0;
|
||||
padding: 8px 0;
|
||||
margin-left: 48px;
|
||||
|
||||
&--selected {
|
||||
background: #1C2025;
|
||||
background: #131519;
|
||||
cursor: initial;
|
||||
margin-left: 0;
|
||||
padding-left: 21px;
|
||||
padding-left: 18px;
|
||||
}
|
||||
|
||||
&-text {
|
||||
color: #fff;
|
||||
font-size: 15px;
|
||||
display: inline-block;
|
||||
line-height: 24px;
|
||||
text-overflow: ellipsis;
|
||||
@@ -56,12 +66,13 @@
|
||||
|
||||
&:hover {
|
||||
.audio-preview-entry {
|
||||
background: #3F4E5E;
|
||||
background: #36383C;
|
||||
margin-left: 0;
|
||||
padding-left: 48px;
|
||||
|
||||
&--selected {
|
||||
padding-left: 21px;
|
||||
padding-left: 18px;
|
||||
background: $newToolbarBackgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +85,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.audio-preview-entry-text {
|
||||
max-width: 256px;
|
||||
}
|
||||
@@ -84,18 +99,19 @@
|
||||
|
||||
&:hover {
|
||||
.audio-preview-entry {
|
||||
background: #3F4E5E;
|
||||
background: #36383C;
|
||||
margin-left: 0;
|
||||
padding-left: 48px;
|
||||
|
||||
&--selected {
|
||||
padding-left: 21px;
|
||||
background: $newToolbarBackgroundColor;
|
||||
padding-left: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.audio-preview-entry-text {
|
||||
max-width: 196px;
|
||||
max-width: 178px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +126,7 @@
|
||||
|
||||
&--check {
|
||||
background: #31B76A;
|
||||
margin-right: 13px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
&--exclamation {
|
||||
@@ -121,6 +137,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-hr {
|
||||
border-top: 1px solid #4C4D50;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
&-test-button {
|
||||
display: none;
|
||||
background: #FFF;
|
||||
@@ -129,23 +150,16 @@
|
||||
color: #1C2025;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
padding: 4px 16px;
|
||||
padding: 2px 16px;
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: 8px;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
&-meter-mic {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: 18px;
|
||||
}
|
||||
|
||||
// Override @atlaskit/InlineDialog container which is made with styled components
|
||||
& > div:nth-child(2) {
|
||||
outline: none;
|
||||
padding: 0;
|
||||
top: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
}
|
||||
|
||||
.drawer-menu {
|
||||
padding: 0 16px;
|
||||
max-height: 50vh;
|
||||
background: #242528;
|
||||
border-radius: 16px 16px 0 0;
|
||||
@@ -24,12 +23,6 @@
|
||||
height: 44px;
|
||||
cursor: pointer;
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
&:hover {
|
||||
background-color: $overflowMenuItemHoverBG;
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: none;
|
||||
}
|
||||
@@ -67,13 +60,6 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
&:hover {
|
||||
background-color: $overflowMenuItemHoverBG;
|
||||
color: $overflowMenuItemHoverColor;
|
||||
}
|
||||
}
|
||||
|
||||
&.unclickable {
|
||||
cursor: default;
|
||||
}
|
||||
@@ -88,42 +74,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.beta-tag {
|
||||
background: $overflowMenuItemColor;
|
||||
border-radius: 2px;
|
||||
color: $overflowMenuBG;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
margin-left: 8px;
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
.overflow-menu-item-icon {
|
||||
margin-right: 16px;
|
||||
|
||||
i {
|
||||
display: inline;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
i:hover {
|
||||
background-color: initial;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 24px;
|
||||
max-height: 24px;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: #B8C7E0 !important;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.profile-text {
|
||||
max-width: 100%;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@@ -23,44 +23,10 @@
|
||||
flex-direction: row;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
bottom: 10px;
|
||||
transform: translateX(-50%);
|
||||
|
||||
.toolbox-button {
|
||||
&:first-child {
|
||||
.toolbox-icon {
|
||||
border-top-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
svg {
|
||||
fill: $hangupColor;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
.toolbox-icon {
|
||||
border-top-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filmstrip-toolbox {
|
||||
flex-direction: column;
|
||||
|
||||
.toolbox-button {
|
||||
&:nth-child(1) {
|
||||
svg {
|
||||
fill: $hangupColor;
|
||||
}
|
||||
}
|
||||
|
||||
.toolbox-icon {
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
text {
|
||||
fill: black;
|
||||
font-size: 26px;
|
||||
font-weight: 400;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,14 +197,6 @@
|
||||
&> div {
|
||||
margin: 0 12px;
|
||||
}
|
||||
|
||||
.settings-button-small-icon {
|
||||
right: -8px;
|
||||
|
||||
&--hovered {
|
||||
right: -10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,58 +1,3 @@
|
||||
@mixin small-button-size() {
|
||||
.new-toolbox {
|
||||
.toolbox-content {
|
||||
.button-group-center, .button-group-left, .button-group-right {
|
||||
.toolbox-button {
|
||||
.toolbox-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
.toolbox-icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin very-small-button-size() {
|
||||
.new-toolbox {
|
||||
.toolbox-content {
|
||||
.button-group-center, .button-group-left, .button-group-right {
|
||||
.settings-button-small-icon {
|
||||
display: none;
|
||||
}
|
||||
.toolbox-button {
|
||||
.toolbox-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
svg {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
.toolbox-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $verySmallScreen) {
|
||||
.welcome {
|
||||
display: block;
|
||||
@@ -122,21 +67,9 @@
|
||||
}
|
||||
|
||||
.desktop-browser {
|
||||
@media only screen and (max-width: $smallScreen) {
|
||||
@include small-button-size();
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $verySmallScreen) {
|
||||
@include very-small-button-size();
|
||||
}
|
||||
|
||||
&.shift-right {
|
||||
@media only screen and (max-width: $smallScreen + $sidebarWidth) {
|
||||
@include small-button-size()
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $verySmallScreen + $sidebarWidth) {
|
||||
@include very-small-button-size();
|
||||
|
||||
#videoResolutionLabel {
|
||||
display: none;
|
||||
|
||||
@@ -1,84 +1,62 @@
|
||||
.settings-button {
|
||||
&-container {
|
||||
position: relative;
|
||||
.settings-button-container {
|
||||
position: relative;
|
||||
|
||||
.toolbox-icon {
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #d1dbe8;
|
||||
justify-content: center;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
.toolbox-icon {
|
||||
align-items: center;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
&.disabled, .disabled & {
|
||||
cursor: initial;
|
||||
color: #929292;
|
||||
background-color: #36383c;
|
||||
|
||||
&:hover {
|
||||
background-color: #daebfa;
|
||||
border: 1px solid #daebfa;
|
||||
}
|
||||
|
||||
&.toggled {
|
||||
background: #2a3a4b;
|
||||
border: 1px solid #5e6d7a;
|
||||
|
||||
svg {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #5e6d7a;
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled, .disabled & {
|
||||
cursor: initial;
|
||||
color: #fff;
|
||||
background-color: #a4b8d1;
|
||||
|
||||
&:hover {
|
||||
background-color: #a4b8d1;
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: #5e6d7a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-small-icon {
|
||||
background: #FFF;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
border-radius: 50%;
|
||||
bottom: 0;
|
||||
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.25);
|
||||
cursor: pointer;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
right: 4px;
|
||||
width: 16px;
|
||||
|
||||
&> svg {
|
||||
fill: #5e6d7a;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
&--disabled {
|
||||
background-color: #a4b8d1;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&--hovered {
|
||||
bottom: -1px;
|
||||
height: 20px;
|
||||
right: 2px;
|
||||
width: 20px;
|
||||
|
||||
&> svg {
|
||||
margin-top: 6px;
|
||||
background-color: #36383c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.settings-button-small-icon {
|
||||
background: #36383C;
|
||||
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25), 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
position: absolute;
|
||||
right: -4px;
|
||||
top: -3px;
|
||||
|
||||
&:hover {
|
||||
background: #F2F3F4;
|
||||
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25), 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
|
||||
|
||||
&> svg {
|
||||
fill: #000;
|
||||
}
|
||||
|
||||
&.settings-button-small-icon--disabled {
|
||||
background: #36383C;
|
||||
|
||||
&> svg {
|
||||
fill: #929292;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&> svg {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
&--disabled {
|
||||
background-color: #36383c;
|
||||
cursor: default;
|
||||
|
||||
&> svg {
|
||||
fill: #929292;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
|
||||
&.visible {
|
||||
bottom: 0;
|
||||
.toolbox-background {
|
||||
bottom: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
&.no-buttons {
|
||||
@@ -48,253 +45,227 @@
|
||||
width: calc(100% - #{$sidebarWidth});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toolbox-background {
|
||||
background-image: linear-gradient(to top, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0));
|
||||
transition: bottom .3s ease-in;
|
||||
height: 160px;
|
||||
width: 100%;
|
||||
bottom: -160px;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
z-index: $toolbarBackgroundZ;
|
||||
.toolbox-content {
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
position: relative;
|
||||
z-index: $toolbarZ;
|
||||
|
||||
.button-group-center,
|
||||
.button-group-left,
|
||||
.button-group-right {
|
||||
display: flex;
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
.toolbox-content {
|
||||
box-sizing: border-box;
|
||||
.button-group-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.button-group-right {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.toolbox-button-wth-dialog {
|
||||
display: inline-block;
|
||||
|
||||
&> div {
|
||||
padding: 0;
|
||||
background: $menuBG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toolbox-button {
|
||||
color: $toolbarButtonColor;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
line-height: $newToolbarSize;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.toolbar-button-with-badge {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
||||
.badge-round {
|
||||
bottom: -5px;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
min-width: 20px;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
right: -5px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.toolbox-content-items {
|
||||
background: $newToolbarBackgroundColor;
|
||||
box-shadow: 0px 2px 8px 4px rgba(0, 0, 0, 0.25), 0px 0px 0px 1px rgba(0, 0, 0, 0.15);
|
||||
border-radius: 6px;
|
||||
margin: 0 auto;
|
||||
padding: 6px;
|
||||
text-align: center;
|
||||
|
||||
>div {
|
||||
margin-left: 8px;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.overflow-menu {
|
||||
font-size: 14px;
|
||||
list-style-type: none;
|
||||
padding: 8px 0;
|
||||
background-color: $menuBG;
|
||||
|
||||
.profile-text {
|
||||
max-width: 150px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.overflow-menu-item {
|
||||
align-items: center;
|
||||
color: $overflowMenuItemColor;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
height: 40px;
|
||||
line-height: 24px;
|
||||
padding: 8px 16px;
|
||||
box-sizing: border-box;
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
&:hover {
|
||||
background: $overflowMenuItemBackground;
|
||||
}
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 20px 16px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
z-index: $toolbarZ;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.button-group-center,
|
||||
.button-group-left,
|
||||
.button-group-right {
|
||||
display: flex;
|
||||
width: 33%;
|
||||
&.unclickable {
|
||||
cursor: default;
|
||||
}
|
||||
&.disabled {
|
||||
cursor: initial;
|
||||
color: #929292;
|
||||
|
||||
svg {
|
||||
fill: #929292;
|
||||
}
|
||||
}
|
||||
|
||||
.button-group-center {
|
||||
justify-content: center;
|
||||
|
||||
.toolbox-button {
|
||||
|
||||
.toolbox-icon {
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #d1dbe8;
|
||||
margin: 0px 4px;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
&:hover {
|
||||
background-color: #daebfa;
|
||||
border: 1px solid #daebfa;
|
||||
}
|
||||
}
|
||||
|
||||
&.toggled {
|
||||
background: #2a3a4b;
|
||||
border: 1px solid #5e6d7a;
|
||||
|
||||
svg {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
&:hover {
|
||||
background-color: #5e6d7a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled, .disabled & {
|
||||
cursor: initial;
|
||||
color: #fff;
|
||||
background-color: #a4b8d1;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: #5e6d7a;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
.toolbox-icon {
|
||||
background-color: $hangupColor;
|
||||
border: 1px solid $hangupColor;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
&:hover {
|
||||
background-color: $hangupColor;
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
&.unclickable:hover {
|
||||
background: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button-group-right {
|
||||
justify-content: flex-end;
|
||||
.beta-tag {
|
||||
background: #36383C;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
margin-left: 8px;
|
||||
padding: 0 4px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.overflow-menu-item-icon {
|
||||
margin-right: 16px;
|
||||
|
||||
i {
|
||||
display: inline;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
i:hover {
|
||||
background-color: initial;
|
||||
}
|
||||
}
|
||||
|
||||
.overflow-menu {
|
||||
font-size: 1.2em;
|
||||
list-style-type: none;
|
||||
background-color: $overflowMenuBG;
|
||||
/**
|
||||
* Undo atlaskit padding by reducing margins.
|
||||
*/
|
||||
margin: -16px -24px;
|
||||
padding: 4px 0;
|
||||
img {
|
||||
max-width: 24px;
|
||||
max-height: 24px;
|
||||
}
|
||||
|
||||
.overflow-menu-item {
|
||||
align-items: center;
|
||||
color: $overflowMenuItemColor;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
height: 40px;
|
||||
padding: 5px 12px;
|
||||
box-sizing: border-box;
|
||||
svg {
|
||||
fill: #fff;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
&:hover {
|
||||
background-color: $overflowMenuItemHoverBG;
|
||||
color: $overflowMenuItemHoverColor;
|
||||
}
|
||||
}
|
||||
.overflow-menu-hr {
|
||||
border-top: 1px solid #4C4D50;
|
||||
border-bottom: 0;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
&.unclickable {
|
||||
cursor: default;
|
||||
}
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
&.unclickable:hover {
|
||||
background: inherit;
|
||||
}
|
||||
}
|
||||
&.disabled {
|
||||
cursor: initial;
|
||||
color: #3b475c;
|
||||
}
|
||||
}
|
||||
.toolbox-icon {
|
||||
display: flex;
|
||||
border-radius: 3px;
|
||||
flex-direction: column;
|
||||
font-size: 24px;
|
||||
height: $newToolbarSize;
|
||||
justify-content: center;
|
||||
width: $newToolbarSize;
|
||||
|
||||
.beta-tag {
|
||||
background: $overflowMenuItemColor;
|
||||
border-radius: 2px;
|
||||
color: $overflowMenuBG;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
margin-left: 8px;
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
.overflow-menu-item-icon {
|
||||
margin-right: 16px;
|
||||
|
||||
i {
|
||||
display: inline;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
i:hover {
|
||||
background-color: initial;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 24px;
|
||||
max-height: 24px;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: #B8C7E0 !important;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.profile-text {
|
||||
max-width: 150px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
&:hover {
|
||||
background: $newToolbarButtonHoverColor;
|
||||
}
|
||||
}
|
||||
|
||||
.toolbox-button {
|
||||
color: $toolbarButtonColor;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
line-height: $newToolbarSize;
|
||||
margin: 0 8px;
|
||||
text-align: center;
|
||||
@media (max-width: 320px) {
|
||||
height: 36px;
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
&.toggled {
|
||||
background: $newToolbarButtonToggleColor;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: initial !important;
|
||||
background-color: #36383c !important;
|
||||
|
||||
svg {
|
||||
fill: #929292 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toolbar-button-with-badge {
|
||||
position: relative;
|
||||
.hangup-button {
|
||||
background-color: $hangupColor;
|
||||
|
||||
.badge-round {
|
||||
bottom: -5px;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
min-width: 20px;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
right: -5px;
|
||||
}
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
&:hover {
|
||||
background-color: $hangupHoverColor;
|
||||
}
|
||||
}
|
||||
|
||||
.toolbox-button-wth-dialog {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.toolbox-icon {
|
||||
display: flex;
|
||||
border-radius: 5px;
|
||||
flex-direction: column;
|
||||
font-size: 24px;
|
||||
height: $newToolbarSize;
|
||||
justify-content: center;
|
||||
width: $newToolbarSize;
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
&:hover {
|
||||
background: $newToolbarButtonHoverColor;
|
||||
}
|
||||
}
|
||||
|
||||
&.toggled {
|
||||
background: $newToolbarButtonHoverColor;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: initial !important;
|
||||
background-color: #a4b8d1 !important;
|
||||
|
||||
svg {
|
||||
fill: #fff !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
svg {
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,3 +283,35 @@
|
||||
|
||||
@include transition(all .3s ease-out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Audio and video buttons do not have toggled state.
|
||||
*/
|
||||
.audio-preview,
|
||||
.video-preview {
|
||||
.toolbox-icon.toggled {
|
||||
background: none;
|
||||
|
||||
&:hover {
|
||||
background: $newToolbarButtonHoverColor;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* On small mobile devices make the toolbar full width.
|
||||
*/
|
||||
.toolbox-content-mobile {
|
||||
@media (max-width: 500px) {
|
||||
margin-bottom: 0;
|
||||
|
||||
.toolbox-content-items {
|
||||
border-radius: 0;
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
padding: 6px 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
* Style variables
|
||||
*/
|
||||
$baseFontFamily: -apple-system, BlinkMacSystemFont, 'open_sanslight', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
$hangupColor: #bf2117;
|
||||
$hangupColor:#DD3849;
|
||||
$hangupHoverColor: #F25363;
|
||||
$hangupFontSize: 2em;
|
||||
|
||||
/**
|
||||
@@ -37,20 +38,20 @@ $presence-idle: rgb(172, 172, 172);
|
||||
/**
|
||||
* Toolbar
|
||||
*/
|
||||
$newToolbarBackgroundColor: rgba(22, 38, 55, 0.8);
|
||||
$newToolbarButtonHoverColor: rgba(255, 255, 255, 0.15);
|
||||
$newToolbarButtonToggleColor: rgba(255, 255, 255, 0.2);
|
||||
$newToolbarBackgroundColor: #131519;
|
||||
$newToolbarButtonHoverColor: rgba(255, 255, 255, 0.2);
|
||||
$newToolbarButtonToggleColor: rgba(255, 255, 255, 0.15);
|
||||
$AOTToolbarButtonHoverColor: rgba(14, 20, 35, 0.6);
|
||||
$AOTToolbarButtonToggleColor: rgba(14, 20, 35, 1);
|
||||
$menuBG:#242528;
|
||||
$newToolbarFontSize: 24px;
|
||||
$newToolbarHangupFontSize: 32px;
|
||||
$newToolbarSize: 40px;
|
||||
$newToolbarSize: 48px;
|
||||
$newToolbarSizeWithPadding: calc(#{$newToolbarSize} + 24px);
|
||||
$toolbarTitleFontSize: 19px;
|
||||
$overflowMenuBG: initial;
|
||||
$overflowMenuItemHoverBG: #313D52;
|
||||
$overflowMenuItemHoverColor: #B8C7E0;
|
||||
$overflowMenuItemColor: #B8C7E0;
|
||||
$overflowMenuItemColor: #fff;
|
||||
$overflowMenuItemBackground: #36383C;
|
||||
|
||||
|
||||
/**
|
||||
* Video layout
|
||||
@@ -122,8 +123,8 @@ $zindex10: 10;
|
||||
$reloadZ: 20;
|
||||
$poweredByZ: 100;
|
||||
$ringingZ: 300;
|
||||
$sideToolbarContainerZ: 300;
|
||||
$toolbarZ: 350;
|
||||
$sideToolbarContainerZ: 200;
|
||||
$toolbarZ: 250;
|
||||
$drawerZ: 351;
|
||||
$tooltipsZ: 401;
|
||||
$dropdownMaskZ: 900;
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
.video-preview {
|
||||
background: none;
|
||||
max-height: 290px;
|
||||
display: inline-block;
|
||||
max-height: 344px;
|
||||
|
||||
&-container {
|
||||
background: $menuBG;
|
||||
border-radius: 3px;
|
||||
overflow: auto;
|
||||
padding: 16px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
&-entry {
|
||||
cursor: pointer;
|
||||
height: 135px;
|
||||
margin-bottom: 16px;
|
||||
height: 168px;
|
||||
margin-bottom: 8px;
|
||||
position: relative;
|
||||
width: 240px;
|
||||
width: 284px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
@@ -20,13 +23,15 @@
|
||||
|
||||
&--selected {
|
||||
border: 3px solid #31B76A;
|
||||
border-radius: 3px;
|
||||
cursor: default;
|
||||
height: 129px;
|
||||
width: 234px;
|
||||
height: 162px;
|
||||
width: 278px;
|
||||
}
|
||||
}
|
||||
|
||||
&-video {
|
||||
border-radius: 3px;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
@@ -50,21 +55,28 @@
|
||||
}
|
||||
|
||||
&-label {
|
||||
bottom: 8px;
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
overflow: hidden;
|
||||
padding: 8px;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
width: 220px;
|
||||
width: 100%;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
// Override @atlaskit/InlineDialog container which is made with styled components
|
||||
& > div:nth-child(2) {
|
||||
outline: none;
|
||||
padding: 0;
|
||||
&-container {
|
||||
margin: 0 16px;
|
||||
}
|
||||
|
||||
&-text {
|
||||
background-color: #131519;
|
||||
border-radius: 3px;
|
||||
padding: 2px 8px;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
margin: 0 auto;
|
||||
max-width: calc(100% - 16px);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: fit-content;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,6 +208,11 @@ body.welcome-page {
|
||||
cursor: pointer;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.toolbox-icon {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.welcome-watermark {
|
||||
|
||||
@@ -43,6 +43,7 @@ $flagsImagePath: "../images/";
|
||||
@import 'modals/settings/settings';
|
||||
@import 'modals/speaker_stats/speaker_stats';
|
||||
@import 'modals/video-quality/video-quality';
|
||||
@import 'modals/virtual-background/virtual-background';
|
||||
@import 'modals/local-recording/local-recording';
|
||||
@import 'videolayout_default';
|
||||
@import 'notice';
|
||||
|
||||
44
css/modals/virtual-background/_virtual-background.scss
Normal file
@@ -0,0 +1,44 @@
|
||||
.virtual-background-dialog{
|
||||
display: inline-flex;
|
||||
cursor: pointer;
|
||||
.thumbnail{
|
||||
object-fit: cover;
|
||||
padding: 5px;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
}
|
||||
.thumbnail-selected{
|
||||
object-fit: cover;
|
||||
padding: 5px;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
border: 2px solid #a4b8d1;
|
||||
}
|
||||
.blur-selected{
|
||||
border: 2px solid #a4b8d1;
|
||||
}
|
||||
.virtual-background-none{
|
||||
font-weight: bold;
|
||||
padding: 5px;
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #a4b8d1;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
line-height: 35px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.none-selected{
|
||||
font-weight: bold;
|
||||
padding: 5px;
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
border-radius: 10px;
|
||||
border: 2px solid #a4b8d1;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
line-height: 35px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
BIN
images/virtual-background/background-1.jpg
Normal file
|
After Width: | Height: | Size: 437 KiB |
BIN
images/virtual-background/background-2.jpg
Normal file
|
After Width: | Height: | Size: 284 KiB |
BIN
images/virtual-background/background-3.jpg
Normal file
|
After Width: | Height: | Size: 216 KiB |
BIN
images/virtual-background/background-4.jpg
Normal file
|
After Width: | Height: | Size: 341 KiB |
@@ -198,23 +198,16 @@ var interfaceConfig = {
|
||||
TOOLBAR_ALWAYS_VISIBLE: false,
|
||||
|
||||
/**
|
||||
* The name of the toolbar buttons to display in the toolbar, including the
|
||||
* "More actions" menu. If present, the button will display. Exceptions are
|
||||
* "livestreaming" and "recording" which also require being a moderator and
|
||||
* some values in config.js to be enabled. Also, the "profile" button will
|
||||
* not display for users with a JWT.
|
||||
* Notes:
|
||||
* - it's impossible to choose which buttons go in the "More actions" menu
|
||||
* - it's impossible to control the placement of buttons
|
||||
* - 'desktop' controls the "Share your screen" button
|
||||
* DEPRECATED!
|
||||
* This config was moved to config.js as `toolbarButtons`.
|
||||
*/
|
||||
TOOLBAR_BUTTONS: [
|
||||
'microphone', 'camera', 'closedcaptions', 'desktop', 'embedmeeting', 'fullscreen',
|
||||
'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
|
||||
'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
|
||||
'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
|
||||
'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone', 'mute-video-everyone', 'security'
|
||||
],
|
||||
// TOOLBAR_BUTTONS: [
|
||||
// 'microphone', 'camera', 'closedcaptions', 'desktop', 'embedmeeting', 'fullscreen',
|
||||
// 'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
|
||||
// 'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
|
||||
// 'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
|
||||
// 'tileview', 'select-background', 'download', 'help', 'mute-everyone', 'mute-video-everyone', 'security'
|
||||
// ],
|
||||
|
||||
TOOLBAR_TIMEOUT: 4000,
|
||||
|
||||
|
||||
@@ -292,7 +292,7 @@ PODS:
|
||||
- React
|
||||
- react-native-splash-screen (3.2.0):
|
||||
- React
|
||||
- react-native-webrtc (1.87.3):
|
||||
- react-native-webrtc (1.89.1):
|
||||
- React-Core
|
||||
- react-native-webview (11.0.2):
|
||||
- React-Core
|
||||
@@ -563,7 +563,7 @@ SPEC CHECKSUMS:
|
||||
react-native-keep-awake: eba3137546b10003361b37c761f6c429b59814ae
|
||||
react-native-netinfo: 8d8db463bcc5db66a8ac5c48a7d86beb3b92f61a
|
||||
react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
|
||||
react-native-webrtc: dc1208bdca2c4d091f7b57859e69332bff6f1986
|
||||
react-native-webrtc: ccb0c21eb4fb04326648fbdb4a5d49977e2cf274
|
||||
react-native-webview: b2542d6fd424bcc3e3b2ec5f854f0abb4ec86c87
|
||||
React-RCTActionSheet: bcbc311dc3b47bc8efb2737ff0940239a45789a9
|
||||
React-RCTAnimation: 65f61080ce632f6dea23d52e354ffac9948396c6
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
<string>applinks:beta.meet.jit.si</string>
|
||||
<string>applinks:meet.jit.si</string>
|
||||
</array>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.org.jitsi.meet.appgroup</string>
|
||||
</array>
|
||||
<key>com.apple.developer.siri</key>
|
||||
<true/>
|
||||
</dict>
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
4E51B75E25E4115F0038575A /* DarwinNotificationCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E51B75D25E4115F0038575A /* DarwinNotificationCenter.m */; };
|
||||
4EC49BB725BEDAC100E76218 /* ReplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EC49B8625BED71300E76218 /* ReplayKit.framework */; };
|
||||
4EC49BBB25BEDAC100E76218 /* SampleHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EC49BBA25BEDAC100E76218 /* SampleHandler.m */; };
|
||||
4EC49BBF25BEDAC100E76218 /* JitsiMeetBroadcast Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 4EC49BB625BEDAC100E76218 /* JitsiMeetBroadcast Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
4EC49BCB25BEDB6400E76218 /* SocketConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EC49BCA25BEDB6400E76218 /* SocketConnection.m */; };
|
||||
4EC49BD125BF19CF00E76218 /* SampleUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EC49BD025BF19CF00E76218 /* SampleUploader.m */; };
|
||||
55BEDABDA92D47D399A70A5E /* libPods-JitsiMeet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D878B07B3FBD6E305EAA6B27 /* libPods-JitsiMeet.a */; };
|
||||
DE050389256E904600DEE3A5 /* WebRTC.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = DE050388256E904600DEE3A5 /* WebRTC.xcframework */; };
|
||||
DE05038A256E904600DEE3A5 /* WebRTC.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DE050388256E904600DEE3A5 /* WebRTC.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
@@ -48,6 +54,13 @@
|
||||
remoteGlobalIDString = 0BEA5C241F7B8F73000D0AB4;
|
||||
remoteInfo = JitsiMeetCompanion;
|
||||
};
|
||||
4EC49BBD25BEDAC100E76218 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 4EC49BB525BEDAC100E76218;
|
||||
remoteInfo = "JitsiMeetBroadcast Extension";
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@@ -85,6 +98,17 @@
|
||||
name = "Embed Watch Content";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
4EC49B9025BED71300E76218 /* Embed App Extensions */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
4EC49BBF25BEDAC100E76218 /* JitsiMeetBroadcast Extension.appex in Embed App Extensions */,
|
||||
);
|
||||
name = "Embed App Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@@ -115,6 +139,18 @@
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
4670A512A688E2DC34528282 /* Pods-jitsi-meet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-jitsi-meet.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-jitsi-meet/Pods-jitsi-meet.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
4E51B75C25E4115F0038575A /* DarwinNotificationCenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinNotificationCenter.h; sourceTree = "<group>"; };
|
||||
4E51B75D25E4115F0038575A /* DarwinNotificationCenter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DarwinNotificationCenter.m; sourceTree = "<group>"; };
|
||||
4EC49B8625BED71300E76218 /* ReplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ReplayKit.framework; path = System/Library/Frameworks/ReplayKit.framework; sourceTree = SDKROOT; };
|
||||
4EC49BB625BEDAC100E76218 /* JitsiMeetBroadcast Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "JitsiMeetBroadcast Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
4EC49BB925BEDAC100E76218 /* SampleHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SampleHandler.h; sourceTree = "<group>"; };
|
||||
4EC49BBA25BEDAC100E76218 /* SampleHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleHandler.m; sourceTree = "<group>"; };
|
||||
4EC49BBC25BEDAC100E76218 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
4EC49BC925BEDB6400E76218 /* SocketConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SocketConnection.h; sourceTree = "<group>"; };
|
||||
4EC49BCA25BEDB6400E76218 /* SocketConnection.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SocketConnection.m; sourceTree = "<group>"; };
|
||||
4EC49BCF25BF19CF00E76218 /* SampleUploader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SampleUploader.h; sourceTree = "<group>"; };
|
||||
4EC49BD025BF19CF00E76218 /* SampleUploader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleUploader.m; sourceTree = "<group>"; };
|
||||
4EC49BDB25BF280A00E76218 /* extension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = extension.entitlements; sourceTree = "<group>"; };
|
||||
609CB2080B75F75A89923F3D /* Pods-JitsiMeet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
B3B083EB1D4955FF0069CEE7 /* app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = app.entitlements; sourceTree = "<group>"; };
|
||||
D878B07B3FBD6E305EAA6B27 /* libPods-JitsiMeet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-JitsiMeet.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -153,6 +189,14 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
4EC49BB325BEDAC100E76218 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
4EC49BB725BEDAC100E76218 /* ReplayKit.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
@@ -165,6 +209,7 @@
|
||||
DEFDBBDB25656E3B00344B23 /* WebRTC.xcframework */,
|
||||
0BD6B4361EF82A6B00D1F4CD /* WebRTC.framework */,
|
||||
D878B07B3FBD6E305EAA6B27 /* libPods-JitsiMeet.a */,
|
||||
4EC49B8625BED71300E76218 /* ReplayKit.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@@ -216,6 +261,24 @@
|
||||
path = src;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4EC49BB825BEDAC100E76218 /* JitsiMeetBroadcast Extension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4EC49BDB25BF280A00E76218 /* extension.entitlements */,
|
||||
4EC49BB925BEDAC100E76218 /* SampleHandler.h */,
|
||||
4EC49BBA25BEDAC100E76218 /* SampleHandler.m */,
|
||||
4EC49BC925BEDB6400E76218 /* SocketConnection.h */,
|
||||
4EC49BCA25BEDB6400E76218 /* SocketConnection.m */,
|
||||
4EC49BCF25BF19CF00E76218 /* SampleUploader.h */,
|
||||
4EC49BD025BF19CF00E76218 /* SampleUploader.m */,
|
||||
4EC49BBC25BEDAC100E76218 /* Info.plist */,
|
||||
4E51B75C25E4115F0038575A /* DarwinNotificationCenter.h */,
|
||||
4E51B75D25E4115F0038575A /* DarwinNotificationCenter.m */,
|
||||
);
|
||||
name = "JitsiMeetBroadcast Extension";
|
||||
path = "broadcast-extension";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5E96ADD5E49F3B3822EF9A52 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -236,6 +299,7 @@
|
||||
13B07FAE1A68108700A75B9A /* src */,
|
||||
5E96ADD5E49F3B3822EF9A52 /* Pods */,
|
||||
0BEA5C261F7B8F73000D0AB4 /* Watch app */,
|
||||
4EC49BB825BEDAC100E76218 /* JitsiMeetBroadcast Extension */,
|
||||
0BEA5C351F7B8F73000D0AB4 /* WatchKit extension */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
@@ -248,6 +312,7 @@
|
||||
13B07F961A680F5B00A75B9A /* jitsi-meet.app */,
|
||||
0BEA5C251F7B8F73000D0AB4 /* JitsiMeetCompanion.app */,
|
||||
0BEA5C311F7B8F73000D0AB4 /* JitsiMeetCompanion Extension.appex */,
|
||||
4EC49BB625BEDAC100E76218 /* JitsiMeetBroadcast Extension.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -305,17 +370,36 @@
|
||||
DE11877A21EE09640078D059 /* Setup Google reverse URL handler */,
|
||||
DE4F6D6E22005C0400DE699E /* Setup Dropbox */,
|
||||
0BEA5C491F7B8F73000D0AB4 /* Embed Watch Content */,
|
||||
4EC49B9025BED71300E76218 /* Embed App Extensions */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
0BEA5C401F7B8F73000D0AB4 /* PBXTargetDependency */,
|
||||
4EC49BBE25BEDAC100E76218 /* PBXTargetDependency */,
|
||||
);
|
||||
name = JitsiMeet;
|
||||
productName = "Jitsi Meet";
|
||||
productReference = 13B07F961A680F5B00A75B9A /* jitsi-meet.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
4EC49BB525BEDAC100E76218 /* JitsiMeetBroadcast Extension */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 4EC49BC025BEDAC100E76218 /* Build configuration list for PBXNativeTarget "JitsiMeetBroadcast Extension" */;
|
||||
buildPhases = (
|
||||
4EC49BB225BEDAC100E76218 /* Sources */,
|
||||
4EC49BB325BEDAC100E76218 /* Frameworks */,
|
||||
4EC49BB425BEDAC100E76218 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "JitsiMeetBroadcast Extension";
|
||||
productName = "JitsiMeetBroadcast Extension";
|
||||
productReference = 4EC49BB625BEDAC100E76218 /* JitsiMeetBroadcast Extension.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
@@ -336,8 +420,6 @@
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
13B07F861A680F5B00A75B9A = {
|
||||
DevelopmentTeam = FC967L3QRG;
|
||||
ProvisioningStyle = Automatic;
|
||||
SystemCapabilities = {
|
||||
com.apple.SafariKeychain = {
|
||||
enabled = 1;
|
||||
@@ -347,6 +429,9 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
4EC49BB525BEDAC100E76218 = {
|
||||
CreatedOnToolsVersion = 12.2;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "app" */;
|
||||
@@ -365,6 +450,7 @@
|
||||
13B07F861A680F5B00A75B9A /* JitsiMeet */,
|
||||
0BEA5C241F7B8F73000D0AB4 /* JitsiMeetCompanion */,
|
||||
0BEA5C301F7B8F73000D0AB4 /* JitsiMeetCompanion Extension */,
|
||||
4EC49BB525BEDAC100E76218 /* JitsiMeetBroadcast Extension */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@@ -397,6 +483,13 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
4EC49BB425BEDAC100E76218 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
@@ -532,6 +625,17 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
4EC49BB225BEDAC100E76218 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
4EC49BCB25BEDB6400E76218 /* SocketConnection.m in Sources */,
|
||||
4EC49BBB25BEDAC100E76218 /* SampleHandler.m in Sources */,
|
||||
4E51B75E25E4115F0038575A /* DarwinNotificationCenter.m in Sources */,
|
||||
4EC49BD125BF19CF00E76218 /* SampleUploader.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
@@ -545,6 +649,11 @@
|
||||
target = 0BEA5C241F7B8F73000D0AB4 /* JitsiMeetCompanion */;
|
||||
targetProxy = 0BEA5C3F1F7B8F73000D0AB4 /* PBXContainerItemProxy */;
|
||||
};
|
||||
4EC49BBE25BEDAC100E76218 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 4EC49BB525BEDAC100E76218 /* JitsiMeetBroadcast Extension */;
|
||||
targetProxy = 4EC49BBD25BEDAC100E76218 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
@@ -718,7 +827,7 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIconDebug;
|
||||
CODE_SIGN_ENTITLEMENTS = app.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
@@ -748,7 +857,7 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIconRelease;
|
||||
CODE_SIGN_ENTITLEMENTS = app.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = FC967L3QRG;
|
||||
@@ -770,6 +879,70 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
4EC49BC125BEDAC100E76218 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = "broadcast-extension/extension.entitlements";
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = FC967L3QRG;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = "broadcast-extension/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.meet.broadcast.extension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
4EC49BC225BEDAC100E76218 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = "broadcast-extension/extension.entitlements";
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = FC967L3QRG;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = "broadcast-extension/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.meet.broadcast.extension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
83CBBA201A601CBA00E9B192 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@@ -914,6 +1087,15 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
4EC49BC025BEDAC100E76218 /* Build configuration list for PBXNativeTarget "JitsiMeetBroadcast Extension" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
4EC49BC125BEDAC100E76218 /* Debug */,
|
||||
4EC49BC225BEDAC100E76218 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "app" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
||||
31
ios/app/broadcast-extension/DarwinNotificationCenter.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright @ 2021-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern NSNotificationName const kBroadcastStartedNotification;
|
||||
extern NSNotificationName const kBroadcastStoppedNotification;
|
||||
|
||||
@interface DarwinNotificationCenter: NSObject
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
- (void)postNotificationWithName:(NSNotificationName)name;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
50
ios/app/broadcast-extension/DarwinNotificationCenter.m
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright @ 2021-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "DarwinNotificationCenter.h"
|
||||
|
||||
NSNotificationName const kBroadcastStartedNotification = @"iOS_BroadcastStarted";
|
||||
NSNotificationName const kBroadcastStoppedNotification = @"iOS_BroadcastStopped";
|
||||
|
||||
@implementation DarwinNotificationCenter {
|
||||
CFNotificationCenterRef _notificationCenter;
|
||||
}
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static DarwinNotificationCenter *sharedInstance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[self alloc] init];
|
||||
});
|
||||
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_notificationCenter = CFNotificationCenterGetDarwinNotifyCenter();
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)postNotificationWithName:(NSString*)name {
|
||||
CFNotificationCenterPostNotification(_notificationCenter, (__bridge CFStringRef)name, NULL, NULL, true);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
33
ios/app/broadcast-extension/Info.plist
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>JitsiMeet Broadcast Extension</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>21.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.broadcast-services-upload</string>
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
<string>SampleHandler</string>
|
||||
<key>RPBroadcastProcessMode</key>
|
||||
<string>RPBroadcastProcessModeSampleBuffer</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
21
ios/app/broadcast-extension/SampleHandler.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright @ 2021-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <ReplayKit/ReplayKit.h>
|
||||
|
||||
@interface SampleHandler : RPBroadcastSampleHandler
|
||||
|
||||
@end
|
||||
123
ios/app/broadcast-extension/SampleHandler.m
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright @ 2021-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "SampleHandler.h"
|
||||
#import "SocketConnection.h"
|
||||
#import "SampleUploader.h"
|
||||
#import "DarwinNotificationCenter.h"
|
||||
|
||||
@interface SampleHandler ()
|
||||
|
||||
@property (nonatomic, retain) SocketConnection *clientConnection;
|
||||
@property (nonatomic, retain) SampleUploader *uploader;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SampleHandler
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.clientConnection = [[SocketConnection alloc] initWithFilePath:self.socketFilePath];
|
||||
[self setupConnection];
|
||||
|
||||
self.uploader = [[SampleUploader alloc] initWithConnection:self.clientConnection];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)broadcastStartedWithSetupInfo:(NSDictionary<NSString *,NSObject *> *)setupInfo {
|
||||
// User has requested to start the broadcast. Setup info from the UI extension can be supplied but optional.
|
||||
NSLog(@"broadcast started");
|
||||
|
||||
[[DarwinNotificationCenter sharedInstance] postNotificationWithName:kBroadcastStartedNotification];
|
||||
[self openConnection];
|
||||
}
|
||||
|
||||
- (void)broadcastPaused {
|
||||
// User has requested to pause the broadcast. Samples will stop being delivered.
|
||||
}
|
||||
|
||||
- (void)broadcastResumed {
|
||||
// User has requested to resume the broadcast. Samples delivery will resume.
|
||||
}
|
||||
|
||||
- (void)broadcastFinished {
|
||||
// User has requested to finish the broadcast.
|
||||
[[DarwinNotificationCenter sharedInstance] postNotificationWithName:kBroadcastStoppedNotification];
|
||||
[self.clientConnection close];
|
||||
}
|
||||
|
||||
- (void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType {
|
||||
static NSUInteger frameCount = 0;
|
||||
switch (sampleBufferType) {
|
||||
case RPSampleBufferTypeVideo:
|
||||
// adjust frame rate by using every third frame
|
||||
if (++frameCount%3 == 0 && self.uploader.isReady) {
|
||||
[self.uploader sendSample:sampleBuffer];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Private Methods
|
||||
|
||||
- (NSString *)socketFilePath {
|
||||
// the appGroupIdentifier must match the value provided in the app's info.plist for the RTCAppGroupIdentifier key
|
||||
NSString *appGroupIdentifier = @"group.org.jitsi.meet.appgroup";
|
||||
NSURL *sharedContainer = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:appGroupIdentifier];
|
||||
NSString *socketFilePath = [[sharedContainer URLByAppendingPathComponent:@"rtc_SSFD"] path];
|
||||
|
||||
return socketFilePath;
|
||||
}
|
||||
|
||||
- (void)setupConnection {
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
self.clientConnection.didClose = ^(NSError *error) {
|
||||
NSLog(@"client connection did close: %@", error);
|
||||
if (error) {
|
||||
[weakSelf finishBroadcastWithError:error];
|
||||
}
|
||||
else {
|
||||
NSInteger JMScreenSharingStopped = 10001;
|
||||
NSError *customError = [NSError errorWithDomain:RPRecordingErrorDomain
|
||||
code:JMScreenSharingStopped
|
||||
userInfo:@{NSLocalizedDescriptionKey: @"Screen sharing stopped"}];
|
||||
[weakSelf finishBroadcastWithError:customError];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
- (void)openConnection {
|
||||
dispatch_queue_t queue = dispatch_queue_create("org.jitsi.meet.broadcast.connectTimer", 0);
|
||||
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
|
||||
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), 0.1 * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC);
|
||||
|
||||
dispatch_source_set_event_handler(timer, ^{
|
||||
BOOL success = [self.clientConnection open];
|
||||
if (success) {
|
||||
dispatch_source_cancel(timer);
|
||||
}
|
||||
});
|
||||
|
||||
dispatch_resume(timer);
|
||||
}
|
||||
|
||||
@end
|
||||
33
ios/app/broadcast-extension/SampleUploader.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright @ 2021-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <ReplayKit/ReplayKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class SocketConnection;
|
||||
|
||||
@interface SampleUploader : NSObject
|
||||
|
||||
@property (nonatomic, assign, readonly) BOOL isReady;
|
||||
|
||||
- (instancetype)initWithConnection:(SocketConnection *)connection;
|
||||
- (void)sendSample:(CMSampleBufferRef)sampleBuffer;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
155
ios/app/broadcast-extension/SampleUploader.m
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright @ 2021-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <MessageUI/MessageUI.h>
|
||||
#import <ReplayKit/ReplayKit.h>
|
||||
|
||||
#import "SampleUploader.h"
|
||||
#import "SocketConnection.h"
|
||||
|
||||
static const NSInteger kBufferMaxLenght = 10 * 1024;
|
||||
|
||||
@interface SampleUploader ()
|
||||
|
||||
@property (nonatomic, assign) BOOL isReady;
|
||||
|
||||
@property (nonatomic, strong) dispatch_queue_t serialQueue;
|
||||
@property (nonatomic, strong) SocketConnection *connection;
|
||||
@property (nonatomic, strong) CIContext *imageContext;
|
||||
|
||||
@property (nonatomic, strong) NSData *dataToSend;
|
||||
@property (nonatomic, assign) NSUInteger byteIndex;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SampleUploader
|
||||
|
||||
- (instancetype)initWithConnection:(SocketConnection *)connection {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.serialQueue = dispatch_queue_create("org.jitsi.meet.broadcast.sampleUploader", DISPATCH_QUEUE_SERIAL);
|
||||
|
||||
self.connection = connection;
|
||||
[self setupConnection];
|
||||
|
||||
self.imageContext = [[CIContext alloc] initWithOptions:nil];
|
||||
self.isReady = false;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)sendSample:(CMSampleBufferRef)sampleBuffer {
|
||||
self.isReady = false;
|
||||
|
||||
self.dataToSend = [self prepareSample:sampleBuffer];
|
||||
self.byteIndex = 0;
|
||||
|
||||
dispatch_async(self.serialQueue, ^{
|
||||
[self sendData];
|
||||
});
|
||||
}
|
||||
|
||||
// MARK: Private Methods
|
||||
|
||||
- (void)setupConnection {
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
self.connection.didOpen = ^{
|
||||
weakSelf.isReady = true;
|
||||
};
|
||||
self.connection.streamHasSpaceAvailable = ^{
|
||||
dispatch_async(weakSelf.serialQueue, ^{
|
||||
weakSelf.isReady = ![weakSelf sendData];
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
This function downscales and converts to jpeg the provided sample buffer, then wraps the resulted image data into a CFHTTPMessageRef. Returns the serialized CFHTTPMessageRef.
|
||||
*/
|
||||
- (NSData *)prepareSample:(CMSampleBufferRef)sampleBuffer {
|
||||
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
|
||||
|
||||
CVPixelBufferLockBaseAddress(imageBuffer, kCVPixelBufferLock_ReadOnly);
|
||||
|
||||
CGFloat scaleFactor = 2;
|
||||
size_t width = CVPixelBufferGetWidth(imageBuffer)/scaleFactor;
|
||||
size_t height = CVPixelBufferGetHeight(imageBuffer)/scaleFactor;
|
||||
|
||||
CGAffineTransform scaleTransform = CGAffineTransformMakeScale(1/scaleFactor, 1/scaleFactor);
|
||||
NSData *bufferData = [self jpegDataFromPixelBuffer:imageBuffer withScaling:scaleTransform];
|
||||
|
||||
CVPixelBufferUnlockBaseAddress(imageBuffer, kCVPixelBufferLock_ReadOnly);
|
||||
|
||||
if (bufferData) {
|
||||
CFHTTPMessageRef httpResponse = CFHTTPMessageCreateResponse(kCFAllocatorDefault, 200, NULL, kCFHTTPVersion1_1);
|
||||
CFHTTPMessageSetHeaderFieldValue(httpResponse, (__bridge CFStringRef)@"Content-Length", (__bridge CFStringRef)[NSString stringWithFormat:@"%ld", bufferData.length]);
|
||||
CFHTTPMessageSetHeaderFieldValue(httpResponse, (__bridge CFStringRef)@"Buffer-Width", (__bridge CFStringRef)[NSString stringWithFormat:@"%ld", width]);
|
||||
CFHTTPMessageSetHeaderFieldValue(httpResponse, (__bridge CFStringRef)@"Buffer-Height", (__bridge CFStringRef)[NSString stringWithFormat:@"%ld", height]);
|
||||
|
||||
CFHTTPMessageSetBody(httpResponse, (__bridge CFDataRef)bufferData);
|
||||
|
||||
CFDataRef serializedMessage = CFHTTPMessageCopySerializedMessage(httpResponse);
|
||||
CFRelease(httpResponse);
|
||||
|
||||
return CFBridgingRelease(serializedMessage);
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)sendData {
|
||||
if (!self.dataToSend) {
|
||||
NSLog(@"no data to send");
|
||||
return false;
|
||||
}
|
||||
|
||||
NSUInteger bytesLeft = self.dataToSend.length - self.byteIndex;
|
||||
|
||||
NSInteger length = bytesLeft > kBufferMaxLenght ? kBufferMaxLenght : bytesLeft;
|
||||
uint8_t buffer[length];
|
||||
[self.dataToSend getBytes:&buffer range:NSMakeRange(self.byteIndex, length)];
|
||||
|
||||
length = [self.connection writeBufferToStream:buffer maxLength:length];
|
||||
if (length > 0) {
|
||||
self.byteIndex += length;
|
||||
bytesLeft -= length;
|
||||
|
||||
if (bytesLeft == 0) {
|
||||
NSLog(@"video sample processed successfully");
|
||||
self.dataToSend = nil;
|
||||
self.byteIndex = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
NSLog(@"writeBufferToStream failure");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
- (NSData *)jpegDataFromPixelBuffer:(CVPixelBufferRef)pixelBuffer withScaling:(CGAffineTransform)scaleTransform {
|
||||
CIImage *image = [[CIImage alloc] initWithCVPixelBuffer:pixelBuffer];
|
||||
image = [image imageByApplyingTransform:scaleTransform];
|
||||
|
||||
NSDictionary *options = @{(NSString *)kCGImageDestinationLossyCompressionQuality: [NSNumber numberWithFloat:1.0]};
|
||||
NSData *imageData = [self.imageContext JPEGRepresentationOfImage:image
|
||||
colorSpace:image.colorSpace
|
||||
options:options];
|
||||
return imageData;
|
||||
}
|
||||
|
||||
@end
|
||||
34
ios/app/broadcast-extension/SocketConnection.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright @ 2021-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface SocketConnection : NSObject
|
||||
|
||||
@property (nonatomic, copy, nullable) void (^didOpen)(void);
|
||||
@property (nonatomic, copy, nullable) void (^didClose)(NSError*);
|
||||
@property (nonatomic, copy, nullable) void (^streamHasSpaceAvailable)(void);
|
||||
|
||||
- (instancetype)initWithFilePath:(nonnull NSString *)filePath;
|
||||
- (BOOL)open;
|
||||
- (void)close;
|
||||
- (NSInteger)writeBufferToStream:(const uint8_t*)buffer maxLength:(NSInteger)length;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
189
ios/app/broadcast-extension/SocketConnection.m
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright @ 2021-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#import "SocketConnection.h"
|
||||
|
||||
@interface SocketConnection () <NSStreamDelegate>
|
||||
|
||||
@property (nonatomic, copy) NSString *filePath;
|
||||
|
||||
@property (nonatomic, strong) NSInputStream *inputStream;
|
||||
@property (nonatomic, strong) NSOutputStream *outputStream;
|
||||
|
||||
@property (nonatomic, strong) NSThread *networkThread;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SocketConnection {
|
||||
int _socket;
|
||||
struct sockaddr_un _socketAddr;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFilePath:(NSString *)path {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.filePath = path;
|
||||
|
||||
[self setupSocketWithFilePath:path];
|
||||
[self setupNetworkThread];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)open {
|
||||
NSLog(@"Open socket connection");
|
||||
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:self.filePath]) {
|
||||
NSLog(@"failure: socket file missing");
|
||||
return false;
|
||||
}
|
||||
|
||||
int status = connect(_socket, (struct sockaddr *)&_socketAddr, sizeof(_socketAddr));
|
||||
if (status < 0) {
|
||||
NSLog(@"failure: socket connect (%d)", status);
|
||||
return false;
|
||||
}
|
||||
|
||||
[self.networkThread start];
|
||||
|
||||
CFReadStreamRef readStream;
|
||||
CFWriteStreamRef writeStream;
|
||||
|
||||
CFStreamCreatePairWithSocket(kCFAllocatorDefault, _socket, &readStream, &writeStream);
|
||||
|
||||
self.inputStream = (__bridge_transfer NSInputStream *)readStream;
|
||||
self.inputStream.delegate = self;
|
||||
[self.inputStream setProperty:@"kCFBooleanTrue" forKey:@"kCFStreamPropertyShouldCloseNativeSocket"];
|
||||
|
||||
self.outputStream = (__bridge_transfer NSOutputStream *)writeStream;
|
||||
self.outputStream.delegate = self;
|
||||
[self.outputStream setProperty:@"kCFBooleanTrue" forKey:@"kCFStreamPropertyShouldCloseNativeSocket"];
|
||||
|
||||
[self performSelector:@selector(scheduleStreams) onThread:self.networkThread withObject:nil waitUntilDone:true];
|
||||
|
||||
[self.inputStream open];
|
||||
[self.outputStream open];
|
||||
|
||||
NSLog(@"read stream status: %ld", CFReadStreamGetStatus(readStream));
|
||||
NSLog(@"write stream status: %ld", CFWriteStreamGetStatus(writeStream));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
- (void)close {
|
||||
[self performSelector:@selector(unscheduleStreams) onThread:self.networkThread withObject:nil waitUntilDone:true];
|
||||
|
||||
self.inputStream.delegate = nil;
|
||||
self.outputStream.delegate = nil;
|
||||
|
||||
[self.inputStream close];
|
||||
[self.outputStream close];
|
||||
|
||||
[self.networkThread cancel];
|
||||
}
|
||||
|
||||
- (NSInteger)writeBufferToStream:(const uint8_t*)buffer maxLength:(NSInteger)length {
|
||||
return [self.outputStream write:buffer maxLength:length];
|
||||
}
|
||||
|
||||
// MARK: Private Methods
|
||||
|
||||
- (BOOL)isOpen {
|
||||
return self.inputStream.streamStatus == NSStreamStatusOpen && self.outputStream.streamStatus == NSStreamStatusOpen;
|
||||
}
|
||||
|
||||
- (void)setupSocketWithFilePath:(NSString*)path {
|
||||
_socket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
memset(&_socketAddr, 0, sizeof(_socketAddr));
|
||||
_socketAddr.sun_family = AF_UNIX;
|
||||
strncpy(_socketAddr.sun_path, path.UTF8String, sizeof(_socketAddr.sun_path) - 1);
|
||||
}
|
||||
|
||||
- (void)setupNetworkThread {
|
||||
self.networkThread = [[NSThread alloc] initWithBlock:^{
|
||||
do {
|
||||
@autoreleasepool {
|
||||
[[NSRunLoop currentRunLoop] run];
|
||||
}
|
||||
} while (![NSThread currentThread].isCancelled);
|
||||
}];
|
||||
self.networkThread.qualityOfService = NSQualityOfServiceUserInitiated;
|
||||
}
|
||||
|
||||
- (void)scheduleStreams {
|
||||
[self.inputStream scheduleInRunLoop:NSRunLoop.currentRunLoop forMode:NSRunLoopCommonModes];
|
||||
[self.outputStream scheduleInRunLoop:NSRunLoop.currentRunLoop forMode:NSRunLoopCommonModes];
|
||||
}
|
||||
|
||||
- (void)unscheduleStreams {
|
||||
[self.inputStream removeFromRunLoop:NSRunLoop.currentRunLoop forMode:NSRunLoopCommonModes];
|
||||
[self.outputStream removeFromRunLoop:NSRunLoop.currentRunLoop forMode:NSRunLoopCommonModes];
|
||||
}
|
||||
|
||||
- (void)notifyDidClose:(NSError *)error {
|
||||
if (self.didClose) {
|
||||
self.didClose(error);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - NSStreamDelegate
|
||||
|
||||
@implementation SocketConnection (NSStreamDelegate)
|
||||
|
||||
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
|
||||
switch (eventCode) {
|
||||
case NSStreamEventOpenCompleted:
|
||||
NSLog(@"client stream open completed");
|
||||
if (aStream == self.outputStream && self.didOpen) {
|
||||
self.didOpen();
|
||||
}
|
||||
break;
|
||||
case NSStreamEventHasBytesAvailable:
|
||||
if (aStream == self.inputStream) {
|
||||
uint8_t buffer;
|
||||
NSInteger numberOfBytesRead = [(NSInputStream *)aStream read:&buffer maxLength:sizeof(buffer)];
|
||||
if (!numberOfBytesRead && aStream.streamStatus == NSStreamStatusAtEnd) {
|
||||
NSLog(@"server socket closed");
|
||||
[self close];
|
||||
[self notifyDidClose:nil];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NSStreamEventHasSpaceAvailable:
|
||||
if (aStream == self.outputStream && self.streamHasSpaceAvailable) {
|
||||
NSLog(@"client stream has space available");
|
||||
self.streamHasSpaceAvailable();
|
||||
}
|
||||
break;
|
||||
case NSStreamEventErrorOccurred:
|
||||
NSLog(@"client stream error occurred: %@", aStream.streamError);
|
||||
[self close];
|
||||
[self notifyDidClose:aStream.streamError];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
10
ios/app/broadcast-extension/extension.entitlements
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.org.jitsi.meet.appgroup</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -51,7 +51,7 @@
|
||||
if ([FIRUtilities appContainsRealServiceInfoPlist]) {
|
||||
NSLog(@"Enabling Firebase");
|
||||
[FIRApp configure];
|
||||
// Crashlytics defaults to disabled wirth the FirebaseCrashlyticsCollectionEnabled Info.plist key.
|
||||
// Crashlytics defaults to disabled with the FirebaseCrashlyticsCollectionEnabled Info.plist key.
|
||||
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:![jitsiMeet isCrashReportingDisabled]];
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>FirebaseCrashlyticsCollectionEnabled</key>
|
||||
<string>false</string>
|
||||
<key>FirebaseScreenReportingEnabled</key>
|
||||
<false/>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
@@ -66,14 +68,18 @@
|
||||
<string>See your scheduled meetings in the app.</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Participate in meetings with video.</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>Participate in meetings with voice.</string>
|
||||
<key>NSLocalNetworkUsageDescription</key>
|
||||
<string>Local network is used for establishing Peer-to-Peer connections.</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>Participate in meetings with voice.</string>
|
||||
<key>NSUserActivityTypes</key>
|
||||
<array>
|
||||
<string>org.jitsi.JitsiMeet.ios.conference</string>
|
||||
</array>
|
||||
<key>RTCAppGroupIdentifier</key>
|
||||
<string>group.org.jitsi.meet.appgroup</string>
|
||||
<key>RTCScreenSharingExtension</key>
|
||||
<string>org.jitsi.meet.broadcast.extension</string>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>audio</string>
|
||||
@@ -99,7 +105,5 @@
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>FirebaseCrashlyticsCollectionEnabled</key>
|
||||
<string>false</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -35,7 +35,7 @@ fi
|
||||
|
||||
echo "PR_REPO_SLUG=${PR_REPO_SLUG} PR_BRANCH=${PR_BRANCH}"
|
||||
|
||||
# do the marge and git log
|
||||
# do the merge and git log
|
||||
|
||||
if [ $PR_BRANCH != "master" ]; then
|
||||
echo "Will merge ${PR_REPO_SLUG}/${PR_BRANCH} into master"
|
||||
|
||||
@@ -90,7 +90,7 @@ echo "importing dev-key.p12"
|
||||
security import ${CERT_DIR}/dev-key.p12 -k ios-build.keychain -P $IOS_SIGNING_CERT_PASSWORD -A
|
||||
|
||||
echo "will set-key-partition-list"
|
||||
# Fix for OS X Sierra that hungs in the codesign step
|
||||
# Fix for OS X Sierra that hangs in the codesign step
|
||||
security set-key-partition-list -S apple-tool:,apple: -s -k $ENCRYPTION_PASSWORD ios-build.keychain > /dev/null
|
||||
echo "done set-key-partition-list"
|
||||
|
||||
|
||||
@@ -16,6 +16,20 @@ platform :ios do
|
||||
app_identifier: "com.atlassian.JitsiMeet.ios"
|
||||
)
|
||||
|
||||
# Set the broadcast extension identifier
|
||||
update_app_identifier(
|
||||
xcodeproj: "app/app.xcodeproj",
|
||||
plist_path: "broadcast-extension/Info.plist",
|
||||
app_identifier: "com.atlassian.JitsiMeet.ios.broadcast"
|
||||
)
|
||||
update_info_plist(
|
||||
xcodeproj: "app/app.xcodeproj",
|
||||
plist_path: "src/Info.plist",
|
||||
block: proc do |plist|
|
||||
plist["RTCScreenSharingExtension"] = "com.atlassian.JitsiMeet.ios.broadcast"
|
||||
end
|
||||
)
|
||||
|
||||
# Set the (watch) app identifier
|
||||
update_app_identifier(
|
||||
xcodeproj: "app/app.xcodeproj",
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
0BCA49601EC4B6C600B793EE /* POSIX.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BCA495D1EC4B6C600B793EE /* POSIX.m */; };
|
||||
0BCA49611EC4B6C600B793EE /* Proximity.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BCA495E1EC4B6C600B793EE /* Proximity.m */; };
|
||||
0BD906EA1EC0C00300C8C18E /* JitsiMeet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BD906E81EC0C00300C8C18E /* JitsiMeet.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
4E51B76425E5345E0038575A /* ScheenshareEventEmiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E51B76225E5345E0038575A /* ScheenshareEventEmiter.h */; };
|
||||
4E51B76525E5345E0038575A /* ScheenshareEventEmiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E51B76325E5345E0038575A /* ScheenshareEventEmiter.m */; };
|
||||
6C31EDC820C06D490089C899 /* recordingOn.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 6C31EDC720C06D490089C899 /* recordingOn.mp3 */; };
|
||||
6C31EDCA20C06D530089C899 /* recordingOff.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 6C31EDC920C06D530089C899 /* recordingOff.mp3 */; };
|
||||
6F08DF7D4458EE3CF3F36F6D /* libPods-JitsiMeetSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E4376CA6886DE68FD7A4294B /* libPods-JitsiMeetSDK.a */; };
|
||||
@@ -85,6 +87,8 @@
|
||||
0BD906E51EC0C00300C8C18E /* JitsiMeetSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = JitsiMeetSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0BD906E81EC0C00300C8C18E /* JitsiMeet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeet.h; sourceTree = "<group>"; };
|
||||
0BD906E91EC0C00300C8C18E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
4E51B76225E5345E0038575A /* ScheenshareEventEmiter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScheenshareEventEmiter.h; sourceTree = "<group>"; };
|
||||
4E51B76325E5345E0038575A /* ScheenshareEventEmiter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScheenshareEventEmiter.m; sourceTree = "<group>"; };
|
||||
6C31EDC720C06D490089C899 /* recordingOn.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = recordingOn.mp3; path = ../../sounds/recordingOn.mp3; sourceTree = "<group>"; };
|
||||
6C31EDC920C06D530089C899 /* recordingOff.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = recordingOff.mp3; path = ../../sounds/recordingOff.mp3; sourceTree = "<group>"; };
|
||||
75635B0820751D6D00F29C9F /* joined.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = joined.wav; path = ../../sounds/joined.wav; sourceTree = "<group>"; };
|
||||
@@ -231,6 +235,8 @@
|
||||
C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */,
|
||||
C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */,
|
||||
C81E9AB825AC5AD800B134D9 /* ExternalAPI.h */,
|
||||
4E51B76225E5345E0038575A /* ScheenshareEventEmiter.h */,
|
||||
4E51B76325E5345E0038575A /* ScheenshareEventEmiter.m */,
|
||||
);
|
||||
path = src;
|
||||
sourceTree = "<group>";
|
||||
@@ -298,6 +304,7 @@
|
||||
0B93EF7E1EC9DDCD0030D24D /* RCTBridgeWrapper.h in Headers */,
|
||||
DE81A2DE2317ED5400AE1940 /* JitsiMeetBaseLogHandler.h in Headers */,
|
||||
DEA9F284258A5D9900D4CD74 /* JitsiMeetSDK.h in Headers */,
|
||||
4E51B76425E5345E0038575A /* ScheenshareEventEmiter.h in Headers */,
|
||||
DE65AACC2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h in Headers */,
|
||||
0B412F221EDEF6EA00B1A0A6 /* JitsiMeetViewDelegate.h in Headers */,
|
||||
0BD906EA1EC0C00300C8C18E /* JitsiMeet.h in Headers */,
|
||||
@@ -466,6 +473,7 @@
|
||||
C69EFA0C209A0F660027712B /* JMCallKitEmitter.swift in Sources */,
|
||||
DEFE535621FB2E8300011A3A /* ReactUtils.m in Sources */,
|
||||
C6A34261204EF76800E062DD /* DragGestureController.swift in Sources */,
|
||||
4E51B76525E5345E0038575A /* ScheenshareEventEmiter.m in Sources */,
|
||||
A4A934E9212F3ADB001E9388 /* Dropbox.m in Sources */,
|
||||
C69EFA0D209A0F660027712B /* JMCallKitProxy.swift in Sources */,
|
||||
DE81A2D52316AC4D00AE1940 /* JitsiMeetLogger.m in Sources */,
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#import "RCTBridgeWrapper.h"
|
||||
#import "ReactUtils.h"
|
||||
#import "RNSplashScreen.h"
|
||||
#import "ScheenshareEventEmiter.h"
|
||||
|
||||
#import <RNGoogleSignin/RNGoogleSignin.h>
|
||||
#import <WebRTC/RTCLogging.h>
|
||||
@@ -31,6 +32,7 @@
|
||||
@implementation JitsiMeet {
|
||||
RCTBridgeWrapper *_bridgeWrapper;
|
||||
NSDictionary *_launchOptions;
|
||||
ScheenshareEventEmiter *_screenshareEventEmiter;
|
||||
}
|
||||
|
||||
#pragma mak - This class is a singleton
|
||||
@@ -50,6 +52,9 @@
|
||||
if (self = [super init]) {
|
||||
// Initialize the on and only bridge for interfacing with React Native.
|
||||
_bridgeWrapper = [[RCTBridgeWrapper alloc] init];
|
||||
|
||||
// Initialize the listener for handling start/stop screensharing notifications.
|
||||
_screenshareEventEmiter = [[ScheenshareEventEmiter alloc] init];
|
||||
|
||||
// Register a fatal error handler for React.
|
||||
registerReactFatalErrorHandler();
|
||||
|
||||
@@ -184,7 +184,7 @@ static void initializeViewsMap() {
|
||||
// conference. However, React and, respectively,
|
||||
// appProperties/initialProperties are declarative expressions i.e. one and
|
||||
// the same URL will not trigger an automatic re-render in the JavaScript
|
||||
// source code. The workaround implemented bellow introduces imperativeness
|
||||
// source code. The workaround implemented below introduces imperativeness
|
||||
// in React Component props by defining a unique value per invocation.
|
||||
props[@"timestamp"] = @(mach_absolute_time());
|
||||
|
||||
|
||||
25
ios/sdk/src/ScheenshareEventEmiter.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright @ 2021-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface ScheenshareEventEmiter : NSObject
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
63
ios/sdk/src/ScheenshareEventEmiter.m
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright @ 2021-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "ScheenshareEventEmiter.h"
|
||||
#import "JitsiMeet+Private.h"
|
||||
#import "ExternalAPI.h"
|
||||
|
||||
NSNotificationName const kBroadcastStartedNotification = @"iOS_BroadcastStarted";
|
||||
NSNotificationName const kBroadcastStoppedNotification = @"iOS_BroadcastStopped";
|
||||
|
||||
@implementation ScheenshareEventEmiter {
|
||||
CFNotificationCenterRef _notificationCenter;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_notificationCenter = CFNotificationCenterGetDarwinNotifyCenter();
|
||||
[self setupObserver];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self clearObserver];
|
||||
}
|
||||
|
||||
// MARK: Private Methods
|
||||
|
||||
- (void)setupObserver {
|
||||
CFNotificationCenterAddObserver(_notificationCenter, (__bridge const void *)(self), broadcastToggleNotificationCallback, (__bridge CFStringRef)kBroadcastStartedNotification, NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
CFNotificationCenterAddObserver(_notificationCenter, (__bridge const void *)(self), broadcastToggleNotificationCallback, (__bridge CFStringRef)kBroadcastStoppedNotification, NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
}
|
||||
|
||||
- (void)clearObserver {
|
||||
CFNotificationCenterRemoveObserver(_notificationCenter, (__bridge const void *)(self), (__bridge CFStringRef)kBroadcastStartedNotification, NULL);
|
||||
CFNotificationCenterRemoveObserver(_notificationCenter, (__bridge const void *)(self), (__bridge CFStringRef)kBroadcastStoppedNotification, NULL);
|
||||
}
|
||||
|
||||
void broadcastToggleNotificationCallback(CFNotificationCenterRef center,
|
||||
void *observer,
|
||||
CFStringRef name,
|
||||
const void *object,
|
||||
CFDictionaryRef userInfo) {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI toggleScreenShare];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -76,7 +76,7 @@ internal final class JMCallKitEmitter: NSObject, CXProviderDelegate {
|
||||
|
||||
// Avoid mute actions ping-pong: if the mute action was caused by
|
||||
// the JS side (we requested a transaction) don't call the delegate
|
||||
// method. If it was called by the provder itself (when the user presses
|
||||
// method. If it was called by the provider itself (when the user presses
|
||||
// the mute button in the CallKit view) then call the delegate method.
|
||||
//
|
||||
// NOTE: don't try to be clever and remove this. Been there, done that.
|
||||
|
||||
@@ -29,7 +29,7 @@ public protocol PiPViewCoordinatorDelegate: class {
|
||||
/// when is presented in Picure in Picture mode.
|
||||
public class PiPViewCoordinator {
|
||||
|
||||
/// Limits the boundries of view position on screen when minimized
|
||||
/// Limits the boundaries of view position on screen when minimized
|
||||
public var dragBoundInsets: UIEdgeInsets = UIEdgeInsets(top: 25,
|
||||
left: 5,
|
||||
bottom: 5,
|
||||
|
||||
@@ -60,7 +60,7 @@ fi
|
||||
|
||||
echo "PR_REPO_SLUG=${PR_REPO_SLUG} PR_BRANCH=${PR_BRANCH}"
|
||||
|
||||
# do the marge and git log
|
||||
# do the merge and git log
|
||||
|
||||
if [ $PR_BRANCH != "master" ]; then
|
||||
echo "Will merge ${PR_REPO_SLUG}/${PR_BRANCH} into master"
|
||||
|
||||
@@ -332,6 +332,11 @@
|
||||
"embedMeeting": {
|
||||
"title": "Embed this meeting"
|
||||
},
|
||||
"virtualBackground": {
|
||||
"title": "Backgrounds",
|
||||
"enableBlur": "Enable blur",
|
||||
"removeBackground": "Remove background"
|
||||
},
|
||||
"feedback": {
|
||||
"average": "Average",
|
||||
"bad": "Bad",
|
||||
@@ -748,9 +753,10 @@
|
||||
"toggleCamera": "Toggle camera",
|
||||
"toggleFilmstrip": "Toggle filmstrip",
|
||||
"videomute": "Toggle mute video",
|
||||
"videoblur": "Toggle video blur"
|
||||
"selectBackground": "Select Background"
|
||||
},
|
||||
"addPeople": "Add people to your call",
|
||||
"audioSettings": "Audio settings",
|
||||
"audioOnlyOff": "Disable low bandwidth mode",
|
||||
"audioOnlyOn": "Enable low bandwidth mode",
|
||||
"audioRoute": "Select the sound device",
|
||||
@@ -809,8 +815,7 @@
|
||||
"tileViewToggle": "Toggle tile view",
|
||||
"toggleCamera": "Toggle camera",
|
||||
"videomute": "Start / Stop camera",
|
||||
"startvideoblur": "Blur my background",
|
||||
"stopvideoblur": "Disable background blur"
|
||||
"selectBackground": "Select background"
|
||||
},
|
||||
"transcribing": {
|
||||
"ccButtonTooltip": "Start / Stop subtitles",
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
setPassword,
|
||||
setSubject
|
||||
} from '../../react/features/base/conference';
|
||||
import { overwriteConfig, getWhitelistedJSON } from '../../react/features/base/config';
|
||||
import { parseJWTFromURLParams } from '../../react/features/base/jwt';
|
||||
import JitsiMeetJS, { JitsiRecordingConstants } from '../../react/features/base/lib-jitsi-meet';
|
||||
import { MEDIA_TYPE } from '../../react/features/base/media';
|
||||
@@ -356,6 +357,11 @@ function initCommands() {
|
||||
},
|
||||
'kick-participant': participantId => {
|
||||
APP.store.dispatch(kickParticipant(participantId));
|
||||
},
|
||||
'overwrite-config': config => {
|
||||
const whitelistedConfig = getWhitelistedJSON('config', config);
|
||||
|
||||
APP.store.dispatch(overwriteConfig(whitelistedConfig));
|
||||
}
|
||||
};
|
||||
transport.on('event', ({ data, name }) => {
|
||||
|
||||
3
modules/API/external/external_api.js
vendored
@@ -37,6 +37,7 @@ const commands = {
|
||||
intiatePrivateChat: 'initiate-private-chat',
|
||||
kickParticipant: 'kick-participant',
|
||||
muteEveryone: 'mute-everyone',
|
||||
overwriteConfig: 'overwrite-config',
|
||||
password: 'password',
|
||||
pinParticipant: 'pin-participant',
|
||||
resizeLargeVideo: 'resize-large-video',
|
||||
@@ -196,7 +197,7 @@ function parseArguments(args) {
|
||||
* @param {any} value - The value to be parsed.
|
||||
* @returns {string|undefined} The parsed value that can be used for setting
|
||||
* sizes through the style property. If invalid value is passed the method
|
||||
* retuns undefined.
|
||||
* returns undefined.
|
||||
*/
|
||||
function parseSizeParam(value) {
|
||||
let parsedValue;
|
||||
|
||||
@@ -63,7 +63,7 @@ function doExternalAuth(room, lockPassword) {
|
||||
|
||||
/**
|
||||
* Redirect the user to the token authentication service for the login to be
|
||||
* performed. Once complete it is expected that the service wil bring the user
|
||||
* performed. Once complete it is expected that the service will bring the user
|
||||
* back with "?jwt={the JWT token}" query parameter added.
|
||||
* @param {string} [roomName] the name of the conference room.
|
||||
*/
|
||||
@@ -76,7 +76,7 @@ function redirectToTokenAuthService(roomName) {
|
||||
/**
|
||||
* Initializes 'message' listener that will wait for a JWT token to be received
|
||||
* from the token authentication service opened in a popup window.
|
||||
* @param room the name fo the conference room.
|
||||
* @param room the name of the conference room.
|
||||
*/
|
||||
function initJWTTokenListener(room) {
|
||||
/**
|
||||
@@ -108,7 +108,7 @@ function initJWTTokenListener(room) {
|
||||
roomName, APP.conference._getConferenceOptions());
|
||||
|
||||
// Authenticate from the new connection to get
|
||||
// the session-ID from the focus, which wil then be used
|
||||
// the session-ID from the focus, which will then be used
|
||||
// to upgrade current connection's user role
|
||||
|
||||
newRoom.room.moderator.authenticate()
|
||||
@@ -116,7 +116,7 @@ function initJWTTokenListener(room) {
|
||||
connection.disconnect();
|
||||
|
||||
// At this point we'll have session-ID stored in
|
||||
// the settings. It wil be used in the call below
|
||||
// the settings. It will be used in the call below
|
||||
// to upgrade user's role
|
||||
room.room.moderator.authenticate()
|
||||
.then(() => {
|
||||
|
||||
@@ -498,7 +498,7 @@ export default class SharedVideoManager {
|
||||
* Receives events for local audio mute/unmute by local user.
|
||||
* @param muted boolena whether it is muted or not.
|
||||
* @param {boolean} indicates if this mute was a result of user interaction,
|
||||
* i.e. pressing the mute button or it was programatically triggerred
|
||||
* i.e. pressing the mute button or it was programmatically triggered
|
||||
*/
|
||||
onLocalAudioMuted(muted, userInteraction) {
|
||||
if (!this.player) {
|
||||
|
||||
@@ -37,7 +37,7 @@ const UIUtil = {
|
||||
* @param {string} url - The redirect URL.
|
||||
* NOTE: Currently used to redirect to 3rd party location for
|
||||
* authentication. In most cases redirectWithStoredParams action must be
|
||||
* used instead of this method in order to preserve curent URL params.
|
||||
* used instead of this method in order to preserve current URL params.
|
||||
*/
|
||||
redirect(url) {
|
||||
window.location.href = url;
|
||||
|
||||
@@ -221,6 +221,8 @@ export default class RemoteVideo extends SmallVideo {
|
||||
|
||||
streamElement.autoplay = !config.testing?.noAutoPlayVideo;
|
||||
streamElement.id = `remoteVideo_${stream.getId()}`;
|
||||
streamElement.mute = true;
|
||||
streamElement.playsInline = true;
|
||||
|
||||
// Put new stream element always in front
|
||||
streamElement = UIUtils.prependChild(this.container, streamElement);
|
||||
|
||||
@@ -350,7 +350,7 @@ export default class SmallVideo {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initalizes any browser specific properties. Currently sets the overflow
|
||||
* Initializes any browser specific properties. Currently sets the overflow
|
||||
* property for Qt browsers on Windows to hidden, thus fixing the following
|
||||
* problem:
|
||||
* Some browsers don't have full support of the object-fit property for the
|
||||
@@ -428,9 +428,9 @@ export default class SmallVideo {
|
||||
_shouldTriggerPin(event) {
|
||||
// TODO Checking the classes is a workround to allow events to bubble into
|
||||
// the DisplayName component if it was clicked. React's synthetic events
|
||||
// will fire after jQuery handlers execute, so stop propogation at this
|
||||
// will fire after jQuery handlers execute, so stop propagation at this
|
||||
// point will prevent DisplayName from getting click events. This workaround
|
||||
// should be removeable once LocalVideo is a React Component because then
|
||||
// should be removable once LocalVideo is a React Component because then
|
||||
// the components share the same eventing system.
|
||||
const $source = $(event.target || event.srcElement);
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ function computeDesktopVideoSize( // eslint-disable-line max-params
|
||||
videoSpaceWidth,
|
||||
videoSpaceHeight) {
|
||||
if (videoWidth === 0 || videoHeight === 0 || videoSpaceWidth === 0 || videoSpaceHeight === 0) {
|
||||
// Avoid NaN values caused by devision by 0.
|
||||
// Avoid NaN values caused by division by 0.
|
||||
return [ 0, 0 ];
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ function computeCameraVideoSize( // eslint-disable-line max-params
|
||||
videoSpaceHeight,
|
||||
videoLayoutFit) {
|
||||
if (videoWidth === 0 || videoHeight === 0 || videoSpaceWidth === 0 || videoSpaceHeight === 0) {
|
||||
// Avoid NaN values caused by devision by 0.
|
||||
// Avoid NaN values caused by division by 0.
|
||||
return [ 0, 0 ];
|
||||
}
|
||||
|
||||
@@ -411,7 +411,7 @@ export class VideoContainer extends LargeContainer {
|
||||
const [ width, height ] = this._getVideoSize(containerWidth, containerHeight);
|
||||
|
||||
if (width === 0 || height === 0) {
|
||||
// We don't need to set 0 for width or height since the visibility is controled by the visibility css prop
|
||||
// We don't need to set 0 for width or height since the visibility is controlled by the visibility css prop
|
||||
// on the largeVideoElementsContainer. Also if the width/height of the video element is 0 the attached
|
||||
// stream won't be played. Normally if we attach a new stream we won't resize the video element until the
|
||||
// stream has been played. But setting width/height to 0 will prevent the video from playing.
|
||||
@@ -610,7 +610,7 @@ export class VideoContainer extends LargeContainer {
|
||||
// explicitly disabled.
|
||||
if (interfaceConfig.DISABLE_VIDEO_BACKGROUND
|
||||
|| browser.isFirefox()
|
||||
|| browser.isSafari()) {
|
||||
|| browser.isWebKitBased()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -596,7 +596,7 @@ const VideoLayout = {
|
||||
localVideoThumbnail && localVideoThumbnail.updateDOMLocation();
|
||||
VideoLayout.resizeVideoArea();
|
||||
|
||||
// Rerender the thumbnails since they are dependant on the layout because of the tooltip positioning.
|
||||
// Rerender the thumbnails since they are dependent on the layout because of the tooltip positioning.
|
||||
localVideoThumbnail && localVideoThumbnail.rerender();
|
||||
Object.values(remoteVideos).forEach(remoteVideoThumbnail => remoteVideoThumbnail.rerender());
|
||||
},
|
||||
|
||||
@@ -46,7 +46,14 @@ export class TaskQueue {
|
||||
this._currentTask = this._queue.shift() || null;
|
||||
|
||||
if (this._currentTask) {
|
||||
this._currentTask(this._onTaskComplete);
|
||||
logger.debug('Executing a task.');
|
||||
|
||||
try {
|
||||
this._currentTask(this._onTaskComplete);
|
||||
} catch (error) {
|
||||
logger.error(`Task execution failed: ${error}`);
|
||||
this._onTaskComplete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +65,7 @@ export class TaskQueue {
|
||||
*/
|
||||
_onTaskComplete() {
|
||||
this._currentTask = null;
|
||||
logger.debug('Task completed.');
|
||||
this._executeNext();
|
||||
}
|
||||
}
|
||||
|
||||
52
package-lock.json
generated
@@ -2586,9 +2586,9 @@
|
||||
}
|
||||
},
|
||||
"@jitsi/js-utils": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@jitsi/js-utils/-/js-utils-1.0.5.tgz",
|
||||
"integrity": "sha512-1APQyuqQaYDR+W7cdgzsaBo6x8dpF8sfelcBf3ngNU3Jd+DzuuwUvCMTbr2+cCuy6w59ZAuQ7e2ixCnnOXOW4Q==",
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jitsi/js-utils/-/js-utils-1.0.6.tgz",
|
||||
"integrity": "sha512-XdLvgzhEhMsrzHBDgBydvWneGXSZ8ycg+dEK9bs2CLQhH5A9cHOOToDl9p/skts7WHQp4C8nkhsNzWC/cRvszQ==",
|
||||
"requires": {
|
||||
"bowser": "2.7.0",
|
||||
"js-md5": "0.7.3"
|
||||
@@ -6985,24 +6985,30 @@
|
||||
"integrity": "sha512-T7mYop3aDpRHIQaUYcmzmh6j9MAe560n6ukqjJMbVC6bVTau7dSpvB18bcsBPPtOSe10cKxhJFtlbEzLa0LL1g=="
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "6.5.3",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
|
||||
"integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
|
||||
"version": "6.5.4",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
|
||||
"integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bn.js": "^4.4.0",
|
||||
"brorand": "^1.0.1",
|
||||
"bn.js": "^4.11.9",
|
||||
"brorand": "^1.1.0",
|
||||
"hash.js": "^1.0.0",
|
||||
"hmac-drbg": "^1.0.0",
|
||||
"inherits": "^2.0.1",
|
||||
"minimalistic-assert": "^1.0.0",
|
||||
"minimalistic-crypto-utils": "^1.0.0"
|
||||
"hmac-drbg": "^1.0.1",
|
||||
"inherits": "^2.0.4",
|
||||
"minimalistic-assert": "^1.0.1",
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
"version": "4.11.9",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
|
||||
"integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
|
||||
"version": "4.12.0",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
|
||||
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
|
||||
"dev": true
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
@@ -10259,8 +10265,8 @@
|
||||
}
|
||||
},
|
||||
"lib-jitsi-meet": {
|
||||
"version": "github:jitsi/lib-jitsi-meet#f1ec96678002a88a0a87bb0a6fec1f5d642813d2",
|
||||
"from": "github:jitsi/lib-jitsi-meet#f1ec96678002a88a0a87bb0a6fec1f5d642813d2",
|
||||
"version": "github:jitsi/lib-jitsi-meet#676c7a910505833810314a665ad1e825a158850c",
|
||||
"from": "github:jitsi/lib-jitsi-meet#676c7a910505833810314a665ad1e825a158850c",
|
||||
"requires": {
|
||||
"@jitsi/js-utils": "1.0.2",
|
||||
"@jitsi/sdp-interop": "1.0.3",
|
||||
@@ -11486,9 +11492,9 @@
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.19.4",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.19.4.tgz",
|
||||
"integrity": "sha512-1xFTAknSLfc47DIxHDUbnJWC+UwgWxATmymaxIPQpmMh7LBm7ZbwVEsuushqwL2GYZU0jie4xO+TK44hJPjNSQ=="
|
||||
"version": "2.29.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
|
||||
},
|
||||
"moment-duration-format": {
|
||||
"version": "2.2.2",
|
||||
@@ -14071,9 +14077,9 @@
|
||||
"integrity": "sha512-iqdJ1KpZbR4XGahgVmaeibB7kDhyMT7wrylINgJaYBY38IAiI0LF32VX1umO4pko6n21YF5I/kSeNQ+OXGqqow=="
|
||||
},
|
||||
"react-native-webrtc": {
|
||||
"version": "1.87.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-1.87.3.tgz",
|
||||
"integrity": "sha512-fWnaEHFCFD7YnPR95aaUqLQ5b4dY4av0qHjmwHXeLHGvGrVeWF1je9PNhet7PDHUIJa4GIYKB/8+co51SXm5dA==",
|
||||
"version": "1.89.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-1.89.1.tgz",
|
||||
"integrity": "sha512-YBvSoSpw3dvRQr5LcOmdS/56arCBwtrIqdgPuYURbGheJbGAE/wYfeqMKa2fiIQ6EoYkFNZPDV5n4M7/f3KvlQ==",
|
||||
"requires": {
|
||||
"base64-js": "^1.1.2",
|
||||
"cross-os": "^1.3.0",
|
||||
|
||||
11
package.json
@@ -32,7 +32,7 @@
|
||||
"@atlaskit/theme": "11.0.2",
|
||||
"@atlaskit/toggle": "12.0.3",
|
||||
"@atlaskit/tooltip": "17.1.2",
|
||||
"@jitsi/js-utils": "1.0.5",
|
||||
"@jitsi/js-utils": "1.0.6",
|
||||
"@microsoft/microsoft-graph-client": "1.1.0",
|
||||
"@react-native-async-storage/async-storage": "1.13.2",
|
||||
"@react-native-community/google-signin": "3.0.1",
|
||||
@@ -55,7 +55,7 @@
|
||||
"jquery-i18next": "1.2.1",
|
||||
"js-md5": "0.6.1",
|
||||
"jwt-decode": "2.2.0",
|
||||
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#f1ec96678002a88a0a87bb0a6fec1f5d642813d2",
|
||||
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#676c7a910505833810314a665ad1e825a158850c",
|
||||
"libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.29.1",
|
||||
@@ -84,7 +84,7 @@
|
||||
"react-native-svg-transformer": "0.14.3",
|
||||
"react-native-url-polyfill": "1.2.0",
|
||||
"react-native-watch-connectivity": "0.4.3",
|
||||
"react-native-webrtc": "1.87.3",
|
||||
"react-native-webrtc": "1.89.1",
|
||||
"react-native-webview": "11.0.2",
|
||||
"react-native-youtube-iframe": "1.2.3",
|
||||
"react-redux": "7.1.0",
|
||||
@@ -148,7 +148,10 @@
|
||||
"scripts": {
|
||||
"lint": "eslint . && flow",
|
||||
"postinstall": "jetify",
|
||||
"validate": "npm ls"
|
||||
"validate": "npm ls",
|
||||
"start": "make dev",
|
||||
"ios": "react-native run-ios",
|
||||
"android": "react-native run-android"
|
||||
},
|
||||
"browser": {
|
||||
"jQuery-Impromptu": "jQuery-Impromptu/src/jquery-impromptu.js"
|
||||
|
||||
@@ -48,11 +48,11 @@ export default class Toolbar extends Component<Props> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className = { `always-on-top-toolbox ${className}` }
|
||||
className = { `toolbox-content-items always-on-top-toolbox ${className}` }
|
||||
onMouseOut = { onMouseOut }
|
||||
onMouseOver = { onMouseOver }>
|
||||
<AudioMuteButton />
|
||||
<HangupButton />
|
||||
<HangupButton customClass = 'hangup-button' />
|
||||
<VideoMuteButton />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -25,7 +25,6 @@ import '../base/testing/reducer';
|
||||
import '../base/tracks/reducer';
|
||||
import '../base/user-interaction/reducer';
|
||||
import '../billing-counter/reducer';
|
||||
import '../blur/reducer';
|
||||
import '../calendar-sync/reducer';
|
||||
import '../chat/reducer';
|
||||
import '../deep-linking/reducer';
|
||||
|
||||
@@ -12,5 +12,5 @@ import '../remote-control/reducer';
|
||||
import '../screenshot-capture/reducer';
|
||||
import '../shared-video/reducer';
|
||||
import '../talk-while-muted/reducer';
|
||||
|
||||
import '../virtual-background/reducer';
|
||||
import './reducers.any';
|
||||
|
||||
@@ -55,6 +55,6 @@ export default {
|
||||
button: 'rgb(255, 255, 255)',
|
||||
buttonToggled: 'rgb(38, 58, 76)',
|
||||
buttonToggledBorder: getRGBAFormat('#a4b8d1', 0.6),
|
||||
hangup: 'rgb(225, 45, 45)'
|
||||
hangup: 'rgb(227,79,86)'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ import { getName } from '../../app/functions';
|
||||
import { endpointMessageReceived } from '../../subtitles';
|
||||
import { JITSI_CONNECTION_CONFERENCE_KEY } from '../connection';
|
||||
import { JitsiConferenceEvents } from '../lib-jitsi-meet';
|
||||
import { setAudioMuted, setVideoMuted } from '../media';
|
||||
import { MEDIA_TYPE, setAudioMuted, setVideoMuted } from '../media';
|
||||
import {
|
||||
dominantSpeakerChanged,
|
||||
getLocalParticipant,
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
participantRoleChanged,
|
||||
participantUpdated
|
||||
} from '../participants';
|
||||
import { getLocalTracks, trackAdded, trackRemoved } from '../tracks';
|
||||
import { getLocalTracks, replaceLocalTrack, trackAdded, trackRemoved } from '../tracks';
|
||||
import {
|
||||
getBackendSafePath,
|
||||
getBackendSafeRoomName,
|
||||
@@ -72,10 +72,11 @@ declare var APP: Object;
|
||||
*
|
||||
* @param {JitsiConference} conference - The JitsiConference instance.
|
||||
* @param {Dispatch} dispatch - The Redux dispatch function.
|
||||
* @param {Object} state - The Redux state.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _addConferenceListeners(conference, dispatch) {
|
||||
function _addConferenceListeners(conference, dispatch, state) {
|
||||
// A simple logger for conference errors received through
|
||||
// the listener. These errors are not handled now, but logged.
|
||||
conference.on(JitsiConferenceEvents.CONFERENCE_ERROR,
|
||||
@@ -118,13 +119,12 @@ function _addConferenceListeners(conference, dispatch) {
|
||||
conference.on(
|
||||
JitsiConferenceEvents.STARTED_MUTED,
|
||||
() => {
|
||||
const audioMuted = Boolean(conference.startAudioMuted);
|
||||
const videoMuted = Boolean(conference.startVideoMuted);
|
||||
const audioMuted = Boolean(conference.isStartAudioMuted());
|
||||
const videoMuted = Boolean(conference.isStartVideoMuted());
|
||||
const localTracks = getLocalTracks(state['features/base/tracks']);
|
||||
|
||||
sendAnalytics(createStartMutedConfigurationEvent(
|
||||
'remote', audioMuted, videoMuted));
|
||||
logger.log(`Start muted: ${audioMuted ? 'audio, ' : ''}${
|
||||
videoMuted ? 'video' : ''}`);
|
||||
sendAnalytics(createStartMutedConfigurationEvent('remote', audioMuted, videoMuted));
|
||||
logger.log(`Start muted: ${audioMuted ? 'audio, ' : ''}${videoMuted ? 'video' : ''}`);
|
||||
|
||||
// XXX Jicofo tells lib-jitsi-meet to start with audio and/or video
|
||||
// muted i.e. Jicofo expresses an intent. Lib-jitsi-meet has turned
|
||||
@@ -136,6 +136,14 @@ function _addConferenceListeners(conference, dispatch) {
|
||||
// acting on Jicofo's intent without the app's knowledge.
|
||||
dispatch(setAudioMuted(audioMuted));
|
||||
dispatch(setVideoMuted(videoMuted));
|
||||
|
||||
// Remove the tracks from peerconnection as well.
|
||||
for (const track of localTracks) {
|
||||
if ((audioMuted && track.jitsiTrack.getType() === MEDIA_TYPE.AUDIO)
|
||||
|| (videoMuted && track.jitsiTrack.getType() === MEDIA_TYPE.VIDEO)) {
|
||||
replaceLocalTrack(track.jitsiTrack, null, conference);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Dispatches into features/base/tracks follow:
|
||||
@@ -448,7 +456,7 @@ export function createConference() {
|
||||
|
||||
dispatch(_conferenceWillJoin(conference));
|
||||
|
||||
_addConferenceListeners(conference, dispatch);
|
||||
_addConferenceListeners(conference, dispatch, state);
|
||||
|
||||
sendLocalParticipant(state, conference);
|
||||
|
||||
|
||||
@@ -48,3 +48,14 @@ export const SET_CONFIG = 'SET_CONFIG';
|
||||
* }
|
||||
*/
|
||||
export const UPDATE_CONFIG = 'UPDATE_CONFIG';
|
||||
|
||||
/**
|
||||
* The redux action which overwrites configurations represented by the feature
|
||||
* base/config. The passed on config values overwrite the current values for given props.
|
||||
*
|
||||
* {
|
||||
* type: OVERWRITE_CONFIG,
|
||||
* config: Object
|
||||
* }
|
||||
*/
|
||||
export const OVERWRITE_CONFIG = 'OVERWRITE_CONFIG';
|
||||
|
||||
@@ -6,7 +6,13 @@ import type { Dispatch } from 'redux';
|
||||
import { addKnownDomains } from '../known-domains';
|
||||
import { parseURIString } from '../util';
|
||||
|
||||
import { CONFIG_WILL_LOAD, LOAD_CONFIG_ERROR, SET_CONFIG, UPDATE_CONFIG } from './actionTypes';
|
||||
import {
|
||||
CONFIG_WILL_LOAD,
|
||||
LOAD_CONFIG_ERROR,
|
||||
SET_CONFIG,
|
||||
UPDATE_CONFIG,
|
||||
OVERWRITE_CONFIG
|
||||
} from './actionTypes';
|
||||
import { _CONFIG_STORE_PREFIX } from './constants';
|
||||
import { setConfigFromURLParams } from './functions';
|
||||
|
||||
@@ -67,6 +73,22 @@ export function loadConfigError(error: Error, locationURL: URL) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites some config values.
|
||||
*
|
||||
* @param {Object} config - The new options (to overwrite).
|
||||
* @returns {{
|
||||
* type: OVERWRITE_CONFIG,
|
||||
* config: Object
|
||||
* }}
|
||||
*/
|
||||
export function overwriteConfig(config: Object) {
|
||||
return {
|
||||
type: OVERWRITE_CONFIG,
|
||||
config
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the configuration represented by the feature base/config. The
|
||||
* configuration is defined and consumed by the library lib-jitsi-meet but some
|
||||
|
||||
@@ -157,6 +157,8 @@ export default [
|
||||
'stereo',
|
||||
'subject',
|
||||
'testing',
|
||||
'toolbarButtons',
|
||||
'useHostPageLocalStorage',
|
||||
'useTurnUdp',
|
||||
'videoQuality.persist',
|
||||
'webrtcIceTcpDisable',
|
||||
|
||||
@@ -6,3 +6,17 @@
|
||||
* @type string
|
||||
*/
|
||||
export const _CONFIG_STORE_PREFIX = 'config.js';
|
||||
|
||||
/**
|
||||
* The list of all possible UI buttons.
|
||||
*
|
||||
* @protected
|
||||
* @type Array<string>
|
||||
*/
|
||||
export const TOOLBAR_BUTTONS = [
|
||||
'microphone', 'camera', 'closedcaptions', 'desktop', 'embedmeeting', 'fullscreen',
|
||||
'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
|
||||
'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
|
||||
'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
|
||||
'tileview', 'select-background', 'download', 'help', 'mute-everyone', 'mute-video-everyone', 'security'
|
||||
];
|
||||
|
||||
@@ -82,7 +82,7 @@ export function overrideConfigJSON(
|
||||
}
|
||||
if (configObj) {
|
||||
const configJSON
|
||||
= _getWhitelistedJSON(configName, json[configName]);
|
||||
= getWhitelistedJSON(configName, json[configName]);
|
||||
|
||||
if (!_.isEmpty(configJSON)) {
|
||||
logger.info(
|
||||
@@ -111,11 +111,10 @@ export function overrideConfigJSON(
|
||||
* @param {string} configName - The config name, one of config,
|
||||
* interfaceConfig, loggingConfig.
|
||||
* @param {Object} configJSON - The object with keys and values to override.
|
||||
* @private
|
||||
* @returns {Object} - The result object only with the keys
|
||||
* that are whitelisted.
|
||||
*/
|
||||
function _getWhitelistedJSON(configName, configJSON) {
|
||||
export function getWhitelistedJSON(configName: string, configJSON: Object): Object {
|
||||
if (configName === 'interfaceConfig') {
|
||||
return _.pick(configJSON, INTERFACE_CONFIG_WHITELIST);
|
||||
} else if (configName === 'config') {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// @flow
|
||||
|
||||
import { TOOLBAR_BUTTONS } from './constants';
|
||||
|
||||
export * from './functions.any';
|
||||
|
||||
/**
|
||||
@@ -30,3 +32,15 @@ export function getDialOutStatusUrl(state: Object): string {
|
||||
export function getDialOutUrl(state: Object): string {
|
||||
return state['features/base/config'].guestDialOutUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of enabled toolbar buttons.
|
||||
*
|
||||
* @param {Object} state - The redux state.
|
||||
* @returns {Array<string>} - The list of enabled toolbar buttons.
|
||||
*/
|
||||
export function getToolbarButtons(state: Object): Array<string> {
|
||||
const { toolbarButtons } = state['features/base/config'];
|
||||
|
||||
return Array.isArray(toolbarButtons) ? toolbarButtons : TOOLBAR_BUTTONS;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,17 @@ import _ from 'lodash';
|
||||
|
||||
import { equals, ReducerRegistry, set } from '../redux';
|
||||
|
||||
import { UPDATE_CONFIG, CONFIG_WILL_LOAD, LOAD_CONFIG_ERROR, SET_CONFIG } from './actionTypes';
|
||||
import {
|
||||
UPDATE_CONFIG,
|
||||
CONFIG_WILL_LOAD,
|
||||
LOAD_CONFIG_ERROR,
|
||||
SET_CONFIG,
|
||||
OVERWRITE_CONFIG
|
||||
} from './actionTypes';
|
||||
import { _cleanupConfig } from './functions';
|
||||
|
||||
declare var interfaceConfig: Object;
|
||||
|
||||
/**
|
||||
* The initial state of the feature base/config when executing in a
|
||||
* non-React Native environment. The mandatory configuration to be passed to
|
||||
@@ -88,6 +96,12 @@ ReducerRegistry.register('features/base/config', (state = _getInitialState(), ac
|
||||
|
||||
case SET_CONFIG:
|
||||
return _setConfig(state, action);
|
||||
|
||||
case OVERWRITE_CONFIG:
|
||||
return {
|
||||
...state,
|
||||
...action.config
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
@@ -197,6 +211,10 @@ function _translateLegacyConfig(oldValue: Object) {
|
||||
}
|
||||
});
|
||||
|
||||
if (typeof interfaceConfig === 'object' && Array.isArray(interfaceConfig.TOOLBAR_BUTTONS)) {
|
||||
newValue.toolbarButtons = interfaceConfig.TOOLBAR_BUTTONS;
|
||||
}
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,11 @@ export const bottomSheetStyles = {
|
||||
alignItems: 'stretch',
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'flex-end'
|
||||
justifyContent: 'flex-end',
|
||||
maxWidth: 500,
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
width: '100%'
|
||||
},
|
||||
|
||||
sheetItemContainer: {
|
||||
|
||||
@@ -92,7 +92,7 @@ export function isSupportedBrowser() {
|
||||
export function isSupportedMobileBrowser() {
|
||||
return (Platform.OS === 'android' && browser.isChromiumBased())
|
||||
|| (Platform.OS === 'android' && browser.isFirefox())
|
||||
|| (Platform.OS === 'ios' && browser.isSafari());
|
||||
|| (Platform.OS === 'ios' && browser.isWebKitBased());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,7 +11,7 @@ export const ADD_PEOPLE_ENABLED = 'add-people.enabled';
|
||||
* Used by apps that do not use Jitsi audio.
|
||||
* Default: disabled (false)
|
||||
*/
|
||||
export const ANDROID_AUDIO_FOCUS_DISABLED = 'android.audio-focus.disabled';
|
||||
export const AUDIO_FOCUS_DISABLED = 'audio-focus.disabled';
|
||||
|
||||
/**
|
||||
* Flag indicating if the audio mute button should be displayed.
|
||||
@@ -56,6 +56,12 @@ export const CHAT_ENABLED = 'chat.enabled';
|
||||
*/
|
||||
export const FILMSTRIP_ENABLED = 'filmstrip.enabled';
|
||||
|
||||
/**
|
||||
* Flag indicating if fullscreen (immersive) mode should be enabled.
|
||||
* Default: enabled (true).
|
||||
*/
|
||||
export const FULLSCREEN_ENABLED = 'fullscreen.enabled';
|
||||
|
||||
/**
|
||||
* Flag indicating if the Help button should be enabled.
|
||||
* Default: enabled (true).
|
||||
|
||||
@@ -44,7 +44,7 @@ type Props = {
|
||||
};
|
||||
|
||||
export const DEFAULT_COLOR = navigator.product === 'ReactNative' ? 'white' : undefined;
|
||||
export const DEFAULT_SIZE = navigator.product === 'ReactNative' ? 36 : 24;
|
||||
export const DEFAULT_SIZE = navigator.product === 'ReactNative' ? 36 : 22;
|
||||
|
||||
/**
|
||||
* Implements an Icon component that takes a loaded SVG file as prop and renders it as an icon.
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<svg width="10" height="7" viewBox="0 0 10 7" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.41115 6.05746C8.71903 6.39955 9.24594 6.42729 9.58803 6.1194C9.93012 5.81152 9.95786 5.28461 9.64997 4.94252L5.72917 0.562752C5.39813 0.194935 4.82138 0.194935 4.49034 0.562752L0.63061 4.94252C0.322728 5.28461 0.35046 5.81152 0.692552 6.1194C1.03464 6.42729 1.56155 6.39955 1.86943 6.05746L5.10975 2.36593L8.41115 6.05746Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.41115 6.05746C8.71903 6.39955 9.24594 6.42729 9.58803 6.1194C9.93012 5.81152 9.95786 5.28461 9.64997 4.94252L5.72917 0.562752C5.39813 0.194935 4.82138 0.194935 4.49034 0.562752L0.63061 4.94252C0.322728 5.28461 0.35046 5.81152 0.692552 6.1194C1.03464 6.42729 1.56155 6.39955 1.86943 6.05746L5.10975 2.36593L8.41115 6.05746Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 492 B After Width: | Height: | Size: 480 B |
@@ -1,16 +1,3 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<title>blur-background</title>
|
||||
<path fill="#a4b8d1" d="M14.667 12c0 1.473-1.194 2.667-2.667 2.667s-2.667-1.194-2.667-2.667c0-1.473 1.194-2.667 2.667-2.667s2.667 1.194 2.667 2.667z"></path>
|
||||
<path fill="#a4b8d1" d="M22.667 12c0 1.473-1.194 2.667-2.667 2.667s-2.667-1.194-2.667-2.667c0-1.473 1.194-2.667 2.667-2.667s2.667 1.194 2.667 2.667z"></path>
|
||||
<path fill="#a4b8d1" d="M14.667 20c0 1.473-1.194 2.667-2.667 2.667s-2.667-1.194-2.667-2.667c0-1.473 1.194-2.667 2.667-2.667s2.667 1.194 2.667 2.667z"></path>
|
||||
<path fill="#a4b8d1" d="M13.333 26.667c0 0.736-0.597 1.333-1.333 1.333s-1.333-0.597-1.333-1.333c0-0.736 0.597-1.333 1.333-1.333s1.333 0.597 1.333 1.333z"></path>
|
||||
<path fill="#a4b8d1" d="M21.333 26.667c0 0.736-0.597 1.333-1.333 1.333s-1.333-0.597-1.333-1.333c0-0.736 0.597-1.333 1.333-1.333s1.333 0.597 1.333 1.333z"></path>
|
||||
<path fill="#a4b8d1" d="M6.667 20c0 0.736-0.597 1.333-1.333 1.333s-1.333-0.597-1.333-1.333c0-0.736 0.597-1.333 1.333-1.333s1.333 0.597 1.333 1.333z"></path>
|
||||
<path fill="#a4b8d1" d="M6.667 12c0 0.736-0.597 1.333-1.333 1.333s-1.333-0.597-1.333-1.333c0-0.736 0.597-1.333 1.333-1.333s1.333 0.597 1.333 1.333z"></path>
|
||||
<path fill="#a4b8d1" d="M28 20c0 0.736-0.597 1.333-1.333 1.333s-1.333-0.597-1.333-1.333c0-0.736 0.597-1.333 1.333-1.333s1.333 0.597 1.333 1.333z"></path>
|
||||
<path fill="#a4b8d1" d="M28 12c0 0.736-0.597 1.333-1.333 1.333s-1.333-0.597-1.333-1.333c0-0.736 0.597-1.333 1.333-1.333s1.333 0.597 1.333 1.333z"></path>
|
||||
<path fill="#a4b8d1" d="M13.333 5.333c0 0.736-0.597 1.333-1.333 1.333s-1.333-0.597-1.333-1.333c0-0.736 0.597-1.333 1.333-1.333s1.333 0.597 1.333 1.333z"></path>
|
||||
<path fill="#a4b8d1" d="M21.333 5.333c0 0.736-0.597 1.333-1.333 1.333s-1.333-0.597-1.333-1.333c0-0.736 0.597-1.333 1.333-1.333s1.333 0.597 1.333 1.333z"></path>
|
||||
<path fill="#a4b8d1" d="M22.667 20c0 1.473-1.194 2.667-2.667 2.667s-2.667-1.194-2.667-2.667c0-1.473 1.194-2.667 2.667-2.667s2.667 1.194 2.667 2.667z"></path>
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.25 4.58333C8.75626 4.58333 9.16667 4.17293 9.16667 3.66667C9.16667 3.16041 8.75626 2.75 8.25 2.75C7.74374 2.75 7.33333 3.16041 7.33333 3.66667C7.33333 4.17293 7.74374 4.58333 8.25 4.58333ZM8.25 10.0833C9.26252 10.0833 10.0833 9.26252 10.0833 8.25C10.0833 7.23748 9.26252 6.41667 8.25 6.41667C7.23748 6.41667 6.41667 7.23748 6.41667 8.25C6.41667 9.26252 7.23748 10.0833 8.25 10.0833ZM13.75 10.0833C14.7625 10.0833 15.5833 9.26252 15.5833 8.25C15.5833 7.23748 14.7625 6.41667 13.75 6.41667C12.7375 6.41667 11.9167 7.23748 11.9167 8.25C11.9167 9.26252 12.7375 10.0833 13.75 10.0833ZM10.0833 13.75C10.0833 14.7625 9.26252 15.5833 8.25 15.5833C7.23748 15.5833 6.41667 14.7625 6.41667 13.75C6.41667 12.7375 7.23748 11.9167 8.25 11.9167C9.26252 11.9167 10.0833 12.7375 10.0833 13.75ZM8.25 19.25C8.75626 19.25 9.16667 18.8396 9.16667 18.3333C9.16667 17.8271 8.75626 17.4167 8.25 17.4167C7.74374 17.4167 7.33333 17.8271 7.33333 18.3333C7.33333 18.8396 7.74374 19.25 8.25 19.25ZM14.6667 18.3333C14.6667 18.8396 14.2563 19.25 13.75 19.25C13.2437 19.25 12.8333 18.8396 12.8333 18.3333C12.8333 17.8271 13.2437 17.4167 13.75 17.4167C14.2563 17.4167 14.6667 17.8271 14.6667 18.3333ZM3.66667 14.6667C4.17293 14.6667 4.58333 14.2563 4.58333 13.75C4.58333 13.2437 4.17293 12.8333 3.66667 12.8333C3.16041 12.8333 2.75 13.2437 2.75 13.75C2.75 14.2563 3.16041 14.6667 3.66667 14.6667ZM4.58333 8.25C4.58333 8.75626 4.17293 9.16667 3.66667 9.16667C3.16041 9.16667 2.75 8.75626 2.75 8.25C2.75 7.74374 3.16041 7.33333 3.66667 7.33333C4.17293 7.33333 4.58333 7.74374 4.58333 8.25ZM18.3333 14.6667C18.8396 14.6667 19.25 14.2563 19.25 13.75C19.25 13.2437 18.8396 12.8333 18.3333 12.8333C17.8271 12.8333 17.4167 13.2437 17.4167 13.75C17.4167 14.2563 17.8271 14.6667 18.3333 14.6667ZM19.25 8.25C19.25 8.75626 18.8396 9.16667 18.3333 9.16667C17.8271 9.16667 17.4167 8.75626 17.4167 8.25C17.4167 7.74374 17.8271 7.33333 18.3333 7.33333C18.8396 7.33333 19.25 7.74374 19.25 8.25ZM14.6667 3.66667C14.6667 4.17293 14.2563 4.58333 13.75 4.58333C13.2437 4.58333 12.8333 4.17293 12.8333 3.66667C12.8333 3.16041 13.2437 2.75 13.75 2.75C14.2563 2.75 14.6667 3.16041 14.6667 3.66667ZM13.75 15.5833C14.7625 15.5833 15.5833 14.7625 15.5833 13.75C15.5833 12.7375 14.7625 11.9167 13.75 11.9167C12.7375 11.9167 11.9167 12.7375 11.9167 13.75C11.9167 14.7625 12.7375 15.5833 13.75 15.5833Z"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.4 KiB |
3
react/features/base/icons/svg/camera-empty-disabled.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.84074 5.49992H6.81762L3.42398 2.10629C3.06002 1.74232 2.47001 1.74223 2.10617 2.10608C1.74232 2.46992 1.74241 3.05993 2.10638 3.42389L4.1824 5.49992H3.66668C2.65415 5.49992 1.83334 6.32073 1.83334 7.33325V14.6666C1.83334 15.6791 2.65415 16.4999 3.66668 16.4999H13.75C14.154 16.4999 14.5274 16.3693 14.8304 16.1479L18.576 19.8936C18.94 20.2575 19.53 20.2576 19.8939 19.8938C20.2577 19.5299 20.2576 18.9399 19.8936 18.5759L15.5833 14.2656V14.2425L13.75 12.4092V12.4323L8.65095 7.33325H8.67407L6.84074 5.49992ZM13.75 9.77398V9.16659V7.33325H11.3093L9.47595 5.49992H13.75C14.7625 5.49992 15.5833 6.32073 15.5833 7.33325V8.11897L18.7952 6.28361C19.2348 6.03243 19.7947 6.18515 20.0459 6.62471C20.125 6.76321 20.1667 6.91998 20.1667 7.0795V14.9203C20.1667 15.2643 19.9772 15.5641 19.6969 15.7209L15.9614 11.9853L18.3333 13.3408V8.65908L15.5833 10.2305V11.6073L13.75 9.77398ZM3.66668 7.33325H6.01574L13.3491 14.6666H3.66668V7.33325Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
3
react/features/base/icons/svg/camera-empty.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.75 5.5H3.66668C2.65415 5.5 1.83334 6.32081 1.83334 7.33333V14.6667C1.83334 15.6792 2.65415 16.5 3.66668 16.5H13.75C14.7625 16.5 15.5833 15.6792 15.5833 14.6667V13.881L18.7952 15.7163C18.9337 15.7955 19.0905 15.8371 19.25 15.8371C19.7563 15.8371 20.1667 15.4267 20.1667 14.9204V7.07958C20.1667 6.92006 20.125 6.76329 20.0459 6.62479C19.7947 6.18523 19.2348 6.03252 18.7952 6.28369L15.5833 8.11905V7.33333C15.5833 6.32081 14.7625 5.5 13.75 5.5ZM13.75 9.16667V12.8333V14.6667H3.66668V7.33333H13.75V9.16667ZM18.3333 13.3408L15.5833 11.7694V10.2306L18.3333 8.65916V13.3408Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 729 B |
@@ -1,6 +1,3 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<title>camera-take-picture</title>
|
||||
<path d="M22.667 16c0 3.682-2.985 6.667-6.667 6.667s-6.667-2.985-6.667-6.667c0-3.682 2.985-6.667 6.667-6.667s6.667 2.985 6.667 6.667z"></path>
|
||||
<path d="M16 24c4.418 0 8-3.582 8-8s-3.582-8-8-8v0c-4.418 0-8 3.582-8 8s3.582 8 8 8v0zM16 25.333c-5.155 0-9.333-4.179-9.333-9.333s4.179-9.333 9.333-9.333v0c5.155 0 9.333 4.179 9.333 9.333s-4.179 9.333-9.333 9.333v0z"></path>
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 20.1666C5.93743 20.1666 1.83337 16.0626 1.83337 11C1.83337 5.93737 5.93743 1.83331 11 1.83331C16.0627 1.83331 20.1667 5.93737 20.1667 11C20.1667 16.0626 16.0627 20.1666 11 20.1666ZM11 18.3333C15.0501 18.3333 18.3334 15.0501 18.3334 11C18.3334 6.94989 15.0501 3.66665 11 3.66665C6.94995 3.66665 3.66671 6.94989 3.66671 11C3.66671 15.0501 6.94995 18.3333 11 18.3333ZM15.5834 11C15.5834 13.5313 13.5313 15.5833 11 15.5833C8.46874 15.5833 6.41671 13.5313 6.41671 11C6.41671 8.46867 8.46874 6.41665 11 6.41665C13.5313 6.41665 15.5834 8.46867 15.5834 11Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 541 B After Width: | Height: | Size: 709 B |
@@ -1,5 +1,3 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<title>chat</title>
|
||||
<path d="M26.688 21.313v-16h-21.375v18.688l2.688-2.688h18.688zM26.688 2.688c1.438 0 2.625 1.188 2.625 2.625v16c0 1.438-1.188 2.688-2.625 2.688h-18.688l-5.313 5.313v-24c0-1.438 1.188-2.625 2.625-2.625h21.375z"></path>
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.5834 20.1959C16.0896 20.1959 16.5 19.7854 16.5 19.2792V14.6666H19.25C19.7563 14.6666 20.1667 14.2562 20.1667 13.75V2.74998C20.1667 2.24372 19.7563 1.83331 19.25 1.83331H2.75004C2.24378 1.83331 1.83337 2.24372 1.83337 2.74998V13.75C1.83337 14.2562 2.24378 14.6666 2.75004 14.6666H10.5927L14.8761 19.8623C15.0502 20.0735 15.3096 20.1959 15.5834 20.1959ZM3.66671 3.66665H18.3334V12.8333H14.6667V16.7262L11.4573 12.8333H3.66671V3.66665Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 375 B After Width: | Height: | Size: 593 B |
@@ -1,5 +1,3 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<title>closed_caption</title>
|
||||
<path d="M18 11.016v-1.031c0-0.563-0.422-0.984-0.984-0.984h-3c-0.563 0-1.031 0.422-1.031 0.984v4.031c0 0.563 0.469 0.984 1.031 0.984h3c0.563 0 0.984-0.422 0.984-0.984v-1.031h-1.5v0.516h-2.016v-3h2.016v0.516h1.5zM11.016 11.016v-1.031c0-0.563-0.469-0.984-1.031-0.984h-3c-0.563 0-0.984 0.422-0.984 0.984v4.031c0 0.563 0.422 0.984 0.984 0.984h3c0.563 0 1.031-0.422 1.031-0.984v-1.031h-1.5v0.516h-2.016v-3h2.016v0.516h1.5zM18.984 3.984c1.078 0 2.016 0.938 2.016 2.016v12c0 1.078-0.938 2.016-2.016 2.016h-13.969c-1.125 0-2.016-0.938-2.016-2.016v-12c0-1.078 0.891-2.016 2.016-2.016h13.969z"></path>
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.66671 3.66665H18.3334V18.3333H3.66671V3.66665ZM1.83337 3.66665C1.83337 2.65412 2.65419 1.83331 3.66671 1.83331H18.3334C19.3459 1.83331 20.1667 2.65412 20.1667 3.66665V18.3333C20.1667 19.3458 19.3459 20.1666 18.3334 20.1666H3.66671C2.65419 20.1666 1.83337 19.3458 1.83337 18.3333V3.66665ZM6.87046 13.9461C7.31535 14.1924 7.82776 14.3156 8.40771 14.3156C8.74932 14.3156 9.08298 14.2719 9.40871 14.1845C9.73443 14.0891 10.0204 13.962 10.2667 13.8031C10.4018 13.7237 10.4971 13.6363 10.5527 13.541C10.6163 13.4377 10.648 13.3185 10.648 13.1835C10.648 13.0166 10.6043 12.8776 10.517 12.7664C10.4296 12.6552 10.3223 12.5996 10.1952 12.5996C10.1078 12.5996 10.0204 12.6194 9.93304 12.6591C9.84565 12.6909 9.74237 12.7426 9.62321 12.8141C9.43254 12.9173 9.25776 13.0008 9.09887 13.0643C8.94793 13.1199 8.77315 13.1477 8.57454 13.1477C8.08198 13.1477 7.70065 12.9888 7.43054 12.6711C7.16837 12.3453 7.03729 11.8846 7.03729 11.2887C7.03729 10.685 7.16837 10.2242 7.43054 9.9064C7.70065 9.58067 8.08198 9.41781 8.57454 9.41781C8.7811 9.41781 8.96382 9.44959 9.12271 9.51315C9.2816 9.56876 9.44843 9.6482 9.62321 9.75148C9.71854 9.80709 9.81387 9.85476 9.90921 9.89448C10.0045 9.9342 10.0959 9.95406 10.1833 9.95406C10.3183 9.95406 10.4256 9.90242 10.505 9.79915C10.5924 9.68792 10.6361 9.54492 10.6361 9.37015C10.6361 9.11592 10.509 8.9054 10.2548 8.73856C10.0165 8.58762 9.7384 8.46845 9.42062 8.38106C9.11079 8.29367 8.80096 8.24998 8.49112 8.24998C7.90323 8.24998 7.38287 8.37709 6.93004 8.63131C6.47721 8.88554 6.12368 9.24701 5.86946 9.71573C5.62318 10.1765 5.50004 10.7088 5.50004 11.3126C5.50004 11.9163 5.61921 12.4446 5.85754 12.8975C6.09587 13.3503 6.43351 13.6999 6.87046 13.9461ZM12.6891 13.9461C13.134 14.1924 13.6464 14.3156 14.2264 14.3156C14.568 14.3156 14.9017 14.2719 15.2274 14.1845C15.5531 14.0891 15.8391 13.962 16.0854 13.8031C16.2204 13.7237 16.3158 13.6363 16.3714 13.541C16.4349 13.4377 16.4667 13.3185 16.4667 13.1835C16.4667 13.0166 16.423 12.8776 16.3356 12.7664C16.2483 12.6552 16.141 12.5996 16.0139 12.5996C15.9265 12.5996 15.8391 12.6194 15.7517 12.6591C15.6643 12.6909 15.5611 12.7426 15.4419 12.8141C15.2512 12.9173 15.0764 13.0008 14.9176 13.0643C14.7666 13.1199 14.5918 13.1477 14.3932 13.1477C13.9007 13.1477 13.5193 12.9888 13.2492 12.6711C12.9871 12.3453 12.856 11.8846 12.856 11.2887C12.856 10.685 12.9871 10.2242 13.2492 9.9064C13.5193 9.58067 13.9007 9.41781 14.3932 9.41781C14.5998 9.41781 14.7825 9.44959 14.9414 9.51315C15.1003 9.56876 15.2671 9.6482 15.4419 9.75148C15.5372 9.80709 15.6326 9.85476 15.7279 9.89448C15.8232 9.9342 15.9146 9.95406 16.002 9.95406C16.137 9.95406 16.2443 9.90242 16.3237 9.79915C16.4111 9.68792 16.4548 9.54492 16.4548 9.37015C16.4548 9.11592 16.3277 8.9054 16.0735 8.73856C15.8351 8.58762 15.5571 8.46845 15.2393 8.38106C14.9295 8.29367 14.6196 8.24998 14.3098 8.24998C13.7219 8.24998 13.2016 8.37709 12.7487 8.63131C12.2959 8.88554 11.9424 9.24701 11.6881 9.71573C11.4419 10.1765 11.3187 10.7088 11.3187 11.3126C11.3187 11.9163 11.4379 12.4446 11.6762 12.8975C11.9146 13.3503 12.2522 13.6999 12.6891 13.9461Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 760 B After Width: | Height: | Size: 3.2 KiB |
@@ -1,4 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.8716 7.70278C15.4611 7.33332 15.4278 6.70103 15.7972 6.29052C16.1667 5.88001 16.799 5.84673 17.2095 6.21619L22.4652 10.9212C22.9066 11.3184 22.9066 12.0105 22.4652 12.4077L17.2095 17.0394C16.799 17.4089 16.1667 17.3756 15.7972 16.9651C15.4278 16.5546 15.4611 15.9223 15.8716 15.5528L20.3014 11.6645L15.8716 7.70278Z" fill="#A4B8D1"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.4651 15.5531C8.87561 15.9225 8.90889 16.5548 8.53943 16.9653C8.16997 17.3759 7.53768 17.4091 7.12717 17.0397L1.87145 12.3347C1.43007 11.9375 1.43007 11.2454 1.87145 10.8481L7.12717 6.21644C7.53768 5.84698 8.16997 5.88026 8.53943 6.29077C8.90889 6.70128 8.87561 7.33357 8.4651 7.70302L4.03526 11.5914L8.4651 15.5531Z" fill="#A4B8D1"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.8716 7.70278C15.4611 7.33332 15.4278 6.70103 15.7972 6.29052C16.1667 5.88001 16.799 5.84673 17.2095 6.21619L22.4652 10.9212C22.9066 11.3184 22.9066 12.0105 22.4652 12.4077L17.2095 17.0394C16.799 17.4089 16.1667 17.3756 15.7972 16.9651C15.4278 16.5546 15.4611 15.9223 15.8716 15.5528L20.3014 11.6645L15.8716 7.70278Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.4651 15.5531C8.87561 15.9225 8.90889 16.5548 8.53943 16.9653C8.16997 17.3759 7.53768 17.4091 7.12717 17.0397L1.87145 12.3347C1.43007 11.9375 1.43007 11.2454 1.87145 10.8481L7.12717 6.21644C7.53768 5.84698 8.16997 5.88026 8.53943 6.29077C8.90889 6.70128 8.87561 7.33357 8.4651 7.70302L4.03526 11.5914L8.4651 15.5531Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 876 B After Width: | Height: | Size: 848 B |
3
react/features/base/icons/svg/document.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.75 1.83331H14.2869C14.53 1.83331 14.7632 1.92989 14.9351 2.1018L18.0648 5.23149C18.2367 5.4034 18.3333 5.63656 18.3333 5.87968V19.25C18.3333 19.7562 17.9229 20.1666 17.4166 20.1666H4.58329C4.07703 20.1666 3.66663 19.7562 3.66663 19.25V2.74998C3.66663 2.24372 4.07703 1.83331 4.58329 1.83331H11.9166H13.75ZM11.9166 3.66665V6.41665C11.9166 7.42917 12.7374 8.24998 13.75 8.24998H16.5V18.3333H5.49996V3.66665H11.9166ZM16.5 6.41665H13.75V3.66665H13.9072L16.5 6.25937V6.41665ZM8.24996 14.6666C7.7437 14.6666 7.33329 15.0771 7.33329 15.5833C7.33329 16.0896 7.7437 16.5 8.24996 16.5H13.75C14.2562 16.5 14.6666 16.0896 14.6666 15.5833C14.6666 15.0771 14.2562 14.6666 13.75 14.6666H8.24996ZM7.33329 12.8333C7.33329 12.3271 7.7437 11.9166 8.24996 11.9166H13.75C14.2562 11.9166 14.6666 12.3271 14.6666 12.8333C14.6666 13.3396 14.2562 13.75 13.75 13.75H8.24996C7.7437 13.75 7.33329 13.3396 7.33329 12.8333ZM8.24996 9.16665C7.7437 9.16665 7.33329 9.57705 7.33329 10.0833C7.33329 10.5896 7.7437 11 8.24996 11H13.75C14.2562 11 14.6666 10.5896 14.6666 10.0833C14.6666 9.57705 14.2562 9.16665 13.75 9.16665H8.24996Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 13.3705V5C11 4.44772 11.4477 4 12 4C12.5523 4 13 4.44772 13 5V13.4667L15.631 10.5433C16.0005 10.1328 16.6328 10.0995 17.0433 10.469C17.4538 10.8384 17.4871 11.4707 17.1176 11.8812L12.1064 17.4492C12.0727 17.4867 12.0139 17.4867 11.9802 17.4492L6.96897 11.8812C6.59951 11.4707 6.63278 10.8384 7.04329 10.469C7.4538 10.0995 8.08609 10.1328 8.45555 10.5433L11 13.3705ZM20 15C20 14.4477 20.4477 14 21 14C21.5523 14 22 14.4477 22 15V21C22 21.5523 21.5523 22 21 22H3C2.96548 22 2.93137 21.9983 2.89776 21.9948C2.3935 21.9436 2 21.5178 2 21V15C2 14.4477 2.44772 14 3 14C3.55228 14 4 14.4477 4 15V20H20V15Z" fill="#A4B8D1"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 13.3705V5C11 4.44772 11.4477 4 12 4C12.5523 4 13 4.44772 13 5V13.4667L15.631 10.5433C16.0005 10.1328 16.6328 10.0995 17.0433 10.469C17.4538 10.8384 17.4871 11.4707 17.1176 11.8812L12.1064 17.4492C12.0727 17.4867 12.0139 17.4867 11.9802 17.4492L6.96897 11.8812C6.59951 11.4707 6.63278 10.8384 7.04329 10.469C7.4538 10.0995 8.08609 10.1328 8.45555 10.5433L11 13.3705ZM20 15C20 14.4477 20.4477 14 21 14C21.5523 14 22 14.4477 22 15V21C22 21.5523 21.5523 22 21 22H3C2.96548 22 2.93137 21.9983 2.89776 21.9948C2.3935 21.9436 2 21.5178 2 21V15C2 14.4477 2.44772 14 3 14C3.55228 14 4 14.4477 4 15V20H20V15Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 773 B After Width: | Height: | Size: 759 B |
@@ -1,5 +1,6 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<title>exit-full-screen</title>
|
||||
<path d="M21.313 10.688h4v2.625h-6.625v-6.625h2.625v4zM18.688 25.313v-6.625h6.625v2.625h-4v4h-2.625zM10.688 10.688v-4h2.625v6.625h-6.625v-2.625h4zM6.688 21.313v-2.625h6.625v6.625h-2.625v-4h-4z"></path>
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.4166 8.24998L17.4166 10.0833L12.8333 10.0833C12.327 10.0833 11.9166 9.67291 11.9166 9.16665L11.9166 4.58331L13.75 4.58331L13.75 8.24998L17.4166 8.24998Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.58337 8.24998L4.58337 10.0833L9.16671 10.0833C9.67297 10.0833 10.0834 9.67291 10.0834 9.16665L10.0834 4.58331L8.25004 4.58331L8.25004 8.24998L4.58337 8.24998Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.4166 13.75L17.4166 11.9167L12.8333 11.9167C12.327 11.9167 11.9166 12.3271 11.9166 12.8334L11.9166 17.4167L13.75 17.4167L13.75 13.75L17.4166 13.75Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.58337 13.75L4.58337 11.9167L9.16671 11.9167C9.67297 11.9167 10.0834 12.3271 10.0834 12.8334L10.0834 17.4167L8.25004 17.4167L8.25004 13.75L4.58337 13.75Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 372 B After Width: | Height: | Size: 941 B |
@@ -1,5 +1,3 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<title>feedback</title>
|
||||
<path d="M1.333 28h5.333v-16h-5.333v16zM30.667 13.333c0-1.467-1.2-2.667-2.667-2.667h-8.413l1.267-6.093 0.040-0.427c0-0.547-0.227-1.053-0.587-1.413l-1.413-1.4-8.773 8.787c-0.493 0.48-0.787 1.147-0.787 1.88v13.333c0 1.467 1.2 2.667 2.667 2.667h12c1.107 0 2.053-0.667 2.453-1.627l4.027-9.4c0.12-0.307 0.187-0.627 0.187-0.973v-2.547l-0.013-0.013 0.013-0.107z"></path>
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.27842 7.06629L10.5284 2.11629C10.8187 1.94211 11.1814 1.94211 11.4717 2.11629L19.7217 7.06629C19.9978 7.23195 20.1667 7.53033 20.1667 7.85232V19.25C20.1667 19.7562 19.7563 20.1666 19.25 20.1666H2.75004C2.24378 20.1666 1.83337 19.7562 1.83337 19.25V7.85232C1.83337 7.53033 2.00231 7.23195 2.27842 7.06629ZM3.66671 10.0428V18.3333H18.3334V10.0428L11.5367 14.9514C11.2164 15.1828 10.7837 15.1828 10.4633 14.9514L3.66671 10.0428ZM4.11297 8.10358L11 13.0776L17.8871 8.10358L11 3.97133L4.11297 8.10358ZM9.05228 8.70755C8.62239 8.97492 8.05714 8.84317 7.78976 8.41327C7.52239 7.98337 7.65414 7.41812 8.08404 7.15075L10.5159 5.63825C10.813 5.45351 11.1892 5.45392 11.4859 5.63932L13.9127 7.15608C14.342 7.42439 14.4725 7.98993 14.2042 8.41924C13.9359 8.84855 13.3703 8.97906 12.941 8.71074L11.9167 8.07054V11C11.9167 11.5062 11.5063 11.9166 11 11.9166C10.4938 11.9166 10.0834 11.5062 10.0834 11V8.06626L9.05228 8.70755Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 526 B After Width: | Height: | Size: 1.0 KiB |
@@ -1,5 +1,3 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<title>full-screen</title>
|
||||
<path d="M18.688 6.688h6.625v6.625h-2.625v-4h-4v-2.625zM22.688 22.688v-4h2.625v6.625h-6.625v-2.625h4zM6.688 13.313v-6.625h6.625v2.625h-4v4h-2.625zM9.313 18.688v4h4v2.625h-6.625v-6.625h2.625z"></path>
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.25 2.75H3.66667C3.16041 2.75 2.75 3.16041 2.75 3.66667V8.25H4.58333V4.58333H8.25V2.75ZM13.75 4.58333V2.75H18.3333C18.8396 2.75 19.25 3.16041 19.25 3.66667V8.25H17.4167V4.58333H13.75ZM13.75 17.4167H17.4167V13.75H19.25V18.3333C19.25 18.8396 18.8396 19.25 18.3333 19.25H13.75V17.4167ZM4.58333 13.75V17.4167H8.25V19.25H3.66667C3.16041 19.25 2.75 18.8396 2.75 18.3333V13.75H4.58333Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 365 B After Width: | Height: | Size: 537 B |
@@ -1 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z"/></svg>
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 18.3334C5.39765 18.3334 1.66669 14.6024 1.66669 10C1.66669 5.39765 5.39765 1.66669 10 1.66669C14.6024 1.66669 18.3334 5.39765 18.3334 10C18.3334 14.6024 14.6024 18.3334 10 18.3334ZM10 16.6667C13.6819 16.6667 16.6667 13.6819 16.6667 10C16.6667 6.31812 13.6819 3.33335 10 3.33335C6.31812 3.33335 3.33335 6.31812 3.33335 10C3.33335 13.6819 6.31812 16.6667 10 16.6667ZM9.24807 14.8926C9.44555 15.064 9.67667 15.1498 9.94143 15.1498C10.1975 15.1498 10.4232 15.063 10.6185 14.8893C10.8138 14.7157 10.9115 14.477 10.9115 14.1732C10.9115 13.8998 10.8182 13.6697 10.6315 13.4831C10.4449 13.2965 10.2149 13.2031 9.94143 13.2031C9.66365 13.2031 9.42928 13.2965 9.2383 13.4831C9.04733 13.6697 8.95184 13.8998 8.95184 14.1732C8.95184 14.4814 9.05058 14.7212 9.24807 14.8926ZM7.16148 6.76109C6.89672 7.18427 6.76434 7.60202 6.76434 8.01434C6.76434 8.214 6.84789 8.39954 7.01499 8.57098C7.1821 8.74243 7.38717 8.82815 7.63023 8.82815C8.04256 8.82815 8.3225 8.58292 8.47007 8.09247C8.62632 7.62372 8.81729 7.2689 9.04299 7.02802C9.26868 6.78713 9.62024 6.66669 10.0977 6.66669C10.5057 6.66669 10.8388 6.78604 11.097 7.02476C11.3553 7.26348 11.4844 7.55644 11.4844 7.90367C11.4844 8.08162 11.4421 8.24655 11.3574 8.39846C11.2728 8.55037 11.1686 8.68817 11.0449 8.81187C10.9212 8.93557 10.7205 9.11894 10.4427 9.362C10.1259 9.63978 9.87415 9.87958 9.68752 10.0814C9.50089 10.2832 9.35115 10.5176 9.2383 10.7845C9.12545 11.0515 9.06903 11.3672 9.06903 11.7318C9.06903 12.0226 9.14607 12.2418 9.30015 12.3893C9.45423 12.5369 9.64412 12.6107 9.86981 12.6107C10.3038 12.6107 10.5621 12.385 10.6446 11.9336C10.6923 11.7209 10.7281 11.5723 10.752 11.4877C10.7758 11.403 10.8095 11.3184 10.8529 11.2337C10.8963 11.1491 10.9625 11.0558 11.0515 10.9538C11.1404 10.8518 11.2587 10.7335 11.4063 10.599C11.9401 10.1215 12.3101 9.78192 12.5163 9.5801C12.7225 9.37827 12.9004 9.13848 13.0502 8.8607C13.1999 8.58292 13.2748 8.25957 13.2748 7.89065C13.2748 7.42189 13.1435 6.98787 12.8809 6.58856C12.6183 6.18925 12.2461 5.8735 11.7643 5.6413C11.2826 5.40909 10.727 5.29299 10.0977 5.29299C9.42059 5.29299 8.82815 5.43188 8.32033 5.70966C7.81252 5.98743 7.42624 6.33791 7.16148 6.76109Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 381 B After Width: | Height: | Size: 2.2 KiB |
3
react/features/base/icons/svg/horizontal-points.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.41667 11C6.41667 12.0125 5.59586 12.8334 4.58333 12.8334C3.57081 12.8334 2.75 12.0125 2.75 11C2.75 9.9875 3.57081 9.16669 4.58333 9.16669C5.59586 9.16669 6.41667 9.9875 6.41667 11ZM11 12.8334C12.0125 12.8334 12.8333 12.0125 12.8333 11C12.8333 9.9875 12.0125 9.16669 11 9.16669C9.98748 9.16669 9.16667 9.9875 9.16667 11C9.16667 12.0125 9.98748 12.8334 11 12.8334ZM17.4167 12.8334C18.4292 12.8334 19.25 12.0125 19.25 11C19.25 9.9875 18.4292 9.16669 17.4167 9.16669C16.4041 9.16669 15.5833 9.9875 15.5833 11C15.5833 12.0125 16.4041 12.8334 17.4167 12.8334Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 725 B |
@@ -18,6 +18,8 @@ export { default as IconBlurBackground } from './blur-background.svg';
|
||||
export { default as IconPlusCalendar } from './calendar-plus.svg';
|
||||
export { default as IconCamera } from './camera.svg';
|
||||
export { default as IconCameraDisabled } from './camera-disabled.svg';
|
||||
export { default as IconCameraEmpty } from './camera-empty.svg';
|
||||
export { default as IconCameraEmptyDisabled } from './camera-empty-disabled.svg';
|
||||
export { default as IconCancelSelection } from './cancel.svg';
|
||||
export { default as IconChat } from './chat.svg';
|
||||
export { default as IconChatSend } from './send.svg';
|
||||
@@ -35,6 +37,7 @@ export { default as IconDeviceBluetooth } from './bluetooth.svg';
|
||||
export { default as IconDeviceEarpiece } from './phone-talk.svg';
|
||||
export { default as IconDeviceHeadphone } from './headset.svg';
|
||||
export { default as IconDeviceSpeaker } from './volume.svg';
|
||||
export { default as IconDeviceDocument } from './document.svg';
|
||||
export { default as IconDominantSpeaker } from './dominant-speaker.svg';
|
||||
export { default as IconDownload } from './download.svg';
|
||||
export { default as IconDragHandle } from './drag-handle.svg';
|
||||
@@ -50,10 +53,11 @@ export { default as IconFullScreen } from './full-screen.svg';
|
||||
export { default as IconGoogle } from './google.svg';
|
||||
export { default as IconHangup } from './hangup.svg';
|
||||
export { default as IconHelp } from './help.svg';
|
||||
export { default as IconHorizontalPoints } from './horizontal-points.svg';
|
||||
export { default as IconInfo } from './info.svg';
|
||||
export { default as IconInviteMore } from './user-plus.svg';
|
||||
export { default as IconKick } from './kick.svg';
|
||||
export { default as IconLiveStreaming } from './public.svg';
|
||||
export { default as IconLiveStreaming } from './live-streaming.svg';
|
||||
export { default as IconMeetingLocked } from './meeting-locked.svg';
|
||||
export { default as IconMeetingUnlocked } from './meeting-unlocked.svg';
|
||||
export { default as IconMenu } from './menu.svg';
|
||||
@@ -65,6 +69,7 @@ export { default as IconMeter } from './meter.svg';
|
||||
export { default as IconMicDisabled } from './mic-disabled.svg';
|
||||
export { default as IconMicrophone } from './microphone.svg';
|
||||
export { default as IconMicrophoneEmpty } from './microphone-empty.svg';
|
||||
export { default as IconMicrophoneEmptySlash } from './microphone-empty-slash.svg';
|
||||
export { default as IconModerator } from './star.svg';
|
||||
export { default as IconMuteEveryone } from './mute-everyone.svg';
|
||||
export { default as IconMuteEveryoneElse } from './mute-everyone-else.svg';
|
||||
@@ -104,6 +109,7 @@ export { default as IconVideoQualityAudioOnly } from './AUD.svg';
|
||||
export { default as IconVideoQualityHD } from './HD.svg';
|
||||
export { default as IconVideoQualityLD } from './LD.svg';
|
||||
export { default as IconVideoQualitySD } from './SD.svg';
|
||||
export { default as IconVirtualBackground } from './virtual-background.svg';
|
||||
export { default as IconVolume } from './volume.svg';
|
||||
export { default as IconVolumeEmpty } from './volume-empty.svg';
|
||||
export { default as IconVolumeOff } from './volume-off.svg';
|
||||
|
||||
3
react/features/base/icons/svg/live-streaming.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 20.1666C5.93743 20.1666 1.83337 16.0626 1.83337 11C1.83337 5.93737 5.93743 1.83331 11 1.83331C16.0627 1.83331 20.1667 5.93737 20.1667 11C20.1667 16.0626 16.0627 20.1666 11 20.1666ZM11 18.3333C11.1961 18.3333 11.3903 18.3256 11.5824 18.3105C10.5501 17.4264 9.59313 16.3138 8.75825 15.0021C7.49738 15.1948 6.17459 15.1866 4.82269 14.9536C6.12637 16.9863 8.4059 18.3333 11 18.3333ZM10.6533 14.5474C11.6128 15.9231 12.7188 17.0044 13.8859 17.7437C14.1557 17.6281 14.4172 17.4967 14.6691 17.3508C14.6706 17.3303 14.6728 17.3097 14.6757 17.2891C14.9298 15.4814 14.8751 13.8467 14.5451 12.3479C13.4001 13.3267 12.0838 14.0737 10.6533 14.5474ZM13.9392 10.4127C12.7459 11.6082 11.287 12.4733 9.66815 12.9309C8.46905 10.6745 7.6302 7.85533 7.39828 4.61061C7.82671 4.36858 8.28191 4.1684 8.75833 4.01561C8.80512 4.05571 8.86081 4.10342 8.91909 4.15334C9.07324 4.28538 9.24549 4.43294 9.31893 4.49632C9.59915 4.73815 9.83649 4.94781 10.0699 5.16136C10.6639 5.70485 11.1866 6.23341 11.6714 6.79528C12.6385 7.9162 13.4037 9.11177 13.9392 10.4127ZM15.2335 8.82952C14.6633 7.68289 13.9328 6.60978 13.0594 5.59762C12.5235 4.9765 11.9513 4.39785 11.3074 3.80875C11.2561 3.76175 11.2046 3.71502 11.1527 3.6682C13.297 3.712 15.2153 4.6762 16.5286 6.18183C16.2018 7.14657 15.7642 8.03341 15.2335 8.82952ZM16.0362 10.823C16.502 12.3121 16.7196 13.9188 16.6584 15.6652C17.7048 14.3975 18.3334 12.7721 18.3334 11C18.3334 9.96873 18.1205 8.98721 17.7363 8.09693C17.275 9.09641 16.7022 10.0096 16.0362 10.823ZM3.91853 12.8686C5.24374 13.2472 6.54603 13.3714 7.78607 13.2697C6.75554 11.1791 6.01023 8.711 5.68385 5.94863C4.43382 7.26378 3.66671 9.0423 3.66671 11C3.66671 11.6534 3.75216 12.2868 3.9125 12.8897L3.91853 12.8686Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
3
react/features/base/icons/svg/microphone-empty-slash.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.33331 8.65095V11C7.33331 12.711 8.5053 14.1483 10.0903 14.553C10.0857 14.5902 10.0833 14.6282 10.0833 14.6667V16.424C7.48208 15.9876 5.49998 13.7253 5.49998 11C5.49998 10.4937 5.08957 10.0833 4.58331 10.0833C4.07705 10.0833 3.66665 10.4937 3.66665 11C3.66665 14.7397 6.46586 17.8255 10.0833 18.2766V19.25C10.0833 19.7563 10.4937 20.1667 11 20.1667C11.5062 20.1667 11.9166 19.7563 11.9166 19.25V18.2766C13.2504 18.1103 14.4729 17.5858 15.4849 16.8025L18.576 19.8936C18.94 20.2576 19.53 20.2577 19.8938 19.8939C20.2577 19.53 20.2576 18.94 19.8936 18.576L16.8025 15.4849C16.8058 15.4805 16.8092 15.4762 16.8125 15.4718L15.5016 14.1609C15.4984 14.1654 15.4952 14.1699 15.492 14.1744L14.1668 12.8493C14.1697 12.8444 14.1725 12.8395 14.1754 12.8347L12.7803 11.4396C12.7788 11.4458 12.7772 11.4519 12.7756 11.4581L9.16665 7.84907V7.82595L7.33331 5.99262V6.01574L3.42395 2.10638C3.05999 1.74241 2.46998 1.74232 2.10614 2.10617C1.74229 2.47001 1.74238 3.06002 2.10635 3.42398L7.33331 8.65095ZM9.16665 10.4843V11C9.16665 12.0125 9.98746 12.8333 11 12.8333C11.1581 12.8333 11.3116 12.8133 11.458 12.7757L9.16665 10.4843ZM12.8492 14.1669C12.5591 14.3367 12.2435 14.4677 11.9097 14.553C11.9143 14.5902 11.9166 14.6282 11.9166 14.6667V16.424C12.7471 16.2846 13.5145 15.9592 14.1744 15.492L12.8492 14.1669ZM14.6666 10.6907L12.8333 8.8574V5.50001C12.8333 4.48749 12.0125 3.66668 11 3.66668C10.0851 3.66668 9.3267 4.33685 9.18897 5.21306L7.7592 3.78329C8.37493 2.62333 9.5952 1.83334 11 1.83334C13.025 1.83334 14.6666 3.47497 14.6666 5.50001V10.6907ZM16.3316 12.3557L17.7787 13.8028C18.1361 12.9393 18.3333 11.9927 18.3333 11C18.3333 10.4937 17.9229 10.0833 17.4166 10.0833C16.9104 10.0833 16.5 10.4937 16.5 11C16.5 11.4679 16.4416 11.9221 16.3316 12.3557Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 6C16 3.79086 14.2091 2 12 2C9.79086 2 8 3.79086 8 6V12C8 13.8666 9.27853 15.4346 11.0076 15.8759C11.0026 15.9166 11 15.958 11 16V17.917C8.16229 17.441 6 14.973 6 12C6 11.4477 5.55228 11 5 11C4.44772 11 4 11.4477 4 12C4 16.0796 7.05369 19.446 11 19.9381V21C11 21.5523 11.4477 22 12 22C12.5523 22 13 21.5523 13 21V19.9381C16.9463 19.446 20 16.0796 20 12C20 11.4477 19.5523 11 19 11C18.4477 11 18 11.4477 18 12C18 14.973 15.8377 17.441 13 17.917V16C13 15.958 12.9974 15.9166 12.9924 15.8759C14.7215 15.4346 16 13.8666 16 12V6ZM12 4C10.8954 4 10 4.89543 10 6V12C10 13.1046 10.8954 14 12 14C13.1046 14 14 13.1046 14 12V6C14 4.89543 13.1046 4 12 4Z" fill="#A4B8D1"/>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 6C16 3.79086 14.2091 2 12 2C9.79086 2 8 3.79086 8 6V12C8 13.8666 9.27853 15.4346 11.0076 15.8759C11.0026 15.9166 11 15.958 11 16V17.917C8.16229 17.441 6 14.973 6 12C6 11.4477 5.55228 11 5 11C4.44772 11 4 11.4477 4 12C4 16.0796 7.05369 19.446 11 19.9381V21C11 21.5523 11.4477 22 12 22C12.5523 22 13 21.5523 13 21V19.9381C16.9463 19.446 20 16.0796 20 12C20 11.4477 19.5523 11 19 11C18.4477 11 18 11.4477 18 12C18 14.973 15.8377 17.441 13 17.917V16C13 15.958 12.9974 15.9166 12.9924 15.8759C14.7215 15.4346 16 13.8666 16 12V6ZM12 4C10.8954 4 10 4.89543 10 6V12C10 13.1046 10.8954 14 12 14C13.1046 14 14 13.1046 14 12V6C14 4.89543 13.1046 4 12 4Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 817 B After Width: | Height: | Size: 791 B |