Skip to content

Commit 5c70d29

Browse files
committed
Add the possibility to flag features on OSMCha
1 parent df4dbcb commit 5c70d29

File tree

5 files changed

+197
-13
lines changed

5 files changed

+197
-13
lines changed

lib/config.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
export const config = {
22
overpassBase: 'https://overpass.maptime.in/api/interpreter',
3+
osmchaBase: 'https://osmcha.org/',
34
osmBase: 'https://www.openstreetmap.org/api/0.6/',
4-
mapboxAccessToken: 'pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJjam10OXpmc2YwMXI5M3BqeTRiMDBqMHVyIn0.LIcIDe3TZLSDdTWDoojzNg',
5+
mapboxAccessToken:
6+
'pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJjam10OXpmc2YwMXI5M3BqeTRiMDBqMHVyIn0.LIcIDe3TZLSDdTWDoojzNg',
57
S3_URL: 'https://s3.amazonaws.com/mapbox/real-changesets/production/'
68
};

lib/featureDiff.js

Lines changed: 130 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,26 @@ import PropTypes from 'prop-types';
55
import { propsDiff } from './propsDiff';
66
import { Dropdown } from './dropdown';
77
import { cmap } from './render';
8+
import { config } from './config';
89

910
//Calculates the difference in the selected features
1011

1112
export const displayDiff = function(
1213
id,
1314
featureMap,
15+
changesetId,
1416
metadataContainer,
1517
tagsContainer,
1618
membersContainer
1719
) {
1820
var featuresWithId = featureMap[id];
1921

2022
reactDOM(
21-
<MetadataTable featuresWithId={featuresWithId} id={id} />,
23+
<MetadataTable
24+
featuresWithId={featuresWithId}
25+
id={id}
26+
changesetId={changesetId}
27+
/>,
2228
metadataContainer
2329
);
2430
reactDOM(<TagsTable featuresWithId={featuresWithId} />, tagsContainer);
@@ -31,7 +37,76 @@ export const displayDiff = function(
3137
}
3238
};
3339

