sending message nicely
This commit is contained in:
@@ -11,9 +11,9 @@ export default class Conversation {
|
|||||||
activeMembers: string[]; // userIds
|
activeMembers: string[]; // userIds
|
||||||
membersInLiveRoom: string[] = [] as string[]; // all members in a live call right now for this convo
|
membersInLiveRoom: string[] = [] as string[]; // all members in a live call right now for this convo
|
||||||
|
|
||||||
cachedAudioClips: AudioClip[] = [] as AudioClip[];
|
cachedAudioClip?: AudioClip; // last message pretty much
|
||||||
cachedDrawerItems: Link[] = [] as Link[];
|
cachedDrawerItem?: Link; // last link pretty much
|
||||||
tldrClips: AudioClip[] = [] as AudioClip[];
|
cachedTldrClip?: string;
|
||||||
|
|
||||||
createdDate: Timestamp = Timestamp.now();
|
createdDate: Timestamp = Timestamp.now();
|
||||||
createdByUserId: string;
|
createdByUserId: string;
|
||||||
@@ -68,7 +68,7 @@ export enum ConversationMemberState {
|
|||||||
export class AudioClip {
|
export class AudioClip {
|
||||||
id: string = uuid();
|
id: string = uuid();
|
||||||
|
|
||||||
audioDataUrl: string;
|
audioDataUrl?: string;
|
||||||
|
|
||||||
senderUserId: string;
|
senderUserId: string;
|
||||||
createdDate: Timestamp = Timestamp.now();
|
createdDate: Timestamp = Timestamp.now();
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ enum Collections {
|
|||||||
// v2
|
// v2
|
||||||
conversations = "conversations",
|
conversations = "conversations",
|
||||||
conversationMembers = "members",
|
conversationMembers = "members",
|
||||||
|
conversationAudioClips = "audioClips",
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Collections;
|
export default Collections;
|
||||||
|
|||||||
@@ -9,9 +9,13 @@ import {
|
|||||||
runTransaction,
|
runTransaction,
|
||||||
writeBatch,
|
writeBatch,
|
||||||
} from "firebase/firestore";
|
} from "firebase/firestore";
|
||||||
import Conversation, { ConversationMember } from "../models/conversation";
|
import Conversation, {
|
||||||
|
AudioClip,
|
||||||
|
ConversationMember,
|
||||||
|
ConversationMemberState,
|
||||||
|
} from "../models/conversation";
|
||||||
import Collections from "./collections";
|
import Collections from "./collections";
|
||||||
import { ConversationMemberState } from "../models/conversation";
|
import { cloudStorageService } from "./index";
|
||||||
|
|
||||||
export default class ConversationService {
|
export default class ConversationService {
|
||||||
private db: Firestore = getFirestore();
|
private db: Firestore = getFirestore();
|
||||||
@@ -103,4 +107,47 @@ export default class ConversationService {
|
|||||||
|
|
||||||
await setDoc(docRef, newUpdates, { merge: true });
|
await setDoc(docRef, newUpdates, { merge: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sendAudioClip(
|
||||||
|
createdByUserId: string,
|
||||||
|
audioMp3File: File,
|
||||||
|
convoId: string
|
||||||
|
) {
|
||||||
|
// upload to cloud storage
|
||||||
|
const downloadUrl = await cloudStorageService.uploadMessageAudioFile(
|
||||||
|
audioMp3File
|
||||||
|
);
|
||||||
|
const newAudioClip = new AudioClip(downloadUrl, createdByUserId);
|
||||||
|
newAudioClip.audioDataUrl = downloadUrl;
|
||||||
|
|
||||||
|
const audioClipRef = doc(
|
||||||
|
this.db,
|
||||||
|
Collections.conversations,
|
||||||
|
convoId,
|
||||||
|
Collections.conversationAudioClips,
|
||||||
|
newAudioClip.id
|
||||||
|
);
|
||||||
|
|
||||||
|
const conversationDoc = doc(this.db, Collections.conversations, convoId);
|
||||||
|
|
||||||
|
await runTransaction(this.db, async (transaction) => {
|
||||||
|
// want to add to the long term collection of all audio clips for a conversation
|
||||||
|
transaction.set(
|
||||||
|
audioClipRef,
|
||||||
|
{ ...newAudioClip, createdDate: serverTimestamp() },
|
||||||
|
{ merge: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// want to make updates to the conversation document itself: set the last item for just the basic information to be
|
||||||
|
// published to users
|
||||||
|
transaction.set(
|
||||||
|
conversationDoc,
|
||||||
|
{
|
||||||
|
lastActivityDate: serverTimestamp(),
|
||||||
|
cachedAudioClip: { ...newAudioClip, createdDate: serverTimestamp() },
|
||||||
|
},
|
||||||
|
{ merge: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
|
import CloudStorageService from "./cloudStorageService";
|
||||||
import ConversationService from "./conversationService";
|
import ConversationService from "./conversationService";
|
||||||
import UserService from "./userService";
|
import UserService from "./userService";
|
||||||
|
|
||||||
export const conversationService = new ConversationService();
|
export const conversationService = new ConversationService();
|
||||||
|
|
||||||
export const userService = new UserService();
|
export const userService = new UserService();
|
||||||
|
|
||||||
|
export const cloudStorageService = new CloudStorageService();
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ import { useEffect, useState } from "react";
|
|||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import MicRecorder from "mic-recorder-to-mp3";
|
import MicRecorder from "mic-recorder-to-mp3";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import { conversationService } from "../../../common/services/index";
|
||||||
|
import { AudioClip } from "@nirvana/common/models/conversation";
|
||||||
|
import { useAuth } from "../../contexts/authContext";
|
||||||
|
|
||||||
// New instance
|
// New instance
|
||||||
const recorder = new MicRecorder({
|
const recorder = new MicRecorder({
|
||||||
@@ -29,12 +32,14 @@ const recorder = new MicRecorder({
|
|||||||
const MAX_SHORTCUT_MAPPINGS_PRIORITY = 8;
|
const MAX_SHORTCUT_MAPPINGS_PRIORITY = 8;
|
||||||
|
|
||||||
export default function Priority() {
|
export default function Priority() {
|
||||||
|
const { currUser } = useAuth();
|
||||||
|
|
||||||
const priorityConvos = useRecoilValue(priorityConvosSelector);
|
const priorityConvos = useRecoilValue(priorityConvosSelector);
|
||||||
const [mapShortcutsToConvoId, setmapShortcutsToConvoId] = useState<
|
const [mapShortcutsToConvoId, setmapShortcutsToConvoId] = useState<
|
||||||
Map<string, string>
|
Map<string, string>
|
||||||
>(new Map<string, string>());
|
>(new Map<string, string>());
|
||||||
|
|
||||||
const setSelectedConversationId = useSetRecoilState(
|
const [selectedConvoId, setSelectedConversationId] = useRecoilState(
|
||||||
selectedPriorityConvoAtom
|
selectedPriorityConvoAtom
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -110,6 +115,10 @@ export default function Priority() {
|
|||||||
|
|
||||||
const startRecording = () => {
|
const startRecording = () => {
|
||||||
// check if there is a person selected
|
// check if there is a person selected
|
||||||
|
if (!selectedConvoId) {
|
||||||
|
toast.error("You must select a person first!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// check that we have mic permissions
|
// check that we have mic permissions
|
||||||
if (!hasMicPermissions) {
|
if (!hasMicPermissions) {
|
||||||
@@ -149,10 +158,15 @@ export default function Priority() {
|
|||||||
|
|
||||||
setIsRecording(false);
|
setIsRecording(false);
|
||||||
|
|
||||||
|
if (!selectedConvoId) {
|
||||||
|
toast.error("problem in sending clip");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
recorder
|
recorder
|
||||||
.stop()
|
.stop()
|
||||||
.getMp3()
|
.getMp3()
|
||||||
.then(([buffer, blob]) => {
|
.then(async ([buffer, blob]) => {
|
||||||
const blobURL = URL.createObjectURL(blob);
|
const blobURL = URL.createObjectURL(blob);
|
||||||
|
|
||||||
const file = new File(buffer, uuidv4() + ".mp3", {
|
const file = new File(buffer, uuidv4() + ".mp3", {
|
||||||
@@ -163,6 +177,16 @@ export default function Priority() {
|
|||||||
const player = new Audio(URL.createObjectURL(file));
|
const player = new Audio(URL.createObjectURL(file));
|
||||||
// player.onended = onEndedPlaying;
|
// player.onended = onEndedPlaying;
|
||||||
player.play();
|
player.play();
|
||||||
|
|
||||||
|
// send to service which handles the upload to blob and also the conversation database
|
||||||
|
await conversationService.sendAudioClip(
|
||||||
|
currUser!.uid,
|
||||||
|
file,
|
||||||
|
selectedConvoId
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("successfully sent audio clip");
|
||||||
|
toast.success("successfully sent audio clip");
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|||||||
Reference in New Issue
Block a user