building a lot of the modal for the creating room and close to being done
This commit is contained in:
@@ -1,18 +1,21 @@
|
|||||||
import { Modal } from "antd";
|
import { Divider, Modal, Select } from "antd";
|
||||||
import { useEffect } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
ShowModalType,
|
ShowModalType,
|
||||||
useKeyboardContext,
|
useKeyboardContext,
|
||||||
} from "../../contexts/keyboardContext";
|
} from "../../contexts/keyboardContext";
|
||||||
|
|
||||||
|
const { Option } = Select;
|
||||||
|
|
||||||
const thisModalType = ShowModalType.createRoom;
|
const thisModalType = ShowModalType.createRoom;
|
||||||
|
|
||||||
export default function CreateRoomModal() {
|
export default function CreateRoomModal() {
|
||||||
const { pastedLink, handleModalType, showModalType } = useKeyboardContext();
|
const { pastedLink, handleModalType, showModalType } = useKeyboardContext();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// check if link is valid google meet link
|
// todo: check if link is valid google meet link? again?
|
||||||
}, []);
|
setRoomLink(pastedLink);
|
||||||
|
}, [pastedLink]);
|
||||||
|
|
||||||
const handleCloseModal = () => {
|
const handleCloseModal = () => {
|
||||||
handleModalType(ShowModalType.na);
|
handleModalType(ShowModalType.na);
|
||||||
@@ -20,6 +23,36 @@ export default function CreateRoomModal() {
|
|||||||
|
|
||||||
const handleSubmit = () => {};
|
const handleSubmit = () => {};
|
||||||
|
|
||||||
|
const [roomLink, setRoomLink] = useState<string>(pastedLink);
|
||||||
|
const [membersSelected, setMembersSelected] = useState<string[]>([]);
|
||||||
|
|
||||||
|
function handleSelectMember(value) {
|
||||||
|
// setMemberSelection()
|
||||||
|
console.log(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
const children = [];
|
||||||
|
for (let i = 10; i < 36; i++) {
|
||||||
|
children.push(
|
||||||
|
<Option key={i.toString(36) + i}>{i.toString(36) + i}</Option>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const MemberSelection = () => {
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
mode="multiple"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
placeholder="Please select"
|
||||||
|
defaultValue={["a10", "c12"]}
|
||||||
|
onChange={handleSelectMember}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title="Create Room"
|
title="Create Room"
|
||||||
@@ -28,9 +61,68 @@ export default function CreateRoomModal() {
|
|||||||
onOk={handleSubmit}
|
onOk={handleSubmit}
|
||||||
onCancel={handleCloseModal}
|
onCancel={handleCloseModal}
|
||||||
>
|
>
|
||||||
<p>some contents...</p>
|
<div className="flex flex-col">
|
||||||
<p>some contents...</p>
|
<span className="flex flex-col items-start">
|
||||||
<p>some contents...</p>
|
<span className="text-md">Link</span>
|
||||||
|
<span className="text-gray-300 text-xs mb-2">
|
||||||
|
Please make sure this is valid so that your team can join properly.
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
className="w-full rounded-lg bg-gray-50 p-3"
|
||||||
|
value={roomLink}
|
||||||
|
onChange={(e) => setRoomLink(e.target.value)}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div className="flex flex-row justify-between space-x-3 mt-4">
|
||||||
|
<span className="flex flex-col items-start flex-1 ">
|
||||||
|
<span className="text-md">Room Name</span>
|
||||||
|
<span className="text-gray-300 text-xs mb-2 flex-1">
|
||||||
|
Be specific enough, everyone down the hall will see this.
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
placeholder="ex. Design - Ecommerce Figma"
|
||||||
|
className="w-full rounded-lg bg-gray-50 p-3"
|
||||||
|
value={""}
|
||||||
|
onChange={(e) => setRoomLink(e.target.value)}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
<span className="flex flex-col items-start flex-1 mt-4">
|
||||||
|
<span className="text-md">People</span>
|
||||||
|
<span className="text-gray-300 text-xs mb-2 flex-1">
|
||||||
|
Optional - Add anyone you want or just tell them later.
|
||||||
|
</span>
|
||||||
|
{MemberSelection()}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span className="flex flex-col items-start flex-1 mt-4">
|
||||||
|
<span className="text-md">Subtitle</span>
|
||||||
|
<span className="text-gray-300 text-xs mb-2 flex-1">Optional</span>
|
||||||
|
<input
|
||||||
|
placeholder="ex. Looking for feedback if..."
|
||||||
|
className="w-full rounded-lg bg-gray-50 p-3"
|
||||||
|
value={""}
|
||||||
|
onChange={(e) => setRoomLink(e.target.value)}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span className="flex flex-col items-start flex-1 mt-4">
|
||||||
|
<span className="text-md">Attachment</span>
|
||||||
|
<span className="text-gray-300 text-xs mb-2">
|
||||||
|
Optional - add a ppt or meeting notes for people to follow along
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
placeholder="https://"
|
||||||
|
className="w-full rounded-lg bg-gray-50 p-3"
|
||||||
|
value={""}
|
||||||
|
onChange={(e) => setRoomLink(e.target.value)}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { Message } from "../models/message";
|
|||||||
import { useAuth } from "./authContext";
|
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";
|
||||||
|
|
||||||
interface KeyboardContextInterface {
|
interface KeyboardContextInterface {
|
||||||
selectedTeammate: string; // can only have one selected
|
selectedTeammate: string; // can only have one selected
|
||||||
@@ -324,7 +325,7 @@ export default function KeyboardContextProvider({ children }) {
|
|||||||
|
|
||||||
console.log("sending message to " + selectedTeammate);
|
console.log("sending message to " + selectedTeammate);
|
||||||
|
|
||||||
setSelectedTeamMember(null);
|
handleResetView();
|
||||||
} else if (event.keyCode == KeyCode.Ctrl) {
|
} else if (event.keyCode == KeyCode.Ctrl) {
|
||||||
setCtrlDown(false);
|
setCtrlDown(false);
|
||||||
}
|
}
|
||||||
@@ -334,10 +335,16 @@ export default function KeyboardContextProvider({ children }) {
|
|||||||
|
|
||||||
const handleKeyboardShortcut = useCallback(
|
const handleKeyboardShortcut = useCallback(
|
||||||
(event) => {
|
(event) => {
|
||||||
|
// no need to monitor repeats
|
||||||
if (event.repeat) {
|
if (event.repeat) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle for when in modals, don't want any of this crap
|
||||||
|
if (showModalType != ShowModalType.na || !showModalType) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
console.log(event.keyCode);
|
console.log(event.keyCode);
|
||||||
|
|
||||||
// recording
|
// recording
|
||||||
@@ -361,7 +368,7 @@ export default function KeyboardContextProvider({ children }) {
|
|||||||
else if (teamShortcutMappings[event.keyCode]) {
|
else if (teamShortcutMappings[event.keyCode]) {
|
||||||
setSelectedTeamMember(teamShortcutMappings[event.keyCode]);
|
setSelectedTeamMember(teamShortcutMappings[event.keyCode]);
|
||||||
} else if (event.keyCode == KeyCode.Escape) {
|
} else if (event.keyCode == KeyCode.Escape) {
|
||||||
setSelectedTeamMember(null);
|
handleResetView();
|
||||||
} else if (event.keyCode == KeyCode.Space) {
|
} else if (event.keyCode == KeyCode.Space) {
|
||||||
// listen to last message in convo
|
// listen to last message in convo
|
||||||
if (isSilenceMode) {
|
if (isSilenceMode) {
|
||||||
@@ -386,6 +393,8 @@ export default function KeyboardContextProvider({ children }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (event.keyCode == KeyCode.Ctrl) {
|
} else if (event.keyCode == KeyCode.Ctrl) {
|
||||||
|
handleResetView();
|
||||||
|
|
||||||
setCtrlDown(true);
|
setCtrlDown(true);
|
||||||
toast("control down");
|
toast("control down");
|
||||||
} else if (event.keyCode == KeyCode.Q && ctrlDown) {
|
} else if (event.keyCode == KeyCode.Q && ctrlDown) {
|
||||||
@@ -395,9 +404,32 @@ export default function KeyboardContextProvider({ children }) {
|
|||||||
} else if (event.keyCode == KeyCode.V && ctrlDown) {
|
} else if (event.keyCode == KeyCode.V && ctrlDown) {
|
||||||
toast("pasting link");
|
toast("pasting link");
|
||||||
|
|
||||||
setSelectedTeamMember(null);
|
navigator.clipboard
|
||||||
|
.readText()
|
||||||
|
.then((text) => {
|
||||||
|
console.log("Pasted content: ", text);
|
||||||
|
|
||||||
setShowModalType(ShowModalType.createRoom);
|
// check that the link is valid
|
||||||
|
if (!isValidHttpUrl(text)) {
|
||||||
|
toast.error("Not a valid link");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set it as we should show modal regardless now
|
||||||
|
setPastedLink(text);
|
||||||
|
|
||||||
|
// see which modal to go to based on room vs. attachment
|
||||||
|
// https://meet.google.com/soc-ebwc-rkt
|
||||||
|
if (text.includes("meet.google.com")) {
|
||||||
|
setShowModalType(ShowModalType.createRoom);
|
||||||
|
} else {
|
||||||
|
setShowModalType(ShowModalType.createLink);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error("Failed to read clipboard contents: ", err);
|
||||||
|
toast.error("Please enable permissions for clipboard");
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
toast("Invalid keyboard shortcut.");
|
toast("Invalid keyboard shortcut.");
|
||||||
}
|
}
|
||||||
@@ -416,6 +448,12 @@ export default function KeyboardContextProvider({ children }) {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function handleResetView() {
|
||||||
|
setSelectedTeamMember(null);
|
||||||
|
setShowModalType(ShowModalType.na);
|
||||||
|
setPlayerSrc(null);
|
||||||
|
}
|
||||||
|
|
||||||
// IMPORTANT: shortcut handlers need to be updated as the function has to have the fresh state
|
// IMPORTANT: shortcut handlers need to be updated as the function has to have the fresh state
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("updating event listeners");
|
console.log("updating event listeners");
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
export default function isValidHttpUrl(potentialUrl: string) {
|
||||||
|
let url;
|
||||||
|
|
||||||
|
try {
|
||||||
|
url = new URL(potentialUrl);
|
||||||
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return url.protocol === "http:" || url.protocol === "https:";
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
export default class Room {
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
title: string;
|
||||||
|
subtitle: string;
|
||||||
|
|
||||||
|
roomLink: string; // google meet link for now
|
||||||
|
|
||||||
|
roomMembers: string[]; //userIds of "mandatory"/invited people including the person who created it
|
||||||
|
|
||||||
|
attachments: string[]; // the links themselves (NOT Ids)...there will be duplicate entries in the attachments table which will be created
|
||||||
|
|
||||||
|
roomType: RoomType;
|
||||||
|
|
||||||
|
approximateDateTime: string; // vaguely say when the meeting should be...give user pointers
|
||||||
|
}
|
||||||
|
|
||||||
|
enum RoomType {
|
||||||
|
now = "now",
|
||||||
|
scheduled = "scheduled", // one time sort of standard meeting
|
||||||
|
recurring = "recurring", //daily standup
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user