Skip to content
Permalink
Browse files

elm(crowd-map-filter): transfer crowd map filter to elm

  • Loading branch information...
AkkarinForest committed Feb 21, 2019
1 parent e14b1c0 commit d9c2f60280013e399187586dd8b77b3330bfe9fa
@@ -187,6 +187,12 @@ http-spinner {
}
}

.crowd-map-slider {
margin-left:10px;
margin-right:10px;
width: 85%;
}

.legend {
margin:0;
padding:20px 0 0;
@@ -1,4 +1,5 @@
import _ from 'underscore';
import { Elm } from '../../../elm/src/Main.elm';

export const MobileSessionsMapCtrl = (
$scope,
@@ -60,9 +61,6 @@ export const MobileSessionsMapCtrl = (
crowdMap: false,
});

$scope.minResolution = 10;
$scope.maxResolution = 50;

if (!params.get('data').heat) sensors.fetchHeatLevels();

storage.updateFromDefaults();
@@ -109,4 +107,27 @@ export const MobileSessionsMapCtrl = (
}, true);

$scope.setDefaults();

if (process.env.NODE_ENV !== 'test') {
angular.element(document).ready(function () {
const node = document.getElementById('crowdMapLayer');

const flags = {
isCrowdMapOn: $scope.params.get('data').crowdMap || false,
crowdMapResolution: $scope.params.get('data').gridResolution || 25,
}

const elmApp = Elm.Main.init({ node: node, flags: flags });

elmApp.ports.toggleCrowdMap.subscribe(() => {
storage.toggleCrowdMapData();
$scope.sessions.fetch();
});

elmApp.ports.updateResolutionPort.subscribe((newResolution) => {
storage.updateCrowdMapResolution(newResolution);
sessionsUtils.updateCrowdMapLayer($scope.sessions.allSessionIds());
});
});
}
}
@@ -43,7 +43,7 @@ export const storage = (params, $rootScope, utils) => {
}
params.update({data: obj});
},
updateCrowdMapLayer: function() {
updateCrowdMapDataInParams: function() {
params.update({
data: {
...this.data,
@@ -70,11 +70,6 @@ export const storage = (params, $rootScope, utils) => {
this.data.location = { ...this.data.location, address: '' };
this.update('location');
},
resetCrowdMapLayer: function() {
this.data.gridResolution = this.defaults.gridResolution;
this.data.crowdMap = this.defaults.crowdMap;
this.updateCrowdMapLayer();
},
updateDefaults: function(newData) {
this.defaults = utils.merge(this.defaults, newData);
},
@@ -89,8 +84,15 @@ export const storage = (params, $rootScope, utils) => {
},
isCrowdMapLayerOn: function() {
return this.data.crowdMap;
},
toggleCrowdMapData: function() {
this.set("crowdMap",!this.isCrowdMapLayerOn());
this.updateCrowdMapDataInParams();
},
updateCrowdMapResolution: function(newResolution) {
this.set("gridResolution", newResolution);
this.updateCrowdMapDataInParams();
}
};
return new Storage();
}

@@ -3,10 +3,6 @@ angular.module("aircasting").factory('storageEvents', ['storage', '$rootScope',
var StorageEvents = function() {};
var self;
StorageEvents.prototype = {
onResolutionSlide : function(event, ui) {
storage.set("gridResolution", ui.value);
$rootScope.$digest();
},
onMonthDaySlide : function(event, ui) {
storage.setInHash("time", "dayFrom", _.min(ui.values));
storage.setInHash("time", "dayTo", _.max(ui.values));
@@ -1,6 +1,7 @@
import test from 'blue-tape';
import { mock } from './helpers';
import { storage } from '../code/services/_storage';
import sinon from 'sinon';

test('resetAddress calls params.update with emptied address', t => {
const params = mock('update');
@@ -25,39 +26,35 @@ test('isCrowdMapLayerOn', t => {
t.end();
});

test('updateCrowdMapLayer updates params preserving old values', t => {
test('updateCrowdMapDataInParams updates params preserving old values', t => {
const params = mock('update');
const service = _storage({ params });
service.set('crowdMap', true);
service.set('gridResolution', 1);
service.set('heat', {});

const actual = service.updateCrowdMapLayer();
const actual = service.updateCrowdMapDataInParams();

const expected = { data: { gridResolution: 1, crowdMap: true, heat: {} } };
t.true(params.wasCalledWith(expected));

t.end();
});

test('resetCrowdMapLayer resets to defaults and calls updateCrowdMapLayer', t => {
const params = mock('update');
test('toggleCrowdMapData toggles crowdMap value in params and crowdMap value in storage', t => {
const update = sinon.spy();
const params = { update };
const service = _storage({ params });
service.updateDefaults({
gridResolution: 2,
crowdMap: false,
});
service.set('crowdMap', true);
service.set('gridResolution', 1);
service.set('crowdMap', false);

const actual = service.resetCrowdMapLayer();
service.toggleCrowdMapData();

const expected = { data: { gridResolution: 2, crowdMap: false, heat: {} } };
t.true(params.wasCalledWith(expected));
const expected = { data: { gridResolution: undefined, crowdMap: true, heat: {}}};
t.true(update.calledWith(expected));
t.true(service.get('crowdMap'));

t.end();
});

const _storage = ({ params }) => {
const $rootScope = { $new: () => ({ $watch: () => {} }) };
const utils = {
@@ -1 +1,134 @@
module Main exposing (..)
port module Main exposing (Msg(..), defaultModel, update, view)

import Browser
import Html exposing (Html, div, input, label, p, span, text)
import Html.Attributes exposing (checked, class, for, id, max, min, type_, value)
import Html.Events exposing (on, onClick, targetValue)
import Json.Decode



---- MODEL ----


type alias Model =
{ crowdMapResolution : Int
, isCrowdMapOn : Bool
}


type alias Flags =
{ crowdMapResolution : Int
, isCrowdMapOn : Bool
}


init : Flags -> ( Model, Cmd Msg )
init flags =
( { defaultModel
| isCrowdMapOn = flags.isCrowdMapOn
, crowdMapResolution = flags.crowdMapResolution
}
, Cmd.none
)


defaultModel : Model
defaultModel =
{ crowdMapResolution = 25
, isCrowdMapOn = False
}



---- UPDATE ----


port toggleCrowdMap : () -> Cmd a


port updateResolutionPort : Int -> Cmd a


type Msg
= ToggleCrowdMap
| UpdateCrowdMapResolution Int


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
ToggleCrowdMap ->
( { model | isCrowdMapOn = not model.isCrowdMapOn }, toggleCrowdMap () )

UpdateCrowdMapResolution resolution ->
( { model | crowdMapResolution = resolution }, updateResolutionPort resolution )



---- VIEW ----


view : Model -> Html Msg
view model =
div []
[ viewCrowdMapCheckBox model.isCrowdMapOn
, viewCrowdMapSlider (String.fromInt model.crowdMapResolution)
]


viewCrowdMapCheckBox : Bool -> Html Msg
viewCrowdMapCheckBox isCrowdMapOn =
div [ class "textfield" ]
[ p []
[ input
[ id "checkbox-crowd-map"
, type_ "checkbox"
, checked isCrowdMapOn
, onClick ToggleCrowdMap
]
[]
, label [ for "checkbox-crowd-map" ]
[ text "Crowd Map" ]
]
]


viewCrowdMapSlider : String -> Html Msg
viewCrowdMapSlider resolution =
div [ id "crowd-map-slider" ]
[ p []
[ text "Resolution" ]
, div []
[ input
[ class "crowd-map-slider"
, onChange (String.toInt >> Maybe.withDefault 25 >> UpdateCrowdMapResolution)
, value resolution
, max "50"
, min "10"
, type_ "range"
]
[]
, span []
[ text resolution ]
]
]


onChange : (String -> msg) -> Html.Attribute msg
onChange tagger =
on "change" (Json.Decode.map tagger Html.Events.targetValue)



---- PROGRAM ----


main : Program Flags Model Msg
main =
Browser.element
{ view = view
, init = init
, update = update
, subscriptions = \_ -> Sub.none
}

0 comments on commit d9c2f60

Please sign in to comment.
You can’t perform that action at this time.