creating announcement easy done
This commit is contained in:
@@ -13,6 +13,7 @@ import { SendService } from "../services/sendService";
|
|||||||
import { useTeamDashboardContext } from "./teamDashboardContext";
|
import { useTeamDashboardContext } from "./teamDashboardContext";
|
||||||
import isValidHttpUrl from "../helpers/urlHelper";
|
import isValidHttpUrl from "../helpers/urlHelper";
|
||||||
import { GlobalHotKeys, KeyMap } from "react-hotkeys";
|
import { GlobalHotKeys, KeyMap } from "react-hotkeys";
|
||||||
|
import Announcement from "../models/announcement";
|
||||||
|
|
||||||
interface KeyboardContextInterface {
|
interface KeyboardContextInterface {
|
||||||
selectedTeammate: string; // can only have one selected
|
selectedTeammate: string; // can only have one selected
|
||||||
@@ -22,6 +23,7 @@ interface KeyboardContextInterface {
|
|||||||
addTeamShortcutBinding: Function;
|
addTeamShortcutBinding: Function;
|
||||||
|
|
||||||
isRecording: Boolean; // can only record if someone is selected or maybe for an announcement
|
isRecording: Boolean; // can only record if someone is selected or maybe for an announcement
|
||||||
|
isRecordingAnnouncement: boolean;
|
||||||
|
|
||||||
isMuted: Boolean;
|
isMuted: Boolean;
|
||||||
isSilenceMode: Boolean; // won't automatically listen to notifications or sounds
|
isSilenceMode: Boolean; // won't automatically listen to notifications or sounds
|
||||||
@@ -78,6 +80,8 @@ export default function KeyboardContextProvider({ children }) {
|
|||||||
// SECTION: set up for shortcuts and recording and such
|
// SECTION: set up for shortcuts and recording and such
|
||||||
const [selectedTeammate, setSelectedTeamMember] = useState<string>(null); // id of selected teammate
|
const [selectedTeammate, setSelectedTeamMember] = useState<string>(null); // id of selected teammate
|
||||||
const [isRecording, setIsRecording] = useState<Boolean>(false);
|
const [isRecording, setIsRecording] = useState<Boolean>(false);
|
||||||
|
const [isRecordingAnnouncement, setIsRecordingAnnouncement] =
|
||||||
|
useState<boolean>(false);
|
||||||
const [hasRecPermit, setHasRecPermit] = useState<Boolean>(false);
|
const [hasRecPermit, setHasRecPermit] = useState<Boolean>(false);
|
||||||
|
|
||||||
const [ctrlDown, setCtrlDown] = useState<boolean>(false);
|
const [ctrlDown, setCtrlDown] = useState<boolean>(false);
|
||||||
@@ -109,7 +113,7 @@ export default function KeyboardContextProvider({ children }) {
|
|||||||
const [audioQueue, setAudioQueue] = useState<string[]>([]); // queue for the player to keep playing
|
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, team } = useTeamDashboardContext();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!allMessages.length) {
|
if (!allMessages.length) {
|
||||||
@@ -148,6 +152,7 @@ export default function KeyboardContextProvider({ children }) {
|
|||||||
selectTeamMember,
|
selectTeamMember,
|
||||||
addTeamShortcutBinding,
|
addTeamShortcutBinding,
|
||||||
isRecording,
|
isRecording,
|
||||||
|
isRecordingAnnouncement,
|
||||||
teamShortcutMappings,
|
teamShortcutMappings,
|
||||||
|
|
||||||
isMuted,
|
isMuted,
|
||||||
@@ -527,11 +532,52 @@ export default function KeyboardContextProvider({ children }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function startAnnouncement() {
|
function startAnnouncement() {
|
||||||
toast.success("recording announcement");
|
setIsRecordingAnnouncement(true);
|
||||||
|
|
||||||
|
startRecording();
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendAnnouncement() {
|
async function sendAnnouncement() {
|
||||||
toast.success("announcement sent to team");
|
toast.success("announcement sent to team");
|
||||||
|
setIsRecordingAnnouncement(false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const file = await stopRecording();
|
||||||
|
|
||||||
|
// confirm with user that he wants to make the announcement
|
||||||
|
// before sending and all
|
||||||
|
// show this 2 seconds after playing entire message
|
||||||
|
setTimeout(async () => {
|
||||||
|
if (
|
||||||
|
confirm(
|
||||||
|
"Send this announcement to team? OR just cancel and create a new one to restate something."
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
const downloadUrl = await cloudStorageService.uploadMessageAudioFile(
|
||||||
|
file
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("file is stored: " + downloadUrl);
|
||||||
|
|
||||||
|
// create announcement object and send to firestore
|
||||||
|
const newAnnounce = new Announcement(
|
||||||
|
downloadUrl,
|
||||||
|
team.id,
|
||||||
|
currUser.uid
|
||||||
|
);
|
||||||
|
|
||||||
|
await sendService.sendAnnouncement(newAnnounce);
|
||||||
|
|
||||||
|
toast.success("clip sent");
|
||||||
|
} else {
|
||||||
|
toast.error("cancelled announcement");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
} catch (error) {
|
||||||
|
toast.error("problem in sending");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const keyMap: KeyMap = {
|
const keyMap: KeyMap = {
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Timestamp } from "firebase/firestore";
|
||||||
|
|
||||||
|
export default class Announcement {
|
||||||
|
id: string;
|
||||||
|
teamId: string;
|
||||||
|
audioDataUrl: string; // link to cloud storage file
|
||||||
|
|
||||||
|
state: AnnouncementState = AnnouncementState.active;
|
||||||
|
|
||||||
|
createdByUserId: string;
|
||||||
|
createdDate: Timestamp;
|
||||||
|
lastUpdatedDate: Timestamp;
|
||||||
|
|
||||||
|
constructor(_audioUrl: string, _teamId: string, _createdByUserId: string) {
|
||||||
|
this.audioDataUrl = _audioUrl;
|
||||||
|
this.createdByUserId = _createdByUserId;
|
||||||
|
this.teamId = _teamId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum AnnouncementState {
|
||||||
|
active = "active",
|
||||||
|
resolved = "resolved",
|
||||||
|
deleted = "deleted",
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import {
|
||||||
|
addDoc,
|
||||||
|
collection,
|
||||||
|
doc,
|
||||||
|
Firestore,
|
||||||
|
getFirestore,
|
||||||
|
serverTimestamp,
|
||||||
|
setDoc,
|
||||||
|
} from "firebase/firestore";
|
||||||
|
import { AnnouncementState } from "../models/announcement";
|
||||||
|
import { Collections } from "./collections";
|
||||||
|
|
||||||
|
export class AnnouncementService {
|
||||||
|
private db: Firestore = getFirestore();
|
||||||
|
|
||||||
|
async updateAnnouncementState(
|
||||||
|
announcementId: string,
|
||||||
|
newState: AnnouncementState
|
||||||
|
) {
|
||||||
|
const docRef = doc(this.db, Collections.announcements, announcementId);
|
||||||
|
await setDoc(
|
||||||
|
docRef,
|
||||||
|
{ state: newState, lastUpdatedDate: serverTimestamp() },
|
||||||
|
{ merge: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
getFirestore,
|
getFirestore,
|
||||||
serverTimestamp,
|
serverTimestamp,
|
||||||
} from "firebase/firestore";
|
} from "firebase/firestore";
|
||||||
|
import Announcement from "../models/announcement";
|
||||||
import Link from "../models/link";
|
import Link from "../models/link";
|
||||||
import { Message } from "../models/message";
|
import { Message } from "../models/message";
|
||||||
import { Collections } from "./collections";
|
import { Collections } from "./collections";
|
||||||
@@ -31,4 +32,11 @@ export class SendService {
|
|||||||
createdDate: serverTimestamp(),
|
createdDate: serverTimestamp(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sendAnnouncement(announcement: Announcement) {
|
||||||
|
await addDoc(collection(this.db, Collections.announcements), {
|
||||||
|
...announcement,
|
||||||
|
createdDate: serverTimestamp(),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user