Merge branch 'livekit' into eslint-upgrade

This commit is contained in:
Robin
2023-10-11 10:30:57 -04:00
100 changed files with 2600 additions and 9682 deletions

View File

@@ -22,15 +22,14 @@ import { MatrixClient } from "matrix-js-sdk";
import { Modal } from "../Modal";
import styles from "./SettingsModal.module.css";
import { TabContainer, TabItem } from "../tabs/Tabs";
import { ReactComponent as AudioIcon } from "../icons/Audio.svg";
import { ReactComponent as VideoIcon } from "../icons/Video.svg";
import { ReactComponent as DeveloperIcon } from "../icons/Developer.svg";
import { ReactComponent as OverflowIcon } from "../icons/Overflow.svg";
import { ReactComponent as UserIcon } from "../icons/User.svg";
import { ReactComponent as FeedbackIcon } from "../icons/Feedback.svg";
import AudioIcon from "../icons/Audio.svg?react";
import VideoIcon from "../icons/Video.svg?react";
import DeveloperIcon from "../icons/Developer.svg?react";
import OverflowIcon from "../icons/Overflow.svg?react";
import UserIcon from "../icons/User.svg?react";
import FeedbackIcon from "../icons/Feedback.svg?react";
import { SelectInput } from "../input/SelectInput";
import {
useShowInspector,
useOptInAnalytics,
useDeveloperSettingsTab,
useShowConnectionStats,
@@ -38,8 +37,6 @@ import {
isFirefox,
} from "./useSetting";
import { FieldRow, InputField } from "../input/Input";
import { Button } from "../button";
import { useDownloadDebugLog } from "./submit-rageshake";
import { Body, Caption } from "../typography/Typography";
import { AnalyticsNotice } from "../analytics/AnalyticsNotice";
import { ProfileSettingsTab } from "./ProfileSettingsTab";
@@ -62,7 +59,6 @@ interface Props {
export const SettingsModal: FC<Props> = (props) => {
const { t } = useTranslation();
const [showInspector, setShowInspector] = useShowInspector();
const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics();
const [developerSettingsTab, setDeveloperSettingsTab] =
useDeveloperSettingsTab();
@@ -70,8 +66,6 @@ export const SettingsModal: FC<Props> = (props) => {
useShowConnectionStats();
const [enableE2EE, setEnableE2EE] = useEnableE2EE();
const downloadDebugLog = useDownloadDebugLog();
// Generate a `SelectInput` with a list of devices for a given device kind.
const generateDeviceSelection = (
devices: MediaDevice,
@@ -237,18 +231,6 @@ export const SettingsModal: FC<Props> = (props) => {
})}
</Body>
</FieldRow>
<FieldRow>
<InputField
id="showInspector"
name="inspector"
label={t("Show call inspector")}
type="checkbox"
checked={showInspector}
onChange={(e: ChangeEvent<HTMLInputElement>): void =>
setShowInspector(e.target.checked)
}
/>
</FieldRow>
<FieldRow>
<InputField
id="showConnectionStats"
@@ -278,9 +260,6 @@ export const SettingsModal: FC<Props> = (props) => {
}
/>
</FieldRow>
<FieldRow>
<Button onPress={downloadDebugLog}>{t("Download debug logs")}</Button>
</FieldRow>
</TabItem>
);

View File

@@ -41,6 +41,7 @@ import EventEmitter from "events";
import { throttle } from "lodash";
import { logger } from "matrix-js-sdk/src/logger";
import { randomString } from "matrix-js-sdk/src/randomstring";
import { LoggingMethod } from "loglevel";
// the length of log data we keep in indexeddb (and include in the reports)
const MAX_LOG_SIZE = 1024 * 1024 * 5; // 5 MB
@@ -50,15 +51,13 @@ const MAX_LOG_SIZE = 1024 * 1024 * 5; // 5 MB
// we can batch the writes a little.
const MAX_FLUSH_INTERVAL_MS = 2 * 1000;
// only descend this far into nested object trees
const DEPTH_LIMIT = 3;
enum ConsoleLoggerEvent {
Log = "log",
}
type LogFunction = (
...args: (Error | DOMException | object | string)[]
) => void;
type LogFunctionName = "log" | "info" | "warn" | "error";
// A class which monkey-patches the global console and stores log lines.
interface LogEntry {
@@ -69,37 +68,11 @@ interface LogEntry {
class ConsoleLogger extends EventEmitter {
private logs = "";
private originalFunctions: { [key in LogFunctionName]?: LogFunction } = {};
public monkeyPatch(consoleObj: Console): void {
// Monkey-patch console logging
const consoleFunctionsToLevels = {
log: "I",
info: "I",
warn: "W",
error: "E",
};
Object.entries(consoleFunctionsToLevels).forEach(([name, level]) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const originalFn = consoleObj[name].bind(consoleObj);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.originalFunctions[name] = originalFn;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
consoleObj[name] = (...args): void => {
this.log(level, ...args);
originalFn(...args);
};
});
}
public log(
level: string,
...args: (Error | DOMException | object | string)[]
): void {
public log = (
level: LogLevel,
...args: (Error | DOMException | object | string | undefined)[]
): void => {
// We don't know what locale the user may be running so use ISO strings
const ts = new Date().toISOString();
@@ -129,7 +102,7 @@ class ConsoleLogger extends EventEmitter {
this.logs += line;
this.emit(ConsoleLoggerEvent.Log);
}
};
/**
* Returns the log lines to flush to disk and empties the internal log buffer
@@ -510,7 +483,7 @@ declare global {
*/
export function init(): Promise<void> {
global.mx_rage_logger = new ConsoleLogger();
global.mx_rage_logger.monkeyPatch(window.console);
setLogExtension(global.mx_rage_logger.log);
return tryInitStorage();
}
@@ -581,13 +554,65 @@ type StringifyReplacer = (
// Injects `<$ cycle-trimmed $>` wherever it cuts a cyclical object relationship
const getCircularReplacer = (): StringifyReplacer => {
const seen = new WeakSet();
return (key: string, value: unknown): unknown => {
const depthMap = new WeakMap<object, number>();
return function (this: unknown, key: string, value: unknown): unknown {
if (typeof value === "object" && value !== null) {
if (seen.has(value)) {
return "<$ cycle-trimmed $>";
}
seen.add(value);
let depth = 0;
if (this) {
depth = depthMap.get(this) ?? 0;
}
depthMap.set(value, depth + 1);
if (depth > DEPTH_LIMIT) return "<$ object-pruned $>";
}
return value;
};
};
enum LogLevel {
trace = 0,
debug = 1,
info = 2,
warn = 3,
error = 4,
silent = 5,
}
type LogExtensionFunc = (
level: LogLevel,
...rest: (Error | DOMException | object | string)[]
) => void;
type LogLevelString = keyof typeof LogLevel;
/**
* This method borrowed from livekit (who also use loglevel and in turn essentially
* took loglevel's example honouring log levels). Adds a loglevel logging extension
* in the recommended way.
*/
export function setLogExtension(extension: LogExtensionFunc): void {
const originalFactory = logger.methodFactory;
logger.methodFactory = function (
methodName,
configLevel,
loggerName
): LoggingMethod {
const rawMethod = originalFactory(methodName, configLevel, loggerName);
const logLevel = LogLevel[methodName as LogLevelString];
const needLog = logLevel >= configLevel && logLevel < LogLevel.silent;
return (...args) => {
rawMethod.apply(this, args);
if (needLog) {
extension(logLevel, ...args);
}
};
};
logger.setLevel(logger.getLevel()); // Be sure to call setLevel method in order to apply plugin
}

View File

@@ -14,22 +14,16 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import {
ComponentProps,
useCallback,
useContext,
useEffect,
useState,
} from "react";
import { ComponentProps, useCallback, useEffect, useState } from "react";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import pako from "pako";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { ClientEvent } from "matrix-js-sdk/src/client";
import { logger } from "matrix-js-sdk/src/logger";
import { getLogsForReport } from "./rageshake";
import { useClient } from "../ClientContext";
import { InspectorContext } from "../room/GroupCallInspector";
import { Config } from "../config/Config";
import { ElementCallOpenTelemetry } from "../otel/otel";
import { RageshakeRequestModal } from "../room/RageshakeRequestModal";
@@ -57,10 +51,6 @@ export function useSubmitRageshake(): {
} {
const { client } = useClient();
// The value of the context is the whole tuple returned from setState,
// so we just want the current state.
const [inspectorState] = useContext(InspectorContext) ?? [];
const [{ sending, sent, error }, setState] = useState<{
sending: boolean;
sent: boolean;
@@ -269,16 +259,6 @@ export function useSubmitRageshake(): {
gzip(ElementCallOpenTelemetry.instance.rageshakeProcessor!.dump()),
"traces.json.gz"
);
if (inspectorState) {
body.append(
"file",
new Blob([JSON.stringify(inspectorState)], {
type: "text/plain",
}),
"groupcall.txt"
);
}
}
if (opts.rageshakeRequestId) {
@@ -296,10 +276,10 @@ export function useSubmitRageshake(): {
setState({ sending: false, sent: true, error: undefined });
} catch (error) {
setState({ sending: false, sent: false, error: error as Error });
console.error(error);
logger.error(error);
}
},
[client, inspectorState, sending]
[client, sending]
);
return {
@@ -310,27 +290,6 @@ export function useSubmitRageshake(): {
};
}
export function useDownloadDebugLog(): () => void {
const json = useContext(InspectorContext);
const downloadDebugLog = useCallback(() => {
const blob = new Blob([JSON.stringify(json)], { type: "application/json" });
const url = URL.createObjectURL(blob);
const el = document.createElement("a");
el.href = url;
el.download = "groupcall.json";
el.style.display = "none";
document.body.appendChild(el);
el.click();
setTimeout(() => {
URL.revokeObjectURL(url);
el.parentNode!.removeChild(el);
}, 0);
}, [json]);
return downloadDebugLog;
}
export function useRageshakeRequest(): (
roomId: string,
rageshakeRequestId: string

View File

@@ -83,9 +83,6 @@ export const useSpatialAudio = (): DisableableSetting<boolean> => {
return [false, null];
};
export const useShowInspector = (): Setting<boolean> =>
useSetting("show-inspector", false);
// null = undecided
export const useOptInAnalytics = (): DisableableSetting<boolean | null> => {
const settingVal = useSetting<boolean | null>("opt-in-analytics", null);