IanGallacher/SC2-AI-Website

View on GitHub
client-src/js/component/alert.jsx

Summary

Maintainability
A
2 hrs
Test Coverage
import React from "react";
import PropTypes from "prop-types";

import AlertLogic from "./../logic/alert.js";

class Alert extends React.Component {
  constructor() {
    super();
    this.state = {visable: false};
  }

  static propTypes = {
    invisable: PropTypes.bool
  }

  componentDidMount() {
    // Creates the element with 0 opacity.
    // Once visable is true, we transition to 1 opacity.
    setTimeout(() => this.setState({visable: true}), 0);
  }

  render() {
    let props = this.props;
    let visable = this.state.visable ? " alert-visable" : "";
    if(this.props.invisable) visable = "";
    return (
      <div className={props.cssClass + visable}
        onClick={() => AlertLogic.removeAlertWithId(props.id) }>
        <div className="alert-text">
          {props.message}
        </div>
      </div>
    );
  }
}

export default class AlertZone extends React.Component {
  constructor(props) {
    super(props);
    this.state = { messages: props.messages, destroying: [] };
  }

  static propTypes = {
    invisable: PropTypes.bool,
    messages: PropTypes.array
  }

  UNSAFE_componentWillReceiveProps(props) {
    // If the prop has removed the element, update the state
    for(let message of this.state.messages) {
      if(!props.messages.find(e => e.id === message.id))
        this._deleteMessage(message);
    }
    for(let message of props.messages) {
      if(!this.state.messages.find(e => e.id === message.id)) {
        this.state.messages.push(message);
        this.setState({ messages:  this.state.messages });
      }
    }
  }

  _deleteMessage(mess) {
    this.setState( {destroying: this.state.destroying.concat([mess.id])} );
    setTimeout(() => this.setState({
      messages: this.state.messages.filter(e => e != mess),
      destroying: this.state.destroying.filter(ele => ele === mess.id)
    }), 200);
  }

  render() {
    return <div className="alert-zone">
      {
        this.state.messages.slice(0).reverse().map((message) =>
          <Alert key={message.id}
            id={message.id}
            invisable={(this.state.destroying.indexOf(message.id) > -1)}
            cssClass={message.cssClass}
            message={message.message}/>
        )
      }
    </div>;
  }
}