somewhat of a queue working and also changing to a nicer map object for the store

This commit is contained in:
talksik
2022-01-18 03:08:06 -08:00
parent 355b37d435
commit cf064f5545
3 changed files with 75 additions and 40 deletions
+3 -13
View File
@@ -15,17 +15,7 @@ import { useEffect, useState } from "react";
import { toast } from "react-hot-toast"; import { toast } from "react-hot-toast";
import { TeamMemberRole, TeamMemberStatus } from "../../models/teamMember"; import { TeamMemberRole, TeamMemberStatus } from "../../models/teamMember";
import UserService from "../../services/userService"; import UserService from "../../services/userService";
import { import { getFirestore } from "firebase/firestore";
collection,
doc,
DocumentSnapshot,
getFirestore,
onSnapshot,
orderBy,
query,
Unsubscribe,
where,
} from "firebase/firestore";
import { Collections } from "../../services/collections"; import { Collections } from "../../services/collections";
import { KeyCode } from "../../globals/keycode"; import { KeyCode } from "../../globals/keycode";
import { Tooltip } from "antd"; import { Tooltip } from "antd";
@@ -107,8 +97,8 @@ export default function TeamVoiceLine() {
return teamUsers.map((tmember, i) => { return teamUsers.map((tmember, i) => {
var isMessageIncoming: boolean = false; var isMessageIncoming: boolean = false;
if ( if (
tmember.id in messagesByTeamMate && messagesByTeamMate.has(tmember.id) &&
messagesByTeamMate[tmember.id][0]?.receiverUserId == currUser.uid messagesByTeamMate.get(tmember.id)[0]?.receiverUserId == currUser.uid
) { ) {
isMessageIncoming = true; isMessageIncoming = true;
} }
+54 -12
View File
@@ -13,6 +13,7 @@ import { useAuth } from "./authContext";
import { SendService } from "../services/sendService"; import { SendService } from "../services/sendService";
import { useTeamDashboardContext } from "./teamDashboardContext"; import { useTeamDashboardContext } from "./teamDashboardContext";
import isValidHttpUrl from "../helpers/urlHelper"; import isValidHttpUrl from "../helpers/urlHelper";
import ReactPlayer from "react-player/lazy";
interface KeyboardContextInterface { interface KeyboardContextInterface {
selectedTeammate: string; // can only have one selected selectedTeammate: string; // can only have one selected
@@ -107,6 +108,8 @@ export default function KeyboardContextProvider({ children }) {
new MicRecorder({ bitRate: 128 }) new MicRecorder({ bitRate: 128 })
); );
const [audioQueue, setAudioQueue] = useState<string[]>([]); // queue for the player to keep playing
// playing incoming messages // playing incoming messages
const { allMessages, messagesByTeamMate } = useTeamDashboardContext(); const { allMessages, messagesByTeamMate } = useTeamDashboardContext();
@@ -126,10 +129,21 @@ export default function KeyboardContextProvider({ children }) {
// start player on the bottom // start player on the bottom
// autoplay message // autoplay message
setPlayerSrc(allMessages[0].audioDataUrl); // add to the queue
setAudioQueue((prevQueue) => [...prevQueue, allMessages[0].audioDataUrl]);
} }
}, [allMessages]); }, [allMessages]);
// manage audio queue
useEffect(() => {
// every time queue changes,
// setPlayerSrc as the next item if there is any
if (audioQueue && audioQueue.length > 0) {
setPlayerSrc(audioQueue[0]);
}
}, [audioQueue]);
const value: KeyboardContextInterface = { const value: KeyboardContextInterface = {
selectedTeammate, selectedTeammate,
selectTeamMember, selectTeamMember,
@@ -281,10 +295,12 @@ export default function KeyboardContextProvider({ children }) {
function onEndedPlaying(e) { function onEndedPlaying(e) {
toast.success("finished playing"); toast.success("finished playing");
// hide the player // remove from queue and the queue manager will handle the rest
setPlayerSrc(null); setAudioQueue((prevQueue) => {
let newQueue: string[] = [...prevQueue];
// if there are still items in the player queue, then change the src and play the subsequent messages newQueue.shift();
return newQueue;
});
} }
const handleKeyUp = useCallback( const handleKeyUp = useCallback(
@@ -353,7 +369,9 @@ export default function KeyboardContextProvider({ children }) {
if (!audioInputDeviceId) { if (!audioInputDeviceId) {
toast.error("No microphone selected"); toast.error("No microphone selected");
} else if (!hasRecPermit) { } else if (!hasRecPermit) {
toast.error("You did not allow recording permission!"); toast.error(
"You did not allow microphone permissions in your browser!"
);
} else if (!selectedTeammate) { } else if (!selectedTeammate) {
toast.error("Please select a team member or announcements first"); toast.error("Please select a team member or announcements first");
} else if (isMuted) { } else if (isMuted) {
@@ -378,17 +396,41 @@ export default function KeyboardContextProvider({ children }) {
toast.error("select a team member first to play"); toast.error("select a team member first to play");
} else { } else {
// alright now you are good to play last message chunk in conversation with selected user // alright now you are good to play last message chunk in conversation with selected user
// todo create last chunk by iterating until next person, and create a playlist
const arrayMessagesforUser: Message[] =
messagesByTeamMate.get(selectedTeammate);
if ( if (
selectedTeammate in messagesByTeamMate && messagesByTeamMate.has(selectedTeammate) &&
messagesByTeamMate[selectedTeammate] && arrayMessagesforUser &&
messagesByTeamMate[selectedTeammate].length > 0 arrayMessagesforUser.length > 0
) { ) {
var convoChunk: string[] = [];
console.log("playing from this cache"); console.log("playing from this cache");
console.log(messagesByTeamMate); // wait for x changes, and then break adding to the queue...I want to hear the past loop of conversation maybe
setPlayerSrc(messagesByTeamMate[selectedTeammate][0].audioDataUrl); const maxConvoChanges: number = 2;
var convoChangeCount: number = 0;
var currTalkerId = arrayMessagesforUser[0].senderUserId;
for (const audioMessage of arrayMessagesforUser) {
if (audioMessage.senderUserId != currTalkerId) {
convoChangeCount += 1;
}
// heard enough of this convo
if (convoChangeCount == maxConvoChanges) {
break;
}
convoChunk.push(audioMessage.audioDataUrl);
currTalkerId = audioMessage.senderUserId;
}
// reverse the chunk so that I listen to the messages in order
convoChunk.reverse();
// add convo chunk to the queue player
setAudioQueue((prevQueue) => [...prevQueue, ...convoChunk]);
} else { } else {
toast("nothing to play"); toast("nothing to play");
} }
+18 -15
View File
@@ -30,7 +30,7 @@ interface TeamDashboardContextInterface {
user: User; // REALTIME - 1 user: User; // REALTIME - 1
messagesByTeamMate: {}; // REALTIME: string of teammate userid and array of messages - 1 messagesByTeamMate: Map<string, Message[]>; // REALTIME: string of teammate userid and array of messages - 1
allMessages: Message[]; // REALTIME: 1 allMessages: Message[]; // REALTIME: 1
teamUsers: User[]; // REALTIME teammates - n team members => n listeners teamUsers: User[]; // REALTIME teammates - n team members => n listeners
@@ -115,7 +115,7 @@ export function TeamDashboardContextProvider({ children }) {
); );
// if you are not a member of this team, then get out of here // if you are not a member of this team, then get out of here
// but have to check through email invite and userid // but have to check through email invite and userid
if ( if (
returnedTeamMember && returnedTeamMember &&
returnedTeamMember.status == TeamMemberStatus.deleted returnedTeamMember.status == TeamMemberStatus.deleted
@@ -224,7 +224,9 @@ export function TeamDashboardContextProvider({ children }) {
const [teamUsersMap, setTeamUsersMap] = useState<{}>({}); const [teamUsersMap, setTeamUsersMap] = useState<{}>({});
const [allMessages, setAllMessages] = useState<Message[]>([]); const [allMessages, setAllMessages] = useState<Message[]>([]);
const [messagesByTeamMate, setMessagesByTeamMate] = useState<{}>({}); const [messagesByTeamMate, setMessagesByTeamMate] = useState<
Map<string, Message[]>
>(new Map());
// SECTION: REALTIME listener for all incoming messages // SECTION: REALTIME listener for all incoming messages
useEffect(() => { useEffect(() => {
@@ -257,28 +259,29 @@ export function TeamDashboardContextProvider({ children }) {
// update map of teammate to relevant messages // update map of teammate to relevant messages
setMessagesByTeamMate((prevMap) => { setMessagesByTeamMate((prevMap) => {
// if the map contains the teammate userid already, then cool, just unshift to that array // if the map contains the teammate userid already, then cool, just unshift to that array
const newMap = { ...prevMap }; var newMap: Map<string, Message[]> = new Map(
if (newMessage.receiverUserId in prevMap) { prevMap.set("dummy", [] as Message[])
// won't be in map if I am the receiver );
newMap[newMessage.receiverUserId] = [ if (prevMap.has(newMessage.receiverUserId)) {
newMap.set(newMessage.receiverUserId, [
newMessage, newMessage,
...prevMap[newMessage.receiverUserId], ...prevMap.get(newMessage.receiverUserId),
]; ]);
} // if this is the first relevant message linked to this receiver, } // if this is the first relevant message linked to this receiver,
//then create a new array //then create a new array
else { else {
newMap[newMessage.receiverUserId] = [newMessage]; newMap.set(newMessage.receiverUserId, [newMessage]);
} }
// todo: if I am the receiver, still want to put it in the right conversation // todo: if I am the receiver, still want to put it in the right conversation
if (newMessage.receiverUserId == currUser.uid) { if (newMessage.receiverUserId == currUser.uid) {
if (newMessage.senderUserId in prevMap) { if (prevMap.has(newMessage.senderUserId)) {
newMap[newMessage.senderUserId] = [ newMap.set(newMessage.senderUserId, [
newMessage, newMessage,
...prevMap[newMessage.senderUserId], ...prevMap.get(newMessage.senderUserId),
]; ]);
} else { } else {
newMap[newMessage.senderUserId] = [newMessage]; newMap.set(newMessage.senderUserId, [newMessage]);
} }
} }