voice progress

This commit is contained in:
MathMan05 2025-05-14 11:24:14 -05:00
parent 4578ff866f
commit 476fc542a5
8 changed files with 131 additions and 42 deletions

View file

@ -1124,7 +1124,7 @@ class Channel extends SnowFlake {
loading.classList.add("loading");
this.rendertyping();
this.localuser.getSidePannel();
if (this.voice && localStorage.getItem("Voice enabled")) {
if (this.voice && this.localuser.voiceAllowed) {
this.localuser.joinVoice(this);
}
(document.getElementById("typebox") as HTMLDivElement).contentEditable = "" + this.canMessage;

View file

@ -0,0 +1 @@
<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg"><path style="fill:#1a1a1a;stroke:#000;stroke-width:9.5499;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none" d="M21.77 6.28h4.45v20.79h-4.45z"/><path style="fill:none;fill-rule:evenodd;stroke:#000;stroke-width:6;stroke-linecap:round;stroke-dasharray:none" d="M33.6 36.26c-5.97 7.08-16.86 7.8-23.89 1.87-.69-.6-1.34-1.23-1.93-1.92" transform="rotate(.28 1357.13 750.4)"/><path style="fill:#1a1a1a;stroke:#000;stroke-width:3.40741;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none" d="M22.39 36.59h3.08v6.47h-3.08z"/><path style="fill:#1a1a1a;stroke:#000;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none" d="M17.91 44.11h12.11v.36H17.91z"/></svg>

After

Width:  |  Height:  |  Size: 768 B

View file

@ -0,0 +1 @@
<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg"><path d="m26.2 26.5-.7.6h.7z" style="baseline-shift:baseline;display:inline;overflow:visible;vector-effect:none;stroke-linecap:round;stroke-linejoin:round;enable-background:accumulate;stop-color:#000;stop-opacity:1"/><path d="m31 22.5-4.8 4v.6h-.7l-5.4 4.4a4.8 4.8 0 0 0 1.7.3h4.4a4.8 4.8 0 0 0 4.8-4.7ZM21.8 14.6l4.4-3.7V6.3h-4.4z" style="baseline-shift:baseline;display:inline;overflow:visible;vector-effect:none;stroke-linecap:round;stroke-linejoin:round;enable-background:accumulate;stop-color:#000;stop-opacity:1"/><path d="m17 18.5 4.8-4V6.4h4.4v4.6L31 7v-.6a4.8 4.8 0 0 0-4.8-4.8h-4.4A4.8 4.8 0 0 0 17 6.3Z" style="baseline-shift:baseline;display:inline;overflow:visible;vector-effect:none;stroke-linecap:round;stroke-linejoin:round;enable-background:accumulate;stop-color:#000;stop-opacity:1"/><path d="m19.6 32-5.1 4.2a20 20 0 0 0 24.8-4.4 3 3 0 0 0-.3-4.2 3 3 0 0 0-4.2.4 14 14 0 0 1-15.2 4z" style="baseline-shift:baseline;display:inline;overflow:visible;opacity:1;vector-effect:none;fill-rule:evenodd;stroke-linecap:round;enable-background:accumulate;stop-color:#000;stop-opacity:1"/><g style="opacity:1"><path style="baseline-shift:baseline;display:inline;overflow:visible;vector-effect:none;fill:#1a1a1a;stroke-linecap:round;stroke-linejoin:round;enable-background:accumulate;stop-color:#000;stop-opacity:1" d="M22.4 36.6h3V43h-3z"/><path style="baseline-shift:baseline;display:inline;overflow:visible;vector-effect:none;stroke-linecap:round;stroke-linejoin:round;enable-background:accumulate;stop-color:#000;stop-opacity:1" d="M22.4 34.9a1.7 1.7 0 0 0-1.7 1.7V43a1.7 1.7 0 0 0 1.7 1.7h3a1.7 1.7 0 0 0 1.8-1.7v-6.5a1.7 1.7 0 0 0-1.7-1.7z"/></g><g style="opacity:1"><path style="baseline-shift:baseline;display:inline;overflow:visible;vector-effect:none;fill:#1a1a1a;stroke-linecap:round;stroke-linejoin:round;enable-background:accumulate;stop-color:#000;stop-opacity:1" d="M18 44.1h12v.4H18Z"/><path style="baseline-shift:baseline;display:inline;overflow:visible;vector-effect:none;stroke-linecap:round;stroke-linejoin:round;enable-background:accumulate;stop-color:#000;stop-opacity:1" d="M18 41.1a3 3 0 0 0-3 3v.4a3 3 0 0 0 3 3h12a3 3 0 0 0 3-3V44a3 3 0 0 0-3-3z"/></g><path style="fill:#1a1a1a;stroke:#000;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none" d="m3.7 37.3 38.8-32"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -58,8 +58,9 @@
</div>
</div>
<div id="user-actions">
<span id="settings" class="svgicon svg-settings"></span>
<div id="user-actions" class="flexltr">
<div><span id="mic" class="svgicon svg-mic"></span></div>
<div><span id="settings" class="svgicon svg-settings"></span></div>
</div>
</div>
</div>

View file

@ -1,4 +1,4 @@
type readyjson = {
interface readyjson {
op: 0;
t: "READY";
s: number;
@ -120,7 +120,39 @@ type readyjson = {
flags: number;
};
};
};
}
interface readySuplemental {
op: 0;
t: "READY_SUPPLEMENTAL";
s: number;
d: {
merged_presences: {
guilds: [];
friends: [];
};
merged_members: [];
lazy_private_channels: [];
guilds: {
voice_states: {
user_id: string;
suppress: boolean;
session_id: string;
self_video: boolean;
self_mute: boolean;
self_deaf: boolean;
self_stream: boolean;
request_to_speak_timestamp: null;
mute: boolean;
deaf: boolean;
channel_id: string; //weird reasons, don't question it too much
guild_id: string;
}[];
id: string;
embedded_activities: [];
}[];
disclose: [];
};
}
interface banObj {
reason: string | null;
user: {
@ -508,6 +540,7 @@ type roleCreate = {
s: 6;
};
type wsjson =
| readySuplemental
| roleCreate
| {
op: 0;
@ -704,22 +737,23 @@ type memberChunk = {
chunk_count: number;
not_found: string[];
};
export type voiceStatus = {
guild_id: string;
channel_id: string;
user_id: string;
member?: memberjson;
session_id: string;
deaf: boolean;
mute: boolean;
self_deaf: boolean;
self_mute: boolean;
self_video: boolean;
suppress: boolean;
};
type voiceupdate = {
op: 0;
t: "VOICE_STATE_UPDATE";
d: {
guild_id: string;
channel_id: string;
user_id: string;
member: memberjson;
session_id: string;
deaf: boolean;
mute: boolean;
self_deaf: boolean;
self_mute: boolean;
self_video: boolean;
suppress: boolean;
};
d: voiceStatus;
s: number;
};
type voiceserverupdate = {

View file

@ -243,6 +243,21 @@ class Localuser {
if (this.perminfo.user.disableColors === undefined) this.perminfo.user.disableColors = true;
this.updateTranslations();
}
readysup = false;
get voiceAllowed() {
return this.readysup || localStorage.getItem("Voice enabled");
}
mute = true;
deaf = false;
updateMic() {
const mic = document.getElementById("mic") as HTMLElement;
mic.classList.remove("svg-mic", "svg-micmute");
if (this.mute) {
mic.classList.add("svg-micmute");
} else {
mic.classList.add("svg-mic");
}
}
async gottenReady(ready: readyjson): Promise<void> {
await I18n.done;
this.initialized = true;
@ -273,6 +288,12 @@ class Localuser {
members[thing[0].guild_id] = thing[0];
}
}
this.updateMic();
const mic = document.getElementById("mic") as HTMLElement;
mic.onclick = () => {
this.mute = !this.mute;
this.updateMic();
};
for (const thing of ready.d.guilds) {
const temp = new Guild(thing, this, members[thing.id]);
this.guilds.push(temp);
@ -722,9 +743,22 @@ class Localuser {
this.memberListUpdate(temp);
break;
}
case "READY_SUPPLEMENTAL":
{
temp.d.guilds.forEach((_) =>
_.voice_states.forEach((status) => {
if (this.voiceFactory && status.channel_id) {
this.voiceFactory.voiceStateUpdate(status);
console.log(status);
}
}),
);
this.readysup = temp.d.guilds.length !== 0;
}
break;
case "VOICE_STATE_UPDATE":
if (this.voiceFactory) {
this.voiceFactory.voiceStateUpdate(temp);
this.voiceFactory.voiceStateUpdate(temp.d);
}
break;
@ -838,7 +872,9 @@ class Localuser {
async joinVoice(channel: Channel) {
if (!this.voiceFactory) return;
if (!this.ws) return;
this.ws.send(JSON.stringify(this.voiceFactory.joinVoice(channel.id, channel.guild.id)));
this.ws.send(
JSON.stringify(this.voiceFactory.joinVoice(channel.id, channel.guild.id, this.mute)),
);
return undefined;
}
changeVCStatus(status: string) {
@ -891,6 +927,9 @@ class Localuser {
if (!guild) return;
const channel = this.channelfocus;
if (!channel) return;
if (channel.voice && this.voiceAllowed) {
return;
}
if (list) {
const counts = new Map<string, number>();
for (const thing of list.d.ops[0].items) {

View file

@ -538,6 +538,21 @@ textarea {
aspect-ratio: 1/1;
flex-shrink: 0;
}
.svg-mic {
height: 22px;
width: 22px;
margin: 6px;
mask: url(/icons/mic.svg);
mask-size: contain !important;
}
.svg-micmute {
height: 22px;
width: 22px;
margin: 6px;
mask: url(/icons/micmute.svg);
background-color: var(--red);
mask-size: contain !important;
}
.mobileback {
visibility: hidden;
height: 0px;
@ -1186,10 +1201,6 @@ span.instanceStatus {
#userinfo {
min-width: 50%;
padding: 0 6px;
background: var(--user-info-bg);
color: var(--user-info-text);
border-radius: 8px;
box-sizing: border-box;
gap: 6px;
cursor: pointer;
}
@ -1205,11 +1216,14 @@ span.instanceStatus {
#status {
font-size: 0.8em;
}
#user-actions {
#user-actions > * {
border-radius: 50%;
cursor: pointer;
background: var(--user-info-bg);
color: var(--user-info-text);
box-sizing: border-box;
}
#user-actions:hover {
#user-actions > :hover {
background: var(--dock-hover);
}
#settings {

View file

@ -1,5 +1,4 @@
import {memberjson, sdpback, voiceserverupdate, voiceupdate, webRTCSocket} from "./jsontypes.js";
import {memberjson, sdpback, voiceserverupdate, voiceStatus, webRTCSocket} from "./jsontypes.js";
class VoiceFactory {
settings: {id: string};
constructor(usersettings: VoiceFactory["settings"]) {
@ -28,7 +27,7 @@ class VoiceFactory {
}
onJoin = (_voice: Voice) => {};
onLeave = (_voice: Voice) => {};
joinVoice(channelId: string, guildId: string) {
joinVoice(channelId: string, guildId: string, self_mute = false) {
const voice = this.voiceChannels.get(channelId);
if (this.currentVoice && this.currentVoice.ws) {
this.currentVoice.leave();
@ -42,7 +41,7 @@ class VoiceFactory {
d: {
guild_id: guildId,
channel_id: channelId,
self_mute: false, //todo
self_mute,
self_deaf: false, //todo
self_video: false, //What is this? I have some guesses
flags: 2, //?????
@ -51,16 +50,16 @@ class VoiceFactory {
};
}
userMap = new Map<string, Voice>();
voiceStateUpdate(update: voiceupdate) {
const prev = this.userMap.get(update.d.user_id);
voiceStateUpdate(update: voiceStatus) {
const prev = this.userMap.get(update.user_id);
console.log(prev, this.userMap);
if (prev) {
prev.disconnect(update.d.user_id);
prev.disconnect(update.user_id);
this.onLeave(prev);
}
const voice = this.voiceChannels.get(update.d.channel_id);
const voice = this.voiceChannels.get(update.channel_id);
if (voice) {
this.userMap.set(update.d.user_id, voice);
this.userMap.set(update.user_id, voice);
voice.voiceupdate(update);
}
}
@ -696,11 +695,11 @@ a=rtcp-mux\r`;
}
onMemberChange = (_member: memberjson | string, _joined: boolean) => {};
userids = new Map<string, {}>();
async voiceupdate(update: voiceupdate) {
async voiceupdate(update: voiceStatus) {
console.log("Update!");
this.userids.set(update.d.member.id, {deaf: update.d.deaf, muted: update.d.mute});
this.onMemberChange(update.d.member, true);
if (update.d.member.id === this.userid && this.open) {
this.userids.set(update.user_id, {deaf: update.deaf, muted: update.mute});
this.onMemberChange(update?.member || update.user_id, true);
if (update.user_id === this.userid && this.open) {
if (!update) {
this.status = "bad responce from WS";
return;
@ -737,9 +736,9 @@ a=rtcp-mux\r`;
JSON.stringify({
op: 0,
d: {
server_id: update.d.guild_id,
user_id: update.d.user_id,
session_id: update.d.session_id,
server_id: update.guild_id,
user_id: update.user_id,
session_id: update.session_id,
token: this.urlobj.token,
video: false,
streams: [