mirror of
https://github.com/revoltchat/revite.git
synced 2024-11-26 09:00:57 -05:00
Add deafen button
This commit is contained in:
parent
db43c02e01
commit
ccda5e8609
7 changed files with 124 additions and 16 deletions
|
@ -12,12 +12,12 @@ import { AppContext, useClient } from "../../../context/revoltjs/RevoltClient";
|
||||||
|
|
||||||
import IconBase, { IconBaseProps } from "../IconBase";
|
import IconBase, { IconBaseProps } from "../IconBase";
|
||||||
import fallback from "../assets/user.png";
|
import fallback from "../assets/user.png";
|
||||||
|
import {VolumeMute} from "@styled-icons/boxicons-solid";
|
||||||
|
|
||||||
type VoiceStatus = "muted";
|
|
||||||
interface Props extends IconBaseProps<User> {
|
interface Props extends IconBaseProps<User> {
|
||||||
mask?: string;
|
mask?: string;
|
||||||
status?: boolean;
|
status?: boolean;
|
||||||
voice?: VoiceStatus;
|
voice?: string;
|
||||||
showServerIdentity?: boolean;
|
showServerIdentity?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ export function useStatusColour(user?: User) {
|
||||||
: theme["status-invisible"];
|
: theme["status-invisible"];
|
||||||
}
|
}
|
||||||
|
|
||||||
const VoiceIndicator = styled.div<{ status: VoiceStatus }>`
|
const VoiceIndicator = styled.div<{ status: string }>`
|
||||||
width: 10px;
|
width: 10px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
border-radius: var(--border-radius-half);
|
border-radius: var(--border-radius-half);
|
||||||
|
@ -47,7 +47,7 @@ const VoiceIndicator = styled.div<{ status: VoiceStatus }>`
|
||||||
}
|
}
|
||||||
|
|
||||||
${(props) =>
|
${(props) =>
|
||||||
props.status === "muted" &&
|
(props.status === "muted" || props.status === "deaf") &&
|
||||||
css`
|
css`
|
||||||
background: var(--error);
|
background: var(--error);
|
||||||
`}
|
`}
|
||||||
|
@ -125,7 +125,9 @@ export default observer(
|
||||||
{props.voice && (
|
{props.voice && (
|
||||||
<foreignObject x="22" y="22" width="10" height="10">
|
<foreignObject x="22" y="22" width="10" height="10">
|
||||||
<VoiceIndicator status={props.voice}>
|
<VoiceIndicator status={props.voice}>
|
||||||
{props.voice === "muted" && (
|
{props.voice === "deaf" && (
|
||||||
|
<VolumeMute size={6} />
|
||||||
|
) ||props.voice === "muted" && (
|
||||||
<MicrophoneOff size={6} />
|
<MicrophoneOff size={6} />
|
||||||
)}
|
)}
|
||||||
</VoiceIndicator>
|
</VoiceIndicator>
|
||||||
|
|
|
@ -40,6 +40,8 @@ export default class VoiceClient extends EventEmitter<VoiceEvents> {
|
||||||
sendTransport?: Transport;
|
sendTransport?: Transport;
|
||||||
recvTransport?: Transport;
|
recvTransport?: Transport;
|
||||||
|
|
||||||
|
isDeaf?: boolean;
|
||||||
|
|
||||||
userId?: string;
|
userId?: string;
|
||||||
roomId?: string;
|
roomId?: string;
|
||||||
participants: Map<string, VoiceUser>;
|
participants: Map<string, VoiceUser>;
|
||||||
|
@ -54,6 +56,8 @@ export default class VoiceClient extends EventEmitter<VoiceEvents> {
|
||||||
this.participants = new Map();
|
this.participants = new Map();
|
||||||
this.consumers = new Map();
|
this.consumers = new Map();
|
||||||
|
|
||||||
|
this.isDeaf = false;
|
||||||
|
|
||||||
this.signaling.on(
|
this.signaling.on(
|
||||||
"data",
|
"data",
|
||||||
(json) => {
|
(json) => {
|
||||||
|
|
|
@ -143,6 +143,33 @@ class VoiceStateReference {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isDeaf() {
|
||||||
|
if(!this.client)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return this.client.isDeaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
async startDeafen() {
|
||||||
|
if(!this.client)
|
||||||
|
return console.log("No client object"); // ! TODO: let the user know
|
||||||
|
|
||||||
|
this.client.isDeaf = true;
|
||||||
|
|
||||||
|
this.client?.consumers.forEach(consumer => {
|
||||||
|
consumer.audio?.pause();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async stopDeafen() {
|
||||||
|
if(!this.client)
|
||||||
|
return console.log("No client object"); // ! TODO: let the user know
|
||||||
|
|
||||||
|
this.client.isDeaf = false;
|
||||||
|
this.client?.consumers.forEach(consumer => {
|
||||||
|
consumer.audio?.resume();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async startProducing(type: ProduceType) {
|
async startProducing(type: ProduceType) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "audio": {
|
case "audio": {
|
||||||
|
|
|
@ -11,6 +11,18 @@ import { useClient } from "../../../context/revoltjs/RevoltClient";
|
||||||
|
|
||||||
import UserIcon from "../../../components/common/user/UserIcon";
|
import UserIcon from "../../../components/common/user/UserIcon";
|
||||||
import Button from "../../../components/ui/Button";
|
import Button from "../../../components/ui/Button";
|
||||||
|
import {
|
||||||
|
Megaphone,
|
||||||
|
Microphone,
|
||||||
|
MicrophoneOff,
|
||||||
|
PhoneOff,
|
||||||
|
Speaker,
|
||||||
|
VolumeFull,
|
||||||
|
VolumeMute
|
||||||
|
} from "@styled-icons/boxicons-solid";
|
||||||
|
import Tooltip from "../../../components/common/Tooltip";
|
||||||
|
import {Hashnode, Speakerdeck, Teamspeak} from "@styled-icons/simple-icons";
|
||||||
|
import VoiceClient from "../../../lib/vortex/VoiceClient";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -89,7 +101,8 @@ export default observer(({ id }: Props) => {
|
||||||
target={user}
|
target={user}
|
||||||
status={false}
|
status={false}
|
||||||
voice={
|
voice={
|
||||||
voiceState.participants!.get(id)
|
client.user?._id === id && voiceState.isDeaf()?"deaf"
|
||||||
|
: voiceState.participants!.get(id)
|
||||||
?.audio
|
?.audio
|
||||||
? undefined
|
? undefined
|
||||||
: "muted"
|
: "muted"
|
||||||
|
@ -115,18 +128,38 @@ export default observer(({ id }: Props) => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
|
<Tooltip content={"Leave call"} placement={"bottom"}>
|
||||||
<Button error onClick={voiceState.disconnect}>
|
<Button error onClick={voiceState.disconnect}>
|
||||||
<Text id="app.main.channel.voice.leave" />
|
<PhoneOff width={25} />
|
||||||
</Button>
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
{voiceState.isProducing("audio") ? (
|
{voiceState.isProducing("audio") ? (
|
||||||
|
<Tooltip content={"Mute microphone"} placement={"bottom"}>
|
||||||
<Button onClick={() => voiceState.stopProducing("audio")}>
|
<Button onClick={() => voiceState.stopProducing("audio")}>
|
||||||
<Text id="app.main.channel.voice.mute" />
|
<Microphone width={25} />
|
||||||
</Button>
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
) : (
|
) : (
|
||||||
|
<Tooltip content={"Unmute microphone"} placement={"bottom"}>
|
||||||
<Button onClick={() => voiceState.startProducing("audio")}>
|
<Button onClick={() => voiceState.startProducing("audio")}>
|
||||||
<Text id="app.main.channel.voice.unmute" />
|
<MicrophoneOff width={25} />
|
||||||
</Button>
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
|
{voiceState.isDeaf() ? (
|
||||||
|
<Tooltip content={"Deafen"} placement={"bottom"}>
|
||||||
|
<Button onClick={() => voiceState.stopDeafen()}>
|
||||||
|
<VolumeMute width={25} />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
): (
|
||||||
|
<Tooltip content={"Deafen"} placement={"bottom"}>
|
||||||
|
<Button onClick={() => voiceState.startDeafen()}>
|
||||||
|
<VolumeFull width={25} />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
)
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</VoiceBase>
|
</VoiceBase>
|
||||||
);
|
);
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
Flask,
|
Flask,
|
||||||
User,
|
User,
|
||||||
Megaphone,
|
Megaphone,
|
||||||
|
Shield,
|
||||||
} from "@styled-icons/boxicons-solid";
|
} from "@styled-icons/boxicons-solid";
|
||||||
import { Route, Switch, useHistory } from "react-router-dom";
|
import { Route, Switch, useHistory } from "react-router-dom";
|
||||||
import { LIBRARY_VERSION } from "revolt.js";
|
import { LIBRARY_VERSION } from "revolt.js";
|
||||||
|
@ -76,6 +77,11 @@ export default function Settings() {
|
||||||
icon: <IdCard size={20} />,
|
icon: <IdCard size={20} />,
|
||||||
title: <Text id="app.settings.pages.profile.title" />,
|
title: <Text id="app.settings.pages.profile.title" />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "privacy",
|
||||||
|
icon: <Shield size={20} />,
|
||||||
|
title: <Text id="app.settings.pages.profile.title" />,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "sessions",
|
id: "sessions",
|
||||||
icon: <CheckShield size={20} />,
|
icon: <CheckShield size={20} />,
|
||||||
|
|
36
src/pages/settings/panes/Privacy.tsx
Normal file
36
src/pages/settings/panes/Privacy.tsx
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import styles from "./Panes.module.scss";
|
||||||
|
import { Text } from "preact-i18n";
|
||||||
|
|
||||||
|
import { dispatch } from "../../../redux";
|
||||||
|
import { connectState } from "../../../redux/connector";
|
||||||
|
import { SyncKeys, SyncOptions } from "../../../redux/reducers/sync";
|
||||||
|
|
||||||
|
import Checkbox from "../../../components/ui/Checkbox";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
options?: SyncOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Component(props: Props) {
|
||||||
|
return (
|
||||||
|
<div className={styles.notifications}>
|
||||||
|
<Checkbox
|
||||||
|
key={"everyone_dm"}
|
||||||
|
checked={false}
|
||||||
|
description={
|
||||||
|
<Text
|
||||||
|
id={`app.settings.pages.privacy.allow_dms.d`}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
onChange={(enabled) => {console.log(enabled)}}>
|
||||||
|
<Text id="app.settings.pages.privacy.allow_dms.t" />
|
||||||
|
</Checkbox>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Sync = connectState(Component, (state) => {
|
||||||
|
return {
|
||||||
|
options: state.sync,
|
||||||
|
};
|
||||||
|
});
|
|
@ -152,7 +152,7 @@ export const Overview = observer(({ server }: Props) => {
|
||||||
<Text id="general.disabled" />
|
<Text id="general.disabled" />
|
||||||
</option>
|
</option>
|
||||||
{server.channels
|
{server.channels
|
||||||
.filter((x) => typeof x !== "undefined")
|
.filter((x) => (typeof x !== "undefined" && x.channel_type === "TextChannel"))
|
||||||
.map((channel) => (
|
.map((channel) => (
|
||||||
<option key={channel!._id} value={channel!._id}>
|
<option key={channel!._id} value={channel!._id}>
|
||||||
{getChannelName(channel!, true)}
|
{getChannelName(channel!, true)}
|
||||||
|
|
Loading…
Reference in a new issue