ref(analytics) Convert to TS (#12099)
This commit is contained in:
parent
9323b86e3c
commit
f4b46128bc
|
@ -72,13 +72,13 @@ export const VIDEO_MUTE = 'video.mute';
|
|||
* Creates an event which indicates that a certain action was requested through
|
||||
* the jitsi-meet API.
|
||||
*
|
||||
* @param {Object} action - The action which was requested through the
|
||||
* @param {string} action - The action which was requested through the
|
||||
* jitsi-meet API.
|
||||
* @param {Object} attributes - Attributes to attach to the event.
|
||||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createApiEvent(action, attributes = {}) {
|
||||
export function createApiEvent(action: string, attributes = {}) {
|
||||
return {
|
||||
action,
|
||||
attributes,
|
||||
|
@ -93,7 +93,7 @@ export function createApiEvent(action, attributes = {}) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createAudioOnlyChangedEvent(enabled) {
|
||||
export function createAudioOnlyChangedEvent(enabled: boolean) {
|
||||
return {
|
||||
action: `audio.only.${enabled ? 'enabled' : 'disabled'}`
|
||||
};
|
||||
|
@ -107,7 +107,7 @@ export function createAudioOnlyChangedEvent(enabled) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createConnectionEvent(action, attributes = {}) {
|
||||
export function createConnectionEvent(action: string, attributes = {}) {
|
||||
return {
|
||||
action,
|
||||
actionSubject: 'connection',
|
||||
|
@ -124,7 +124,7 @@ export function createConnectionEvent(action, attributes = {}) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createCalendarClickedEvent(eventName, attributes = {}) {
|
||||
export function createCalendarClickedEvent(eventName: string, attributes = {}) {
|
||||
return {
|
||||
action: 'clicked',
|
||||
actionSubject: eventName,
|
||||
|
@ -175,7 +175,7 @@ export function createCalendarConnectedEvent(attributes = {}) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createRecentClickedEvent(eventName, attributes = {}) {
|
||||
export function createRecentClickedEvent(eventName: string, attributes = {}) {
|
||||
return {
|
||||
action: 'clicked',
|
||||
actionSubject: eventName,
|
||||
|
@ -193,7 +193,7 @@ export function createRecentClickedEvent(eventName, attributes = {}) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createChromeExtensionBannerEvent(installPressed, attributes = {}) {
|
||||
export function createChromeExtensionBannerEvent(installPressed: boolean, attributes = {}) {
|
||||
return {
|
||||
action: installPressed ? 'install' : 'cancel',
|
||||
attributes,
|
||||
|
@ -229,7 +229,7 @@ export function createRecentSelectedEvent(attributes = {}) {
|
|||
* sendAnalytics.
|
||||
*/
|
||||
export function createDeepLinkingPageEvent(
|
||||
action, actionSubject, attributes = {}) {
|
||||
action: string, actionSubject: string, attributes = {}) {
|
||||
return {
|
||||
action,
|
||||
actionSubject,
|
||||
|
@ -247,7 +247,7 @@ export function createDeepLinkingPageEvent(
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createDeviceChangedEvent(mediaType, deviceType) {
|
||||
export function createDeviceChangedEvent(mediaType: string, deviceType: string) {
|
||||
return {
|
||||
action: 'device.changed',
|
||||
attributes: {
|
||||
|
@ -264,7 +264,7 @@ export function createDeviceChangedEvent(mediaType, deviceType) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createE2EEEvent(action) {
|
||||
export function createE2EEEvent(action: string) {
|
||||
return {
|
||||
action,
|
||||
actionSubject: 'e2ee'
|
||||
|
@ -293,7 +293,7 @@ export function createFeedbackOpenEvent() {
|
|||
* sendAnalytics.
|
||||
*/
|
||||
export function createInviteDialogEvent(
|
||||
action, actionSubject, attributes = {}) {
|
||||
action: string, actionSubject: string, attributes = {}) {
|
||||
return {
|
||||
action,
|
||||
actionSubject,
|
||||
|
@ -310,8 +310,13 @@ export function createInviteDialogEvent(
|
|||
* @param {Object} [details] - Extra info, see {@code NetworkInfo} type defined by the 'base/net-info' feature.
|
||||
* @returns {Object}
|
||||
*/
|
||||
export function createNetworkInfoEvent({ isOnline, networkType, details }) {
|
||||
const attributes = { isOnline };
|
||||
export function createNetworkInfoEvent({ isOnline, networkType, details }:
|
||||
{ details?: Object, isOnline: boolean, networkType?: string }) {
|
||||
const attributes: {
|
||||
details?: Object;
|
||||
isOnline: boolean;
|
||||
networkType?: string;
|
||||
} = { isOnline };
|
||||
|
||||
// Do no include optional stuff or Amplitude handler will log warnings.
|
||||
networkType && (attributes.networkType = networkType);
|
||||
|
@ -345,7 +350,7 @@ export function createOfferAnswerFailedEvent() {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createPageReloadScheduledEvent(reason, timeout, details) {
|
||||
export function createPageReloadScheduledEvent(reason: string, timeout: number, details: Object) {
|
||||
return {
|
||||
action: 'page.reload.scheduled',
|
||||
attributes: {
|
||||
|
@ -365,7 +370,7 @@ export function createPageReloadScheduledEvent(reason, timeout, details) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createPinnedEvent(action, participantId, attributes) {
|
||||
export function createPinnedEvent(action: string, participantId: string, attributes = {}) {
|
||||
return {
|
||||
type: TYPE_TRACK,
|
||||
action,
|
||||
|
@ -392,7 +397,7 @@ export function createPinnedEvent(action, participantId, attributes) {
|
|||
* @param {string} action - The action.
|
||||
* @returns {Object}
|
||||
*/
|
||||
export function createPollEvent(action) {
|
||||
export function createPollEvent(action: string) {
|
||||
return {
|
||||
action: `poll.${action}`
|
||||
};
|
||||
|
@ -407,7 +412,7 @@ export function createPollEvent(action) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createProfilePanelButtonEvent(buttonName, attributes = {}) {
|
||||
export function createProfilePanelButtonEvent(buttonName: string, attributes = {}) {
|
||||
return {
|
||||
action: 'clicked',
|
||||
actionSubject: buttonName,
|
||||
|
@ -429,7 +434,7 @@ export function createProfilePanelButtonEvent(buttonName, attributes = {}) {
|
|||
* sendAnalytics.
|
||||
*/
|
||||
export function createRecordingDialogEvent(
|
||||
dialogName, buttonName, attributes = {}) {
|
||||
dialogName: string, buttonName: string, attributes = {}) {
|
||||
return {
|
||||
action: 'clicked',
|
||||
actionSubject: buttonName,
|
||||
|
@ -449,7 +454,7 @@ export function createRecordingDialogEvent(
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createLiveStreamingDialogEvent(dialogName, buttonName) {
|
||||
export function createLiveStreamingDialogEvent(dialogName: string, buttonName: string) {
|
||||
return {
|
||||
action: 'clicked',
|
||||
actionSubject: buttonName,
|
||||
|
@ -465,7 +470,14 @@ export function createLiveStreamingDialogEvent(dialogName, buttonName) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createLocalTracksDurationEvent(duration) {
|
||||
export function createLocalTracksDurationEvent(duration: {
|
||||
audio: { value: number };
|
||||
conference: { value: number };
|
||||
video: {
|
||||
camera: { value: number };
|
||||
desktop: { value: number };
|
||||
};
|
||||
}) {
|
||||
const { audio, video, conference } = duration;
|
||||
const { camera, desktop } = video;
|
||||
|
||||
|
@ -491,7 +503,7 @@ export function createLocalTracksDurationEvent(duration) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createRecordingEvent(action, type, value) {
|
||||
export function createRecordingEvent(action: string, type: string, value: number) {
|
||||
return {
|
||||
action,
|
||||
actionSubject: `recording.${type}`,
|
||||
|
@ -509,7 +521,11 @@ export function createRecordingEvent(action, type, value) {
|
|||
* @param {number} timeSinceLeft - How many seconds since the last conference was left.
|
||||
* @returns {Object} The event in a format suitable for sending via sendAnalytics.
|
||||
*/
|
||||
export function createRejoinedEvent({ url, lastConferenceDuration, timeSinceLeft }) {
|
||||
export function createRejoinedEvent({ url, lastConferenceDuration, timeSinceLeft }: {
|
||||
lastConferenceDuration: number;
|
||||
timeSinceLeft: number;
|
||||
url: string;
|
||||
}) {
|
||||
return {
|
||||
action: 'rejoined',
|
||||
attributes: {
|
||||
|
@ -530,7 +546,7 @@ export function createRejoinedEvent({ url, lastConferenceDuration, timeSinceLeft
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createRemoteMuteConfirmedEvent(participantId, mediaType) {
|
||||
export function createRemoteMuteConfirmedEvent(participantId: string, mediaType: string) {
|
||||
return {
|
||||
action: 'clicked',
|
||||
attributes: {
|
||||
|
@ -551,7 +567,7 @@ export function createRemoteMuteConfirmedEvent(participantId, mediaType) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createRemoteVideoMenuButtonEvent(buttonName, attributes) {
|
||||
export function createRemoteVideoMenuButtonEvent(buttonName: string, attributes = {}) {
|
||||
return {
|
||||
action: 'clicked',
|
||||
actionSubject: buttonName,
|
||||
|
@ -569,8 +585,13 @@ export function createRemoteVideoMenuButtonEvent(buttonName, attributes) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createRTCStatsTraceCloseEvent(closeEvent) {
|
||||
const event = {
|
||||
export function createRTCStatsTraceCloseEvent(closeEvent: {code: string; reason: string;}) {
|
||||
const event: {
|
||||
action: string;
|
||||
code?: string;
|
||||
reason?: string;
|
||||
source: string;
|
||||
} = {
|
||||
action: 'trace.onclose',
|
||||
source: 'rtcstats'
|
||||
};
|
||||
|
@ -590,7 +611,7 @@ export function createRTCStatsTraceCloseEvent(closeEvent) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createScreenSharingEvent(action, value = null) {
|
||||
export function createScreenSharingEvent(action: string, value = null) {
|
||||
return {
|
||||
action,
|
||||
actionSubject: 'screen.sharing',
|
||||
|
@ -606,7 +627,7 @@ export function createScreenSharingEvent(action, value = null) {
|
|||
* @param {Object} attributes - Additional information that describes the issue.
|
||||
* @returns {Object} The event in a format suitable for sending via sendAnalytics.
|
||||
*/
|
||||
export function createScreenSharingIssueEvent(attributes) {
|
||||
export function createScreenSharingIssueEvent(attributes = {}) {
|
||||
return {
|
||||
action: 'screen.sharing.issue',
|
||||
attributes
|
||||
|
@ -621,7 +642,7 @@ export function createScreenSharingIssueEvent(attributes) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createSharedVideoEvent(action, attributes = {}) {
|
||||
export function createSharedVideoEvent(action: string, attributes = {}) {
|
||||
return {
|
||||
action,
|
||||
attributes,
|
||||
|
@ -646,7 +667,7 @@ export function createSharedVideoEvent(action, attributes = {}) {
|
|||
* sendAnalytics.
|
||||
*/
|
||||
export function createShortcutEvent(
|
||||
shortcut,
|
||||
shortcut: string,
|
||||
action = ACTION_SHORTCUT_TRIGGERED,
|
||||
attributes = {},
|
||||
source = 'keyboard.shortcut') {
|
||||
|
@ -666,7 +687,7 @@ export function createShortcutEvent(
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createStartAudioOnlyEvent(audioOnly) {
|
||||
export function createStartAudioOnlyEvent(audioOnly: boolean) {
|
||||
return {
|
||||
action: 'start.audio.only',
|
||||
attributes: {
|
||||
|
@ -693,7 +714,7 @@ export function createStartSilentEvent() {
|
|||
* @param {string} elementID - The ID of the HTMLAudioElement.
|
||||
* @returns {Object} The event in a format suitable for sending via sendAnalytics.
|
||||
*/
|
||||
export function createAudioPlayErrorEvent(elementID) {
|
||||
export function createAudioPlayErrorEvent(elementID: string) {
|
||||
return {
|
||||
action: 'audio.play.error',
|
||||
attributes: {
|
||||
|
@ -708,7 +729,7 @@ export function createAudioPlayErrorEvent(elementID) {
|
|||
* @param {string} elementID - The ID of the HTMLAudioElement.
|
||||
* @returns {Object} The event in a format suitable for sending via sendAnalytics.
|
||||
*/
|
||||
export function createAudioPlaySuccessEvent(elementID) {
|
||||
export function createAudioPlaySuccessEvent(elementID: string) {
|
||||
return {
|
||||
action: 'audio.play.success',
|
||||
attributes: {
|
||||
|
@ -731,9 +752,9 @@ export function createAudioPlaySuccessEvent(elementID) {
|
|||
* sendAnalytics.
|
||||
*/
|
||||
export function createStartMutedConfigurationEvent(
|
||||
source,
|
||||
audioMute,
|
||||
videoMute) {
|
||||
source: string,
|
||||
audioMute: boolean,
|
||||
videoMute: boolean) {
|
||||
return {
|
||||
action: 'start.muted.configuration',
|
||||
attributes: {
|
||||
|
@ -754,7 +775,7 @@ export function createStartMutedConfigurationEvent(
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createSyncTrackStateEvent(mediaType, muted) {
|
||||
export function createSyncTrackStateEvent(mediaType: string, muted: boolean) {
|
||||
return {
|
||||
action: 'sync.track.state',
|
||||
attributes: {
|
||||
|
@ -776,7 +797,7 @@ export function createSyncTrackStateEvent(mediaType, muted) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createToolbarEvent(buttonName, attributes = {}) {
|
||||
export function createToolbarEvent(buttonName: string, attributes = {}) {
|
||||
return {
|
||||
action: 'clicked',
|
||||
actionSubject: buttonName,
|
||||
|
@ -794,7 +815,7 @@ export function createToolbarEvent(buttonName, attributes = {}) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createReactionMenuEvent(buttonName) {
|
||||
export function createReactionMenuEvent(buttonName: string) {
|
||||
return {
|
||||
action: 'clicked',
|
||||
actionSubject: 'button',
|
||||
|
@ -830,7 +851,7 @@ export function createReactionSoundsDisabledEvent() {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createTrackMutedEvent(mediaType, reason, muted = true) {
|
||||
export function createTrackMutedEvent(mediaType: string, reason: string, muted = true) {
|
||||
return {
|
||||
action: 'track.muted',
|
||||
attributes: {
|
||||
|
@ -848,7 +869,7 @@ export function createTrackMutedEvent(mediaType, reason, muted = true) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createVpaasConferenceJoinedEvent(tenant) {
|
||||
export function createVpaasConferenceJoinedEvent(tenant: string) {
|
||||
return {
|
||||
action: 'vpaas.conference.joined',
|
||||
attributes: {
|
||||
|
@ -866,7 +887,7 @@ export function createVpaasConferenceJoinedEvent(tenant) {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createWelcomePageEvent(action, actionSubject, attributes = {}) {
|
||||
export function createWelcomePageEvent(action: string, actionSubject: string, attributes = {}) {
|
||||
return {
|
||||
action,
|
||||
actionSubject,
|
||||
|
@ -894,7 +915,7 @@ export function createScreensharingCaptureTakenEvent() {
|
|||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createBreakoutRoomsEvent(actionSubject) {
|
||||
export function createBreakoutRoomsEvent(actionSubject: string) {
|
||||
return {
|
||||
action: 'clicked',
|
||||
actionSubject: `${actionSubject}.button`,
|
|
@ -1,7 +1,10 @@
|
|||
// @flow
|
||||
|
||||
/* eslint-disable lines-around-comment */
|
||||
// @ts-ignore
|
||||
import { API_ID } from '../../../modules/API/constants';
|
||||
// @ts-ignore
|
||||
import { getName as getAppName } from '../app/functions';
|
||||
import { IStore } from '../app/types';
|
||||
// @ts-ignore
|
||||
import { getAnalyticsRoomName } from '../base/conference';
|
||||
import {
|
||||
checkChromeExtensionsInstalled,
|
||||
|
@ -11,11 +14,16 @@ import JitsiMeetJS, {
|
|||
analytics,
|
||||
browser
|
||||
} from '../base/lib-jitsi-meet';
|
||||
// @ts-ignore
|
||||
import { isAnalyticsEnabled } from '../base/lib-jitsi-meet/functions';
|
||||
import { getJitsiMeetGlobalNS, loadScript, parseURIString } from '../base/util';
|
||||
// @ts-ignore
|
||||
import { loadScript } from '../base/util';
|
||||
import { getJitsiMeetGlobalNS } from '../base/util/helpers';
|
||||
import { inIframe } from '../base/util/iframeUtils';
|
||||
import { parseURIString } from '../base/util/uri';
|
||||
|
||||
import { AmplitudeHandler, MatomoHandler } from './handlers';
|
||||
import AmplitudeHandler from './handlers/AmplitudeHandler';
|
||||
import MatomoHandler from './handlers/MatomoHandler';
|
||||
import logger from './logger';
|
||||
|
||||
/**
|
||||
|
@ -155,7 +163,7 @@ export async function createHandlers({ getState }: { getState: Function }) {
|
|||
* @param {Array<Object>} handlers - The analytics handlers.
|
||||
* @returns {void}
|
||||
*/
|
||||
export function initAnalytics(store: Store, handlers: Array<Object>) {
|
||||
export function initAnalytics(store: IStore, handlers: Array<Object>) {
|
||||
const { getState, dispatch } = store;
|
||||
|
||||
if (!isAnalyticsEnabled(getState) || handlers.length === 0) {
|
||||
|
@ -168,9 +176,9 @@ export function initAnalytics(store: Store, handlers: Array<Object>) {
|
|||
deploymentInfo
|
||||
} = config;
|
||||
const { group, server } = state['features/base/jwt'];
|
||||
const { locationURL = {} } = state['features/base/connection'];
|
||||
const { locationURL = { href: '' } } = state['features/base/connection'];
|
||||
const { tenant } = parseURIString(locationURL.href) || {};
|
||||
const permanentProperties = {};
|
||||
const permanentProperties: any = {};
|
||||
|
||||
if (server) {
|
||||
permanentProperties.server = server;
|
||||
|
@ -199,7 +207,7 @@ export function initAnalytics(store: Store, handlers: Array<Object>) {
|
|||
if (deploymentInfo) {
|
||||
for (const key in deploymentInfo) {
|
||||
if (deploymentInfo.hasOwnProperty(key)) {
|
||||
permanentProperties[key] = deploymentInfo[key];
|
||||
permanentProperties[key] = deploymentInfo[key as keyof typeof deploymentInfo];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -232,7 +240,7 @@ export function initAnalytics(store: Store, handlers: Array<Object>) {
|
|||
* @returns {Promise} Resolves with the handlers that have been successfully loaded and rejects if there are no handlers
|
||||
* loaded or the analytics is disabled.
|
||||
*/
|
||||
function _loadHandlers(scriptURLs = [], handlerConstructorOptions) {
|
||||
function _loadHandlers(scriptURLs: any[] = [], handlerConstructorOptions: Object) {
|
||||
const promises = [];
|
||||
|
||||
for (const url of scriptURLs) {
|
||||
|
@ -241,7 +249,7 @@ function _loadHandlers(scriptURLs = [], handlerConstructorOptions) {
|
|||
() => {
|
||||
return { type: 'success' };
|
||||
},
|
||||
error => {
|
||||
(error: Error) => {
|
||||
return {
|
||||
type: 'error',
|
||||
error,
|
|
@ -1,13 +1,44 @@
|
|||
export interface IEvent {
|
||||
action?: string;
|
||||
actionSubject?: string;
|
||||
attributes?: {
|
||||
[key: string]: string|undefined;
|
||||
},
|
||||
name?: string;
|
||||
source?: string;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
interface Options {
|
||||
amplitudeAPPKey?: string;
|
||||
blackListedEvents?: string[];
|
||||
envType?: string;
|
||||
googleAnalyticsTrackingId?: string;
|
||||
group?: string;
|
||||
host?: string;
|
||||
matomoEndpoint?: string;
|
||||
matomoSiteID?: string;
|
||||
product?: string;
|
||||
subproduct?: string;
|
||||
user?: string;
|
||||
version?: string;
|
||||
whiteListedEvents?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract implementation of analytics handler.
|
||||
*/
|
||||
export default class AbstractHandler {
|
||||
_enabled: boolean;
|
||||
_whiteListedEvents: Array<string>|undefined;
|
||||
_blackListedEvents: Array<string>|undefined;
|
||||
|
||||
/**
|
||||
* Creates new instance.
|
||||
*
|
||||
* @param {Object} options - Optional parameters.
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
constructor(options: Options = {}) {
|
||||
this._enabled = false;
|
||||
this._whiteListedEvents = options.whiteListedEvents;
|
||||
|
||||
|
@ -28,7 +59,7 @@ export default class AbstractHandler {
|
|||
* @param {Object} event - The analytics event.
|
||||
* @returns {string} - The extracted name.
|
||||
*/
|
||||
_extractName(event) {
|
||||
_extractName(event: IEvent) {
|
||||
// Page events have a single 'name' field.
|
||||
if (event.type === 'page') {
|
||||
return event.name;
|
||||
|
@ -65,12 +96,12 @@ export default class AbstractHandler {
|
|||
* @param {Object} event - The event.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_shouldIgnore(event) {
|
||||
_shouldIgnore(event: IEvent) {
|
||||
if (!event || !this._enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const name = this._extractName(event);
|
||||
const name = this._extractName(event) ?? '';
|
||||
|
||||
if (Array.isArray(this._whiteListedEvents)) {
|
||||
return this._whiteListedEvents.indexOf(name) === -1;
|
|
@ -1,13 +1,18 @@
|
|||
/* eslint-disable lines-around-comment */
|
||||
import logger from '../logger';
|
||||
|
||||
import AbstractHandler from './AbstractHandler';
|
||||
import AbstractHandler, { IEvent } from './AbstractHandler';
|
||||
// @ts-ignore
|
||||
import { fixDeviceID } from './amplitude/fixDeviceID';
|
||||
// @ts-ignore
|
||||
import amplitude from './amplitude/lib';
|
||||
|
||||
/**
|
||||
* Analytics handler for Amplitude.
|
||||
*/
|
||||
export default class AmplitudeHandler extends AbstractHandler {
|
||||
_deviceId: string;
|
||||
_userId: Object;
|
||||
/**
|
||||
* Creates new instance of the Amplitude analytics handler.
|
||||
*
|
||||
|
@ -15,14 +20,14 @@ export default class AmplitudeHandler extends AbstractHandler {
|
|||
* @param {string} options.amplitudeAPPKey - The Amplitude app key required
|
||||
* by the Amplitude API.
|
||||
*/
|
||||
constructor(options) {
|
||||
constructor(options: any) {
|
||||
super(options);
|
||||
|
||||
const { amplitudeAPPKey, user } = options;
|
||||
|
||||
this._enabled = true;
|
||||
|
||||
const onError = e => {
|
||||
const onError = (e: Error) => {
|
||||
logger.error('Error initializing Amplitude', e);
|
||||
this._enabled = false;
|
||||
};
|
||||
|
@ -31,7 +36,7 @@ export default class AmplitudeHandler extends AbstractHandler {
|
|||
amplitude.getInstance().init(amplitudeAPPKey);
|
||||
fixDeviceID(amplitude.getInstance()).then(() => {
|
||||
amplitude.getInstance().getDeviceId()
|
||||
.then(deviceId => {
|
||||
.then((deviceId: string) => {
|
||||
this._deviceId = deviceId;
|
||||
});
|
||||
});
|
||||
|
@ -57,7 +62,7 @@ export default class AmplitudeHandler extends AbstractHandler {
|
|||
* @param {Object} userProps - The user portperties.
|
||||
* @returns {void}
|
||||
*/
|
||||
setUserProperties(userProps) {
|
||||
setUserProperties(userProps: Object) {
|
||||
if (this._enabled) {
|
||||
amplitude.getInstance().setUserProperties(userProps);
|
||||
}
|
||||
|
@ -71,7 +76,7 @@ export default class AmplitudeHandler extends AbstractHandler {
|
|||
* lib-jitsi-meet.
|
||||
* @returns {void}
|
||||
*/
|
||||
sendEvent(event) {
|
||||
sendEvent(event: IEvent) {
|
||||
if (this._shouldIgnore(event)) {
|
||||
return;
|
||||
}
|
|
@ -1,13 +1,15 @@
|
|||
/* global ga */
|
||||
|
||||
import { getJitsiMeetGlobalNS } from '../../base/util';
|
||||
import { getJitsiMeetGlobalNS } from '../../base/util/helpers';
|
||||
|
||||
import AbstractHandler from './AbstractHandler';
|
||||
import AbstractHandler, { IEvent } from './AbstractHandler';
|
||||
|
||||
/**
|
||||
* Analytics handler for Google Analytics.
|
||||
*/
|
||||
class GoogleAnalyticsHandler extends AbstractHandler {
|
||||
_userProperties: Object;
|
||||
_userPropertiesString: string;
|
||||
|
||||
/**
|
||||
* Creates new instance of the GA analytics handler.
|
||||
|
@ -16,7 +18,7 @@ class GoogleAnalyticsHandler extends AbstractHandler {
|
|||
* @param {string} options.googleAnalyticsTrackingId - The GA track id
|
||||
* required by the GA API.
|
||||
*/
|
||||
constructor(options) {
|
||||
constructor(options: any) {
|
||||
super(options);
|
||||
|
||||
this._userProperties = {};
|
||||
|
@ -37,16 +39,20 @@ class GoogleAnalyticsHandler extends AbstractHandler {
|
|||
* required by the GA API.
|
||||
* @returns {void}
|
||||
*/
|
||||
_initGoogleAnalytics(options) {
|
||||
_initGoogleAnalytics(options: any) {
|
||||
/**
|
||||
* TODO: Keep this local, there's no need to add it to window.
|
||||
*/
|
||||
/* eslint-disable */
|
||||
/* eslint-disable */ // @ts-ignore
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
// @ts-ignore
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
/* eslint-enable */
|
||||
// @ts-ignore
|
||||
ga('create', options.googleAnalyticsTrackingId, 'auto');
|
||||
|
||||
// @ts-ignore
|
||||
ga('send', 'pageview');
|
||||
}
|
||||
|
||||
|
@ -60,11 +66,11 @@ class GoogleAnalyticsHandler extends AbstractHandler {
|
|||
* suitable value.
|
||||
* @private
|
||||
*/
|
||||
_extractValue(event) {
|
||||
let value = event && event.attributes && event.attributes.value;
|
||||
_extractValue(event: IEvent) {
|
||||
let value: string|number|undefined = event && event.attributes && event.attributes.value;
|
||||
|
||||
// Try to extract an integer from the "value" attribute.
|
||||
value = Math.round(parseFloat(value));
|
||||
value = Math.round(parseFloat(value ?? ''));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@ -78,7 +84,7 @@ class GoogleAnalyticsHandler extends AbstractHandler {
|
|||
* analytics event.
|
||||
* @private
|
||||
*/
|
||||
_extractLabel(event) {
|
||||
_extractLabel(event: IEvent) {
|
||||
const { attributes = {} } = event;
|
||||
const labelsArray
|
||||
= Object.keys(attributes).map(key => `${key}=${attributes[key]}`);
|
||||
|
@ -94,7 +100,7 @@ class GoogleAnalyticsHandler extends AbstractHandler {
|
|||
* @param {Object} userProps - The permanent portperties.
|
||||
* @returns {void}
|
||||
*/
|
||||
setUserProperties(userProps = {}) {
|
||||
setUserProperties(userProps: any = {}) {
|
||||
if (!this._enabled) {
|
||||
return;
|
||||
}
|
||||
|
@ -120,12 +126,17 @@ class GoogleAnalyticsHandler extends AbstractHandler {
|
|||
* lib-jitsi-meet.
|
||||
* @returns {void}
|
||||
*/
|
||||
sendEvent(event) {
|
||||
sendEvent(event: IEvent) {
|
||||
if (this._shouldIgnore(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const gaEvent = {
|
||||
const gaEvent: {
|
||||
eventAction?: string;
|
||||
eventCategory: string;
|
||||
eventLabel: string;
|
||||
eventValue?: number;
|
||||
} = {
|
||||
'eventCategory': 'jitsi-meet',
|
||||
'eventAction': this._extractName(event),
|
||||
'eventLabel': this._extractLabel(event)
|
||||
|
@ -136,6 +147,7 @@ class GoogleAnalyticsHandler extends AbstractHandler {
|
|||
gaEvent.eventValue = value;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
ga('send', 'event', gaEvent);
|
||||
}
|
||||
|
|
@ -1,13 +1,14 @@
|
|||
/* global _paq */
|
||||
|
||||
import { getJitsiMeetGlobalNS } from '../../base/util';
|
||||
import { getJitsiMeetGlobalNS } from '../../base/util/helpers';
|
||||
|
||||
import AbstractHandler from './AbstractHandler';
|
||||
import AbstractHandler, { IEvent } from './AbstractHandler';
|
||||
|
||||
/**
|
||||
* Analytics handler for Matomo.
|
||||
*/
|
||||
export default class MatomoHandler extends AbstractHandler {
|
||||
_userProperties: Object;
|
||||
|
||||
/**
|
||||
* Creates new instance of the Matomo handler.
|
||||
|
@ -16,7 +17,7 @@ export default class MatomoHandler extends AbstractHandler {
|
|||
* @param {string} options.matomoEndpoint - The Matomo endpoint.
|
||||
* @param {string} options.matomoSiteID - The site ID.
|
||||
*/
|
||||
constructor(options) {
|
||||
constructor(options: any) {
|
||||
super(options);
|
||||
this._userProperties = {};
|
||||
|
||||
|
@ -43,9 +44,11 @@ export default class MatomoHandler extends AbstractHandler {
|
|||
* @param {string} options.matomoSiteID - The site ID.
|
||||
* @returns {void}
|
||||
*/
|
||||
_initMatomo(options) {
|
||||
_initMatomo(options: any) {
|
||||
// @ts-ignore
|
||||
const _paq = window._paq || [];
|
||||
|
||||
// @ts-ignore
|
||||
window._paq = _paq;
|
||||
|
||||
_paq.push([ 'trackPageView' ]);
|
||||
|
@ -70,7 +73,7 @@ export default class MatomoHandler extends AbstractHandler {
|
|||
g.async = true;
|
||||
g.defer = true;
|
||||
g.src = `${u}matomo.js`;
|
||||
s.parentNode.insertBefore(g, s);
|
||||
s.parentNode?.insertBefore(g, s);
|
||||
})();
|
||||
}
|
||||
|
||||
|
@ -84,11 +87,11 @@ export default class MatomoHandler extends AbstractHandler {
|
|||
* suitable value.
|
||||
* @private
|
||||
*/
|
||||
_extractValue(event) {
|
||||
_extractValue(event: IEvent) {
|
||||
const value = event && event.attributes && event.attributes.value;
|
||||
|
||||
// Try to extract an integer from the 'value' attribute.
|
||||
return Math.round(parseFloat(value));
|
||||
return Math.round(parseFloat(value ?? ''));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -97,7 +100,7 @@ export default class MatomoHandler extends AbstractHandler {
|
|||
* @param {Object} userProps - The permanent properties.
|
||||
* @returns {void}
|
||||
*/
|
||||
setUserProperties(userProps = {}) {
|
||||
setUserProperties(userProps: any = {}) {
|
||||
if (!this._enabled) {
|
||||
return;
|
||||
}
|
||||
|
@ -108,6 +111,7 @@ export default class MatomoHandler extends AbstractHandler {
|
|||
Object.keys(userProps)
|
||||
.filter(key => visitScope.indexOf(key) === -1)
|
||||
.forEach((key, index) => {
|
||||
// @ts-ignore
|
||||
_paq.push([
|
||||
'setCustomVariable',
|
||||
1 + index,
|
||||
|
@ -122,6 +126,7 @@ export default class MatomoHandler extends AbstractHandler {
|
|||
Object.keys(userProps)
|
||||
.filter(key => visitScope.indexOf(key) !== -1)
|
||||
.forEach((key, index) => {
|
||||
// @ts-ignore
|
||||
_paq.push([
|
||||
'setCustomVariable',
|
||||
1 + index,
|
||||
|
@ -141,18 +146,19 @@ export default class MatomoHandler extends AbstractHandler {
|
|||
* lib-jitsi-meet.
|
||||
* @returns {void}
|
||||
*/
|
||||
sendEvent(event) {
|
||||
sendEvent(event: IEvent) {
|
||||
if (this._shouldIgnore(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const value = this._extractValue(event);
|
||||
const matomoEvent = [ 'trackEvent', 'jitsi-meet', this._extractName(event) ];
|
||||
const matomoEvent: Array<string|number|undefined> = [ 'trackEvent', 'jitsi-meet', this._extractName(event) ];
|
||||
|
||||
if (!isNaN(value)) {
|
||||
matomoEvent.push(value);
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
_paq.push(matomoEvent);
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ import DeviceInfo from 'react-native-device-info';
|
|||
* @param {AmplitudeClient} amplitude - The amplitude instance.
|
||||
* @returns {void}
|
||||
*/
|
||||
export async function fixDeviceID(amplitude) {
|
||||
export async function fixDeviceID(amplitude: any) {
|
||||
await DefaultPreference.setName('jitsi-preferences');
|
||||
|
||||
const current = await DefaultPreference.get('amplitudeDeviceId');
|
|
@ -4,6 +4,6 @@
|
|||
* @param {AmplitudeClient} amplitude - The amplitude instance.
|
||||
* @returns {void}
|
||||
*/
|
||||
export function fixDeviceID(amplitude) { // eslint-disable-line no-unused-vars
|
||||
export function fixDeviceID(amplitude: any) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-ignore
|
||||
import amplitude from 'amplitude-js';
|
||||
|
||||
export default amplitude;
|
|
@ -1,5 +1,3 @@
|
|||
// @flow
|
||||
|
||||
import { getLogger } from '../base/logging/functions';
|
||||
|
||||
export default getLogger('features/analytics');
|
|
@ -1,20 +1,23 @@
|
|||
// @flow
|
||||
|
||||
/* eslint-disable lines-around-comment */
|
||||
import { IState } from '../app/types';
|
||||
import {
|
||||
CONFERENCE_JOINED,
|
||||
CONFERENCE_WILL_LEAVE,
|
||||
SET_ROOM
|
||||
} from '../base/conference';
|
||||
import { SET_CONFIG } from '../base/config';
|
||||
import { SET_NETWORK_INFO } from '../base/net-info';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
} from '../base/conference/actionTypes';
|
||||
import { SET_CONFIG } from '../base/config/actionTypes';
|
||||
import { SET_NETWORK_INFO } from '../base/net-info/actionTypes';
|
||||
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
|
||||
import {
|
||||
getLocalAudioTrack,
|
||||
getLocalVideoTrack,
|
||||
TRACK_ADDED,
|
||||
TRACK_REMOVED,
|
||||
TRACK_UPDATED
|
||||
} from '../base/tracks';
|
||||
} from '../base/tracks/actionTypes';
|
||||
import {
|
||||
getLocalAudioTrack,
|
||||
getLocalVideoTrack
|
||||
// @ts-ignore
|
||||
} from '../base/tracks/functions';
|
||||
|
||||
import { createLocalTracksDurationEvent, createNetworkInfoEvent } from './AnalyticsEvents';
|
||||
import { UPDATE_LOCAL_TRACKS_DURATION } from './actionTypes';
|
||||
|
@ -26,7 +29,7 @@ import { createHandlers, initAnalytics, resetAnalytics, sendAnalytics } from './
|
|||
* @param {Object} state - The redux state.
|
||||
* @returns {Object} - The local tracks duration.
|
||||
*/
|
||||
function calculateLocalTrackDuration(state) {
|
||||
function calculateLocalTrackDuration(state: IState) {
|
||||
const now = Date.now();
|
||||
const { localTracksDuration } = state['features/analytics'];
|
||||
const { conference } = state['features/base/conference'];
|
||||
|
@ -60,8 +63,8 @@ function calculateLocalTrackDuration(state) {
|
|||
} else {
|
||||
const { videoType } = videoTrack;
|
||||
|
||||
if (video[videoType].startedTime === -1) {
|
||||
newDuration.video[videoType].startedTime = now;
|
||||
if (video[videoType as keyof typeof video].startedTime === -1) {
|
||||
newDuration.video[videoType as keyof typeof video].startedTime = now;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,9 @@ import { equals } from '../redux/functions';
|
|||
import { SET_JWT } from './actionTypes';
|
||||
|
||||
export interface IJwtState {
|
||||
group?: string;
|
||||
jwt?: string;
|
||||
server?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -341,7 +341,7 @@ module.exports = (_env, argv) => {
|
|||
}),
|
||||
Object.assign({}, config, {
|
||||
entry: {
|
||||
'analytics-ga': './react/features/analytics/handlers/GoogleAnalyticsHandler.js'
|
||||
'analytics-ga': './react/features/analytics/handlers/GoogleAnalyticsHandler.ts'
|
||||
},
|
||||
plugins: [
|
||||
...config.plugins,
|
||||
|
|
Loading…
Reference in New Issue