mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-20 20:29:06 +00:00
Add shared rooms
This commit is contained in:
40
server/migrations/versions/a7122bc0b2ca_add_shared_rooms.py
Normal file
40
server/migrations/versions/a7122bc0b2ca_add_shared_rooms.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
"""Add shared rooms
|
||||||
|
|
||||||
|
Revision ID: a7122bc0b2ca
|
||||||
|
Revises: 74b2b0236931
|
||||||
|
Create Date: 2024-10-04 16:41:28.841889
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = "a7122bc0b2ca"
|
||||||
|
down_revision: Union[str, None] = "74b2b0236931"
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column(
|
||||||
|
"room",
|
||||||
|
sa.Column(
|
||||||
|
"is_shared",
|
||||||
|
sa.Boolean(),
|
||||||
|
server_default=sa.text("0"),
|
||||||
|
nullable=False,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_column("room", "is_shared")
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
@@ -36,6 +36,9 @@ rooms = sqlalchemy.Table(
|
|||||||
nullable=False,
|
nullable=False,
|
||||||
server_default="automatic-2nd-participant",
|
server_default="automatic-2nd-participant",
|
||||||
),
|
),
|
||||||
|
sqlalchemy.Column(
|
||||||
|
"is_shared", sqlalchemy.Boolean, nullable=False, server_default=false()
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -53,6 +56,7 @@ class Room(BaseModel):
|
|||||||
recording_trigger: Literal[
|
recording_trigger: Literal[
|
||||||
"none", "prompt", "automatic", "automatic-2nd-participant"
|
"none", "prompt", "automatic", "automatic-2nd-participant"
|
||||||
] = "automatic-2nd-participant"
|
] = "automatic-2nd-participant"
|
||||||
|
is_shared: bool = False
|
||||||
|
|
||||||
|
|
||||||
class RoomController:
|
class RoomController:
|
||||||
@@ -98,6 +102,7 @@ class RoomController:
|
|||||||
room_mode: str,
|
room_mode: str,
|
||||||
recording_type: str,
|
recording_type: str,
|
||||||
recording_trigger: str,
|
recording_trigger: str,
|
||||||
|
is_shared: bool,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Add a new room
|
Add a new room
|
||||||
@@ -112,6 +117,7 @@ class RoomController:
|
|||||||
room_mode=room_mode,
|
room_mode=room_mode,
|
||||||
recording_type=recording_type,
|
recording_type=recording_type,
|
||||||
recording_trigger=recording_trigger,
|
recording_trigger=recording_trigger,
|
||||||
|
is_shared=is_shared,
|
||||||
)
|
)
|
||||||
query = rooms.insert().values(**room.model_dump())
|
query = rooms.insert().values(**room.model_dump())
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class Room(BaseModel):
|
|||||||
room_mode: str
|
room_mode: str
|
||||||
recording_type: str
|
recording_type: str
|
||||||
recording_trigger: str
|
recording_trigger: str
|
||||||
|
is_shared: bool
|
||||||
|
|
||||||
|
|
||||||
class Meeting(BaseModel):
|
class Meeting(BaseModel):
|
||||||
@@ -49,6 +50,7 @@ class CreateRoom(BaseModel):
|
|||||||
room_mode: str
|
room_mode: str
|
||||||
recording_type: str
|
recording_type: str
|
||||||
recording_trigger: str
|
recording_trigger: str
|
||||||
|
is_shared: bool
|
||||||
|
|
||||||
|
|
||||||
class UpdateRoom(BaseModel):
|
class UpdateRoom(BaseModel):
|
||||||
@@ -60,6 +62,7 @@ class UpdateRoom(BaseModel):
|
|||||||
room_mode: str
|
room_mode: str
|
||||||
recording_type: str
|
recording_type: str
|
||||||
recording_trigger: str
|
recording_trigger: str
|
||||||
|
is_shared: bool
|
||||||
|
|
||||||
|
|
||||||
class DeletionStatus(BaseModel):
|
class DeletionStatus(BaseModel):
|
||||||
@@ -100,6 +103,7 @@ async def rooms_create(
|
|||||||
room_mode=room.room_mode,
|
room_mode=room.room_mode,
|
||||||
recording_type=room.recording_type,
|
recording_type=room.recording_type,
|
||||||
recording_trigger=room.recording_trigger,
|
recording_trigger=room.recording_trigger,
|
||||||
|
is_shared=room.is_shared,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ export default function TranscriptBrowser() {
|
|||||||
React.useState<string>();
|
React.useState<string>();
|
||||||
const [deletedItemIds, setDeletedItemIds] = React.useState<string[]>();
|
const [deletedItemIds, setDeletedItemIds] = React.useState<string[]>();
|
||||||
|
|
||||||
|
const myRooms = rooms.filter((room) => !room.is_shared);
|
||||||
|
const sharedRooms = rooms.filter((room) => room.is_shared);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setDeletedItemIds([]);
|
setDeletedItemIds([]);
|
||||||
}, [page, response]);
|
}, [page, response]);
|
||||||
@@ -102,6 +105,7 @@ export default function TranscriptBrowser() {
|
|||||||
const handleSearch = () => {
|
const handleSearch = () => {
|
||||||
setPage(1);
|
setPage(1);
|
||||||
setSearchTerm(searchInputValue);
|
setSearchTerm(searchInputValue);
|
||||||
|
setSelectedSourceKind(null);
|
||||||
setSelectedRoomId("");
|
setSelectedRoomId("");
|
||||||
refetch();
|
refetch();
|
||||||
};
|
};
|
||||||
@@ -205,13 +209,42 @@ export default function TranscriptBrowser() {
|
|||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
{rooms.length > 0 && (
|
{myRooms.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<Heading size="sm" mb={2}>
|
<Heading size="sm">My Rooms</Heading>
|
||||||
My Rooms
|
|
||||||
</Heading>
|
|
||||||
|
|
||||||
{rooms.map((room) => (
|
{myRooms.map((room) => (
|
||||||
|
<Link
|
||||||
|
key={room.id}
|
||||||
|
as={NextLink}
|
||||||
|
href="#"
|
||||||
|
onClick={() => handleFilterTranscripts("room", room.id)}
|
||||||
|
color={
|
||||||
|
selectedSourceKind === "room" &&
|
||||||
|
selectedRoomId === room.id
|
||||||
|
? "blue.500"
|
||||||
|
: "gray.600"
|
||||||
|
}
|
||||||
|
_hover={{ color: "blue.300" }}
|
||||||
|
fontWeight={
|
||||||
|
selectedSourceKind === "room" &&
|
||||||
|
selectedRoomId === room.id
|
||||||
|
? "bold"
|
||||||
|
: "normal"
|
||||||
|
}
|
||||||
|
ml={4}
|
||||||
|
>
|
||||||
|
{room.name}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{sharedRooms.length > 0 && (
|
||||||
|
<>
|
||||||
|
<Heading size="sm">Shared Rooms</Heading>
|
||||||
|
|
||||||
|
{sharedRooms.map((room) => (
|
||||||
<Link
|
<Link
|
||||||
key={room.id}
|
key={room.id}
|
||||||
as={NextLink}
|
as={NextLink}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ const roomInitialState = {
|
|||||||
roomMode: "normal",
|
roomMode: "normal",
|
||||||
recordingType: "cloud",
|
recordingType: "cloud",
|
||||||
recordingTrigger: "automatic-2nd-participant",
|
recordingTrigger: "automatic-2nd-participant",
|
||||||
|
isShared: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RoomsList() {
|
export default function RoomsList() {
|
||||||
@@ -159,6 +160,7 @@ export default function RoomsList() {
|
|||||||
room_mode: room.roomMode,
|
room_mode: room.roomMode,
|
||||||
recording_type: room.recordingType,
|
recording_type: room.recordingType,
|
||||||
recording_trigger: room.recordingTrigger,
|
recording_trigger: room.recordingTrigger,
|
||||||
|
is_shared: room.isShared,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isEditing) {
|
if (isEditing) {
|
||||||
@@ -203,6 +205,7 @@ export default function RoomsList() {
|
|||||||
roomMode: roomData.room_mode,
|
roomMode: roomData.room_mode,
|
||||||
recordingType: roomData.recording_type,
|
recordingType: roomData.recording_type,
|
||||||
recordingTrigger: roomData.recording_trigger,
|
recordingTrigger: roomData.recording_trigger,
|
||||||
|
isShared: roomData.is_shared,
|
||||||
});
|
});
|
||||||
setEditRoomId(roomId);
|
setEditRoomId(roomId);
|
||||||
setIsEditing(true);
|
setIsEditing(true);
|
||||||
@@ -236,6 +239,11 @@ export default function RoomsList() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const myRooms =
|
||||||
|
response?.items.filter((roomData) => !roomData.is_shared) || [];
|
||||||
|
const sharedRooms =
|
||||||
|
response?.items.filter((roomData) => roomData.is_shared) || [];
|
||||||
|
|
||||||
if (loading && !response)
|
if (loading && !response)
|
||||||
return (
|
return (
|
||||||
<Flex flexDir="column" align="center" justify="center" h="100%">
|
<Flex flexDir="column" align="center" justify="center" h="100%">
|
||||||
@@ -375,6 +383,15 @@ export default function RoomsList() {
|
|||||||
isDisabled={!room.zulipAutoPost}
|
isDisabled={!room.zulipAutoPost}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
<FormControl mt={4}>
|
||||||
|
<Checkbox
|
||||||
|
name="isShared"
|
||||||
|
isChecked={room.isShared}
|
||||||
|
onChange={handleRoomChange}
|
||||||
|
>
|
||||||
|
Shared room
|
||||||
|
</Checkbox>
|
||||||
|
</FormControl>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
@@ -396,9 +413,10 @@ export default function RoomsList() {
|
|||||||
</Modal>
|
</Modal>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<VStack>
|
<VStack align="start" mb={6} pt={4} gap={4}>
|
||||||
{response?.items && response.items.length > 0 ? (
|
<Heading size="md">My Rooms</Heading>
|
||||||
response.items.map((roomData) => (
|
{myRooms.length > 0 ? (
|
||||||
|
myRooms.map((roomData) => (
|
||||||
<Card w={"full"} key={roomData.id}>
|
<Card w={"full"} key={roomData.id}>
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<Flex align={"center"}>
|
<Flex align={"center"}>
|
||||||
@@ -445,9 +463,61 @@ export default function RoomsList() {
|
|||||||
</Card>
|
</Card>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<Flex flexDir="column" align="center" justify="center" h="100%">
|
<Text>No rooms found</Text>
|
||||||
<Text>No rooms found</Text>
|
)}
|
||||||
</Flex>
|
</VStack>
|
||||||
|
|
||||||
|
<VStack align="start">
|
||||||
|
<Heading size="md">Shared Rooms</Heading>
|
||||||
|
{sharedRooms.length > 0 ? (
|
||||||
|
sharedRooms.map((roomData) => (
|
||||||
|
<Card w={"full"} key={roomData.id}>
|
||||||
|
<CardBody>
|
||||||
|
<Flex align={"center"}>
|
||||||
|
<Heading size="md">
|
||||||
|
<Link href={`/${roomData.name}`}>{roomData.name}</Link>
|
||||||
|
</Heading>
|
||||||
|
<Spacer />
|
||||||
|
{linkCopied === roomData.name ? (
|
||||||
|
<Text mr={2} color="green.500">
|
||||||
|
Link copied!
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
<IconButton
|
||||||
|
aria-label="Copy URL"
|
||||||
|
icon={<FaLink />}
|
||||||
|
onClick={() => handleCopyUrl(roomData.name)}
|
||||||
|
mr={2}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Menu closeOnSelect={true}>
|
||||||
|
<MenuButton
|
||||||
|
as={IconButton}
|
||||||
|
icon={<FaEllipsisVertical />}
|
||||||
|
aria-label="actions"
|
||||||
|
/>
|
||||||
|
<MenuList>
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => handleEditRoom(roomData.id, roomData)}
|
||||||
|
icon={<FaPencil />}
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => handleDeleteRoom(roomData.id)}
|
||||||
|
icon={<FaTrash color={"red.500"} />}
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</MenuItem>
|
||||||
|
</MenuList>
|
||||||
|
</Menu>
|
||||||
|
</Flex>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<Text>No shared rooms found</Text>
|
||||||
)}
|
)}
|
||||||
</VStack>
|
</VStack>
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@@ -736,6 +736,10 @@ export const $Room = {
|
|||||||
type: "string",
|
type: "string",
|
||||||
title: "Recording Trigger",
|
title: "Recording Trigger",
|
||||||
},
|
},
|
||||||
|
is_shared: {
|
||||||
|
type: "boolean",
|
||||||
|
title: "Is Shared",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
type: "object",
|
type: "object",
|
||||||
required: [
|
required: [
|
||||||
@@ -750,6 +754,7 @@ export const $Room = {
|
|||||||
"room_mode",
|
"room_mode",
|
||||||
"recording_type",
|
"recording_type",
|
||||||
"recording_trigger",
|
"recording_trigger",
|
||||||
|
"is_shared",
|
||||||
],
|
],
|
||||||
title: "Room",
|
title: "Room",
|
||||||
} as const;
|
} as const;
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ export type Room = {
|
|||||||
room_mode: string;
|
room_mode: string;
|
||||||
recording_type: string;
|
recording_type: string;
|
||||||
recording_trigger: string;
|
recording_trigger: string;
|
||||||
|
is_shared: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RtcOffer = {
|
export type RtcOffer = {
|
||||||
|
|||||||
Reference in New Issue
Block a user