Skip to content
Snippets Groups Projects
Commit faaef841 authored by Joni Laukka's avatar Joni Laukka
Browse files

Notifications and notification popup

parent 47aeec0e
No related branches found
No related tags found
4 merge requests!46Development to testing,!41Notifications + small updates,!39Notification view,!32Notification view
This commit is part of merge request !41. Comments created here will be created in the context of that merge request.
...@@ -13,7 +13,7 @@ body { ...@@ -13,7 +13,7 @@ body {
/* UserMap */ /* UserMap */
.map { .map {
position: absolute; position: absolute;
margin-top: 50px; /* margin-top: 50px; */
height: 95vh; height: 95vh;
width: 100vw; width: 100vw;
} }
...@@ -233,3 +233,17 @@ div.login button:hover { ...@@ -233,3 +233,17 @@ div.login button:hover {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.notification-popup {
position: absolute;
z-index: 1010;
}
.notification-popup.warning {
background-color: yellow;
color: black;
}
.notification-popup.alert {
background-color: red;
}
...@@ -64,7 +64,6 @@ export default class GameView extends React.Component { ...@@ -64,7 +64,6 @@ export default class GameView extends React.Component {
handleLeaveFaction = e => { handleLeaveFaction = e => {
let token = sessionStorage.getItem("token"); let token = sessionStorage.getItem("token");
let error = false;
fetch( fetch(
`${process.env.REACT_APP_API_URL}/faction/leave/${ `${process.env.REACT_APP_API_URL}/faction/leave/${
this.state.gameInfo.id this.state.gameInfo.id
...@@ -78,7 +77,6 @@ export default class GameView extends React.Component { ...@@ -78,7 +77,6 @@ export default class GameView extends React.Component {
) )
.then(res => { .then(res => {
if (!res.ok) { if (!res.ok) {
error = true;
} }
return res.json(); return res.json();
}) })
...@@ -91,7 +89,6 @@ export default class GameView extends React.Component { ...@@ -91,7 +89,6 @@ export default class GameView extends React.Component {
// setting the socket signal automatically fires shouldComponentUpdate function where socketSignal prop is present // setting the socket signal automatically fires shouldComponentUpdate function where socketSignal prop is present
// setting socketSignal to null immediately after to avoid multiple database fetches // setting socketSignal to null immediately after to avoid multiple database fetches
getSocketSignal = data => { getSocketSignal = data => {
console.log(data);
this.setState( this.setState(
{ {
socketSignal: data socketSignal: data
...@@ -112,7 +109,6 @@ export default class GameView extends React.Component { ...@@ -112,7 +109,6 @@ export default class GameView extends React.Component {
render() { render() {
const initialPosition = [this.state.lat, this.state.lng]; const initialPosition = [this.state.lat, this.state.lng];
return ( return (
<div> <div>
<Link to="/"> <Link to="/">
...@@ -186,13 +182,11 @@ export default class GameView extends React.Component { ...@@ -186,13 +182,11 @@ export default class GameView extends React.Component {
zoom={this.state.zoom} zoom={this.state.zoom}
mapUrl={this.state.mapUrl} mapUrl={this.state.mapUrl}
currentGameId={this.state.gameInfo.id} currentGameId={this.state.gameInfo.id}
socketSignal={ socketSignal={this.state.socketSignal}
this.state.socketSignal !== null >
? this.state.socketSignal <NotificationPopup socketSignal={this.state.socketSignal} />
: null </UserMap>
}
/>
<NotificationPopup socketSignal={this.state.socketSignal} />
{this.state.form === "edit" && ( {this.state.form === "edit" && (
<EditGameForm <EditGameForm
gameId={this.state.gameInfo.id} gameId={this.state.gameInfo.id}
...@@ -221,6 +215,12 @@ export default class GameView extends React.Component { ...@@ -221,6 +215,12 @@ export default class GameView extends React.Component {
gameId={this.state.gameInfo.id} gameId={this.state.gameInfo.id}
toggleView={() => this.setState({ form: "" })} toggleView={() => this.setState({ form: "" })}
socket={this.state.socket} socket={this.state.socket}
role={this.state.role}
gameState={
this.state.gameInfo !== undefined
? this.state.gameInfo.state
: ""
}
/> />
)} )}
</div> </div>
......
import React from "react";
export default class NotificationCard extends React.Component {
render() {
return (
<div>
{this.props.notification.type} : {this.props.notification.message}
</div>
);
}
}
import React from "react"; import React from "react";
export default class NotificationPopup extends React.Component { export default class NotificationPopup extends React.Component {
state = {
lastNotification: null,
visible: true
};
componentDidUpdate(prevProps, prevState) { componentDidUpdate(prevProps, prevState) {
if (prevProps.socketSignal === "alert") { if (
console.log("alert"); prevProps.socketSignal !== null &&
} prevProps.socketSignal !== this.state.lastNotification
if (prevProps.socketSignal === "note") { ) {
console.log("note"); if (prevProps.socketSignal.type === "alert") {
this.setState({
lastNotification: prevProps.socketSignal,
visible: true
});
}
if (prevProps.socketSignal.type === "note") {
this.setState({
lastNotification: prevProps.socketSignal,
visible: true
});
}
} }
} }
render() { render() {
if (this.state.lastNotification !== null && this.state.visible) {
return (
<div
className={
this.state.lastNotification.type === "alert"
? "notification-popup alert"
: "notification-popup warning"
}
>
<button
onClick={() => {
this.setState({ visible: false });
}}
>
Close
</button>
<br />
<label>
{this.state.lastNotification.type === "alert" ? "ALERT" : "Note"}
</label>
<p>{this.state.lastNotification.message}</p>
</div>
);
}
return false; return false;
} }
} }
import React from "react"; import React from "react";
import NotificationCard from "./NotificationCard";
export default class NotificationView extends React.Component { export default class NotificationView extends React.Component {
state = { state = {
notifications: [], notifications: [],
notificationInput: "" notificationInput: "",
notificationTypeInput: "note"
}; };
componentDidMount() { componentDidMount() {
...@@ -19,39 +21,59 @@ export default class NotificationView extends React.Component { ...@@ -19,39 +21,59 @@ export default class NotificationView extends React.Component {
}) })
.then(res => res.json()) .then(res => res.json())
.then(res => { .then(res => {
console.log(res); this.setState({ notifications: res.reverse() });
//this.setState({ notifications: res });
}); });
} }
handleSend = e => { handleSend = e => {
e.preventDefault(); e.preventDefault();
console.log(this.props.socket); if (this.state.notificationInput === "") {
alert("notification message can't be empty");
this.props.socket.emit(this.props.gameId, { } else {
type: "alert", this.props.socket.emit("game-info", {
message: "asd" type: this.state.notificationTypeInput,
}); message: this.state.notificationInput,
game: this.props.gameId
});
this.getNotifications(this.props.gameId);
this.setState({ notificationInput: "" });
}
}; };
render() { render() {
let notifications = this.state.notifications.map(notification => (
<NotificationCard key={notification.id} notification={notification} />
));
return ( return (
<div className="fade-main"> <div className="fade-main">
<button onClick={() => this.props.toggleView()}>Close</button> <button onClick={() => this.props.toggleView()}>Close</button>
<div> <div>
<form onSubmit={this.handleSend}> {this.props.role === "admin" && this.props.gameState !== "ENDED" && (
<input <form onSubmit={this.handleSend}>
type="text" <select
value={this.state.notificationInput} value={this.state.notificationTypeInput}
onChange={e => onChange={e =>
this.setState({ notificationInput: e.target.value }) this.setState({ notificationTypeInput: e.target.value })
} }
placeholder="Notification text..." >
/> <option value="note">Note</option>
<button type="submit">Send Notification</button> <option value="alert">Alert</option>
</form> </select>
<input
type="text"
value={this.state.notificationInput}
onChange={e =>
this.setState({ notificationInput: e.target.value })
}
placeholder="Notification message..."
/>
<button type="submit">Send Notification</button>
</form>
)}
</div> </div>
{notifications}
</div> </div>
); );
} }
......
...@@ -17,7 +17,7 @@ export default class ClientSocket extends React.Component { ...@@ -17,7 +17,7 @@ export default class ClientSocket extends React.Component {
// initiate the socket on component mount // initiate the socket on component mount
async componentWillMount() { async componentWillMount() {
console.log("hi socket"); // console.log("hi socket");
// need to explicitly update drawings and trackings when gameID first becomes available // need to explicitly update drawings and trackings when gameID first becomes available
if (this.props.gameId !== null) { if (this.props.gameId !== null) {
await this.props.getSocketSignal("drawing-update"); await this.props.getSocketSignal("drawing-update");
...@@ -38,7 +38,7 @@ export default class ClientSocket extends React.Component { ...@@ -38,7 +38,7 @@ export default class ClientSocket extends React.Component {
// disconnect the socket on component dismount // disconnect the socket on component dismount
componentWillUnmount() { componentWillUnmount() {
console.log("bye socket"); // console.log("bye socket");
this.state.sock.disconnect(); this.state.sock.disconnect();
} }
...@@ -47,7 +47,6 @@ export default class ClientSocket extends React.Component { ...@@ -47,7 +47,6 @@ export default class ClientSocket extends React.Component {
// set the socket to listen gameId-thread // set the socket to listen gameId-thread
socket.on(this.props.gameId, data => { socket.on(this.props.gameId, data => {
console.log("on " + data);
this.props.getSocketSignal(data); this.props.getSocketSignal(data);
// check socket update type // check socket update type
this.setState({ update: data.type }); this.setState({ update: data.type });
......
...@@ -149,38 +149,41 @@ class UserMap extends Component { ...@@ -149,38 +149,41 @@ class UserMap extends Component {
render() { render() {
return ( return (
<Map <div>
className="map" <Map
center={this.props.position} className="map"
zoom={this.props.zoom} center={this.props.position}
minZoom="7" zoom={this.props.zoom}
maxZoom="17" minZoom="7"
zoomControl={false} maxZoom="17"
> zoomControl={false}
<TileLayer >
attribution='&copy; <a href="https://www.maanmittauslaitos.fi/">Maanmittauslaitos</a>' <TileLayer
url={this.props.mapUrl} attribution='&copy; <a href="https://www.maanmittauslaitos.fi/">Maanmittauslaitos</a>'
/> url={this.props.mapUrl}
<ZoomControl position="topright" /> />
<DrawTools <ZoomControl position="topright" />
position={this.props.position} <DrawTools
sendGeoJSON={this.sendGeoJSON} position={this.props.position}
geoJSONLayer={this.state.geoJSONLayer} sendGeoJSON={this.sendGeoJSON}
currentGameId={this.props.currentGameId} geoJSONLayer={this.state.geoJSONLayer}
/> currentGameId={this.props.currentGameId}
{this.state.ownLat !== null && ( />
<Marker position={[this.state.ownLat, this.state.ownLng]}> {this.state.ownLat !== null && (
<Popup> <Marker position={[this.state.ownLat, this.state.ownLng]}>
User's real position. <Popup>
<br /> User's real position.
</Popup> <br />
</Marker> </Popup>
)} </Marker>
<Player )}
currentGameId={this.props.currentGameId} <Player
socketSignal={this.props.socketSignal} currentGameId={this.props.currentGameId}
/> socketSignal={this.props.socketSignal}
</Map> />
</Map>
{this.props.children}
</div>
); );
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment