mirror of
https://github.com/vector-im/element-call.git
synced 2024-11-24 00:38:31 +08:00
Perform dead code analysis with Knip (#2575)
* Install Knip * Clarify an import that was confusing Knip * Fix issues detected by Knip Including cleaning up some unused code and dependencies, using a React hook that we unintentionally stopped using, and also adding some previously undeclared dependencies. * Run dead code analysis in lint script and CI --------- Co-authored-by: Timo <toger5@hotmail.de>
This commit is contained in:
parent
51ae4c0a88
commit
7bca541cb6
2
.github/workflows/lint.yaml
vendored
2
.github/workflows/lint.yaml
vendored
@ -23,3 +23,5 @@ jobs:
|
||||
run: "yarn run lint:eslint"
|
||||
- name: Type check
|
||||
run: "yarn run lint:types"
|
||||
- name: Dead code analysis
|
||||
run: "yarn run lint:knip"
|
||||
|
3
.github/workflows/test.yaml
vendored
3
.github/workflows/test.yaml
vendored
@ -21,7 +21,8 @@ jobs:
|
||||
run: "yarn run test:coverage"
|
||||
- name: Upload to codecov
|
||||
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
with:
|
||||
flags: unittests
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
fail_ci_if_error: true
|
||||
|
30
knip.ts
Normal file
30
knip.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { KnipConfig } from "knip";
|
||||
|
||||
export default {
|
||||
entry: ["src/main.tsx", "i18next-parser.config.ts"],
|
||||
ignoreBinaries: [
|
||||
// This is deprecated, so Knip doesn't actually recognize it as a globally
|
||||
// installed binary. TODO We should switch to Compose v2:
|
||||
// https://docs.docker.com/compose/migrate/
|
||||
"docker-compose",
|
||||
],
|
||||
ignoreDependencies: [
|
||||
// Used in CSS
|
||||
"normalize.css",
|
||||
// Used for its global type declarations
|
||||
"@types/grecaptcha",
|
||||
// Because we use matrix-js-sdk as a Git dependency rather than consuming
|
||||
// the proper release artifacts, and also import directly from src/, we're
|
||||
// forced to re-install some of the types that it depends on even though
|
||||
// these look unused to Knip
|
||||
"@types/content-type",
|
||||
"@types/sdp-transform",
|
||||
"@types/uuid",
|
||||
// We obviously use this, but if the package has been linked with yarn link,
|
||||
// then Knip will flag it as a false positive
|
||||
// https://github.com/webpro-nl/knip/issues/766
|
||||
"@vector-im/compound-web",
|
||||
"matrix-widget-api",
|
||||
],
|
||||
ignoreExportsUsedInFile: true,
|
||||
} satisfies KnipConfig;
|
109
package.json
109
package.json
@ -8,32 +8,39 @@
|
||||
"serve": "vite preview",
|
||||
"prettier:check": "prettier -c .",
|
||||
"prettier:format": "prettier -w .",
|
||||
"lint": "yarn lint:types && yarn lint:eslint",
|
||||
"lint": "yarn lint:types && yarn lint:eslint && yarn lint:knip",
|
||||
"lint:eslint": "eslint --max-warnings 0 src",
|
||||
"lint:eslint-fix": "eslint --max-warnings 0 src --fix",
|
||||
"lint:knip": "knip",
|
||||
"lint:types": "tsc",
|
||||
"i18n": "node_modules/i18next-parser/bin/cli.js",
|
||||
"i18n:check": "node_modules/i18next-parser/bin/cli.js --fail-on-warnings --fail-on-update",
|
||||
"i18n": "i18next",
|
||||
"i18n:check": "i18next --fail-on-warnings --fail-on-update",
|
||||
"test": "vitest",
|
||||
"test:coverage": "vitest --coverage",
|
||||
"backend": "docker-compose -f backend-docker-compose.yml up"
|
||||
},
|
||||
"dependencies": {
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.16.5",
|
||||
"@babel/preset-env": "^7.22.20",
|
||||
"@babel/preset-react": "^7.22.15",
|
||||
"@babel/preset-typescript": "^7.23.0",
|
||||
"@juggle/resize-observer": "^3.3.1",
|
||||
"@livekit/components-core": "^0.11.0",
|
||||
"@livekit/components-react": "^2.0.0",
|
||||
"@opentelemetry/api": "^1.4.0",
|
||||
"@opentelemetry/context-zone": "^1.9.1",
|
||||
"@opentelemetry/exporter-jaeger": "^1.9.1",
|
||||
"@opentelemetry/core": "^1.25.1",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.52.0",
|
||||
"@opentelemetry/instrumentation-document-load": "^0.39.0",
|
||||
"@opentelemetry/instrumentation-user-interaction": "^0.39.0",
|
||||
"@opentelemetry/resources": "^1.25.1",
|
||||
"@opentelemetry/sdk-trace-base": "^1.25.1",
|
||||
"@opentelemetry/sdk-trace-web": "^1.9.1",
|
||||
"@opentelemetry/semantic-conventions": "^1.25.1",
|
||||
"@radix-ui/react-dialog": "^1.0.4",
|
||||
"@radix-ui/react-slider": "^1.1.2",
|
||||
"@radix-ui/react-visually-hidden": "^1.0.3",
|
||||
"@react-aria/button": "^3.3.4",
|
||||
"@react-aria/focus": "^3.5.0",
|
||||
"@react-aria/interactions": "^3.9.1",
|
||||
"@react-aria/listbox": "^3.5.1",
|
||||
"@react-aria/menu": "^3.3.0",
|
||||
"@react-aria/overlays": "^3.7.3",
|
||||
"@react-aria/select": "^3.6.0",
|
||||
@ -42,71 +49,40 @@
|
||||
"@react-aria/utils": "^3.10.0",
|
||||
"@react-spring/web": "^9.4.4",
|
||||
"@react-stately/collections": "^3.3.4",
|
||||
"@react-stately/list": "^3.5.1",
|
||||
"@react-stately/menu": "^3.3.1",
|
||||
"@react-stately/select": "^3.1.3",
|
||||
"@react-stately/tabs": "^3.1.1",
|
||||
"@react-stately/tooltip": "^3.0.5",
|
||||
"@react-stately/tree": "^3.2.0",
|
||||
"@sentry/react": "^8.0.0",
|
||||
"@sentry/tracing": "^7.0.0",
|
||||
"@types/lodash": "^4.14.199",
|
||||
"@use-gesture/react": "^10.2.11",
|
||||
"@vector-im/compound-design-tokens": "^1.0.0",
|
||||
"@vector-im/compound-web": "^6.0.0",
|
||||
"@vitejs/plugin-basic-ssl": "^1.0.1",
|
||||
"@vitejs/plugin-react": "^4.0.1",
|
||||
"buffer": "^6.0.3",
|
||||
"classnames": "^2.3.1",
|
||||
"events": "^3.3.0",
|
||||
"i18next": "^23.0.0",
|
||||
"i18next-browser-languagedetector": "^8.0.0",
|
||||
"i18next-http-backend": "^2.0.0",
|
||||
"livekit-client": "^2.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#467908703bc67fa3e23d978f5549e2709d4acf74",
|
||||
"matrix-widget-api": "^1.8.2",
|
||||
"normalize.css": "^8.0.1",
|
||||
"observable-hooks": "^4.2.3",
|
||||
"pako": "^2.0.4",
|
||||
"postcss-preset-env": "^10.0.0",
|
||||
"posthog-js": "^1.29.0",
|
||||
"react": "18",
|
||||
"react-dom": "18",
|
||||
"react-i18next": "^15.0.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-use-clipboard": "^1.0.7",
|
||||
"react-use-measure": "^2.1.1",
|
||||
"rxjs": "^7.8.1",
|
||||
"sdp-transform": "^2.14.1",
|
||||
"tinyqueue": "^3.0.0",
|
||||
"unique-names-generator": "^4.6.0",
|
||||
"uuid": "10",
|
||||
"vaul": "^0.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.16.5",
|
||||
"@babel/preset-env": "^7.22.20",
|
||||
"@babel/preset-react": "^7.22.15",
|
||||
"@babel/preset-typescript": "^7.23.0",
|
||||
"@react-spring/rafz": "^9.7.3",
|
||||
"@react-types/dialog": "^3.5.5",
|
||||
"@react-types/menu": "^3.6.1",
|
||||
"@react-types/overlays": "^3.6.1",
|
||||
"@react-types/shared": "^3.13.1",
|
||||
"@react-types/tabs": "^3.1.1",
|
||||
"@sentry/react": "^8.0.0",
|
||||
"@sentry/vite-plugin": "^2.0.0",
|
||||
"@testing-library/dom": "^10.1.0",
|
||||
"@testing-library/react": "^16.0.0",
|
||||
"@testing-library/user-event": "^14.5.1",
|
||||
"@types/content-type": "^1.1.5",
|
||||
"@types/dom-screen-wake-lock": "^1.0.1",
|
||||
"@types/dompurify": "^3.0.2",
|
||||
"@types/grecaptcha": "^3.0.9",
|
||||
"@types/lodash": "^4.14.199",
|
||||
"@types/node": "^20.0.0",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"@types/request": "^2.48.8",
|
||||
"@types/sdp-transform": "^2.4.5",
|
||||
"@types/uuid": "10",
|
||||
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
||||
"@typescript-eslint/parser": "^7.0.0",
|
||||
"@use-gesture/react": "^10.2.11",
|
||||
"@vector-im/compound-design-tokens": "^1.0.0",
|
||||
"@vector-im/compound-web": "^6.0.0",
|
||||
"@vitejs/plugin-basic-ssl": "^1.0.1",
|
||||
"@vitejs/plugin-react": "^4.0.1",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"babel-loader": "^9.0.0",
|
||||
"babel-plugin-transform-vite-meta-env": "^1.0.3",
|
||||
"classnames": "^2.3.1",
|
||||
"eslint": "^8.14.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
@ -118,12 +94,37 @@
|
||||
"eslint-plugin-react-hooks": "^4.5.0",
|
||||
"eslint-plugin-unicorn": "^55.0.0",
|
||||
"global-jsdom": "^24.0.0",
|
||||
"history": "^4.0.0",
|
||||
"i18next": "^23.0.0",
|
||||
"i18next-browser-languagedetector": "^8.0.0",
|
||||
"i18next-http-backend": "^2.0.0",
|
||||
"i18next-parser": "^9.0.0",
|
||||
"jsdom": "^25.0.0",
|
||||
"knip": "^5.27.2",
|
||||
"livekit-client": "^2.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
"loglevel": "^1.9.1",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#467908703bc67fa3e23d978f5549e2709d4acf74",
|
||||
"matrix-widget-api": "^1.8.2",
|
||||
"normalize.css": "^8.0.1",
|
||||
"observable-hooks": "^4.2.3",
|
||||
"pako": "^2.0.4",
|
||||
"postcss": "^8.4.41",
|
||||
"postcss-preset-env": "^10.0.0",
|
||||
"posthog-js": "^1.29.0",
|
||||
"prettier": "^3.0.0",
|
||||
"react": "18",
|
||||
"react-dom": "18",
|
||||
"react-i18next": "^15.0.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-use-clipboard": "^1.0.7",
|
||||
"react-use-measure": "^2.1.1",
|
||||
"rxjs": "^7.8.1",
|
||||
"sass": "^1.42.1",
|
||||
"typescript": "^5.1.6",
|
||||
"typescript-eslint-language-service": "^5.0.5",
|
||||
"unique-names-generator": "^4.6.0",
|
||||
"vaul": "^0.9.0",
|
||||
"vite": "^5.0.0",
|
||||
"vite-plugin-html-template": "^1.1.0",
|
||||
"vite-plugin-svgr": "^4.0.0",
|
||||
|
@ -48,6 +48,8 @@
|
||||
"ignoreDeps": [
|
||||
"@react-aria/button",
|
||||
"@react-aria/focus",
|
||||
"@react-aria/interactions",
|
||||
"@react-aria/listbox",
|
||||
"@react-aria/menu",
|
||||
"@react-aria/overlays",
|
||||
"@react-aria/select",
|
||||
@ -55,9 +57,16 @@
|
||||
"@react-aria/tooltip",
|
||||
"@react-aria/utils",
|
||||
"@react-stately/collections",
|
||||
"@react-stately/list",
|
||||
"@react-stately/menu",
|
||||
"@react-stately/select",
|
||||
"@react-stately/tabs",
|
||||
"@react-stately/tooltip",
|
||||
"@react-stately/tree",
|
||||
"@react-types/dialog"
|
||||
"@react-types/dialog",
|
||||
"@react-types/menu",
|
||||
"@react-types/overlays",
|
||||
"@react-types/shared",
|
||||
"@react-types/tabs"
|
||||
]
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
Copyright 2023 New Vector Ltd
|
||||
|
||||
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 { FC, ReactNode } from "react";
|
||||
|
||||
import styles from "./Banner.module.css";
|
||||
|
||||
interface Props {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const Banner: FC<Props> = ({ children }) => {
|
||||
return <div className={styles.banner}>{children}</div>;
|
||||
};
|
@ -40,10 +40,7 @@ import { Caption } from "../typography/Typography";
|
||||
import { Form } from "../form/Form";
|
||||
import { AnalyticsNotice } from "../analytics/AnalyticsNotice";
|
||||
import { E2eeType } from "../e2ee/e2eeType";
|
||||
import {
|
||||
useSetting,
|
||||
optInAnalytics as optInAnalyticsSetting,
|
||||
} from "../settings/settings";
|
||||
import { useOptInAnalytics } from "../settings/settings";
|
||||
|
||||
interface Props {
|
||||
client: MatrixClient;
|
||||
@ -52,7 +49,7 @@ interface Props {
|
||||
export const RegisteredView: FC<Props> = ({ client }) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<Error>();
|
||||
const [optInAnalytics] = useSetting(optInAnalyticsSetting);
|
||||
const [optInAnalytics] = useOptInAnalytics();
|
||||
const history = useHistory();
|
||||
const { t } = useTranslation();
|
||||
const [joinExistingCallModalOpen, setJoinExistingCallModalOpen] =
|
||||
|
@ -43,16 +43,13 @@ import { generateRandomName } from "../auth/generateRandomName";
|
||||
import { AnalyticsNotice } from "../analytics/AnalyticsNotice";
|
||||
import { Config } from "../config/Config";
|
||||
import { E2eeType } from "../e2ee/e2eeType";
|
||||
import {
|
||||
useSetting,
|
||||
optInAnalytics as optInAnalyticsSetting,
|
||||
} from "../settings/settings";
|
||||
import { useOptInAnalytics } from "../settings/settings";
|
||||
|
||||
export const UnauthenticatedView: FC = () => {
|
||||
const { setClient } = useClient();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<Error>();
|
||||
const [optInAnalytics] = useSetting(optInAnalyticsSetting);
|
||||
const [optInAnalytics] = useOptInAnalytics();
|
||||
const { recaptchaKey, register } = useInteractiveRegistration();
|
||||
const { execute, reset, recaptchaId } = useRecaptcha(recaptchaKey);
|
||||
|
||||
|
@ -35,10 +35,7 @@ import { LobbyView } from "./LobbyView";
|
||||
import { E2eeType } from "../e2ee/e2eeType";
|
||||
import { useProfile } from "../profile/useProfile";
|
||||
import { useMuteStates } from "./MuteStates";
|
||||
import {
|
||||
useSetting,
|
||||
optInAnalytics as optInAnalyticsSetting,
|
||||
} from "../settings/settings";
|
||||
import { useOptInAnalytics } from "../settings/settings";
|
||||
|
||||
export const RoomPage: FC = () => {
|
||||
const {
|
||||
@ -83,7 +80,7 @@ export const RoomPage: FC = () => {
|
||||
registerPasswordlessUser,
|
||||
]);
|
||||
|
||||
const [optInAnalytics, setOptInAnalytics] = useSetting(optInAnalyticsSetting);
|
||||
const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics();
|
||||
useEffect(() => {
|
||||
// During the beta, opt into analytics by default
|
||||
if (optInAnalytics === null && setOptInAnalytics) setOptInAnalytics(true);
|
||||
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 New Vector Ltd
|
||||
|
||||
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 { useEffect } from "react";
|
||||
|
||||
import { platform } from "../Platform";
|
||||
|
||||
export function usePageUnload(callback: () => void): void {
|
||||
useEffect(() => {
|
||||
let pageVisibilityTimeout: ReturnType<typeof setTimeout>;
|
||||
|
||||
function onBeforeUnload(event: PageTransitionEvent): void {
|
||||
if (event.type === "visibilitychange") {
|
||||
if (document.visibilityState === "visible") {
|
||||
clearTimeout(pageVisibilityTimeout);
|
||||
} else {
|
||||
// Wait 5 seconds before closing the page to avoid accidentally leaving
|
||||
// TODO: Make this configurable?
|
||||
pageVisibilityTimeout = setTimeout(() => {
|
||||
callback();
|
||||
}, 5000);
|
||||
}
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
// iOS doesn't fire beforeunload event, so leave the call when you hide the page.
|
||||
if (platform === "ios") {
|
||||
window.addEventListener("pagehide", onBeforeUnload);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
document.addEventListener("visibilitychange", onBeforeUnload);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
window.addEventListener("beforeunload", onBeforeUnload);
|
||||
|
||||
return (): void => {
|
||||
window.removeEventListener("pagehide", onBeforeUnload);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
document.removeEventListener("visibilitychange", onBeforeUnload);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
window.removeEventListener("beforeunload", onBeforeUnload);
|
||||
clearTimeout(pageVisibilityTimeout);
|
||||
};
|
||||
}, [callback]);
|
||||
}
|
@ -42,9 +42,9 @@ import {
|
||||
import { widget } from "../widget";
|
||||
import {
|
||||
useSetting,
|
||||
optInAnalytics as optInAnalyticsSetting,
|
||||
developerSettingsTab as developerSettingsTabSetting,
|
||||
duplicateTiles as duplicateTilesSetting,
|
||||
useOptInAnalytics,
|
||||
} from "./settings";
|
||||
import { isFirefox } from "../Platform";
|
||||
|
||||
@ -77,7 +77,7 @@ export const SettingsModal: FC<Props> = ({
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [optInAnalytics, setOptInAnalytics] = useSetting(optInAnalyticsSetting);
|
||||
const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics();
|
||||
const [developerSettingsTab, setDeveloperSettingsTab] = useSetting(
|
||||
developerSettingsTabSetting,
|
||||
);
|
||||
|
@ -15,7 +15,6 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import { useEffect } from "react";
|
||||
import EventEmitter, { EventMap } from "typed-emitter";
|
||||
|
||||
import type {
|
||||
Listener,
|
||||
@ -60,20 +59,3 @@ export function useTypedEventEmitter<
|
||||
};
|
||||
}, [emitter, eventType, listener]);
|
||||
}
|
||||
|
||||
// Shortcut for registering a listener on an eventemitter3 EventEmitter (ie. what the LiveKit SDK uses)
|
||||
export function useEventEmitterThree<
|
||||
EventType extends keyof T,
|
||||
T extends EventMap,
|
||||
>(
|
||||
emitter: EventEmitter<T>,
|
||||
eventType: EventType,
|
||||
listener: T[EventType],
|
||||
): void {
|
||||
useEffect(() => {
|
||||
emitter.on(eventType, listener);
|
||||
return (): void => {
|
||||
emitter.off(eventType, listener);
|
||||
};
|
||||
}, [emitter, eventType, listener]);
|
||||
}
|
||||
|
@ -50,9 +50,6 @@ export const useLocalStorage = (
|
||||
];
|
||||
};
|
||||
|
||||
export const getLocalStorageItem = (key: string): LocalStorageItem =>
|
||||
localStorage.getItem(key);
|
||||
|
||||
export const setLocalStorageItem = (key: string, value: string): void => {
|
||||
localStorage.setItem(key, value);
|
||||
localStorageBus.emit(key, value);
|
||||
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
Copyright 2023 New Vector Ltd
|
||||
|
||||
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 { useRef } from "react";
|
||||
|
||||
/**
|
||||
* React hook that returns the value given on the previous render.
|
||||
*/
|
||||
export function usePrevious<T>(value: T): T | undefined {
|
||||
const ref = useRef<T>();
|
||||
const previous = ref.current;
|
||||
ref.current = value;
|
||||
return previous;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
Copyright 2023 New Vector Ltd
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets the index of the last element in the array to satsify the given
|
||||
* predicate.
|
||||
*/
|
||||
// TODO: remove this once TypeScript recognizes the existence of
|
||||
// Array.prototype.findLastIndex
|
||||
export function findLastIndex<T>(
|
||||
array: T[],
|
||||
predicate: (item: T, index: number) => boolean,
|
||||
): number | null {
|
||||
for (let i = array.length - 1; i >= 0; i--) {
|
||||
if (predicate(array[i], i)) return i;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of elements in an array that satsify the given predicate.
|
||||
*/
|
||||
export const count = <T>(
|
||||
array: T[],
|
||||
predicate: (item: T, index: number) => boolean,
|
||||
): number =>
|
||||
array.reduce(
|
||||
(acc, item, index) => (predicate(item, index) ? acc + 1 : acc),
|
||||
0,
|
||||
);
|
@ -246,38 +246,6 @@ export function sanitiseRoomNameInput(input: string): string {
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* XXX: What is this trying to do? It looks like it's getting the localpart from
|
||||
* a room alias, but why is it splitting on hyphens and then putting spaces in??
|
||||
* @param roomId
|
||||
* @returns
|
||||
*/
|
||||
export function roomNameFromRoomId(roomId: string): string {
|
||||
return roomId
|
||||
.match(/([^:]+):.*$/)![1]
|
||||
.substring(1)
|
||||
.split("-")
|
||||
.map((part) =>
|
||||
part.length > 0 ? part.charAt(0).toUpperCase() + part.slice(1) : part,
|
||||
)
|
||||
.join(" ")
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
export function isLocalRoomId(roomId: string, client: MatrixClient): boolean {
|
||||
if (!roomId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const parts = roomId.match(/[^:]+:(.*)$/)!;
|
||||
|
||||
if (parts.length < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parts[1] === client.getDomain();
|
||||
}
|
||||
|
||||
interface CreateRoomResult {
|
||||
roomId: string;
|
||||
alias?: string;
|
||||
|
@ -31,21 +31,6 @@ export enum ElementWidgetActions {
|
||||
HangupCall = "im.vector.hangup",
|
||||
TileLayout = "io.element.tile_layout",
|
||||
SpotlightLayout = "io.element.spotlight_layout",
|
||||
|
||||
// Element Call -> host requesting to start a screenshare
|
||||
// (ie. expects a ScreenshareStart once the user has picked a source)
|
||||
// Element Call -> host requesting to start a screenshare
|
||||
// (ie. expects a ScreenshareStart once the user has picked a source)
|
||||
// replies with { pending } where pending is true if the host has asked
|
||||
// the user to choose a window and false if not (ie. if the host isn't
|
||||
// running within Electron)
|
||||
ScreenshareRequest = "io.element.screenshare_request",
|
||||
// host -> Element Call telling EC to start screen sharing with
|
||||
// the given source
|
||||
ScreenshareStart = "io.element.screenshare_start",
|
||||
// host -> Element Call telling EC to stop screen sharing, or that
|
||||
// the user cancelled when selecting a source after a ScreenshareRequest
|
||||
ScreenshareStop = "io.element.screenshare_stop",
|
||||
// This can be sent as from or to widget
|
||||
// fromWidget: updates the client about the current device mute state
|
||||
// toWidget: the client requests a specific device mute configuration
|
||||
@ -68,10 +53,6 @@ export interface JoinCallData {
|
||||
videoInput: string | null;
|
||||
}
|
||||
|
||||
export interface ScreenshareStartData {
|
||||
desktopCapturerSourceId: string;
|
||||
}
|
||||
|
||||
export interface WidgetHelpers {
|
||||
api: WidgetApi;
|
||||
lazyActions: LazyEventEmitter;
|
||||
@ -101,8 +82,6 @@ export const widget = ((): WidgetHelpers | null => {
|
||||
ElementWidgetActions.HangupCall,
|
||||
ElementWidgetActions.TileLayout,
|
||||
ElementWidgetActions.SpotlightLayout,
|
||||
ElementWidgetActions.ScreenshareStart,
|
||||
ElementWidgetActions.ScreenshareStop,
|
||||
ElementWidgetActions.DeviceMute,
|
||||
].forEach((action) => {
|
||||
api.on(`action:${action}`, (ev: CustomEvent<IWidgetApiRequest>) => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { defineConfig, mergeConfig } from "vitest/config";
|
||||
import viteConfig from "./vite.config";
|
||||
import viteConfig from "./vite.config.js";
|
||||
|
||||
export default defineConfig((configEnv) =>
|
||||
mergeConfig(
|
||||
|
Loading…
Reference in New Issue
Block a user