From 464b0b2acad03df369351d0478f76e8b802435e6 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Mon, 26 Sep 2016 16:25:38 -0400 Subject: [PATCH] Fix issues with walkthrough --- modules/ui/intro/area.js | 16 +++++++++++-- modules/ui/intro/helper.js | 2 ++ modules/ui/intro/intro.js | 38 ++++++++++++++++++++----------- modules/ui/intro/line.js | 20 +++++++++++++--- modules/ui/intro/navigation.js | 21 ++++++++++++++--- modules/ui/intro/point.js | 18 ++++++++++++++- modules/ui/intro/start_editing.js | 24 ++++++++++++------- 7 files changed, 109 insertions(+), 30 deletions(-) diff --git a/modules/ui/intro/area.js b/modules/ui/intro/area.js index 4b7a8f596..048528e74 100644 --- a/modules/ui/intro/area.js +++ b/modules/ui/intro/area.js @@ -1,8 +1,10 @@ import * as d3 from 'd3'; import { rebind } from '../../util/rebind'; +import { bindOnce } from '../../util/bind_once'; import { t } from '../../util/locale'; import { icon, pad } from './helper'; + export function area(context, reveal) { var dispatch = d3.dispatch('done'), timeout; @@ -11,6 +13,7 @@ export function area(context, reveal) { title: 'intro.areas.title' }; + step.enter = function() { var playground = [-85.63552, 41.94159], corner = [-85.63565411045074, 41.9417715536927]; @@ -21,6 +24,7 @@ export function area(context, reveal) { context.on('enter.intro', addArea); + function addArea(mode) { if (mode.id !== 'add-area') return; context.on('enter.intro', drawArea); @@ -36,6 +40,7 @@ export function area(context, reveal) { }); } + function drawArea(mode) { if (mode.id !== 'draw-area') return; context.on('enter.intro', enterSelect); @@ -51,6 +56,7 @@ export function area(context, reveal) { }); } + function enterSelect(mode) { if (mode.id !== 'select') return; context.map().on('move.intro', null); @@ -64,22 +70,27 @@ export function area(context, reveal) { }, 500); } + function keySearch() { var first = d3.select('.preset-list-item:first-child'); if (first.classed('preset-leisure-playground')) { reveal(first.select('.preset-list-button').node(), t('intro.areas.choose')); - d3.selection.prototype.one.call(context.history(), 'change.intro', selectedPreset); + bindOnce(context.history(), 'change.intro', selectedPreset); d3.select('.preset-search-input').on('keyup.intro', null); } } + function selectedPreset() { reveal('.pane', t('intro.areas.describe', { button: icon('#icon-apply', 'pre-text') })); - context.on('exit.intro', dispatch.done); + context.on('exit.intro', function() { + dispatch.call('done'); + }); } }; + step.exit = function() { window.clearTimeout(timeout); context.on('enter.intro', null); @@ -89,5 +100,6 @@ export function area(context, reveal) { d3.select('.preset-search-input').on('keyup.intro', null); }; + return rebind(step, dispatch, 'on'); } diff --git a/modules/ui/intro/helper.js b/modules/ui/intro/helper.js index 341e5a74e..cd2942067 100644 --- a/modules/ui/intro/helper.js +++ b/modules/ui/intro/helper.js @@ -9,6 +9,7 @@ export function pointBox(point, context) { }; } + export function pad(box, padding, context) { if (box instanceof Array) { var rect = context.surfaceRect(); @@ -26,6 +27,7 @@ export function pad(box, padding, context) { }; } + export function icon(name, svgklass) { return '' + ''; diff --git a/modules/ui/intro/intro.js b/modules/ui/intro/intro.js index 367929902..db5d078f5 100644 --- a/modules/ui/intro/intro.js +++ b/modules/ui/intro/intro.js @@ -2,19 +2,20 @@ import * as d3 from 'd3'; import { t } from '../../util/locale'; import { Entity, Graph } from '../../core/index'; import { Browse } from '../../modes/index'; -import { area } from './area'; -import { line } from './line'; -import { navigation } from './navigation'; -import { point } from './point'; -import { startEditing } from './start_editing'; import { d3curtain } from '../../util/curtain'; import { default as introGraphRaw } from '../../../data/intro_graph.json'; +import { navigation } from './navigation'; +import { point } from './point'; +import { area } from './area'; +import { line } from './line'; +import { startEditing } from './start_editing'; + var sampleIntros = { - area: area, - line: line, navigation: navigation, point: point, + area: area, + line: line, startEditing: startEditing }; @@ -66,9 +67,11 @@ export function intro(context) { w17967444: 'east_st', w17966984: 'portage_ave' }; + return features[id] && t('intro.graph.' + features[id]); } + var introGraph = {}; for (var key in introGraphRaw) { @@ -79,9 +82,8 @@ export function intro(context) { } } + function intro(selection) { - - context.enter(Browse(context)); // Save current map state @@ -109,10 +111,14 @@ export function intro(context) { var curtain = d3curtain(); selection.call(curtain); + function reveal(box, text, options) { options = options || {}; - if (text) curtain.reveal(box, text, options.tooltipClass, options.duration); - else curtain.reveal(box, '', '', options.duration); + if (text) { + curtain.reveal(box, text, options.tooltipClass, options.duration); + } else { + curtain.reveal(box, '', '', options.duration); + } } var steps = ['navigation', 'point', 'area', 'line', 'startEditing'].map(function(step, i) { @@ -139,9 +145,12 @@ export function intro(context) { context.inIntro(false); }); - var navwrap = selection.append('div').attr('class', 'intro-nav-wrap fillD'); + var navwrap = selection + .append('div') + .attr('class', 'intro-nav-wrap fillD'); - var buttonwrap = navwrap.append('div') + var buttonwrap = navwrap + .append('div') .attr('class', 'joined') .selectAll('button.step'); @@ -163,6 +172,7 @@ export function intro(context) { enter(steps[0]); + function enter(newStep) { if (step) { step.exit(); } @@ -177,5 +187,7 @@ export function intro(context) { } } + + return intro; } diff --git a/modules/ui/intro/line.js b/modules/ui/intro/line.js index 0e3a79870..fed0e8a07 100644 --- a/modules/ui/intro/line.js +++ b/modules/ui/intro/line.js @@ -4,9 +4,9 @@ import { rebind } from '../../util/rebind'; import { bindOnce } from '../../util/bind_once'; import { t } from '../../util/locale'; import { icon, pad } from './helper'; - import { DeleteMultiple } from '../../actions/index'; + export function line(context, reveal) { var dispatch = d3.dispatch('done'), timeouts = []; @@ -15,15 +15,18 @@ export function line(context, reveal) { title: 'intro.lines.title' }; + function timeout(f, t) { timeouts.push(window.setTimeout(f, t)); } + function eventCancel() { d3.event.stopPropagation(); d3.event.preventDefault(); } + step.enter = function() { var centroid = [-85.62830, 41.95699]; var midpoint = [-85.62975395449628, 41.95787501510204]; @@ -37,6 +40,7 @@ export function line(context, reveal) { context.on('enter.intro', addLine); + function addLine(mode) { if (mode.id !== 'add-line') return; context.on('enter.intro', drawLine); @@ -52,6 +56,7 @@ export function line(context, reveal) { }); } + function drawLine(mode) { if (mode.id !== 'draw-line') return; context.history().on('change.intro', addIntersection); @@ -68,6 +73,7 @@ export function line(context, reveal) { }); } + // ended line before creating intersection function retry(mode) { if (mode.id !== 'select') return; @@ -83,6 +89,7 @@ export function line(context, reveal) { }, 3000); } + function addIntersection(changes) { if ( _.some(changes.created(), function(d) { return d.type === 'node' && context.graph().parentWays(d).length > 1; @@ -102,6 +109,7 @@ export function line(context, reveal) { } } + function enterSelect(mode) { if (mode.id !== 'select') return; context.map().on('move.intro', null); @@ -111,6 +119,7 @@ export function line(context, reveal) { presetCategory(); } + function presetCategory() { timeout(function() { d3.select('#curtain').style('pointer-events', 'none'); @@ -120,6 +129,7 @@ export function line(context, reveal) { }, 500); } + function roadCategory() { timeout(function() { var grid = d3.select('.subgrid'); @@ -131,6 +141,7 @@ export function line(context, reveal) { }, 500); } + // selected wrong road type function retryPreset() { timeout(function() { @@ -140,14 +151,17 @@ export function line(context, reveal) { }, 500); } + function roadDetails() { reveal('.pane', t('intro.lines.describe', { button: icon('#icon-apply', 'pre-text') })); - context.on('exit.intro', dispatch.done); + context.on('exit.intro', function() { + dispatch.call('done'); + }); } - }; + step.exit = function() { d3.select(window).on('mousedown.intro', null, true); d3.select('#curtain').style('pointer-events', 'none'); diff --git a/modules/ui/intro/navigation.js b/modules/ui/intro/navigation.js index a14a5a88d..360fcb5d2 100644 --- a/modules/ui/intro/navigation.js +++ b/modules/ui/intro/navigation.js @@ -4,6 +4,7 @@ import { rebind } from '../../util/rebind'; import { t } from '../../util/locale'; import { icon, pointBox } from './helper'; + export function navigation(context, reveal) { var dispatch = d3.dispatch('done'), timeouts = []; @@ -12,15 +13,18 @@ export function navigation(context, reveal) { title: 'intro.navigation.title' }; + function set(f, t) { timeouts.push(window.setTimeout(f, t)); } + function eventCancel() { d3.event.stopPropagation(); d3.event.preventDefault(); } + step.enter = function() { var rect = context.surfaceRect(), map = { @@ -40,10 +44,11 @@ export function navigation(context, reveal) { context.on('enter.intro', inspectTownHall); }, 400)); + function townhall() { var hall = [-85.63645945147184, 41.942986488012565]; - var point = context.projection(hall); + if (point[0] < 0 || point[0] > rect.width || point[1] < 0 || point[1] > rect.height) { context.map().center(hall); @@ -58,6 +63,7 @@ export function navigation(context, reveal) { }); } + function inspectTownHall(mode) { if (mode.id !== 'select') return; context.on('enter.intro', null); @@ -69,13 +75,16 @@ export function navigation(context, reveal) { }, 700); } + function streetSearch() { context.on('exit.intro', null); reveal('.search-header input', t('intro.navigation.search', { name: t('intro.graph.spring_st') })); - d3.select('.search-header input').on('keyup.intro', searchResult); + d3.select('.search-header input') + .on('keyup.intro', searchResult); } + function searchResult() { var first = d3.select('.feature-list-item:nth-child(0n+2)'), // skip No Results item firstName = first.select('.entity-name'), @@ -90,10 +99,14 @@ export function navigation(context, reveal) { } } + function selectedStreet() { var springSt = [-85.63585099140167, 41.942506848938926]; context.map().center(springSt); - context.on('exit.intro', dispatch.done); + context.on('exit.intro', function() { + dispatch.call('done'); + }); + set(function() { reveal('.entity-editor-pane', t('intro.navigation.chosen', { @@ -104,6 +117,7 @@ export function navigation(context, reveal) { } }; + step.exit = function() { timeouts.forEach(window.clearTimeout); context.map().on('move.intro', null); @@ -114,5 +128,6 @@ export function navigation(context, reveal) { .on('keyup.intro', null); }; + return rebind(step, dispatch, 'on'); } diff --git a/modules/ui/intro/point.js b/modules/ui/intro/point.js index 23ba4c15f..05afbf724 100644 --- a/modules/ui/intro/point.js +++ b/modules/ui/intro/point.js @@ -1,8 +1,10 @@ import * as d3 from 'd3'; +import { bindOnce } from '../../util/bind_once'; import { rebind } from '../../util/rebind'; import { t } from '../../util/locale'; import { icon, pad } from './helper'; + export function point(context, reveal) { var dispatch = d3.dispatch('done'), timeouts = []; @@ -11,15 +13,18 @@ export function point(context, reveal) { title: 'intro.points.title' }; + function setTimeout(f, t) { timeouts.push(window.setTimeout(f, t)); } + function eventCancel() { d3.event.stopPropagation(); d3.event.preventDefault(); } + step.enter = function() { context.map().centerZoom([-85.63279, 41.94394], 19); reveal('button.add-point', @@ -30,6 +35,7 @@ export function point(context, reveal) { context.on('enter.intro', addPoint); + function addPoint(mode) { if (mode.id !== 'add-point') return; context.on('enter.intro', enterSelect); @@ -43,6 +49,7 @@ export function point(context, reveal) { }); } + function enterSelect(mode) { if (mode.id !== 'select') return; context.map().on('move.intro', null); @@ -55,17 +62,19 @@ export function point(context, reveal) { }, 500); } + function keySearch() { var first = d3.select('.preset-list-item:first-child'); if (first.classed('preset-amenity-cafe')) { reveal(first.select('.preset-list-button').node(), t('intro.points.choose')); - d3.selection.prototype.one.call(context.history(), 'change.intro', selectedPreset); + bindOnce(context.history(), 'change.intro', selectedPreset); d3.select('.preset-search-input') .on('keydown.intro', eventCancel, true) .on('keyup.intro', null); } } + function selectedPreset() { setTimeout(function() { reveal('.entity-editor-pane', t('intro.points.describe'), {tooltipClass: 'intro-points-describe'}); @@ -74,6 +83,7 @@ export function point(context, reveal) { }, 400); } + function closeEditor() { d3.select('.preset-search-input').on('keydown.intro', null); context.history().on('change.intro', null); @@ -81,6 +91,7 @@ export function point(context, reveal) { t('intro.points.close', { button: icon('#icon-apply', 'pre-text') })); } + function selectPoint() { context.on('exit.intro', null); context.history().on('change.intro', null); @@ -95,6 +106,7 @@ export function point(context, reveal) { }); } + function enterReselect(mode) { if (mode.id !== 'select') return; context.map().on('move.intro', null); @@ -107,6 +119,7 @@ export function point(context, reveal) { }, 500); } + function deletePoint() { context.on('exit.intro', null); context.on('enter.intro', enterDelete); @@ -120,6 +133,7 @@ export function point(context, reveal) { }); } + function enterDelete(mode) { if (mode.id !== 'select') return; context.map().on('move.intro', null); @@ -136,6 +150,7 @@ export function point(context, reveal) { }, 300); } + function deleted(changed) { if (changed.deleted().length) { dispatch.call('done'); @@ -144,6 +159,7 @@ export function point(context, reveal) { }; + step.exit = function() { timeouts.forEach(window.clearTimeout); context.on('exit.intro', null); diff --git a/modules/ui/intro/start_editing.js b/modules/ui/intro/start_editing.js index 802b487b7..fd282857e 100644 --- a/modules/ui/intro/start_editing.js +++ b/modules/ui/intro/start_editing.js @@ -4,6 +4,7 @@ import { t } from '../../util/locale'; import { icon } from './helper'; import { modal } from '../modal'; + export function startEditing(context, reveal) { var dispatch = d3.dispatch('done', 'startEditing'), modalSelection, @@ -13,10 +14,12 @@ export function startEditing(context, reveal) { title: 'intro.startediting.title' }; + function timeout(f, t) { timeouts.push(window.setTimeout(f, t)); } + step.enter = function() { reveal('.map-control.help-control', t('intro.startediting.help', { button: icon('#icon-help', 'pre-text') })); @@ -39,25 +42,30 @@ export function startEditing(context, reveal) { var startbutton = modalSelection.select('.content') .attr('class', 'fillL') - .append('button') - .attr('class', 'modal-section huge-modal-button') - .on('click', function() { - modalSelection.remove(); - }); + .append('button') + .attr('class', 'modal-section huge-modal-button') + .on('click', function() { + modalSelection.remove(); + }); - startbutton.append('div') + startbutton + .append('div') .attr('class','illustration'); - startbutton.append('h2') + + startbutton + .append('h2') .text(t('intro.startediting.start')); dispatch.call('startEditing'); }, 10500); }; + step.exit = function() { - if (modalSelection) modalSelection.remove(); + if (modalSelection) { modalSelection.remove(); } timeouts.forEach(window.clearTimeout); }; + return rebind(step, dispatch, 'on'); }