Fix(voice): Voice UI would not react to actions.

Feat(voice): Allow accessing user profile from voice UI.

Fixes #89. Fixes #91.
This commit is contained in:
Paul 2021-10-20 22:39:26 +01:00
parent d6169f3c3a
commit 195a9bda35
4 changed files with 87 additions and 56 deletions

View file

@ -1,3 +1,7 @@
{ {
"recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"] "recommendations": [
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"kol.commit-lint"
]
} }

View file

@ -154,20 +154,25 @@ class VoiceStateReference {
async startDeafen() { async startDeafen() {
if (!this.client) return console.log("No client object"); // ! TODO: let the user know if (!this.client) return console.log("No client object"); // ! TODO: let the user know
if (this.client.isDeaf) return;
this.client.isDeaf = true; this.client.isDeaf = true;
this.client?.consumers.forEach((consumer) => { this.client?.consumers.forEach((consumer) => {
consumer.audio?.pause(); consumer.audio?.pause();
}); });
this.syncState();
} }
async stopDeafen() { async stopDeafen() {
if (!this.client) return console.log("No client object"); // ! TODO: let the user know if (!this.client) return console.log("No client object"); // ! TODO: let the user know
if (!this.client.isDeaf) return;
this.client.isDeaf = false; this.client.isDeaf = false;
this.client?.consumers.forEach((consumer) => { this.client?.consumers.forEach((consumer) => {
consumer.audio?.resume(); consumer.audio?.resume();
}); });
this.syncState();
} }
async startProducing(type: ProduceType) { async startProducing(type: ProduceType) {
@ -192,10 +197,14 @@ class VoiceStateReference {
); );
} }
} }
this.syncState();
} }
stopProducing(type: ProduceType) { async stopProducing(type: ProduceType) {
this.client?.stopProduce(type); await this.client?.stopProduce(type);
this.syncState();
} }
} }

View file

