mirror of
https://github.com/FoggedLens/iD.git
synced 2026-06-04 14:08:13 +02:00
Add privacy policy version check to context and splash screen
(closes #7040) A few other minor things in this commit - migrated several ui modal files to ES6 syntax - switched the splash link from ideditor.org -> ideditor.blog
This commit is contained in:
@@ -4542,6 +4542,9 @@ img.tile-debug {
|
||||
padding: 20px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
.modal-section p:not(:last-of-type) {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
.modal-section.header h3 {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
+4
-2
@@ -739,8 +739,8 @@ en:
|
||||
title: Privacy
|
||||
privacy_link: View the iD privacy policy
|
||||
third_party_icons:
|
||||
description: Show Third Party Preset Icons
|
||||
tooltip: Uncheck this box to avoid loading preset icons from third party sites such as Wikimedia Commons, Facebook, or Twitter.
|
||||
description: Show Third Party Icons
|
||||
tooltip: Uncheck this box to avoid loading icons from third party sites such as Wikimedia Commons, Facebook, or Twitter.
|
||||
restore:
|
||||
heading: You have unsaved changes
|
||||
description: "Do you wish to restore unsaved changes from a previous editing session?"
|
||||
@@ -802,6 +802,8 @@ en:
|
||||
splash:
|
||||
welcome: Welcome to the iD OpenStreetMap editor
|
||||
text: "iD is a friendly but powerful tool for contributing to the world's best free world map. This is version {version}. For more information see {website} and report bugs at {github}."
|
||||
privacy_update: "Our privacy policy has recently been updated."
|
||||
privacy: "{updateMessage} By using this software, you agree to do so in accordance with the iD privacy policy, which can be found {here}."
|
||||
walkthrough: "Start the Walkthrough"
|
||||
start: "Edit now"
|
||||
source_switch:
|
||||
|
||||
Vendored
+4
-2
@@ -933,8 +933,8 @@
|
||||
"title": "Privacy",
|
||||
"privacy_link": "View the iD privacy policy",
|
||||
"third_party_icons": {
|
||||
"description": "Show Third Party Preset Icons",
|
||||
"tooltip": "Uncheck this box to avoid loading preset icons from third party sites such as Wikimedia Commons, Facebook, or Twitter."
|
||||
"description": "Show Third Party Icons",
|
||||
"tooltip": "Uncheck this box to avoid loading icons from third party sites such as Wikimedia Commons, Facebook, or Twitter."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1004,6 +1004,8 @@
|
||||
"splash": {
|
||||
"welcome": "Welcome to the iD OpenStreetMap editor",
|
||||
"text": "iD is a friendly but powerful tool for contributing to the world's best free world map. This is version {version}. For more information see {website} and report bugs at {github}.",
|
||||
"privacy_update": "Our privacy policy has recently been updated.",
|
||||
"privacy": "{updateMessage} By using this software, you agree to do so in accordance with the iD privacy policy, which can be found {here}.",
|
||||
"walkthrough": "Start the Walkthrough",
|
||||
"start": "Edit now"
|
||||
},
|
||||
|
||||
@@ -26,6 +26,7 @@ export function coreContext() {
|
||||
var _deferred = new Set();
|
||||
|
||||
context.version = '2.16.0';
|
||||
context.privacyVersion = '20191217';
|
||||
|
||||
// create a special translation that contains the keys in place of the strings
|
||||
var tkeys = JSON.parse(JSON.stringify(dataEn)); // clone deep
|
||||
|
||||
+41
-41
@@ -3,53 +3,53 @@ import { uiModal } from './modal';
|
||||
|
||||
|
||||
export function uiLoading(context) {
|
||||
var _modalSelection = d3_select(null);
|
||||
var _message = '';
|
||||
var _blocking = false;
|
||||
let _modalSelection = d3_select(null);
|
||||
let _message = '';
|
||||
let _blocking = false;
|
||||
|
||||
|
||||
var loading = function(selection) {
|
||||
_modalSelection = uiModal(selection, _blocking);
|
||||
let loading = (selection) => {
|
||||
_modalSelection = uiModal(selection, _blocking);
|
||||
|
||||
var loadertext = _modalSelection.select('.content')
|
||||
.classed('loading-modal', true)
|
||||
.append('div')
|
||||
.attr('class', 'modal-section fillL');
|
||||
let loadertext = _modalSelection.select('.content')
|
||||
.classed('loading-modal', true)
|
||||
.append('div')
|
||||
.attr('class', 'modal-section fillL');
|
||||
|
||||
loadertext
|
||||
.append('img')
|
||||
.attr('class', 'loader')
|
||||
.attr('src', context.imagePath('loader-white.gif'));
|
||||
loadertext
|
||||
.append('img')
|
||||
.attr('class', 'loader')
|
||||
.attr('src', context.imagePath('loader-white.gif'));
|
||||
|
||||
loadertext
|
||||
.append('h3')
|
||||
.text(_message);
|
||||
|
||||
_modalSelection.select('button.close')
|
||||
.attr('class', 'hide');
|
||||
|
||||
return loading;
|
||||
};
|
||||
|
||||
|
||||
loading.message = function(_) {
|
||||
if (!arguments.length) return _message;
|
||||
_message = _;
|
||||
return loading;
|
||||
};
|
||||
|
||||
|
||||
loading.blocking = function(_) {
|
||||
if (!arguments.length) return _blocking;
|
||||
_blocking = _;
|
||||
return loading;
|
||||
};
|
||||
|
||||
|
||||
loading.close = function() {
|
||||
_modalSelection.remove();
|
||||
};
|
||||
loadertext
|
||||
.append('h3')
|
||||
.text(_message);
|
||||
|
||||
_modalSelection.select('button.close')
|
||||
.attr('class', 'hide');
|
||||
|
||||
return loading;
|
||||
};
|
||||
|
||||
|
||||
loading.message = (val) => {
|
||||
if (!arguments.length) return _message;
|
||||
_message = val;
|
||||
return loading;
|
||||
};
|
||||
|
||||
|
||||
loading.blocking = (val) => {
|
||||
if (!arguments.length) return _blocking;
|
||||
_blocking = val;
|
||||
return loading;
|
||||
};
|
||||
|
||||
|
||||
loading.close = () => {
|
||||
_modalSelection.remove();
|
||||
};
|
||||
|
||||
|
||||
return loading;
|
||||
}
|
||||
|
||||
+60
-63
@@ -1,78 +1,75 @@
|
||||
import {
|
||||
event as d3_event,
|
||||
select as d3_select
|
||||
} from 'd3-selection';
|
||||
import { event as d3_event, select as d3_select } from 'd3-selection';
|
||||
|
||||
import { svgIcon } from '../svg/icon';
|
||||
import { utilKeybinding } from '../util';
|
||||
|
||||
|
||||
export function uiModal(selection, blocking) {
|
||||
var keybinding = utilKeybinding('modal');
|
||||
var previous = selection.select('div.modal');
|
||||
var animate = previous.empty();
|
||||
let keybinding = utilKeybinding('modal');
|
||||
let previous = selection.select('div.modal');
|
||||
let animate = previous.empty();
|
||||
|
||||
previous.transition()
|
||||
.duration(200)
|
||||
.style('opacity', 0)
|
||||
.remove();
|
||||
previous.transition()
|
||||
.duration(200)
|
||||
.style('opacity', 0)
|
||||
.remove();
|
||||
|
||||
var shaded = selection
|
||||
.append('div')
|
||||
.attr('class', 'shaded')
|
||||
.style('opacity', 0);
|
||||
let shaded = selection
|
||||
.append('div')
|
||||
.attr('class', 'shaded')
|
||||
.style('opacity', 0);
|
||||
|
||||
shaded.close = function() {
|
||||
shaded
|
||||
.transition()
|
||||
.duration(200)
|
||||
.style('opacity',0)
|
||||
.remove();
|
||||
|
||||
modal
|
||||
.transition()
|
||||
.duration(200)
|
||||
.style('top','0px');
|
||||
|
||||
d3_select(document)
|
||||
.call(keybinding.unbind);
|
||||
};
|
||||
|
||||
|
||||
var modal = shaded
|
||||
.append('div')
|
||||
.attr('class', 'modal fillL');
|
||||
|
||||
if (!blocking) {
|
||||
shaded.on('click.remove-modal', function() {
|
||||
if (d3_event.target === this) {
|
||||
shaded.close();
|
||||
}
|
||||
});
|
||||
|
||||
modal.append('button')
|
||||
.attr('class', 'close')
|
||||
.on('click', shaded.close)
|
||||
.call(svgIcon('#iD-icon-close'));
|
||||
|
||||
keybinding
|
||||
.on('⌫', shaded.close)
|
||||
.on('⎋', shaded.close);
|
||||
|
||||
d3_select(document)
|
||||
.call(keybinding);
|
||||
}
|
||||
shaded.close = () => {
|
||||
shaded
|
||||
.transition()
|
||||
.duration(200)
|
||||
.style('opacity',0)
|
||||
.remove();
|
||||
|
||||
modal
|
||||
.append('div')
|
||||
.attr('class', 'content');
|
||||
.transition()
|
||||
.duration(200)
|
||||
.style('top','0px');
|
||||
|
||||
if (animate) {
|
||||
shaded.transition().style('opacity', 1);
|
||||
} else {
|
||||
shaded.style('opacity', 1);
|
||||
}
|
||||
d3_select(document)
|
||||
.call(keybinding.unbind);
|
||||
};
|
||||
|
||||
|
||||
return shaded;
|
||||
let modal = shaded
|
||||
.append('div')
|
||||
.attr('class', 'modal fillL');
|
||||
|
||||
if (!blocking) {
|
||||
shaded.on('click.remove-modal', () => {
|
||||
if (d3_event.target === this) {
|
||||
shaded.close();
|
||||
}
|
||||
});
|
||||
|
||||
modal
|
||||
.append('button')
|
||||
.attr('class', 'close')
|
||||
.on('click', shaded.close)
|
||||
.call(svgIcon('#iD-icon-close'));
|
||||
|
||||
keybinding
|
||||
.on('⌫', shaded.close)
|
||||
.on('⎋', shaded.close);
|
||||
|
||||
d3_select(document)
|
||||
.call(keybinding);
|
||||
}
|
||||
|
||||
modal
|
||||
.append('div')
|
||||
.attr('class', 'content');
|
||||
|
||||
if (animate) {
|
||||
shaded.transition().style('opacity', 1);
|
||||
} else {
|
||||
shaded.style('opacity', 1);
|
||||
}
|
||||
|
||||
return shaded;
|
||||
}
|
||||
|
||||
+51
-53
@@ -3,70 +3,68 @@ import { uiModal } from './modal';
|
||||
|
||||
|
||||
export function uiRestore(context) {
|
||||
return function(selection) {
|
||||
if (!context.history().lock() || !context.history().restorableChanges()) return;
|
||||
|
||||
return function(selection) {
|
||||
if (!context.history().lock() || !context.history().restorableChanges())
|
||||
return;
|
||||
let modalSelection = uiModal(selection, true);
|
||||
|
||||
var modalSelection = uiModal(selection, true);
|
||||
modalSelection.select('.modal')
|
||||
.attr('class', 'modal fillL');
|
||||
|
||||
modalSelection.select('.modal')
|
||||
.attr('class', 'modal fillL');
|
||||
let introModal = modalSelection.select('.content');
|
||||
|
||||
var introModal = modalSelection.select('.content');
|
||||
introModal
|
||||
.append('div')
|
||||
.attr('class', 'modal-section')
|
||||
.append('h3')
|
||||
.text(t('restore.heading'));
|
||||
|
||||
introModal
|
||||
.append('div')
|
||||
.attr('class', 'modal-section')
|
||||
.append('h3')
|
||||
.text(t('restore.heading'));
|
||||
introModal
|
||||
.append('div')
|
||||
.attr('class','modal-section')
|
||||
.append('p')
|
||||
.text(t('restore.description'));
|
||||
|
||||
introModal
|
||||
.append('div')
|
||||
.attr('class','modal-section')
|
||||
.append('p')
|
||||
.text(t('restore.description'));
|
||||
let buttonWrap = introModal
|
||||
.append('div')
|
||||
.attr('class', 'modal-actions');
|
||||
|
||||
var buttonWrap = introModal
|
||||
.append('div')
|
||||
.attr('class', 'modal-actions');
|
||||
let restore = buttonWrap
|
||||
.append('button')
|
||||
.attr('class', 'restore')
|
||||
.on('click', () => {
|
||||
context.history().restore();
|
||||
modalSelection.remove();
|
||||
});
|
||||
|
||||
var restore = buttonWrap
|
||||
.append('button')
|
||||
.attr('class', 'restore')
|
||||
.on('click', function() {
|
||||
context.history().restore();
|
||||
modalSelection.remove();
|
||||
});
|
||||
restore
|
||||
.append('svg')
|
||||
.attr('class', 'logo logo-restore')
|
||||
.append('use')
|
||||
.attr('xlink:href', '#iD-logo-restore');
|
||||
|
||||
restore
|
||||
.append('svg')
|
||||
.attr('class', 'logo logo-restore')
|
||||
.append('use')
|
||||
.attr('xlink:href', '#iD-logo-restore');
|
||||
restore
|
||||
.append('div')
|
||||
.text(t('restore.restore'));
|
||||
|
||||
restore
|
||||
.append('div')
|
||||
.text(t('restore.restore'));
|
||||
let reset = buttonWrap
|
||||
.append('button')
|
||||
.attr('class', 'reset')
|
||||
.on('click', () => {
|
||||
context.history().clearSaved();
|
||||
modalSelection.remove();
|
||||
});
|
||||
|
||||
var reset = buttonWrap
|
||||
.append('button')
|
||||
.attr('class', 'reset')
|
||||
.on('click', function() {
|
||||
context.history().clearSaved();
|
||||
modalSelection.remove();
|
||||
});
|
||||
reset
|
||||
.append('svg')
|
||||
.attr('class', 'logo logo-reset')
|
||||
.append('use')
|
||||
.attr('xlink:href', '#iD-logo-reset');
|
||||
|
||||
reset
|
||||
.append('svg')
|
||||
.attr('class', 'logo logo-reset')
|
||||
.append('use')
|
||||
.attr('xlink:href', '#iD-logo-reset');
|
||||
reset
|
||||
.append('div')
|
||||
.text(t('restore.reset'));
|
||||
|
||||
reset
|
||||
.append('div')
|
||||
.text(t('restore.reset'));
|
||||
|
||||
restore.node().focus();
|
||||
};
|
||||
restore.node().focus();
|
||||
};
|
||||
}
|
||||
|
||||
+76
-56
@@ -4,77 +4,97 @@ import { uiModal } from './modal';
|
||||
|
||||
|
||||
export function uiSplash(context) {
|
||||
return (selection) => {
|
||||
// Exception - if there are restorable changes, skip this splash screen.
|
||||
// This is because we currently only support one `uiModal` at a time
|
||||
// and we need to show them `uiRestore`` instead of this one.
|
||||
if (context.history().lock() && context.history().restorableChanges()) return;
|
||||
|
||||
return function(selection) {
|
||||
if (context.storage('sawSplash'))
|
||||
return;
|
||||
// If user has not seen this version of the privacy policy, show the splash again.
|
||||
let updateMessage = '';
|
||||
const sawPrivacyVersion = context.storage('sawPrivacyVersion');
|
||||
if (sawPrivacyVersion !== context.privacyVersion) {
|
||||
updateMessage = t('splash.privacy_update');
|
||||
context.storage('sawSplash', null);
|
||||
}
|
||||
|
||||
context.storage('sawSplash', true);
|
||||
if (context.storage('sawSplash')) return;
|
||||
|
||||
var modalSelection = uiModal(selection);
|
||||
context.storage('sawSplash', true);
|
||||
context.storage('sawPrivacyVersion', context.privacyVersion);
|
||||
|
||||
modalSelection.select('.modal')
|
||||
.attr('class', 'modal-splash modal');
|
||||
let modalSelection = uiModal(selection);
|
||||
|
||||
var introModal = modalSelection.select('.content')
|
||||
.append('div')
|
||||
.attr('class', 'fillL');
|
||||
modalSelection.select('.modal')
|
||||
.attr('class', 'modal-splash modal');
|
||||
|
||||
introModal
|
||||
.append('div')
|
||||
.attr('class','modal-section')
|
||||
.append('h3').text(t('splash.welcome'));
|
||||
let introModal = modalSelection.select('.content')
|
||||
.append('div')
|
||||
.attr('class', 'fillL');
|
||||
|
||||
introModal
|
||||
.append('div')
|
||||
.attr('class','modal-section')
|
||||
.append('p')
|
||||
.html(t('splash.text', {
|
||||
version: context.version,
|
||||
website: '<a href="http://ideditor.com/">ideditor.com</a>',
|
||||
github: '<a href="https://github.com/openstreetmap/iD">github.com</a>'
|
||||
}));
|
||||
introModal
|
||||
.append('div')
|
||||
.attr('class','modal-section')
|
||||
.append('h3')
|
||||
.text(t('splash.welcome'));
|
||||
|
||||
var buttonWrap = introModal
|
||||
.append('div')
|
||||
.attr('class', 'modal-actions');
|
||||
let modalSection = introModal
|
||||
.append('div')
|
||||
.attr('class','modal-section');
|
||||
|
||||
var walkthrough = buttonWrap
|
||||
.append('button')
|
||||
.attr('class', 'walkthrough')
|
||||
.on('click', function() {
|
||||
context.container().call(uiIntro(context));
|
||||
modalSelection.close();
|
||||
});
|
||||
modalSection
|
||||
.append('p')
|
||||
.html(t('splash.text', {
|
||||
version: context.version,
|
||||
website: '<a target="_blank" href="http://ideditor.blog/">ideditor.blog</a>',
|
||||
github: '<a target="_blank" href="https://github.com/openstreetmap/iD">github.com</a>'
|
||||
}));
|
||||
|
||||
walkthrough
|
||||
.append('svg')
|
||||
.attr('class', 'logo logo-walkthrough')
|
||||
.append('use')
|
||||
.attr('xlink:href', '#iD-logo-walkthrough');
|
||||
modalSection
|
||||
.append('p')
|
||||
.html(t('splash.privacy', {
|
||||
updateMessage: updateMessage,
|
||||
here: '<a target="_blank" href="https://github.com/openstreetmap/iD/blob/master/PRIVACY.md">here</a>'
|
||||
}));
|
||||
|
||||
walkthrough
|
||||
.append('div')
|
||||
.text(t('splash.walkthrough'));
|
||||
let buttonWrap = introModal
|
||||
.append('div')
|
||||
.attr('class', 'modal-actions');
|
||||
|
||||
var startEditing = buttonWrap
|
||||
.append('button')
|
||||
.attr('class', 'start-editing')
|
||||
.on('click', modalSelection.close);
|
||||
let walkthrough = buttonWrap
|
||||
.append('button')
|
||||
.attr('class', 'walkthrough')
|
||||
.on('click', () => {
|
||||
context.container().call(uiIntro(context));
|
||||
modalSelection.close();
|
||||
});
|
||||
|
||||
startEditing
|
||||
.append('svg')
|
||||
.attr('class', 'logo logo-features')
|
||||
.append('use')
|
||||
.attr('xlink:href', '#iD-logo-features');
|
||||
walkthrough
|
||||
.append('svg')
|
||||
.attr('class', 'logo logo-walkthrough')
|
||||
.append('use')
|
||||
.attr('xlink:href', '#iD-logo-walkthrough');
|
||||
|
||||
startEditing
|
||||
.append('div')
|
||||
.text(t('splash.start'));
|
||||
walkthrough
|
||||
.append('div')
|
||||
.text(t('splash.walkthrough'));
|
||||
|
||||
let startEditing = buttonWrap
|
||||
.append('button')
|
||||
.attr('class', 'start-editing')
|
||||
.on('click', modalSelection.close);
|
||||
|
||||
modalSelection.select('button.close')
|
||||
.attr('class','hide');
|
||||
startEditing
|
||||
.append('svg')
|
||||
.attr('class', 'logo logo-features')
|
||||
.append('use')
|
||||
.attr('xlink:href', '#iD-logo-features');
|
||||
|
||||
};
|
||||
startEditing
|
||||
.append('div')
|
||||
.text(t('splash.start'));
|
||||
|
||||
modalSelection.select('button.close')
|
||||
.attr('class','hide');
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user