added basic online list

pull/3/head
Simon Huang 6 years ago
parent 1017155720
commit e28f849632

@ -60,6 +60,7 @@ const turtle = {
userId: {
name: 'Username',
},
userCount: 0,
},
},
};

@ -9,32 +9,34 @@ ion-textarea {
margin: 0;
}
.message-toolbar {
padding-left: 5px;
}
.footer-ios ion-toolbar:first-of-type {
padding-top: 5px;
}
.send-msg {
align-items: center;
justify-content: center;
display: flex;
padding-left: 0;
}
.send-button {
width: 100%;
}
.message-col {
white-space: normal;
padding: 10px;
align-self: center;
margin: 0 2px 0 5px;
}
.message-input {
width: 100%;
height: 100%;
border: 1px solid #999;
border-radius: 5px;
text-align: left;
}
@media (max-width: 576px) {
.message-input {
border-radius: 10px;
height: 35px;
}
.send-msg {

@ -1,16 +1,19 @@
import { IonButton, IonCard, IonCol, IonFooter, IonInput, IonRow } from '@ionic/react';
import { IonCard, IonFabButton, IonFooter, IonIcon, IonInput, IonToolbar } from '@ionic/react';
import { sendOutline } from 'ionicons/icons';
import React, { useState } from 'react';
import { db, timestamp } from '../services/firebase';
import './Chatbox.css';
import Messages from './Messages';
import OnlineList from './OnlineList';
type ChatboxProps = {
ownerId: string;
roomId: string;
userId: string;
userList: string[];
};
const Chat: React.FC<ChatboxProps> = ({ ownerId, roomId, userId }) => {
const Chat: React.FC<ChatboxProps> = ({ ownerId, roomId, userId, userList }) => {
const [message, setMessage] = useState(''); // Message to be sent
// Send message to database
@ -38,23 +41,20 @@ const Chat: React.FC<ChatboxProps> = ({ ownerId, roomId, userId }) => {
<IonCard class="chat-card">
<Messages ownerId={ownerId} roomId={roomId} userId={userId}></Messages>
<IonFooter>
<IonRow>
<IonCol size="12" sizeSm="9" class="message-col">
<IonInput
onIonChange={(e) => setMessage(e.detail.value!)}
onKeyDown={(e) => onEnter(e)}
value={message}
placeholder="Send message"
enterkeyhint="send"
class="message-input"
></IonInput>
</IonCol>
<IonCol size="3" class="send-msg">
<IonButton expand="block" color="primary" onClick={sendMessage} class="send-button">
Send
</IonButton>
</IonCol>
</IonRow>
<IonToolbar class="message-toolbar">
<IonInput
onIonChange={(e) => setMessage(e.detail.value!)}
onKeyDown={(e) => onEnter(e)}
value={message}
placeholder="Send message"
enterkeyhint="send"
class="message-input"
></IonInput>
<IonFabButton slot="end" size="small" onClick={sendMessage} class="send-button">
<IonIcon icon={sendOutline}></IonIcon>
</IonFabButton>
<OnlineList userList={userList}></OnlineList>
</IonToolbar>
</IonFooter>
</IonCard>
);

@ -0,0 +1,32 @@
.online-button {
margin: 0 4px 0 0;
align-self: center;
}
.popover-list {
padding-top: 2px;
}
.online-popover .popover-content {
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
}
.list-header {
font-size: 24px;
color: var(--ion-color-primary);
border-bottom: 1px solid #999;
}
.online-item {
--padding-start: 12px;
--min-height: 0;
}
.online-label {
margin-top: 8px;
margin-bottom: 0;
}
ion-backdrop {
cursor: default;
}

@ -0,0 +1,48 @@
import React, { useState } from 'react';
import { IonPopover, IonFabButton, IonIcon, IonList, IonListHeader, IonItem, IonLabel } from '@ionic/react';
import { peopleOutline } from 'ionicons/icons';
import './OnlineList.css';
type OnlineListProps = {
userList: string[];
};
const OnlineList: React.FC<OnlineListProps> = ({ userList }) => {
const [showPopover, setShowPopover] = useState<{ open: boolean; event: Event | undefined }>({
open: false,
event: undefined,
});
return (
<>
<IonPopover
cssClass="online-popover"
isOpen={showPopover.open}
event={showPopover.event}
showBackdrop={false}
onDidDismiss={(e) => setShowPopover({ open: false, event: undefined })}
>
<IonList class="popover-list">
<IonListHeader class="list-header">Online</IonListHeader>
{userList.map((user) => {
return (
<IonItem key={user} class="online-item" lines="none">
<IonLabel class="online-label">{user}</IonLabel>
</IonItem>
);
})}
</IonList>
</IonPopover>
<IonFabButton
slot="end"
size="small"
class="online-button"
onClick={(e) => setShowPopover({ open: true, event: e.nativeEvent })}
>
<IonIcon icon={peopleOutline}></IonIcon>
</IonFabButton>
</>
);
};
export default OnlineList;

@ -19,6 +19,7 @@ const Room: React.FC<RouteComponentProps<{ roomId: string }>> = ({ match }) => {
const [userCount, setUserCount] = useState(0);
const [videoId, setVideoId] = useState('');
const [stateId, setStateId] = useState('');
const [userList, setUserList] = useState<string[]>(['']);
// Verify that the roomId exists in db
useEffect(() => {
@ -73,9 +74,19 @@ const Room: React.FC<RouteComponentProps<{ roomId: string }>> = ({ match }) => {
// Keep track of online user presence in realtime database rooms
roomRef.on('value', async (snapshot) => {
// Populate list of users in a room
const set: string[] = [];
snapshot.forEach((childSnapshot) => {
if (childSnapshot.key !== 'userCount') {
set.push(childSnapshot.child('name').val());
}
});
setUserList(set);
if (!snapshot.hasChild(userId)) {
// Keep userId in the room as long as a connection from the client exists
await roomRef.child(userId).set({ name: 'placeholder' });
const username = (await db.collection('users').doc(userId).get()).data()?.name;
await roomRef.child(userId).set({ name: username });
await roomRef.update({ userCount: increment });
}
});
@ -154,7 +165,7 @@ const Room: React.FC<RouteComponentProps<{ roomId: string }>> = ({ match }) => {
<VideoPlayer ownerId={ownerId} userId={userId} roomId={roomId} stateId={stateId}></VideoPlayer>
</IonCol>
<IonCol size="12" sizeLg="3" class="chat-col">
<Chat ownerId={ownerId} roomId={roomId} userId={userId}></Chat>
<Chat ownerId={ownerId} roomId={roomId} userId={userId} userList={userList}></Chat>
</IonCol>
</IonRow>
</IonGrid>

Loading…
Cancel
Save