@ -7,6 +7,7 @@ import {
PhoneOff, PhoneOff,
Group, Group,
} from "@styled-icons/boxicons-solid"; } from "@styled-icons/boxicons-solid";
import { observer } from "mobx-react-lite";
import { useHistory } from "react-router-dom"; import { useHistory } from "react-router-dom";
import { internalEmit } from "../../../lib/eventEmitter"; import { internalEmit } from "../../../lib/eventEmitter";
@ -90,7 +91,8 @@ export default function HeaderActions({
); );
} }
function VoiceActions({ channel }: Pick<ChannelHeaderProps, "channel">) { const VoiceActions = observer(
({ channel }: Pick<ChannelHeaderProps, "channel">) => {
if ( if (
channel.channel_type === "SavedMessages" || channel.channel_type === "SavedMessages" ||
channel.channel_type === "TextChannel" channel.channel_type === "TextChannel"
@ -123,4 +125,5 @@ function VoiceActions({ channel }: Pick<ChannelHeaderProps, "channel">) {
<PhoneCall size={24} /** ! FIXME: TEMP */ color="red" /> <PhoneCall size={24} /** ! FIXME: TEMP */ color="red" />
</IconButton> </IconButton>
); );
} },
);

View file

@ -1,16 +1,4 @@
import { BarChart } from "@styled-icons/boxicons-regular"; import { BarChart } from "@styled-icons/boxicons-regular";
import { observer } from "mobx-react-lite";
import styled from "styled-components";
import { Text } from "preact-i18n";
import { useMemo } from "preact/hooks";
import { voiceState, VoiceStatus } from "../../../lib/vortex/VoiceState";
import { useClient } from "../../../context/revoltjs/RevoltClient";
import UserIcon from "../../../components/common/user/UserIcon";
import Button from "../../../components/ui/Button";
import { import {
Megaphone, Megaphone,
Microphone, Microphone,
@ -18,11 +6,24 @@ import {
PhoneOff, PhoneOff,
Speaker, Speaker,
VolumeFull, VolumeFull,
VolumeMute VolumeMute,
} from "@styled-icons/boxicons-solid"; } from "@styled-icons/boxicons-solid";
import Tooltip from "../../../components/common/Tooltip"; import { Hashnode, Speakerdeck, Teamspeak } from "@styled-icons/simple-icons";
import {Hashnode, Speakerdeck, Teamspeak} from "@styled-icons/simple-icons"; import { observer } from "mobx-react-lite";
import styled from "styled-components";
import { Text } from "preact-i18n";
import { useMemo } from "preact/hooks";
import VoiceClient from "../../../lib/vortex/VoiceClient"; import VoiceClient from "../../../lib/vortex/VoiceClient";
import { voiceState, VoiceStatus } from "../../../lib/vortex/VoiceState";
import { useIntermediate } from "../../../context/intermediate/Intermediate";
import { useClient } from "../../../context/revoltjs/RevoltClient";
import Tooltip from "../../../components/common/Tooltip";
import UserIcon from "../../../components/common/user/UserIcon";
import Button from "../../../components/ui/Button";
interface Props { interface Props {
id: string; id: string;
@ -59,11 +60,14 @@ const VoiceBase = styled.div`
.participants { .participants {
margin: 20px 0; margin: 20px 0;
justify-content: center; justify-content: center;
pointer-events: none;
user-select: none; user-select: none;
display: flex; display: flex;
gap: 16px; gap: 16px;
div:hover img {
opacity: 0.8;
}
.disconnected { .disconnected {
opacity: 0.5; opacity: 0.5;
} }
@ -79,6 +83,8 @@ const VoiceBase = styled.div`
export default observer(({ id }: Props) => { export default observer(({ id }: Props) => {
if (voiceState.roomId !== id) return null; if (voiceState.roomId !== id) return null;
const { openScreen } = useIntermediate();
const client = useClient(); const client = useClient();
const self = client.users.get(client.user!._id); const self = client.users.get(client.user!._id);
@ -101,12 +107,20 @@ export default observer(({ id }: Props) => {
target={user} target={user}
status={false} status={false}
voice={ voice={
client.user?._id === id && voiceState.isDeaf()?"deaf" client.user?._id === id &&
voiceState.isDeaf()
? "deaf"
: voiceState.participants!.get(id) : voiceState.participants!.get(id)
?.audio ?.audio
? undefined ? undefined
: "muted" : "muted"
} }
onClick={() =>
openScreen({
id: "profile",
user_id: id,
})
}
/> />
</div> </div>
); );
@ -135,13 +149,15 @@ export default observer(({ id }: Props) => {
</Tooltip> </Tooltip>
{voiceState.isProducing("audio") ? ( {voiceState.isProducing("audio") ? (
<Tooltip content={"Mute microphone"} placement={"bottom"}> <Tooltip content={"Mute microphone"} placement={"bottom"}>
<Button onClick={() => voiceState.stopProducing("audio")}> <Button
onClick={() => voiceState.stopProducing("audio")}>
<Microphone width={25} /> <Microphone width={25} />
</Button> </Button>
</Tooltip> </Tooltip>
) : ( ) : (
<Tooltip content={"Unmute microphone"} placement={"bottom"}> <Tooltip content={"Unmute microphone"} placement={"bottom"}>
<Button onClick={() => voiceState.startProducing("audio")}> <Button
onClick={() => voiceState.startProducing("audio")}>
<MicrophoneOff width={25} /> <MicrophoneOff width={25} />
</Button> </Button>
</Tooltip> </Tooltip>
@ -152,14 +168,13 @@ export default observer(({ id }: Props) => {
<VolumeMute width={25} /> <VolumeMute width={25} />
</Button> </Button>
</Tooltip> </Tooltip>
): ( ) : (
<Tooltip content={"Deafen"} placement={"bottom"}> <Tooltip content={"Deafen"} placement={"bottom"}>
<Button onClick={() => voiceState.startDeafen()}> <Button onClick={() => voiceState.startDeafen()}>
<VolumeFull width={25} /> <VolumeFull width={25} />
</Button> </Button>
</Tooltip> </Tooltip>
) )}
}
</div> </div>
</VoiceBase> </VoiceBase>
); );