34-
const MetadataTable = function({ featuresWithId, id }) {
40+
class FlagButton extends React.PureComponent {
41+
constructor(props) {
42+
super(props);
43+
this.state = {
44+
flagState: null
45+
};
46+
}
47+
flagAsBad() {
48+
fetch(
49+
`${config.osmchaBase}api/v1/changesets/${this.props.changesetId}/review-feature/${this.props.type}-${this.props.id}/`,
50+
{
51+
method: 'PUT',
52+
headers: {
53+
'Content-Type': 'application/json',
54+
Authorization: `Token ${this.props.token}`
55+
}
56+
}
57+
)
58+
.then(() => this.setState({ flagState: 'success' }))
59+
.catch(() => this.setState({ flagState: 'error' }));
60+
}
61+
62+
removeFlag() {
63+
fetch(
64+
`${config.osmchaBase}api/v1/changesets/${this.props.changesetId}/review-feature/${this.props.type}-${this.props.id}/`,
65+
{
66+
method: 'DELETE',
67+
headers: {
68+
'Content-Type': 'application/json',
69+
Authorization: `Token ${this.props.token}`
70+
}
71+
}
72+
).then(() => this.setState({ flagState: null }));
73+
}
74+
75+
render() {
76+
return (
77+
<span>
78+
{this.state.flagState === null && (
79+
<button
80+
className="cmap-btn cmap-noselect cmap-pointer cmap-c-link-osm"
81+
onClick={() => this.flagAsBad()}
82+
>
83+
Add to flagged
84+
</button>
85+
)}
86+
{this.state.flagState === 'success' && (
87+
<button
88+
className="cmap-btn cmap-noselect cmap-pointer cmap-c-link-osm b--red bg-white"
89+
onClick={() => this.removeFlag()}
90+
>
91+
<ThumbsDownIcon style={{ verticalAlign: 'middle' }} />
92+
<span className="pl6">Flagged</span>
93+
<i className="gg-close"></i>
94+
</button>
95+
)}
96+
{this.state.flagState === 'error' && <span> Failed</span>}
97+
</span>
98+
);
99+
}
100+
}
101+
102+
FlagButton.propTypes = {
103+
id: PropTypes.string.isRequired,
104+
type: PropTypes.string.isRequired,
105+
token: PropTypes.string.isRequired,
106+
changesetId: PropTypes.number.isRequired
107+
};
108+
109+
const MetadataTable = function({ featuresWithId, id, changesetId }) {
35110
const type = featuresWithId[0].properties.type;
36111
const metadataProps = featuresWithId.map(function(f) {
37112
var filteredProps = Object.assign({}, f.properties);
@@ -41,13 +116,16 @@ const MetadataTable = function({ featuresWithId, id }) {
41116
delete filteredProps.action;
42117
return filteredProps;
43118
});
119+
const token = localStorage.getItem('token');
44120

45121
const metadataHeader = (
46122
<div className="cmap-space-between">
47-
<span>
48-
{type.toUpperCase()}: {id}
49-
</span>
50-
<span>
123+
<div className="cmap-block">
124+
<span>
125+
{type.toUpperCase()}: {id}
126+
</span>
127+
</div>
128+
<div id="cmap-feature-btns">
51129
<Dropdown
52130
display="History"
53131
options={[
@@ -90,7 +168,15 @@ const MetadataTable = function({ featuresWithId, id }) {
90168
}
91169
]}
92170
/>
93-
</span>
171+
{token && (
172+
<FlagButton
173+
token={token}
174+
type={type}
175+
id={id}
176+
changesetId={changesetId}
177+
/>
178+
)}
179+
</div>
94180
</div>
95181
);
96182
return (
@@ -103,7 +189,8 @@ const MetadataTable = function({ featuresWithId, id }) {
103189
};
104190
MetadataTable.propTypes = {
105191
featuresWithId: PropTypes.array.isRequired,
106-
id: PropTypes.string.isRequired
192+
id: PropTypes.string.isRequired,
193+
changesetId: PropTypes.number.isRequired
107194
};
108195

109196
const TagsTable = function({ featuresWithId }) {
@@ -293,7 +380,7 @@ const DiffColumn = function({ diff, prop, type, propClass }) {
293380
target="_blank"
294381
rel="noopener noreferrer"
295382
className="cmap-changeset-link"
296-
href={`//osmcha.org/changesets/${diff[prop][type]}`}
383+
href={`${config.osmchaBase}changesets/${diff[prop][type]}`}
297384
>
298385
{diff[prop][type]}
299386
</a>
@@ -309,3 +396,37 @@ DiffColumn.propTypes = {
309396
type: PropTypes.string.isRequired,
310397
propClass: PropTypes.string
311398
};
399+
400+
const ThumbsDownIcon = props => (
401+
<svg width="14px" height="14px" viewBox="0 0 100 99" {...props}>
402+
<g
403+
id="Symbols"
404+
stroke="none"
405+
strokeWidth="1"
406+
fill="none"
407+
fillRule="evenodd"
408+
>
409+
<g id="icons/Thumbs-down-trans" fill="#CC2C47">
410+
<g
411+
id="Thumbs-up"
412+
transform="translate(50.000000, 49.500000) rotate(-180.000000) translate(-50.000000, -49.500000) "
413+
>
414+
<path
415+
d="M41.8167977,42 L8.65058811,42 L8.65058811,42 C8.15292909,42 7.65635568,42.0464369 7.16732524,42.1387068 C2.82565287,42.9578902 -0.0298885833,47.1415905 0.789294882,51.4832629 L7.77042696,88.4832629 C8.483559,92.2628627 11.7854321,95 15.6317202,95 L15.6317202,95 L92,95 C96.418278,95 100,91.418278 100,87 L100,87 L100,50 C100,45.581722 96.418278,42 92,42 L64.8136835,42 C64.848108,41.339148 64.8257549,40.6662103 64.7423209,39.9866948 L61.0862406,10.2103103 C60.3122149,3.90637709 54.5743956,-0.576498687 48.2704624,0.197526982 L48.2704624,0.197526982 L48.2704624,0.197526982 C41.9665292,0.97155265 37.4836534,6.70937199 38.2576791,13.0133052 L38.2576791,13.0133052 L41.8167977,42 Z"
416+
id="Combined-Shape"
417+
fillOpacity="0.3"
418+
></path>
419+
<rect
420+
id="Rectangle-7"
421+
fillOpacity="0.9"
422+
x="76"
423+
y="37"
424+
width="24"
425+
height="62"
426+
rx="8"
427+
></rect>
428+
</g>
429+
</g>
430+
</g>
431+
</svg>
432+
);

lib/map.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,7 @@ export class Map {
12571257
displayDiff(
12581258
featureId,
12591259
featureMap,
1260+
this.result.changeset.id,
12601261
document.querySelector('.cmap-diff-metadata'),
12611262
document.querySelector('.cmap-diff-tags'),
12621263
document.querySelector('.cmap-diff-members')

lib/sidebar.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import React from 'react';
22
import moment from 'moment';
3+
34
import { getBounds } from './helpers';
45
import { cmap } from './render';
6+
import { config } from './config';
57

68
export function getFeatures(features) {
79
var keys = Object.keys(features);
@@ -202,7 +204,7 @@ export class Sidebar extends React.PureComponent {
202204
target="_blank"
203205
rel="noreferrer"
204206
className="cmap-hlist-item cmap-noselect cmap-pointer cmap-c-link-osmcha"
205-
href={'https://osmcha.org/changesets/' + changesetId + '/'}
207+
href={`${config.osmchaBase}changesets/${changesetId}/`}
206208
>
207209
OSMCha
208210
</a>

public/css/style.css

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,24 @@
3939
padding: 5px 10px;
4040
}
4141

42+
.cmap-container .cmap-block {
43+
position: relative;
44+
display: block !important;
45+
padding-bottom: 6px !important;
46+
}
47+
48+
.cmap-container .cmap-btn {
49+
font-weight: bold;
50+
margin: 0px 3px;
51+
background-color: rgba(0, 0, 0, 0.1);
52+
color: rgb(102, 102, 102) !important;
53+
padding: 3px 12px 1px;
54+
font-size: 12px !important;
55+
cursor: pointer;
56+
border: 1px solid rgba(0, 0, 0, 0.05);
57+
border-radius: 4px !important;
58+
}
59+
4260
.cmap-sidebar section .cmap-heading {
4361
text-transform: uppercase;
4462
font-size: 0.9em;
@@ -258,7 +276,6 @@
258276
display: inline-block !important;
259277
}
260278
.cmap-container .cmap-space-between {
261-
display: flex;
262279
justify-content: space-between;
263280
align-items: center;
264281
}
@@ -380,7 +397,7 @@
380397
background-position: -3px;
381398
}
382399

383-
.cmap-container .cmap-dropdown-content {
400+
.cmap-container .cmap-dropdown-content, .cmap-button {
384401
display: block;
385402
margin-top: 5px;
386403
position: fixed;
@@ -498,3 +515,44 @@
498515
.pointer {
499516
cursor: pointer;
500517
}
518+
519+
.pl6 {
520+
padding-left: 6px !important;
521+
}
522+
523+
.b--red {
524+
border: 1px solid #ff8280 !important;
525+
}
526+
527+
.bg-white {
528+
background-color: #fff !important;
529+
}
530+
531+
.gg-close {
532+
box-sizing: border-box;
533+
position: relative;
534+
display: inline-block;
535+
transform: scale(var(--ggs,1));
536+
width: 10px;
537+
height: 10px;
538+
vertical-align: top !important;
539+
border: 2px solid transparent;
540+
border-radius: 40px
541+
}
542+
.gg-close::after,
543+
.gg-close::before {
544+
content: "";
545+
display: block;
546+
box-sizing: border-box;
547+
position: absolute;
548+
width: 10px;
549+
height: 2px;
550+
background: currentColor;
551+
transform: rotate(45deg);
552+
border-radius: 5px;
553+
top: 8px;
554+
left: 1px
555+
}
556+
.gg-close::after {
557+
transform: rotate(-45deg)
558+
}

0 commit comments

Comments
 (0)