All files index.js

87.5% Statements 49/56
87.1% Branches 27/31
69.23% Functions 9/13
88.89% Lines 48/54

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109          1x       25x 18x   7x   25x 18x   7x   25x 18x   7x   25x 25x 25x 25x     25x                             25x       25x 2x   2x 1x   1x     2x   2x     25x 2x 1x       25x 5x 1x     4x 1x   3x     3x   3x 1x 1x 1x 1x   2x     25x 7x 3x   4x     25x 3x     25x 7x     25x    
export class Seismograph {
  constructor(
    { minShakes, minAmplitude, onShake, delay } = {
      minShakes: 3,
      minAmplitude: 3,
      onShake: () => "EAAAARTHQUAAAAKEEE!",
      delay: 1500
    }
  ) {
    if (typeof minShakes === "number" && minShakes > 0) {
      this.minShakes = minShakes;
    } else {
      this.minShakes = 3;
    }
    if (typeof minAmplitude === "number" && minAmplitude > 0) {
      this.minAmplitude = minAmplitude;
    } else {
      this.minAmplitude = 3;
    }
    if (typeof onShake === "function") {
      this.onShake = onShake;
    } else {
      this.onShake = () => "EAAAARTHQUAAAAKEEE!";
    }
    this.delay = delay > 0 ? delay : 1500;
    this.currentShakes = 0;
    this.lastShake = Date.now();
    this.previousX = null;
  }
 
  startRecording = () => {
    if (typeof DeviceMotionEvent.requestPermission === 'function') {
      // iOS 13+
      DeviceMotionEvent.requestPermission()
        .then(response => {
          if (response == 'granted') {
            window.addEventListener("devicemotion", this._onMotionEvent);
          }
        })
        .catch(console.error)
    } else {
      window.addEventListener("devicemotion", this._onMotionEvent);
    }
  };
 
  stopRecording = () => {
    window.removeEventListener("devicemotion", this._onMotionEvent);
  };
 
  _onMotionEvent = event => {
    let x = null;
 
    if ("acceleration" in event) {
      x = event.acceleration.x;
    } else {
      x = event.accelerationIncludingGravity.x;
    }
 
    this._initValues(x);
 
    this._detectShake(x, this.previousX);
  };
 
  _initValues = x => {
    if (!this.previousX) {
      this.previousX = x;
    }
  };
 
  _detectShake = (current, previous) => {
    if (this._belowTimeThreshold()) {
      return false;
    }
 
    if (!this._checkAmplitude(current, previous)) {
      return false;
    } else {
      ++this.currentShakes;
    }
 
    previous = current;
 
    if (this._shakeThresholdReached()) {
      this.currentShakes = 0;
      this.lastShake = this._currentDate();
      this.onShake();
      return true;
    }
    return false;
  };
 
  _checkAmplitude = (current, previous) => {
    if (Math.sign(current) === Math.sign(previous) || Math.abs(current) < this.minAmplitude) {
      return false;
    }
    return true;
  }
 
  _shakeThresholdReached = () => {
    return this.currentShakes > this.minShakes;
  };
 
  _belowTimeThreshold = () => {
    return this._currentDate() - this.lastShake < this.delay;
  };
 
  _currentDate = () => Date.now();
}