Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions cypress/e2e/tooltips.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,36 @@ describe('Shows Tooltips', () => {
cy.get('.leaflet-tooltip-bottom').should('not.exist');
});

it('Has A Sticky Marker Tooltip If No Pointer Device Is Available', () => {
cy.window().then((win) => {
cy.stub(win, 'matchMedia').callsFake(() => ({
matches: false,
}));
});

cy.get('.leaflet-tooltip-stickynote').should('not.exist');

cy.toolbarButton('marker').click();
cy.get('.leaflet-tooltip-stickynote').should('exist');

cy.get('.leaflet-tooltip-stickynote').then((el) => {
expect(el).to.have.text('Place the markers by clicking the map');
});

cy.get(mapSelector).click(290, 250);

cy.wait(500);

cy.get('.leaflet-tooltip-stickynote').then((el) => {
expect(el.length).to.eq(1);
expect(el).to.have.text('Place the markers by clicking the map');
});

cy.toolbarButton('marker').click();

cy.get('.leaflet-tooltip-stickynote').should('not.exist');
});

it('Has Rectangle Tooltips', () => {
cy.get('.leaflet-tooltip-bottom').should('not.exist');
cy.toolbarButton('rectangle').click();
Expand Down
1 change: 1 addition & 0 deletions src/assets/translations/en.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"tooltips": {
"placeMarker": "Click to place marker",
"placeMarkerTip": "Place the markers by clicking the map",
"firstVertex": "Click to place first vertex",
"continueLine": "Click to continue drawing",
"finishLine": "Click any existing marker to finish",
Expand Down
1 change: 1 addition & 0 deletions src/assets/translations/fi.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"tooltips": {
"placeMarker": "Klikkaa asettaaksesi merkin",
"placeMarkerTip": "Aseta merkkejä kartalle klikkaamalla.",
"firstVertex": "Klikkaa asettaakseni ensimmäisen osuuden",
"continueLine": "Klikkaa jatkaaksesi piirtämistä",
"finishLine": "Klikkaa olemassa olevaa merkkiä lopettaaksesi",
Expand Down
4 changes: 4 additions & 0 deletions src/css/layers.css
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,7 @@
.pm-textarea.pm-hasfocus {
cursor: auto;
}

.leaflet-tooltip-stickynote::before {
display: none;
}
62 changes: 61 additions & 1 deletion src/js/Draw/L.PM.Draw.Marker.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Draw from './L.PM.Draw';
import { getTranslation } from '../helpers';
import { getTranslation, deviceHasFinePointer } from '../helpers';

Draw.Marker = Draw.extend({
initialize(map) {
Expand Down Expand Up @@ -63,6 +63,8 @@ Draw.Marker = Draw.extend({
});
}

this._setupTouchScreenTips();

// fire drawstart event
this._fireDrawStart();
this._setGlobalDrawMode();
Expand Down Expand Up @@ -194,4 +196,62 @@ Draw.Marker = Draw.extend({
this._hintMarker?.setIcon(this.options.markerStyle.icon);
}
},
_setupTouchScreenTips() {
let markerHintTip = null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add the variable to the context: this._markerHintTip


this._map.on('pm:drawstart', (event) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventlistener should be only added if the global option for mobile tooltip is enabled

if (event.shape === 'Marker' && !deviceHasFinePointer()) {
// Hides the "hint marker" as that is confusing for touch screen users.
const drawMarker = this._map.pm.Draw.Marker;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

creating the variable drawMarker is obsolete

drawMarker._hintMarker.remove();

// Creates the touch screen hint "permanently" (while using the tool)
// sticked at the top of the map.
markerHintTip = L.tooltip([0, 0], {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we should use a plain html element, positioned absolute, instead. Then there would be no need to recalculate the position with every move

className: 'leaflet-tooltip-stickynote',
content: getTranslation('tooltips.placeMarkerTip'),
direction: 'bottom',
permanent: true,
}).addTo(this._map);

const updateHandler = () => this._updateHintPosition(markerHintTip);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The call should be throttled this._markerHintTipUpdateHandler = L.Util.throttle(

Reference:

if (!this.throttledReInitDrag) {
this.throttledReInitDrag = L.Util.throttle(
this.reinitGlobalDragMode,
100,
this
);
}


updateHandler();
this._map.on('zoomlevelschange resize move', updateHandler, this);
}
});
this._map.on('pm:drawend', (event) => {
if (event.shape === 'Marker' && markerHintTip) {
markerHintTip.remove();
markerHintTip = null;
this._map.off(
'zoomlevelschange resize move',
this._updateHintPosition,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't remove the correct event listener function

this
);
}
});
},
_updateHintPosition(markerHintTip) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to have markerHintTip as argument, if assigned to the context this._markerHintTip

if (!markerHintTip) {
return;
}

const bounds = this._map.getBounds();

// Calculate the longitude distance of the map's visible area. This allows
// for an easy way to figure out the center point of the map.
const distance = this._map.distance(
bounds.getNorthWest(),
bounds.getNorthEast()
);

// Calculate new bounds with the current latitude distance of the visible
// map from the northwest point of the map. Within these new bounds, the
// east border is at the center of the map.
const newBounds = bounds.getNorthWest().toBounds(distance);

// Set the hint at the top center of the map.
markerHintTip.setLatLng([bounds.getNorth(), newBounds.getEast()]);
},
});
12 changes: 12 additions & 0 deletions src/js/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,3 +282,15 @@ export function getRenderer(layer) {
layer._renderer
);
}

/**
* Checks if the device has a "fine" pointer (such as a mouse) and can therefore
* display the "cursor marker", i.e. the marker that follows the mouse
* movements.
*
* @returns {Boolean} A boolean indicating whether the device has a pointer
* device with a visible cursor.
*/
export function deviceHasFinePointer() {
return window.matchMedia('(pointer:fine)').matches;
}