mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-15 21:48:20 +02:00
Favorite preset
This commit is contained in:
@@ -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
@@ -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"],
|
||||
|
||||
@@ -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.
|
||||
|
||||
Vendored
+4
-9
@@ -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"
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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,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,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,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'
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 |
Reference in New Issue
Block a user