Favorite preset

This commit is contained in:
Brian Hatchl
2019-02-20 15:23:58 -05:00
committed by GitHub
parent d84e945330
commit 1faa6ad839
16 changed files with 193 additions and 33 deletions
+1
View File
@@ -54,6 +54,7 @@
cursor: url(img/cursor-select-remove.png), pointer; /* FF */
}
[class*=" mode-add-preset-"] #map,
.mode-draw-line #map,
.mode-draw-area #map,
.mode-add-line #map,
+21 -1
View File
@@ -1150,28 +1150,47 @@ a.hide-toggle {
background-color: #ececec;
}
.preset-list-item button.preset-favorite-button,
.preset-list-item button.tag-reference-button {
height: 100%;
border: 1px solid #ccc;
flex: 32px;
background: #f6f6f6;
}
[dir='ltr'] .preset-list-item button.preset-favorite-button,
[dir='ltr'] .preset-list-item button.tag-reference-button {
border-left: none;
border-radius: 0 4px 4px 0;
border-radius: 0;
}
[dir='rtl'] .preset-list-item button.preset-favorite-button,
[dir='rtl'] .preset-list-item button.tag-reference-button {
border-right: none;
border-radius: 0;
}
[dir='ltr'] .preset-list-item button:last-child {
border-radius: 0 4px 4px 0;
}
[dir='rtl'] .preset-list-item button:last-child {
border-radius: 4px 0 0 4px;
}
.preset-list-item button.preset-favorite-button:hover,
.preset-list-item button.tag-reference-button:hover {
background: #f1f1f1;
}
.preset-list-item button.preset-favorite-button .icon,
.preset-list-item button.tag-reference-button .icon {
opacity: .5;
}
.preset-list-item button.preset-favorite-button .icon {
fill-opacity: 0;
stroke-width: 1.6;
}
.preset-list-item button.preset-favorite-button.active .icon {
fill-opacity: inherit;
}
img.tag-reference-wiki-image {
float: right;
width: 33.3333%;
@@ -2474,6 +2493,7 @@ input.key-trap {
/* hide and remove from layout */
.inspector-hidden,
.inspector-hover .preset-list-button-wrap .preset-favorite-button,
.inspector-hover .preset-list-button-wrap .tag-reference-button,
.inspector-hover label input[type="checkbox"],
.inspector-hover label input[type="radio"],
+2
View File
@@ -7,6 +7,7 @@ en:
zoom_to: zoom to
copy: copy
open_wikidata: open on wikidata.org
favorite: add to favorites
modes:
add_area:
title: Area
@@ -40,6 +41,7 @@ en:
vertex: Added a node to a way.
relation: Added a relation.
note: Added a note.
title: Add
start:
annotation:
line: Started a line.
+4 -9
View File
@@ -7,7 +7,8 @@
"undo": "undo",
"zoom_to": "zoom to",
"copy": "copy",
"open_wikidata": "open on wikidata.org"
"open_wikidata": "open on wikidata.org",
"favorite": "add to favorites"
},
"modes": {
"add_area": {
@@ -51,7 +52,8 @@
"vertex": "Added a node to a way.",
"relation": "Added a relation.",
"note": "Added a note."
}
},
"title": "Add"
},
"start": {
"annotation": {
@@ -8370,13 +8372,6 @@
"description": "Japan GSI ortho Imagery. Usually better than bing, but a bit older.",
"name": "Japan GSI ortho Imagery"
},
"gsi.go.jp_airphoto": {
"attribution": {
"text": "GSI Japan"
},
"description": "Japan GSI airphoto Imagery. Not fully orthorectified, but a bit newer and/or differently covered than GSI ortho Imagery.",
"name": "Japan GSI airphoto Imagery"
},
"gsi.go.jp_std_map": {
"attribution": {
"text": "GSI Japan"
+1 -1
View File
@@ -323,7 +323,7 @@ export function behaviorDrawWay(context, wayID, index, mode, startGraph, baselin
window.setTimeout(function() {
context.map().dblclickEnable(true);
}, 1000);
var isNewFeature = !mode.isContinuing;
var isNewFeature = !mode.isContinuing && mode.button.indexOf('add-preset-') === -1;
context.enter(modeSelect(context, [wayID]).newFeature(isNewFeature));
};
+32 -1
View File
@@ -57,7 +57,7 @@ export function coreContext() {
addTranslation('en', dataEn);
setLocale('en');
var dispatch = d3_dispatch('enter', 'exit', 'change');
var dispatch = d3_dispatch('enter', 'exit', 'change', 'favoritePreset');
// https://github.com/openstreetmap/iD/issues/772
// http://mathiasbynens.be/notes/localstorage-pattern#comment-9
@@ -312,7 +312,38 @@ export function coreContext() {
/* Presets */
var presets;
context.presets = function() { return presets; };
//get favorites from local storage
context.getFavoritePresets = function() {
return JSON.parse(context.storage('favorite_presets')) || [];
}
context.favoritePreset = function(preset, geom) {
var favs = context.getFavoritePresets();
//add/remove favorites from local storage
if (context.isFavoritePreset(preset, geom)) {
favs = favs.filter(function(d) {
return !(d.id === preset.id && d.geom === geom);
});
} else {
//only allow 3 favorites
//replace the last one
if (favs.length === 3) {
favs = favs.slice(0,2);
}
favs.push({id: preset.id, geom: geom});
}
context.storage('favorite_presets', JSON.stringify(favs));
//and call update on modes
dispatch.call('favoritePreset');
};
context.isFavoritePreset = function(preset, geom) {
var favs = context.getFavoritePresets();
return favs.some(function(d) {
return d.id === preset.id && d.geom === geom;
});
};
/* Map */
var map;
+6 -5
View File
@@ -10,8 +10,8 @@ import { modeDrawArea } from './index';
import { osmNode, osmWay } from '../osm';
export function modeAddArea(context) {
var mode = {
export function modeAddArea(context, customMode, preset) {
var mode = customMode || {
id: 'add-area',
button: 'area',
title: t('modes.add_area.title'),
@@ -26,6 +26,7 @@ export function modeAddArea(context) {
.on('startFromNode', startFromNode);
var defaultTags = { area: 'yes' };
if (preset) defaultTags = preset.setTags(defaultTags, 'area');
function actionClose(wayId) {
@@ -47,7 +48,7 @@ export function modeAddArea(context) {
actionClose(way.id)
);
context.enter(modeDrawArea(context, way.id, startGraph, context.graph()));
context.enter(modeDrawArea(context, way.id, startGraph, context.graph(), mode.button));
}
@@ -64,7 +65,7 @@ export function modeAddArea(context) {
actionAddMidpoint({ loc: loc, edge: edge }, node)
);
context.enter(modeDrawArea(context, way.id, startGraph, context.graph()));
context.enter(modeDrawArea(context, way.id, startGraph, context.graph(), mode.button));
}
@@ -78,7 +79,7 @@ export function modeAddArea(context) {
actionClose(way.id)
);
context.enter(modeDrawArea(context, way.id, startGraph, context.graph()));
context.enter(modeDrawArea(context, way.id, startGraph, context.graph(), mode.button));
}
+9 -6
View File
@@ -10,8 +10,8 @@ import { modeDrawLine } from './index';
import { osmNode, osmWay } from '../osm';
export function modeAddLine(context) {
var mode = {
export function modeAddLine(context, customMode, preset) {
var mode = customMode || {
id: 'add-line',
button: 'line',
title: t('modes.add_line.title'),
@@ -25,11 +25,14 @@ export function modeAddLine(context) {
.on('startFromWay', startFromWay)
.on('startFromNode', startFromNode);
var defaultTags = {};
if (preset) defaultTags = preset.setTags(defaultTags, 'line');
function start(loc) {
var startGraph = context.graph();
var node = osmNode({ loc: loc });
var way = osmWay();
var way = osmWay({ tags: defaultTags });
context.perform(
actionAddEntity(node),
@@ -37,7 +40,7 @@ export function modeAddLine(context) {
actionAddVertex(way.id, node.id)
);
context.enter(modeDrawLine(context, way.id, startGraph, context.graph()));
context.enter(modeDrawLine(context, way.id, startGraph, context.graph(), mode.button));
}
@@ -53,7 +56,7 @@ export function modeAddLine(context) {
actionAddMidpoint({ loc: loc, edge: edge }, node)
);
context.enter(modeDrawLine(context, way.id, startGraph, context.graph()));
context.enter(modeDrawLine(context, way.id, startGraph, context.graph(), mode.button));
}
@@ -66,7 +69,7 @@ export function modeAddLine(context) {
actionAddVertex(way.id, node.id)
);
context.enter(modeDrawLine(context, way.id, startGraph, context.graph()));
context.enter(modeDrawLine(context, way.id, startGraph, context.graph(), mode.button));
}
+6 -3
View File
@@ -6,8 +6,8 @@ import { osmNode } from '../osm';
import { actionAddMidpoint } from '../actions';
export function modeAddPoint(context) {
var mode = {
export function modeAddPoint(context, customMode, preset) {
var mode = customMode || {
id: 'add-point',
button: 'point',
title: t('modes.add_point.title'),
@@ -23,9 +23,12 @@ export function modeAddPoint(context) {
.on('cancel', cancel)
.on('finish', cancel);
var defaultTags = {};
if (preset) defaultTags = preset.setTags(defaultTags, 'point');
function add(loc) {
var node = osmNode({ loc: loc });
var node = osmNode({ loc: loc, tags: defaultTags });
context.perform(
actionAddEntity(node),
+2 -2
View File
@@ -2,9 +2,9 @@ import { t } from '../util/locale';
import { behaviorDrawWay } from '../behavior';
export function modeDrawArea(context, wayId, startGraph, baselineGraph) {
export function modeDrawArea(context, wayId, startGraph, baselineGraph, button) {
var mode = {
button: 'area',
button: button,
id: 'draw-area'
};
+2 -2
View File
@@ -2,9 +2,9 @@ import { t } from '../util/locale';
import { behaviorDrawWay } from '../behavior';
export function modeDrawLine(context, wayID, startGraph, baselineGraph, affix, continuing) {
export function modeDrawLine(context, wayID, startGraph, baselineGraph, button, affix, continuing) {
var mode = {
button: 'line',
button: button,
id: 'draw-line'
};
+1 -1
View File
@@ -27,7 +27,7 @@ export function operationContinue(selectedIDs, context) {
var operation = function() {
var candidate = candidateWays()[0];
context.enter(
modeDrawLine(context, candidate.id, context.graph(), context.graph(), candidate.affix(vertex.id), true)
modeDrawLine(context, candidate.id, context.graph(), context.graph(), 'line', candidate.affix(vertex.id), true)
);
};
+8
View File
@@ -14,6 +14,7 @@ import { tooltip } from '../util/tooltip';
import { actionChangeTags } from '../actions';
import { modeBrowse } from '../modes';
import { svgIcon } from '../svg';
import { uiPresetFavorite } from './preset_favorite';
import { uiPresetIcon } from './preset_icon';
import { uiQuickLinks } from './quick_links';
import { uiRawMemberEditor } from './raw_member_editor';
@@ -35,6 +36,7 @@ export function uiEntityEditor(context) {
var _entityID;
var _activePreset;
var _tagReference;
var _presetFavorite;
var entityIssues = uiEntityIssues(context);
var quickLinks = uiQuickLinks();
@@ -137,6 +139,11 @@ export function uiEntityEditor(context) {
body = body
.merge(bodyEnter);
if (_presetFavorite) {
body.selectAll('.preset-list-button-wrap')
.call(_presetFavorite.button);
}
// update header
if (_tagReference) {
body.selectAll('.preset-list-button-wrap')
@@ -333,6 +340,7 @@ export function uiEntityEditor(context) {
_activePreset = val;
_tagReference = uiTagReference(_activePreset.reference(context.geometry(_entityID)), context)
.showing(false);
_presetFavorite = uiPresetFavorite(_activePreset, context.geometry(_entityID), context);
}
return entityEditor;
};
+35 -2
View File
@@ -11,6 +11,7 @@ import {
} from '../modes';
import { svgIcon } from '../svg';
import { t } from '../util/locale';
import { tooltip } from '../util/tooltip';
import { uiTooltipHtml } from './tooltipHtml';
@@ -82,7 +83,8 @@ export function uiModes(context) {
.on('drawn.modes', debouncedUpdate);
context
.on('enter.modes', update);
.on('enter.modes', update)
.on('favoritePreset.modes', update);
update();
@@ -91,6 +93,37 @@ export function uiModes(context) {
var showNotes = notesEnabled();
var data = showNotes ? modes : modes.slice(0, 3);
// add favorite presets to modes
var favoritePresets = context.getFavoritePresets();
var favoriteModes = favoritePresets.map(function(d) {
var preset = context.presets().item(d.id);
var isMaki = /^maki-/.test(preset.icon);
var icon = '#' + preset.icon + (isMaki ? '-11' : '');
var markerClass = 'add-preset-' + preset.name()
.replace(/\s+/g, '_')
+ '-' + d.geom; //replace spaces with underscores to avoid css interpretation
var favoriteMode = {
id: markerClass,
button: markerClass,
title: t('presets.presets.' + preset.id + '.name'),
description: [t('operations.add.title'), t('presets.presets.' + preset.id + '.name').toLowerCase(), t('geometry.' + d.geom)].join(' '),
key: '',
icon: icon
}
switch (d.geom) {
case 'point':
case 'vertex':
return modeAddPoint(context, favoriteMode, preset);
case 'line':
return modeAddLine(context, favoriteMode, preset);
case 'area':
return modeAddArea(context, favoriteMode, preset);
}
});
data = data.concat(favoriteModes);
var buttons = selection.selectAll('button.add-button')
.data(data, function(d) { return d.id; });
@@ -125,7 +158,7 @@ export function uiModes(context) {
buttonsEnter
.each(function(d) {
d3_select(this)
.call(svgIcon('#iD-icon-' + d.button));
.call(svgIcon(d.icon || '#iD-icon-' + d.button));
});
buttonsEnter
+57
View File
@@ -0,0 +1,57 @@
import _find from 'lodash-es/find';
import _omit from 'lodash-es/omit';
import {
event as d3_event,
select as d3_select
} from 'd3-selection';
import { t } from '../util/locale';
import { svgIcon } from '../svg';
import { uiModes } from './modes';
export function uiPresetFavorite(preset, geom, context) {
var presetFavorite = {};
var _button = d3_select(null);
presetFavorite.button = function(selection) {
var data = (preset.icon) ? [0] : [];
_button = selection.selectAll('.preset-favorite-button')
.data(data);
_button.exit().remove();
_button = _button.enter()
.insert('button', '.tag-reference-button')
.attr('class', 'preset-favorite-button')
.attr('title', t('icons.favorite'))
.attr('tabindex', -1)
.call(svgIcon('#iD-icon-favorite'))
.merge(_button);
_button
.classed('active', function(d) {
return context.isFavoritePreset(preset, geom);
})
.on('click', function () {
d3_event.stopPropagation();
d3_event.preventDefault();
//update state of favorite icon
d3_select(this)
.classed('active', function() {
return !d3_select(this).classed('active');
});
context.favoritePreset(preset, geom);
});
};
return presetFavorite;
}
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="20" height="20" viewBox="0 0 20 20">
<path
d="m 10.013362,4.3412342 2.011,4.075 4.496,0.654 -3.254,3.1709998 0.768,4.479 -4.02,-2.114 -4.0240005,2.114 0.768,-4.479 -3.254,-3.1719998 4.497,-0.653 z" fill="currentColor" stroke="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 510 B