mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-15 21:48:20 +02:00
More guard code to protect against user undos and mode changes
This commit is contained in:
@@ -74,7 +74,7 @@ export function rendererMap(context) {
|
||||
|
||||
context.history()
|
||||
.on('change.map', immediateRedraw)
|
||||
.on('undone.context redone.context', function(stack) {
|
||||
.on('undone.map redone.map', function(stack) {
|
||||
var followSelected = false;
|
||||
if (Array.isArray(stack.selectedIDs)) {
|
||||
followSelected = (stack.selectedIDs.length === 1 && stack.selectedIDs[0][0] === 'n');
|
||||
|
||||
+126
-47
@@ -1,5 +1,6 @@
|
||||
import * as d3 from 'd3';
|
||||
import { t } from '../../util/locale';
|
||||
import { modeBrowse, modeSelect } from '../../modes';
|
||||
import { utilRebind } from '../../util/rebind';
|
||||
import { icon, pad, transitionTime } from './helper';
|
||||
|
||||
@@ -9,7 +10,8 @@ export function uiIntroArea(context, reveal) {
|
||||
playground = [-85.63552, 41.94159],
|
||||
playgroundPreset = context.presets().item('leisure/playground'),
|
||||
descriptionField = context.presets().field('description'),
|
||||
timeouts = [];
|
||||
timeouts = [],
|
||||
areaId;
|
||||
|
||||
|
||||
var chapter = {
|
||||
@@ -29,7 +31,9 @@ export function uiIntroArea(context, reveal) {
|
||||
|
||||
|
||||
function addArea() {
|
||||
context.enter(modeBrowse(context));
|
||||
context.history().reset('initial');
|
||||
areaId = null;
|
||||
|
||||
var msec = transitionTime(playground, context.map().center());
|
||||
if (msec) { reveal(null, null, { duration: 0 }); }
|
||||
@@ -63,6 +67,8 @@ export function uiIntroArea(context, reveal) {
|
||||
return chapter.restart();
|
||||
}
|
||||
|
||||
areaId = null;
|
||||
|
||||
var padding = 120 * Math.pow(2, context.map().zoom() - 19);
|
||||
var box = pad(playground, padding, context);
|
||||
reveal(box, t('intro.areas.start_playground'));
|
||||
@@ -91,23 +97,27 @@ export function uiIntroArea(context, reveal) {
|
||||
return chapter.restart();
|
||||
}
|
||||
|
||||
var padding = 150 * Math.pow(2, context.map().zoom() - 19);
|
||||
areaId = null;
|
||||
|
||||
var padding = 120 * Math.pow(2, context.map().zoom() - 19);
|
||||
var box = pad(playground, padding, context);
|
||||
reveal(box, t('intro.areas.continue_playground'));
|
||||
|
||||
context.map().on('move.intro drawn.intro', function() {
|
||||
padding = 150 * Math.pow(2, context.map().zoom() - 19);
|
||||
padding = 120 * Math.pow(2, context.map().zoom() - 19);
|
||||
box = pad(playground, padding, context);
|
||||
reveal(box, t('intro.areas.continue_playground'), {duration: 0});
|
||||
});
|
||||
|
||||
context.on('enter.intro', function(mode) {
|
||||
if (mode.id === 'draw-area')
|
||||
if (mode.id === 'draw-area') {
|
||||
return;
|
||||
else if (mode.id === 'select')
|
||||
} else if (mode.id === 'select') {
|
||||
areaId = context.selectedIDs()[0];
|
||||
return continueTo(searchPresets);
|
||||
else
|
||||
} else {
|
||||
return chapter.restart();
|
||||
}
|
||||
});
|
||||
|
||||
function continueTo(nextStep) {
|
||||
@@ -119,58 +129,93 @@ export function uiIntroArea(context, reveal) {
|
||||
|
||||
|
||||
function searchPresets() {
|
||||
if (context.mode().id !== 'select') {
|
||||
return chapter.restart();
|
||||
if (!areaId || !context.hasEntity(areaId)) {
|
||||
return addArea();
|
||||
}
|
||||
var ids = context.selectedIDs();
|
||||
if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
|
||||
context.enter(modeSelect(context, [areaId]));
|
||||
}
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
return chapter.restart();
|
||||
});
|
||||
|
||||
d3.select('.preset-search-input')
|
||||
.on('keyup.intro', checkPresetSearch);
|
||||
|
||||
timeout(function() {
|
||||
// reset pane, in case user somehow happened to change it..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '-100%');
|
||||
|
||||
d3.select('.preset-search-input')
|
||||
.on('keydown.intro', null)
|
||||
.on('keyup.intro', checkPresetSearch);
|
||||
|
||||
reveal('.preset-search-input',
|
||||
t('intro.areas.search_playground', { preset: playgroundPreset.name() })
|
||||
);
|
||||
}, 500);
|
||||
}
|
||||
}, 400); // after preset list pane visible..
|
||||
|
||||
context.on('enter.intro', function(mode) {
|
||||
if (!areaId || !context.hasEntity(areaId)) {
|
||||
return continueTo(addArea);
|
||||
}
|
||||
|
||||
function checkPresetSearch() {
|
||||
var first = d3.select('.preset-list-item:first-child');
|
||||
var ids = context.selectedIDs();
|
||||
if (mode.id !== 'select' || !ids.length || ids[0] !== areaId) {
|
||||
// keep the user's area selected..
|
||||
context.enter(modeSelect(context, [areaId]));
|
||||
|
||||
if (first.classed('preset-leisure-playground')) {
|
||||
reveal(first.select('.preset-list-button').node(),
|
||||
t('intro.areas.choose_playground', { preset: playgroundPreset.name() }),
|
||||
{ duration: 300 }
|
||||
);
|
||||
// reset pane, in case user somehow happened to change it..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '-100%');
|
||||
|
||||
d3.select('.preset-search-input')
|
||||
.on('keydown.intro', eventCancel, true)
|
||||
.on('keyup.intro', null);
|
||||
d3.select('.preset-search-input')
|
||||
.on('keydown.intro', null)
|
||||
.on('keyup.intro', checkPresetSearch);
|
||||
|
||||
context.history().on('change.intro', function() {
|
||||
continueTo(clickAddField);
|
||||
});
|
||||
reveal('.preset-search-input',
|
||||
t('intro.areas.search_playground', { preset: playgroundPreset.name() })
|
||||
);
|
||||
|
||||
context.history().on('change.intro', null);
|
||||
}
|
||||
});
|
||||
|
||||
function checkPresetSearch() {
|
||||
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_playground', { preset: playgroundPreset.name() }),
|
||||
{ duration: 300 }
|
||||
);
|
||||
|
||||
d3.select('.preset-search-input')
|
||||
.on('keydown.intro', eventCancel, true)
|
||||
.on('keyup.intro', null);
|
||||
|
||||
context.history().on('change.intro', function() {
|
||||
continueTo(clickAddField);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function continueTo(nextStep) {
|
||||
context.on('exit.intro', null);
|
||||
context.on('enter.intro', null);
|
||||
context.history().on('change.intro', null);
|
||||
d3.select('.preset-search-input').on('keydown.intro', null);
|
||||
d3.select('.preset-search-input').on('keydown.intro keyup.intro', null);
|
||||
nextStep();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function clickAddField() {
|
||||
context.on('exit.intro', function() {
|
||||
return chapter.restart();
|
||||
});
|
||||
if (!areaId || !context.hasEntity(areaId)) {
|
||||
return addArea();
|
||||
}
|
||||
var ids = context.selectedIDs();
|
||||
if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
|
||||
return searchPresets();
|
||||
}
|
||||
|
||||
timeout(function() {
|
||||
// reset pane, in case user somehow happened to change it..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '0%');
|
||||
|
||||
reveal('.more-fields .combobox-input',
|
||||
t('intro.areas.add_field'),
|
||||
{ duration: 300 }
|
||||
@@ -180,7 +225,11 @@ export function uiIntroArea(context, reveal) {
|
||||
.on('click.intro', function() {
|
||||
continueTo(chooseDescriptionField);
|
||||
});
|
||||
}, 300); // after editor pane visible
|
||||
}, 400); // after editor pane visible
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
return continueTo(searchPresets);
|
||||
});
|
||||
|
||||
function continueTo(nextStep) {
|
||||
d3.select('.more-fields .combobox-input').on('click.intro', null);
|
||||
@@ -191,9 +240,13 @@ export function uiIntroArea(context, reveal) {
|
||||
|
||||
|
||||
function chooseDescriptionField() {
|
||||
context.on('exit.intro', function() {
|
||||
return chapter.restart();
|
||||
});
|
||||
if (!areaId || !context.hasEntity(areaId)) {
|
||||
return addArea();
|
||||
}
|
||||
var ids = context.selectedIDs();
|
||||
if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
|
||||
return searchPresets();
|
||||
}
|
||||
|
||||
reveal('div.combobox',
|
||||
t('intro.areas.choose_field', { field: descriptionField.label() }),
|
||||
@@ -203,13 +256,18 @@ export function uiIntroArea(context, reveal) {
|
||||
d3.select('div.combobox')
|
||||
.on('click.intro', function() {
|
||||
timeout(function() {
|
||||
if (d3.select('.form-field-description').empty())
|
||||
if (d3.select('.form-field-description').empty()) {
|
||||
continueTo(retryChooseDescription);
|
||||
else
|
||||
} else {
|
||||
continueTo(describePlayground);
|
||||
}, 300);
|
||||
}
|
||||
}, 300); // after description field added.
|
||||
});
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
return continueTo(searchPresets);
|
||||
});
|
||||
|
||||
function continueTo(nextStep) {
|
||||
d3.select('div.combobox').on('click.intro', null);
|
||||
context.on('exit.intro', null);
|
||||
@@ -219,6 +277,17 @@ export function uiIntroArea(context, reveal) {
|
||||
|
||||
|
||||
function describePlayground() {
|
||||
if (!areaId || !context.hasEntity(areaId)) {
|
||||
return addArea();
|
||||
}
|
||||
var ids = context.selectedIDs();
|
||||
if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
|
||||
return searchPresets();
|
||||
}
|
||||
|
||||
// reset pane, in case user happened to change it..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '0%');
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
continueTo(play);
|
||||
});
|
||||
@@ -236,9 +305,16 @@ export function uiIntroArea(context, reveal) {
|
||||
|
||||
|
||||
function retryChooseDescription() {
|
||||
context.on('exit.intro', function() {
|
||||
return chapter.restart();
|
||||
});
|
||||
if (!areaId || !context.hasEntity(areaId)) {
|
||||
return addArea();
|
||||
}
|
||||
var ids = context.selectedIDs();
|
||||
if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
|
||||
return searchPresets();
|
||||
}
|
||||
|
||||
// reset pane, in case user happened to change it..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '0%');
|
||||
|
||||
reveal('.entity-editor-pane',
|
||||
t('intro.areas.retry_add_field', { field: descriptionField.label() }), {
|
||||
@@ -246,6 +322,10 @@ export function uiIntroArea(context, reveal) {
|
||||
buttonCallback: function() { continueTo(clickAddField); }
|
||||
});
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
return continueTo(searchPresets);
|
||||
});
|
||||
|
||||
function continueTo(nextStep) {
|
||||
context.on('exit.intro', null);
|
||||
nextStep();
|
||||
@@ -273,8 +353,7 @@ export function uiIntroArea(context, reveal) {
|
||||
|
||||
chapter.exit = function() {
|
||||
timeouts.forEach(window.clearTimeout);
|
||||
context.on('enter.intro', null);
|
||||
context.on('exit.intro', null);
|
||||
context.on('enter.intro exit.intro', null);
|
||||
context.map().on('move.intro drawn.intro', null);
|
||||
context.history().on('change.intro', null);
|
||||
d3.select('.preset-search-input').on('keydown.intro keyup.intro', null);
|
||||
|
||||
+141
-77
@@ -1,7 +1,7 @@
|
||||
import * as d3 from 'd3';
|
||||
import _ from 'lodash';
|
||||
import { t } from '../../util/locale';
|
||||
import { modeBrowse } from '../../modes/browse';
|
||||
import { modeBrowse, modeSelect } from '../../modes';
|
||||
import { utilRebind } from '../../util/rebind';
|
||||
import { icon, pad, isMostlySquare, selectMenuItem, transitionTime } from './helper';
|
||||
|
||||
@@ -49,9 +49,9 @@ export function uiIntroBuilding(context, reveal) {
|
||||
|
||||
|
||||
function addHouse() {
|
||||
houseId = null;
|
||||
tankId = null;
|
||||
context.enter(modeBrowse(context));
|
||||
context.history().reset('initial');
|
||||
houseId = null;
|
||||
|
||||
var msec = transitionTime(house, context.map().center());
|
||||
if (msec) { reveal(null, null, { duration: 0 }); }
|
||||
@@ -67,9 +67,6 @@ export function uiIntroBuilding(context, reveal) {
|
||||
.append('use')
|
||||
.attr('xlink:href', '#building-images');
|
||||
|
||||
houseId = null;
|
||||
context.history().reset('initial');
|
||||
|
||||
context.on('enter.intro', function(mode) {
|
||||
if (mode.id !== 'add-area') return;
|
||||
continueTo(startHouse);
|
||||
@@ -85,7 +82,7 @@ export function uiIntroBuilding(context, reveal) {
|
||||
|
||||
function startHouse() {
|
||||
if (context.mode().id !== 'add-area') {
|
||||
return chapter.restart();
|
||||
return continueTo(addHouse);
|
||||
}
|
||||
|
||||
houseId = null;
|
||||
@@ -100,7 +97,7 @@ export function uiIntroBuilding(context, reveal) {
|
||||
|
||||
context.on('enter.intro', function(mode) {
|
||||
if (mode.id !== 'draw-area') return chapter.restart();
|
||||
continueTo(drawHouse);
|
||||
continueTo(continueHouse);
|
||||
});
|
||||
|
||||
}, 550); // after easing
|
||||
@@ -113,12 +110,13 @@ export function uiIntroBuilding(context, reveal) {
|
||||
}
|
||||
|
||||
|
||||
function drawHouse() {
|
||||
function continueHouse() {
|
||||
if (context.mode().id !== 'draw-area') {
|
||||
return chapter.restart();
|
||||
return continueTo(addHouse);
|
||||
}
|
||||
|
||||
houseId = null;
|
||||
|
||||
revealHouse(house, t('intro.buildings.continue_building'));
|
||||
|
||||
context.map().on('move.intro drawn.intro', function() {
|
||||
@@ -175,51 +173,83 @@ export function uiIntroBuilding(context, reveal) {
|
||||
|
||||
|
||||
function chooseCategoryBuilding() {
|
||||
if (context.mode().id !== 'select') {
|
||||
return chapter.restart();
|
||||
if (!houseId || !context.hasEntity(houseId)) {
|
||||
return addHouse();
|
||||
}
|
||||
var ids = context.selectedIDs();
|
||||
if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
|
||||
context.enter(modeSelect(context, [houseId]));
|
||||
}
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
return chapter.restart();
|
||||
});
|
||||
|
||||
var button = d3.select('.preset-category-building .preset-list-button');
|
||||
if (button.empty()) return chapter.restart();
|
||||
|
||||
timeout(function() {
|
||||
// reset pane, in case user somehow happened to change it..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '-100%');
|
||||
|
||||
var button = d3.select('.preset-category-building .preset-list-button');
|
||||
|
||||
reveal(button.node(),
|
||||
t('intro.buildings.choose_category_building', { category: buildingCatetory.name() })
|
||||
);
|
||||
button.on('click.intro', function() { continueTo(choosePresetHouse); });
|
||||
}, 500);
|
||||
|
||||
button.on('click.intro', function() {
|
||||
continueTo(choosePresetHouse);
|
||||
});
|
||||
|
||||
}, 400); // after preset list pane visible..
|
||||
|
||||
|
||||
context.on('enter.intro', function(mode) {
|
||||
if (!houseId || !context.hasEntity(houseId)) {
|
||||
return continueTo(addHouse);
|
||||
}
|
||||
var ids = context.selectedIDs();
|
||||
if (mode.id !== 'select' || !ids.length || ids[0] !== houseId) {
|
||||
return continueTo(chooseCategoryBuilding);
|
||||
}
|
||||
});
|
||||
|
||||
function continueTo(nextStep) {
|
||||
d3.select('.preset-list-button').on('click.intro', null);
|
||||
context.on('exit.intro', null);
|
||||
context.on('enter.intro', null);
|
||||
nextStep();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function choosePresetHouse() {
|
||||
if (context.mode().id !== 'select') {
|
||||
return chapter.restart();
|
||||
if (!houseId || !context.hasEntity(houseId)) {
|
||||
return addHouse();
|
||||
}
|
||||
var ids = context.selectedIDs();
|
||||
if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
|
||||
context.enter(modeSelect(context, [houseId]));
|
||||
}
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
return chapter.restart();
|
||||
});
|
||||
|
||||
var button = d3.select('.preset-building-house .preset-list-button');
|
||||
if (button.empty()) return chapter.restart();
|
||||
|
||||
timeout(function() {
|
||||
// reset pane, in case user somehow happened to change it..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '-100%');
|
||||
|
||||
var button = d3.select('.preset-building-house .preset-list-button');
|
||||
|
||||
reveal(button.node(),
|
||||
t('intro.buildings.choose_preset_house', { preset: housePreset.name() }),
|
||||
{ duration: 300 }
|
||||
);
|
||||
button.on('click.intro', function() { continueTo(closeEditorHouse); });
|
||||
}, 300);
|
||||
|
||||
button.on('click.intro', function() {
|
||||
continueTo(closeEditorHouse);
|
||||
});
|
||||
}, 400); // after preset list pane visible..
|
||||
|
||||
context.on('enter.intro', function(mode) {
|
||||
if (!houseId || !context.hasEntity(houseId)) {
|
||||
return continueTo(addHouse);
|
||||
}
|
||||
var ids = context.selectedIDs();
|
||||
if (mode.id !== 'select' || !ids.length || ids[0] !== houseId) {
|
||||
return continueTo(chooseCategoryBuilding);
|
||||
}
|
||||
});
|
||||
|
||||
function continueTo(nextStep) {
|
||||
d3.select('.preset-list-button').on('click.intro', null);
|
||||
@@ -230,8 +260,12 @@ export function uiIntroBuilding(context, reveal) {
|
||||
|
||||
|
||||
function closeEditorHouse() {
|
||||
if (context.mode().id !== 'select') {
|
||||
return chapter.restart();
|
||||
if (!houseId || !context.hasEntity(houseId)) {
|
||||
return addHouse();
|
||||
}
|
||||
var ids = context.selectedIDs();
|
||||
if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
|
||||
context.enter(modeSelect(context, [houseId]));
|
||||
}
|
||||
|
||||
context.history().checkpoint('hasHouse');
|
||||
@@ -379,8 +413,9 @@ export function uiIntroBuilding(context, reveal) {
|
||||
|
||||
|
||||
function addTank() {
|
||||
tankId = null;
|
||||
context.enter(modeBrowse(context));
|
||||
context.history().reset('doneSquare');
|
||||
tankId = null;
|
||||
|
||||
var msec = transitionTime(tank, context.map().center());
|
||||
if (msec) { reveal(null, null, { duration: 0 }); }
|
||||
@@ -420,7 +455,7 @@ export function uiIntroBuilding(context, reveal) {
|
||||
|
||||
context.on('enter.intro', function(mode) {
|
||||
if (mode.id !== 'draw-area') return chapter.restart();
|
||||
continueTo(drawTank);
|
||||
continueTo(continueTank);
|
||||
});
|
||||
|
||||
}, 550); // after easing
|
||||
@@ -433,11 +468,13 @@ export function uiIntroBuilding(context, reveal) {
|
||||
}
|
||||
|
||||
|
||||
function drawTank() {
|
||||
function continueTank() {
|
||||
if (context.mode().id !== 'draw-area') {
|
||||
return continueTo(addTank);
|
||||
}
|
||||
|
||||
tankId = null;
|
||||
|
||||
revealTank(tank, t('intro.buildings.continue_tank'));
|
||||
|
||||
context.map().on('move.intro drawn.intro', function() {
|
||||
@@ -445,12 +482,14 @@ export function uiIntroBuilding(context, reveal) {
|
||||
});
|
||||
|
||||
context.on('enter.intro', function(mode) {
|
||||
if (mode.id === 'draw-area')
|
||||
if (mode.id === 'draw-area') {
|
||||
return;
|
||||
else if (mode.id === 'select')
|
||||
} else if (mode.id === 'select') {
|
||||
tankId = context.selectedIDs()[0];
|
||||
return continueTo(searchPresetTank);
|
||||
else
|
||||
} else {
|
||||
return continueTo(addTank);
|
||||
}
|
||||
});
|
||||
|
||||
function continueTo(nextStep) {
|
||||
@@ -462,64 +501,89 @@ export function uiIntroBuilding(context, reveal) {
|
||||
|
||||
|
||||
function searchPresetTank() {
|
||||
if (context.mode().id !== 'select') {
|
||||
return continueTo(addTank);
|
||||
if (!tankId || !context.hasEntity(tankId)) {
|
||||
return addTank();
|
||||
}
|
||||
var ids = context.selectedIDs();
|
||||
if (context.mode().id !== 'select' || !ids.length || ids[0] !== tankId) {
|
||||
context.enter(modeSelect(context, [tankId]));
|
||||
}
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
return continueTo(addTank);
|
||||
});
|
||||
|
||||
d3.select('.preset-search-input')
|
||||
.on('keyup.intro', checkPresetSearch);
|
||||
|
||||
timeout(function() {
|
||||
// reset pane, in case user somehow happened to change it..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '-100%');
|
||||
|
||||
d3.select('.preset-search-input')
|
||||
.on('keydown.intro', null)
|
||||
.on('keyup.intro', checkPresetSearch);
|
||||
|
||||
reveal('.preset-search-input',
|
||||
t('intro.buildings.search_tank', { preset: tankPreset.name() })
|
||||
);
|
||||
}, 500);
|
||||
}, 400); // after preset list pane visible..
|
||||
|
||||
function continueTo(nextStep) {
|
||||
context.on('exit.intro', null);
|
||||
d3.select('.preset-search-input').on('keyup.intro', null);
|
||||
nextStep();
|
||||
}
|
||||
}
|
||||
context.on('enter.intro', function(mode) {
|
||||
if (!tankId || !context.hasEntity(tankId)) {
|
||||
return continueTo(addTank);
|
||||
}
|
||||
|
||||
var ids = context.selectedIDs();
|
||||
if (mode.id !== 'select' || !ids.length || ids[0] !== tankId) {
|
||||
// keep the user's area selected..
|
||||
context.enter(modeSelect(context, [tankId]));
|
||||
|
||||
function checkPresetSearch() {
|
||||
var first = d3.select('.preset-list-item:first-child');
|
||||
// reset pane, in case user somehow happened to change it..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '-100%');
|
||||
|
||||
if (first.classed('preset-man_made-storage_tank')) {
|
||||
reveal(first.select('.preset-list-button').node(),
|
||||
t('intro.buildings.choose_tank', { preset: tankPreset.name() }),
|
||||
{ duration: 300 }
|
||||
);
|
||||
d3.select('.preset-search-input')
|
||||
.on('keydown.intro', null)
|
||||
.on('keyup.intro', checkPresetSearch);
|
||||
|
||||
d3.select('.preset-search-input')
|
||||
.on('keydown.intro', eventCancel, true)
|
||||
.on('keyup.intro', null);
|
||||
reveal('.preset-search-input',
|
||||
t('intro.buildings.search_tank', { preset: tankPreset.name() })
|
||||
);
|
||||
|
||||
context.history().on('change.intro', function() {
|
||||
continueTo(closeEditorTank);
|
||||
});
|
||||
context.history().on('change.intro', null);
|
||||
}
|
||||
});
|
||||
|
||||
function checkPresetSearch() {
|
||||
var first = d3.select('.preset-list-item:first-child');
|
||||
|
||||
if (first.classed('preset-man_made-storage_tank')) {
|
||||
reveal(first.select('.preset-list-button').node(),
|
||||
t('intro.buildings.choose_tank', { preset: tankPreset.name() }),
|
||||
{ duration: 300 }
|
||||
);
|
||||
|
||||
d3.select('.preset-search-input')
|
||||
.on('keydown.intro', eventCancel, true)
|
||||
.on('keyup.intro', null);
|
||||
|
||||
context.history().on('change.intro', function() {
|
||||
continueTo(closeEditorTank);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function continueTo(nextStep) {
|
||||
context.on('exit.intro', null);
|
||||
context.on('enter.intro', null);
|
||||
context.history().on('change.intro', null);
|
||||
d3.select('.preset-search-input').on('keydown.intro', null);
|
||||
d3.select('.preset-search-input').on('keydown.intro keyup.intro', null);
|
||||
nextStep();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function closeEditorTank() {
|
||||
if (context.mode().id !== 'select') {
|
||||
return continueTo(addTank);
|
||||
if (!tankId || !context.hasEntity(tankId)) {
|
||||
return addTank();
|
||||
}
|
||||
var ids = context.selectedIDs();
|
||||
if (context.mode().id !== 'select' || !ids.length || ids[0] !== tankId) {
|
||||
context.enter(modeSelect(context, [tankId]));
|
||||
}
|
||||
|
||||
tankId = context.mode().selectedIDs()[0];
|
||||
context.history().checkpoint('hasTank');
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
@@ -560,6 +624,7 @@ export function uiIntroBuilding(context, reveal) {
|
||||
});
|
||||
|
||||
revealTank(tank, t('intro.buildings.rightclick_tank'));
|
||||
|
||||
context.map().on('move.intro drawn.intro', function() {
|
||||
revealTank(tank, t('intro.buildings.rightclick_tank'), { duration: 0 });
|
||||
});
|
||||
@@ -668,8 +733,7 @@ export function uiIntroBuilding(context, reveal) {
|
||||
|
||||
chapter.exit = function() {
|
||||
timeouts.forEach(window.clearTimeout);
|
||||
context.on('enter.intro', null);
|
||||
context.on('exit.intro', null);
|
||||
context.on('enter.intro exit.intro', null);
|
||||
context.map().on('move.intro drawn.intro', null);
|
||||
context.history().on('change.intro', null);
|
||||
d3.select('.preset-search-input').on('keydown.intro keyup.intro', null);
|
||||
|
||||
@@ -50,6 +50,7 @@ export function uiIntroLine(context, reveal) {
|
||||
|
||||
|
||||
function addLine() {
|
||||
context.enter(modeBrowse(context));
|
||||
context.history().reset('initial');
|
||||
|
||||
var msec = transitionTime(tulipRoadStart, context.map().center());
|
||||
@@ -1047,8 +1048,7 @@ export function uiIntroLine(context, reveal) {
|
||||
chapter.exit = function() {
|
||||
timeouts.forEach(window.clearTimeout);
|
||||
d3.select(window).on('mousedown.intro', null, true);
|
||||
context.on('enter.intro', null);
|
||||
context.on('exit.intro', null);
|
||||
context.on('enter.intro exit.intro', null);
|
||||
context.map().on('move.intro drawn.intro', null);
|
||||
context.history().on('change.intro', null);
|
||||
d3.select('.preset-list-button').on('click.intro', null);
|
||||
|
||||
@@ -10,7 +10,6 @@ export function uiIntroNavigation(context, reveal) {
|
||||
timeouts = [],
|
||||
hallId = 'n2061',
|
||||
townHall = [-85.63591, 41.94285],
|
||||
townHallPreset = context.presets().item('amenity/townhall'),
|
||||
springStreetId = 'w397',
|
||||
springStreetEndId = 'n1834',
|
||||
springStreet = [-85.63582, 41.94255];
|
||||
@@ -50,6 +49,7 @@ export function uiIntroNavigation(context, reveal) {
|
||||
|
||||
|
||||
function dragMap() {
|
||||
context.enter(modeBrowse(context));
|
||||
context.history().reset('initial');
|
||||
|
||||
var msec = transitionTime(townHall, context.map().center());
|
||||
@@ -212,6 +212,11 @@ export function uiIntroNavigation(context, reveal) {
|
||||
|
||||
var onClick = function() { continueTo(presetTownHall); };
|
||||
|
||||
reveal('.entity-editor-pane',
|
||||
t('intro.navigation.editor_townhall'),
|
||||
{ buttonText: t('intro.ok'), buttonCallback: onClick }
|
||||
);
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
continueTo(clickTownHall);
|
||||
});
|
||||
@@ -222,11 +227,6 @@ export function uiIntroNavigation(context, reveal) {
|
||||
}
|
||||
});
|
||||
|
||||
reveal('.entity-editor-pane',
|
||||
t('intro.navigation.editor_townhall'),
|
||||
{ buttonText: t('intro.ok'), buttonCallback: onClick }
|
||||
);
|
||||
|
||||
function continueTo(nextStep) {
|
||||
context.on('exit.intro', null);
|
||||
context.history().on('change.intro', null);
|
||||
@@ -238,6 +238,13 @@ export function uiIntroNavigation(context, reveal) {
|
||||
function presetTownHall() {
|
||||
if (!isTownHallSelected()) return clickTownHall();
|
||||
|
||||
// reset pane, in case user happened to change it..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '0%');
|
||||
|
||||
// preset match, in case the user happened to change it.
|
||||
var entity = context.entity(context.selectedIDs()[0]);
|
||||
var preset = context.presets().match(entity, context.graph());
|
||||
|
||||
var onClick = function() { continueTo(fieldsTownHall); };
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
@@ -251,7 +258,7 @@ export function uiIntroNavigation(context, reveal) {
|
||||
});
|
||||
|
||||
reveal('.inspector-body .preset-list-item.inspector-inner',
|
||||
t('intro.navigation.preset_townhall', { preset: townHallPreset.name() }),
|
||||
t('intro.navigation.preset_townhall', { preset: preset.name() }),
|
||||
{ buttonText: t('intro.ok'), buttonCallback: onClick }
|
||||
);
|
||||
|
||||
@@ -266,8 +273,16 @@ export function uiIntroNavigation(context, reveal) {
|
||||
function fieldsTownHall() {
|
||||
if (!isTownHallSelected()) return clickTownHall();
|
||||
|
||||
// reset pane, in case user happened to change it..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '0%');
|
||||
|
||||
var onClick = function() { continueTo(closeTownHall); };
|
||||
|
||||
reveal('.inspector-body .inspector-preset',
|
||||
t('intro.navigation.fields_townhall'),
|
||||
{ buttonText: t('intro.ok'), buttonCallback: onClick }
|
||||
);
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
continueTo(clickTownHall);
|
||||
});
|
||||
@@ -278,11 +293,6 @@ export function uiIntroNavigation(context, reveal) {
|
||||
}
|
||||
});
|
||||
|
||||
reveal('.inspector-body .inspector-preset',
|
||||
t('intro.navigation.fields_townhall'),
|
||||
{ buttonText: t('intro.ok'), buttonCallback: onClick }
|
||||
);
|
||||
|
||||
function continueTo(nextStep) {
|
||||
context.on('exit.intro', null);
|
||||
context.history().on('change.intro', null);
|
||||
@@ -294,16 +304,6 @@ export function uiIntroNavigation(context, reveal) {
|
||||
function closeTownHall() {
|
||||
if (!isTownHallSelected()) return clickTownHall();
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
continueTo(searchStreet);
|
||||
});
|
||||
|
||||
context.history().on('change.intro', function() {
|
||||
if (!context.hasEntity(hallId)) {
|
||||
continueTo(clickTownHall);
|
||||
}
|
||||
});
|
||||
|
||||
var selector = '.entity-editor-pane button.preset-close svg use';
|
||||
var href = d3.select(selector).attr('href') || '#icon-close';
|
||||
|
||||
@@ -311,9 +311,12 @@ export function uiIntroNavigation(context, reveal) {
|
||||
t('intro.navigation.close_townhall', { button: icon(href, 'pre-text') })
|
||||
);
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
continueTo(searchStreet);
|
||||
});
|
||||
|
||||
function continueTo(nextStep) {
|
||||
context.on('exit.intro', null);
|
||||
context.history().on('change.intro', null);
|
||||
nextStep();
|
||||
}
|
||||
}
|
||||
@@ -395,7 +398,11 @@ export function uiIntroNavigation(context, reveal) {
|
||||
});
|
||||
|
||||
context.on('enter.intro', function(mode) {
|
||||
if (mode.id !== 'select') {
|
||||
if (!context.hasEntity(springStreetId)) {
|
||||
return continueTo(searchStreet);
|
||||
}
|
||||
var ids = context.selectedIDs();
|
||||
if (mode.id !== 'select' || !ids.length || ids[0] !== springStreetId) {
|
||||
// keep Spring Street selected..
|
||||
context.enter(modeSelect(context, [springStreetId]));
|
||||
}
|
||||
@@ -457,13 +464,10 @@ export function uiIntroNavigation(context, reveal) {
|
||||
|
||||
chapter.exit = function() {
|
||||
timeouts.forEach(window.clearTimeout);
|
||||
d3.select(window).on('mouseup.intro', null, true);
|
||||
context.on('enter.intro exit.intro', null);
|
||||
context.map().on('move.intro drawn.intro', null);
|
||||
context.on('enter.intro', null);
|
||||
context.on('exit.intro', null);
|
||||
d3.select('.search-header input')
|
||||
.on('keydown.intro', null)
|
||||
.on('keyup.intro', null);
|
||||
context.history().on('change.intro', null);
|
||||
d3.select('.search-header input').on('keydown.intro keyup.intro', null);
|
||||
};
|
||||
|
||||
|
||||
|
||||
+94
-43
@@ -1,5 +1,6 @@
|
||||
import * as d3 from 'd3';
|
||||
import { t, textDirection } from '../../util/locale';
|
||||
import { modeBrowse, modeSelect } from '../../modes';
|
||||
import { utilRebind } from '../../util/rebind';
|
||||
import { icon, pointBox, pad, selectMenuItem, transitionTime } from './helper';
|
||||
|
||||
@@ -30,6 +31,7 @@ export function uiIntroPoint(context, reveal) {
|
||||
|
||||
|
||||
function addPoint() {
|
||||
context.enter(modeBrowse(context));
|
||||
context.history().reset('initial');
|
||||
|
||||
var msec = transitionTime(intersection, context.map().center());
|
||||
@@ -76,6 +78,7 @@ export function uiIntroPoint(context, reveal) {
|
||||
|
||||
context.on('enter.intro', function(mode) {
|
||||
if (mode.id !== 'select') return chapter.restart();
|
||||
pointId = context.mode().selectedIDs()[0];
|
||||
continueTo(searchPreset);
|
||||
});
|
||||
|
||||
@@ -88,58 +91,73 @@ export function uiIntroPoint(context, reveal) {
|
||||
|
||||
|
||||
function searchPreset() {
|
||||
if (context.mode().id !== 'select') {
|
||||
return chapter.restart();
|
||||
if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
|
||||
return addPoint();
|
||||
}
|
||||
|
||||
pointId = context.mode().selectedIDs()[0];
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
return chapter.restart();
|
||||
});
|
||||
|
||||
d3.select('.preset-search-input')
|
||||
.on('keydown.intro', null)
|
||||
.on('keyup.intro', checkPresetSearch);
|
||||
|
||||
timeout(function() {
|
||||
reveal('.preset-search-input',
|
||||
t('intro.points.search_cafe', { preset: cafePreset.name() })
|
||||
);
|
||||
}, 500);
|
||||
}
|
||||
reveal('.preset-search-input',
|
||||
t('intro.points.search_cafe', { preset: cafePreset.name() })
|
||||
);
|
||||
|
||||
context.on('enter.intro', function(mode) {
|
||||
if (!pointId || !context.hasEntity(pointId)) {
|
||||
return continueTo(addPoint);
|
||||
}
|
||||
|
||||
var ids = context.selectedIDs();
|
||||
if (mode.id !== 'select' || !ids.length || ids[0] !== pointId) {
|
||||
// keep the user's point selected..
|
||||
context.enter(modeSelect(context, [pointId]));
|
||||
|
||||
d3.select('.preset-search-input')
|
||||
.on('keydown.intro', null)
|
||||
.on('keyup.intro', checkPresetSearch);
|
||||
|
||||
reveal('.preset-search-input',
|
||||
t('intro.points.search_cafe', { preset: cafePreset.name() })
|
||||
);
|
||||
|
||||
context.history().on('change.intro', null);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function checkPresetSearch() {
|
||||
var first = d3.select('.preset-list-item:first-child');
|
||||
function checkPresetSearch() {
|
||||
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_cafe', { preset: cafePreset.name() }),
|
||||
{ duration: 300 }
|
||||
);
|
||||
if (first.classed('preset-amenity-cafe')) {
|
||||
d3.select('.preset-search-input')
|
||||
.on('keydown.intro', eventCancel, true)
|
||||
.on('keyup.intro', null);
|
||||
|
||||
d3.select('.preset-search-input')
|
||||
.on('keydown.intro', eventCancel, true)
|
||||
.on('keyup.intro', null);
|
||||
reveal(first.select('.preset-list-button').node(),
|
||||
t('intro.points.choose_cafe', { preset: cafePreset.name() }),
|
||||
{ duration: 300 }
|
||||
);
|
||||
|
||||
context.history().on('change.intro', function() {
|
||||
continueTo(aboutFeatureEditor);
|
||||
});
|
||||
context.history().on('change.intro', function() {
|
||||
continueTo(aboutFeatureEditor);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function continueTo(nextStep) {
|
||||
context.on('exit.intro', null);
|
||||
context.on('enter.intro', null);
|
||||
context.history().on('change.intro', null);
|
||||
d3.select('.preset-search-input').on('keydown.intro', null);
|
||||
d3.select('.preset-search-input').on('keydown.intro keyup.intro', null);
|
||||
nextStep();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function aboutFeatureEditor() {
|
||||
context.on('exit.intro', function() {
|
||||
return chapter.restart();
|
||||
});
|
||||
if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
|
||||
return addPoint();
|
||||
}
|
||||
|
||||
timeout(function() {
|
||||
reveal('.entity-editor-pane', t('intro.points.feature_editor'), {
|
||||
@@ -149,6 +167,11 @@ export function uiIntroPoint(context, reveal) {
|
||||
});
|
||||
}, 400);
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
// if user leaves select mode here, just continue with the tutorial.
|
||||
continueTo(reselectPoint);
|
||||
});
|
||||
|
||||
function continueTo(nextStep) {
|
||||
context.on('exit.intro', null);
|
||||
nextStep();
|
||||
@@ -157,13 +180,12 @@ export function uiIntroPoint(context, reveal) {
|
||||
|
||||
|
||||
function addName() {
|
||||
context.on('exit.intro', function() {
|
||||
return chapter.restart();
|
||||
});
|
||||
if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
|
||||
return addPoint();
|
||||
}
|
||||
|
||||
context.history().on('change.intro', function() {
|
||||
continueTo(addCloseEditor);
|
||||
});
|
||||
// reset pane, in case user happened to change it..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '0%');
|
||||
|
||||
timeout(function() {
|
||||
reveal('.entity-editor-pane', t('intro.points.add_name'),
|
||||
@@ -171,6 +193,15 @@ export function uiIntroPoint(context, reveal) {
|
||||
);
|
||||
}, 400);
|
||||
|
||||
context.history().on('change.intro', function() {
|
||||
continueTo(addCloseEditor);
|
||||
});
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
// if user leaves select mode here, just continue with the tutorial.
|
||||
continueTo(reselectPoint);
|
||||
});
|
||||
|
||||
function continueTo(nextStep) {
|
||||
context.on('exit.intro', null);
|
||||
context.history().on('change.intro', null);
|
||||
@@ -180,12 +211,18 @@ export function uiIntroPoint(context, reveal) {
|
||||
|
||||
|
||||
function addCloseEditor() {
|
||||
// reset pane, in case user happened to change it..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '0%');
|
||||
|
||||
var selector = '.entity-editor-pane button.preset-close svg use';
|
||||
var href = d3.select(selector).attr('href') || '#icon-close';
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
continueTo(reselectPoint);
|
||||
});
|
||||
|
||||
reveal('.entity-editor-pane',
|
||||
t('intro.points.add_close', { button: icon('#icon-apply', 'pre-text') })
|
||||
t('intro.points.add_close', { button: icon(href, 'pre-text') })
|
||||
);
|
||||
|
||||
function continueTo(nextStep) {
|
||||
@@ -200,6 +237,8 @@ export function uiIntroPoint(context, reveal) {
|
||||
var entity = context.hasEntity(pointId);
|
||||
if (!entity) return chapter.restart();
|
||||
|
||||
context.enter(modeBrowse(context));
|
||||
|
||||
var msec = transitionTime(entity.loc, context.map().center());
|
||||
if (msec) { reveal(null, null, { duration: 0 }); }
|
||||
context.map().centerEase(entity.loc, msec);
|
||||
@@ -231,6 +270,13 @@ export function uiIntroPoint(context, reveal) {
|
||||
|
||||
|
||||
function updatePoint() {
|
||||
if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
|
||||
return continueTo(reselectPoint);
|
||||
}
|
||||
|
||||
// reset pane, in case user happened to untag the point..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '0%');
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
continueTo(reselectPoint);
|
||||
});
|
||||
@@ -254,10 +300,13 @@ export function uiIntroPoint(context, reveal) {
|
||||
|
||||
|
||||
function updateCloseEditor() {
|
||||
if (context.mode().id !== 'select') {
|
||||
if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
|
||||
return continueTo(reselectPoint);
|
||||
}
|
||||
|
||||
// reset pane, in case user happened to change it..
|
||||
d3.select('.inspector-wrap .panewrap').style('right', '0%');
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
continueTo(rightClickPoint);
|
||||
});
|
||||
@@ -280,6 +329,8 @@ export function uiIntroPoint(context, reveal) {
|
||||
var entity = context.hasEntity(pointId);
|
||||
if (!entity) return chapter.restart();
|
||||
|
||||
context.enter(modeBrowse(context));
|
||||
|
||||
var box = pointBox(entity.loc, context);
|
||||
reveal(box, t('intro.points.rightclick'));
|
||||
|
||||
@@ -339,8 +390,9 @@ export function uiIntroPoint(context, reveal) {
|
||||
});
|
||||
|
||||
context.history().on('change.intro', function(changed) {
|
||||
if (changed.deleted().length)
|
||||
if (changed.deleted().length) {
|
||||
continueTo(undo);
|
||||
}
|
||||
});
|
||||
|
||||
function continueTo(nextStep) {
|
||||
@@ -388,8 +440,7 @@ export function uiIntroPoint(context, reveal) {
|
||||
|
||||
chapter.exit = function() {
|
||||
timeouts.forEach(window.clearTimeout);
|
||||
context.on('exit.intro', null);
|
||||
context.on('enter.intro', null);
|
||||
context.on('enter.intro exit.intro', null);
|
||||
context.map().on('move.intro drawn.intro', null);
|
||||
context.history().on('change.intro', null);
|
||||
d3.select('.preset-search-input').on('keydown.intro keyup.intro', null);
|
||||
|
||||
@@ -14,14 +14,14 @@ export function uiIntroWelcome(context, reveal) {
|
||||
|
||||
function welcome() {
|
||||
context.map().centerZoom([-85.63591, 41.94285], 19);
|
||||
reveal('.intro-nav-wrap',
|
||||
reveal('.intro-nav-wrap .chapter-welcome',
|
||||
t('intro.welcome.welcome'),
|
||||
{ buttonText: t('intro.ok'), buttonCallback: practice }
|
||||
);
|
||||
}
|
||||
|
||||
function practice() {
|
||||
reveal('.intro-nav-wrap',
|
||||
reveal('.intro-nav-wrap .chapter-welcome',
|
||||
t('intro.welcome.practice'),
|
||||
{ buttonText: t('intro.ok'), buttonCallback: chapters }
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user