Compare commits

...

5 Commits

10 changed files with 103 additions and 43 deletions

6
app.js
View File

@@ -31,12 +31,6 @@ if (window.Olm) {
window.APP = {
API,
conference,
// Used for automated performance tests.
connectionTimes: {
'index.loaded': window.indexLoadedTime
},
translation,
UI
};

10
package-lock.json generated
View File

@@ -59,7 +59,7 @@
"js-md5": "0.6.1",
"js-sha512": "0.8.0",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1732.0.0+7841a38e/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1734.0.0+34ceebd2/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
@@ -11860,8 +11860,8 @@
},
"node_modules/lib-jitsi-meet": {
"version": "0.0.0",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1732.0.0+7841a38e/lib-jitsi-meet.tgz",
"integrity": "sha512-YYL7wS88jE9tLpUsIJm3eXQQtSIi7Cf9ZMWA6z8Bspb0u+WaANgVtqgj9BYlJAgdjGvylXljuQXR5t4nd0kk4Q==",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1734.0.0+34ceebd2/lib-jitsi-meet.tgz",
"integrity": "sha512-mHWUJ8Q4uhFsx2EZoRhgq8iGgitXig9hZ+uOuHana2YWjj1ZU0GhS5fl7VGr+LxtsonclQBBbGDt8/JkNLcfgg==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
@@ -27399,8 +27399,8 @@
}
},
"lib-jitsi-meet": {
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1732.0.0+7841a38e/lib-jitsi-meet.tgz",
"integrity": "sha512-YYL7wS88jE9tLpUsIJm3eXQQtSIi7Cf9ZMWA6z8Bspb0u+WaANgVtqgj9BYlJAgdjGvylXljuQXR5t4nd0kk4Q==",
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1734.0.0+34ceebd2/lib-jitsi-meet.tgz",
"integrity": "sha512-mHWUJ8Q4uhFsx2EZoRhgq8iGgitXig9hZ+uOuHana2YWjj1ZU0GhS5fl7VGr+LxtsonclQBBbGDt8/JkNLcfgg==",
"requires": {
"@jitsi/js-utils": "2.2.1",
"@jitsi/logger": "2.0.2",

View File

@@ -65,7 +65,7 @@
"js-md5": "0.6.1",
"js-sha512": "0.8.0",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1732.0.0+7841a38e/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1734.0.0+34ceebd2/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",

View File

@@ -16,6 +16,7 @@ import { getJitsiMeetGlobalNS } from '../base/util/helpers';
import { inIframe } from '../base/util/iframeUtils';
import { loadScript } from '../base/util/loadScript';
import { parseURIString } from '../base/util/uri';
import { isPrejoinPageVisible } from '../prejoin/functions';
import AmplitudeHandler from './handlers/AmplitudeHandler';
import MatomoHandler from './handlers/MatomoHandler';
@@ -158,9 +159,10 @@ export async function createHandlers({ getState }: IStore) {
*
* @param {Store} store - The redux store in which the specified {@code action} is being dispatched.
* @param {Array<Object>} handlers - The analytics handlers.
* @param {boolean|undefined} willShowPrejoin -
* @returns {void}
*/
export function initAnalytics(store: IStore, handlers: Array<Object>) {
export function initAnalytics(store: IStore, handlers: Array<Object>, willShowPrejoin?: boolean) {
const { getState, dispatch } = store;
if (!isAnalyticsEnabled(getState) || handlers.length === 0) {
@@ -180,8 +182,12 @@ export function initAnalytics(store: IStore, handlers: Array<Object>) {
externalApi?: boolean;
group?: string;
inIframe?: boolean;
isPromotedFromVisitor?: boolean;
isVisitor?: boolean;
server?: string;
tenant?: string;
wasLobbyVisible?: boolean;
wasPrejoinDisplayed?: boolean;
websocket?: boolean;
} & typeof deploymentInfo = {};
@@ -207,6 +213,15 @@ export function initAnalytics(store: IStore, handlers: Array<Object>) {
// Report the tenant from the URL.
permanentProperties.tenant = tenant || '/';
permanentProperties.wasPrejoinDisplayed = willShowPrejoin ?? isPrejoinPageVisible(state);
// Currently we don't know if there will be lobby. We will update it to true if we go through lobby.
permanentProperties.wasLobbyVisible = false;
// Setting visitor properties to false by default. We will update them later if it turns out we are visitor.
permanentProperties.isVisitor = false;
permanentProperties.isPromotedFromVisitor = false;
// Optionally, include local deployment information based on the
// contents of window.config.deploymentInfo.
if (deploymentInfo) {

View File

@@ -5,6 +5,7 @@ import {
SET_ROOM
} from '../base/conference/actionTypes';
import { SET_CONFIG } from '../base/config/actionTypes';
import { analytics } from '../base/lib-jitsi-meet';
import { SET_NETWORK_INFO } from '../base/net-info/actionTypes';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import {
@@ -16,6 +17,10 @@ import {
getLocalAudioTrack,
getLocalVideoTrack
} from '../base/tracks/functions';
import { SET_LOBBY_VISIBILITY } from '../lobby/actionTypes';
import { getIsLobbyVisible } from '../lobby/functions';
import { I_AM_VISITOR_MODE } from '../visitors/actionTypes';
import { iAmVisitor } from '../visitors/functions';
import { createLocalTracksDurationEvent, createNetworkInfoEvent } from './AnalyticsEvents';
import { UPDATE_LOCAL_TRACKS_DURATION } from './actionTypes';
@@ -81,6 +86,18 @@ function calculateLocalTrackDuration(state: IReduxState) {
*/
MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
case I_AM_VISITOR_MODE: {
const oldIAmVisitor = iAmVisitor(store.getState());
const result = next(action);
const newIAmVisitor = iAmVisitor(store.getState());
analytics.addPermanentProperties({
isVisitor: newIAmVisitor,
isPromotedFromVisitor: oldIAmVisitor && !newIAmVisitor
});
return result;
}
case SET_CONFIG:
if (navigator.product === 'ReactNative') {
// Resetting the analytics is currently not needed for web because
@@ -97,7 +114,7 @@ MiddlewareRegistry.register(store => next => action => {
const result = next(action);
createHandlersPromise.then(handlers => {
initAnalytics(store, handlers);
initAnalytics(store, handlers, action.willShowPrejoin);
});
return result;
@@ -144,6 +161,14 @@ MiddlewareRegistry.register(store => next => action => {
});
break;
}
case SET_LOBBY_VISIBILITY:
if (getIsLobbyVisible(store.getState())) {
analytics.addPermanentProperties({
wasLobbyVisible: true
});
}
break;
case SET_NETWORK_INFO:
sendAnalytics(
createNetworkInfoEvent({

View File

@@ -150,9 +150,20 @@ export function appNavigate(uri?: string, options: IReloadNowOptions = {}) {
return;
}
let willShowPrejoin = false;
let willShowUnsafeRoomWarning = false;
if (!options.hidePrejoin && isPrejoinPageEnabled(getState()) && room) {
if (isUnsafeRoomWarningEnabled(getState()) && isInsecureRoomName(room)) {
willShowUnsafeRoomWarning = true;
} else {
willShowPrejoin = true;
}
}
dispatch(setLocationURL(locationURL));
dispatch(setConfig(config));
dispatch(setRoom(room));
dispatch(setRoom(room, willShowPrejoin));
if (!room) {
goBackToRoot(getState(), dispatch);
@@ -163,12 +174,10 @@ export function appNavigate(uri?: string, options: IReloadNowOptions = {}) {
dispatch(createDesiredLocalTracks());
dispatch(clearNotifications());
if (!options.hidePrejoin && isPrejoinPageEnabled(getState())) {
if (isUnsafeRoomWarningEnabled(getState()) && isInsecureRoomName(room)) {
navigateRoot(screen.unsafeRoomWarning);
} else {
navigateRoot(screen.preJoin);
}
if (willShowUnsafeRoomWarning) {
navigateRoot(screen.unsafeRoomWarning);
} else if (willShowPrejoin) {
navigateRoot(screen.preJoin);
} else {
dispatch(connect());
navigateRoot(screen.conference.root);

View File

@@ -510,15 +510,18 @@ export function conferenceWillJoin(conference?: IJitsiConference) {
*
* @param {JitsiConference} conference - The JitsiConference instance which will
* be left by the local participant.
* @param {boolean} isRedirect - Indicates if the action has been dispatched as part of visitor promotion.
* @returns {{
* type: CONFERENCE_LEFT,
* conference: JitsiConference
* conference: JitsiConference,
* isRedirect: boolean
* }}
*/
export function conferenceWillLeave(conference?: IJitsiConference) {
export function conferenceWillLeave(conference?: IJitsiConference, isRedirect?: boolean) {
return {
type: CONFERENCE_WILL_LEAVE,
conference
conference,
isRedirect
};
}
@@ -897,15 +900,20 @@ export function setObfuscatedRoom(obfuscatedRoom: string, obfuscatedRoomSource:
*
* @param {(string|undefined)} room - The name of the room of the conference to
* be joined.
* @param {boolean|undefined} willShowPrejoin - Whether the prejoin should be hidden or not.
* NOTE: This argument is used only for mobile currently!
*
* @returns {{
* type: SET_ROOM,
* room: string
* room: string,
* willShowPrejoin: boolean
* }}
*/
export function setRoom(room?: string) {
export function setRoom(room?: string, willShowPrejoin?: boolean) {
return {
type: SET_ROOM,
room
room,
willShowPrejoin
};
}
@@ -1008,7 +1016,7 @@ export function redirect(vnode: string, focusJid: string, username: string) {
}
dispatch(overwriteConfig(newConfig)) // @ts-ignore
.then(() => dispatch(conferenceWillLeave(conference || joining)))
.then(() => dispatch(conferenceWillLeave(conference || joining, true)))
.then(() => dispatch(disconnect()))
.then(() => dispatch(setIAmVisitor(Boolean(vnode))))

View File

@@ -2,6 +2,7 @@ import { useNavigation } from '@react-navigation/native';
import React, { useCallback, useLayoutEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { ScrollView, Text, View, ViewStyle } from 'react-native';
import { Edge } from 'react-native-safe-area-context';
import { useDispatch, useSelector } from 'react-redux';
import { IReduxState } from '../../../app/types';
@@ -39,6 +40,7 @@ const ProfileView = ({ isInWelcomePage }: {
(state: IReduxState) => state['features/base/settings']
);
const participant = useSelector((state: IReduxState) => getLocalParticipant(state));
const { locationURL } = useSelector((state: IReduxState) => state['features/base/connection']);
const [ displayName, setDisplayName ] = useState(reduxDisplayName);
const [ email, setEmail ] = useState(reduxEmail);
@@ -103,7 +105,9 @@ const ProfileView = ({ isInWelcomePage }: {
useLayoutEffect(() => {
navigation.setOptions({
headerLeft,
headerRight: !isInWelcomePage && headerRight
headerRight: !isInWelcomePage
&& !locationURL?.hostname?.includes('8x8.vc')
&& headerRight
});
}, [ navigation ]);
@@ -112,7 +116,7 @@ const ProfileView = ({ isInWelcomePage }: {
disableForcedKeyboardDismiss = { true }
// @ts-ignore
safeAreaInsets = { [ !isInWelcomePage && 'bottom', 'left', 'right' ].filter(Boolean) }
safeAreaInsets = { [ !isInWelcomePage && 'bottom', 'left', 'right' ].filter(Boolean) as Edge[] }
style = { styles.settingsViewContainer }>
<ScrollView
bounces = { isInWelcomePage }

View File

@@ -18,7 +18,12 @@ ReducerRegistry.register<IVisitorsState>('features/visitors', (state = DEFAULT_S
case CONFERENCE_WILL_LEAVE: {
return {
...state,
...DEFAULT_STATE
...DEFAULT_STATE,
// If the action was called because a visitor was promoted don't clear the iAmVisitor field. It will be set
// to false with the I_AM_VISITOR_MODE action and we will be able to distinguish leaving the conference use
// case and promoting a visitor use case.
iAmVisitor: action.isRedirect ? state.iAmVisitor : DEFAULT_STATE.iAmVisitor
};
}
case UPDATE_VISITORS_COUNT: {

View File

@@ -1,5 +1,3 @@
/* global APP */
import React from 'react';
import ReactDOM from 'react-dom';
@@ -13,16 +11,6 @@ import PrejoinApp from './features/prejoin/components/web/PrejoinApp';
const logger = getLogger('index.web');
const OS = Platform.OS;
/**
* Renders the app when the DOM tree has been loaded.
*/
document.addEventListener('DOMContentLoaded', () => {
const now = window.performance.now();
APP.connectionTimes['document.ready'] = now;
logger.log('(TIME) document ready:\t', now);
});
// Workaround for the issue when returning to a page with the back button and
// the page is loaded from the 'back-forward' cache on iOS which causes nothing
// to be rendered.
@@ -42,6 +30,18 @@ if (OS === 'ios') {
const globalNS = getJitsiMeetGlobalNS();
// Used for automated performance tests.
globalNS.connectionTimes = {
'index.loaded': window.indexLoadedTime
};
document.addEventListener('DOMContentLoaded', () => {
const now = window.performance.now();
globalNS.connectionTimes['document.ready'] = now;
logger.log('(TIME) document ready:\t', now);
});
globalNS.entryPoints = {
APP: App,
PREJOIN: PrejoinApp,