Merge pull request #316 from vector-im/dbkr/typescript_round_1
Initial round of typescripting
This commit is contained in:
commit
66aede01dc
12 changed files with 383 additions and 38 deletions
17
src/@types/global.d.ts
vendored
Normal file
17
src/@types/global.d.ts
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
Copyright 2022 Matrix.org Foundation C.I.C.
|
||||
|
||||
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 "matrix-js-sdk/src/@types/global";
|
||||
2
src/@types/modules.d.ts
vendored
Normal file
2
src/@types/modules.d.ts
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/// <reference types="vite/client" />
|
||||
/// <reference types="vite-plugin-svgr/client" />
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useMemo } from "react";
|
||||
import classNames from "classnames";
|
||||
|
||||
import styles from "./Avatar.module.css";
|
||||
|
||||
const backgroundColors = [
|
||||
|
|
@ -13,7 +14,7 @@ const backgroundColors = [
|
|||
"#74D12C",
|
||||
];
|
||||
|
||||
function hashStringToArrIndex(str, arrLength) {
|
||||
function hashStringToArrIndex(str: string, arrLength: number) {
|
||||
let sum = 0;
|
||||
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
|
|
@ -23,7 +24,16 @@ function hashStringToArrIndex(str, arrLength) {
|
|||
return sum % arrLength;
|
||||
}
|
||||
|
||||
export function Avatar({
|
||||
interface Props extends React.HTMLAttributes<HTMLDivElement> {
|
||||
bgKey?: string;
|
||||
src: string;
|
||||
fallback: string;
|
||||
size?: number;
|
||||
className: string;
|
||||
style: React.CSSProperties;
|
||||
}
|
||||
|
||||
export const Avatar: React.FC<Props> = ({
|
||||
bgKey,
|
||||
src,
|
||||
fallback,
|
||||
|
|
@ -31,7 +41,7 @@ export function Avatar({
|
|||
className,
|
||||
style,
|
||||
...rest
|
||||
}) {
|
||||
}) => {
|
||||
const backgroundColor = useMemo(() => {
|
||||
const index = hashStringToArrIndex(
|
||||
bgKey || fallback || src || "",
|
||||
|
|
@ -40,6 +50,7 @@ export function Avatar({
|
|||
return backgroundColors[index];
|
||||
}, [bgKey, src, fallback]);
|
||||
|
||||
/* eslint-disable jsx-a11y/alt-text */
|
||||
return (
|
||||
<div
|
||||
className={classNames(styles.avatar, styles[size || "md"], className)}
|
||||
|
|
@ -55,4 +66,4 @@ export function Avatar({
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
@ -19,6 +19,7 @@ import {
|
|||
adjectives,
|
||||
colors,
|
||||
animals,
|
||||
Config,
|
||||
} from "unique-names-generator";
|
||||
|
||||
const elements = [
|
||||
|
|
@ -142,7 +143,7 @@ const elements = [
|
|||
"oganesson",
|
||||
];
|
||||
|
||||
export function generateRandomName(config) {
|
||||
export function generateRandomName(config: Config): string {
|
||||
return uniqueNamesGenerator({
|
||||
dictionaries: [colors, adjectives, animals, elements],
|
||||
style: "lowerCase",
|
||||
|
|
@ -16,11 +16,23 @@ limitations under the License.
|
|||
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import classNames from "classnames";
|
||||
|
||||
import styles from "./PTTButton.module.css";
|
||||
import { ReactComponent as MicIcon } from "../icons/Mic.svg";
|
||||
import { Avatar } from "../Avatar";
|
||||
|
||||
export function PTTButton({
|
||||
interface Props {
|
||||
showTalkOverError: boolean;
|
||||
activeSpeakerUserId: string;
|
||||
activeSpeakerDisplayName: string;
|
||||
activeSpeakerAvatarUrl: string;
|
||||
activeSpeakerIsLocalUser: boolean;
|
||||
size: number;
|
||||
startTalking: () => void;
|
||||
stopTalking: () => void;
|
||||
}
|
||||
|
||||
export const PTTButton: React.FC<Props> = ({
|
||||
showTalkOverError,
|
||||
activeSpeakerUserId,
|
||||
activeSpeakerDisplayName,
|
||||
|
|
@ -29,17 +41,17 @@ export function PTTButton({
|
|||
size,
|
||||
startTalking,
|
||||
stopTalking,
|
||||
}) {
|
||||
}) => {
|
||||
const [isHeld, setHeld] = useState(false);
|
||||
const onDocumentMouseUp = useCallback(() => {
|
||||
if (isHeld) stopTalking();
|
||||
setHeld(false);
|
||||
}, [isHeld, setHeld]);
|
||||
}, [isHeld, setHeld, stopTalking]);
|
||||
|
||||
const onButtonMouseDown = useCallback(() => {
|
||||
setHeld(true);
|
||||
startTalking();
|
||||
}, [setHeld]);
|
||||
}, [setHeld, startTalking]);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("mouseup", onDocumentMouseUp);
|
||||
|
|
@ -48,7 +60,6 @@ export function PTTButton({
|
|||
window.removeEventListener("mouseup", onDocumentMouseUp);
|
||||
};
|
||||
}, [onDocumentMouseUp]);
|
||||
|
||||
return (
|
||||
<button
|
||||
className={classNames(styles.pttButton, {
|
||||
|
|
@ -79,4 +90,4 @@ export function PTTButton({
|
|||
)}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
@ -15,6 +15,10 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import useMeasure from "react-use-measure";
|
||||
import { ResizeObserver } from "@juggle/resize-observer";
|
||||
import { OtherUserSpeakingError } from "matrix-js-sdk/src/webrtc/groupCall";
|
||||
|
||||
import { useModalTriggerState } from "../Modal";
|
||||
import { SettingsModal } from "../settings/SettingsModal";
|
||||
import { InviteModal } from "./InviteModal";
|
||||
|
|
@ -25,14 +29,11 @@ import { Facepile } from "../Facepile";
|
|||
import { PTTButton } from "./PTTButton";
|
||||
import { PTTFeed } from "./PTTFeed";
|
||||
import { useMediaHandler } from "../settings/useMediaHandler";
|
||||
import useMeasure from "react-use-measure";
|
||||
import { ResizeObserver } from "@juggle/resize-observer";
|
||||
import { usePTT } from "./usePTT";
|
||||
import { Timer } from "./Timer";
|
||||
import { Toggle } from "../input/Toggle";
|
||||
import { getAvatarUrl } from "../matrix-utils";
|
||||
import { ReactComponent as AudioIcon } from "../icons/Audio.svg";
|
||||
import { OtherUserSpeakingError } from "matrix-js-sdk/src/webrtc/groupCall";
|
||||
|
||||
export function PTTCallView({
|
||||
client,
|
||||
|
|
@ -15,8 +15,26 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { GroupCall } from "matrix-js-sdk/src/webrtc/groupCall";
|
||||
import { CallFeed, CallFeedEvent } from "matrix-js-sdk/src/webrtc/callFeed";
|
||||
|
||||
export function usePTT(client, groupCall, userMediaFeeds) {
|
||||
export interface PTTState {
|
||||
pttButtonHeld: boolean;
|
||||
isAdmin: boolean;
|
||||
talkOverEnabled: boolean;
|
||||
setTalkOverEnabled: (boolean) => void;
|
||||
activeSpeakerUserId: string;
|
||||
startTalking: () => void;
|
||||
stopTalking: () => void;
|
||||
unmuteError: Error;
|
||||
}
|
||||
|
||||
export const usePTT = (
|
||||
client: MatrixClient,
|
||||
groupCall: GroupCall,
|
||||
userMediaFeeds: CallFeed[]
|
||||
): PTTState => {
|
||||
const [
|
||||
{
|
||||
pttButtonHeld,
|
||||
|
|
@ -41,7 +59,7 @@ export function usePTT(client, groupCall, userMediaFeeds) {
|
|||
});
|
||||
|
||||
useEffect(() => {
|
||||
function onMuteStateChanged(...args) {
|
||||
function onMuteStateChanged(...args): void {
|
||||
const activeSpeakerFeed = userMediaFeeds.find((f) => !f.isAudioMuted());
|
||||
|
||||
setState((prevState) => ({
|
||||
|
|
@ -53,7 +71,7 @@ export function usePTT(client, groupCall, userMediaFeeds) {
|
|||
}
|
||||
|
||||
for (const callFeed of userMediaFeeds) {
|
||||
callFeed.addListener("mute_state_changed", onMuteStateChanged);
|
||||
callFeed.addListener(CallFeedEvent.MuteStateChanged, onMuteStateChanged);
|
||||
}
|
||||
|
||||
const activeSpeakerFeed = userMediaFeeds.find((f) => !f.isAudioMuted());
|
||||
|
|
@ -65,7 +83,10 @@ export function usePTT(client, groupCall, userMediaFeeds) {
|
|||
|
||||
return () => {
|
||||
for (const callFeed of userMediaFeeds) {
|
||||
callFeed.removeListener("mute_state_changed", onMuteStateChanged);
|
||||
callFeed.removeListener(
|
||||
CallFeedEvent.MuteStateChanged,
|
||||
onMuteStateChanged
|
||||
);
|
||||
}
|
||||
};
|
||||
}, [userMediaFeeds]);
|
||||
|
|
@ -98,7 +119,7 @@ export function usePTT(client, groupCall, userMediaFeeds) {
|
|||
}, [groupCall]);
|
||||
|
||||
useEffect(() => {
|
||||
function onKeyDown(event) {
|
||||
function onKeyDown(event: KeyboardEvent): void {
|
||||
if (event.code === "Space") {
|
||||
event.preventDefault();
|
||||
|
||||
|
|
@ -108,7 +129,7 @@ export function usePTT(client, groupCall, userMediaFeeds) {
|
|||
}
|
||||
}
|
||||
|
||||
function onKeyUp(event) {
|
||||
function onKeyUp(event: KeyboardEvent): void {
|
||||
if (event.code === "Space") {
|
||||
event.preventDefault();
|
||||
|
||||
|
|
@ -116,7 +137,7 @@ export function usePTT(client, groupCall, userMediaFeeds) {
|
|||
}
|
||||
}
|
||||
|
||||
function onBlur() {
|
||||
function onBlur(): void {
|
||||
// TODO: We will need to disable this for a global PTT hotkey to work
|
||||
if (!groupCall.isMicrophoneMuted()) {
|
||||
groupCall.setMicrophoneMuted(true);
|
||||
|
|
@ -161,4 +182,4 @@ export function usePTT(client, groupCall, userMediaFeeds) {
|
|||
stopTalking,
|
||||
unmuteError,
|
||||
};
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue