mirror of
https://github.com/umap-project/umap.git
synced 2025-04-28 19:42:36 +02:00
commit
3e9982c8cb
9 changed files with 82 additions and 78 deletions
|
@ -29,6 +29,11 @@
|
|||
background-color: var(--color-lightCyan);
|
||||
color: var(--color-dark);
|
||||
}
|
||||
.dark [type=button].connected-peers:hover
|
||||
{
|
||||
text-decoration: none;
|
||||
border: 0.5px solid var(--color-brightCyan);
|
||||
}
|
||||
.dark .off.connected-peers {
|
||||
background-color: var(--color-lightGray);
|
||||
color: var(--color-darkGray);
|
||||
|
|
|
@ -1,59 +1,61 @@
|
|||
#umap-tooltip-container {
|
||||
line-height: 20px;
|
||||
.umap-tooltip-container {
|
||||
padding: 5px 10px;
|
||||
width: auto;
|
||||
min-width: 100px;
|
||||
max-width: 300px;
|
||||
position: absolute;
|
||||
box-shadow: var(--block-shadow);
|
||||
display: none;
|
||||
background-color: rgba(40, 40, 40, 0.9);
|
||||
color: #eeeeec;
|
||||
font-size: 0.8em;
|
||||
border-radius: 2px;
|
||||
border-radius: var(--border-radius);
|
||||
z-index: var(--zindex-tooltip);
|
||||
font-weight: normal;
|
||||
max-width: 300px;
|
||||
--tooltip-color: var(--color-darkGray);
|
||||
background-color: var(--tooltip-color);
|
||||
--arrow-size: 8px;
|
||||
}
|
||||
.umap-tooltip #umap-tooltip-container {
|
||||
.tooltip-accent {
|
||||
--tooltip-color: var(--color-lightCyan);
|
||||
}
|
||||
.umap-tooltip .umap-tooltip-container {
|
||||
display: block;
|
||||
}
|
||||
#umap-tooltip-container.tooltip-top:after {
|
||||
.umap-tooltip-container.tooltip-top:after {
|
||||
top: 100%;
|
||||
left: calc(50% - 11px);
|
||||
left: calc(50% - var(--arrow-size));
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border-top-color: rgba(30, 30, 30, 0.8);
|
||||
border-width: 11px;
|
||||
margin-left: calc(-50% + 21px);
|
||||
border-top-color: var(--tooltip-color);
|
||||
border-width: var(--arrow-size);
|
||||
margin-left: calc(-50% + 2 * var(--arrow-size));
|
||||
}
|
||||
#umap-tooltip-container.tooltip-bottom:before {
|
||||
top: -22px;
|
||||
left: calc(50% - 11px);
|
||||
.umap-tooltip-container.tooltip-bottom:before {
|
||||
top: calc(var(--arrow-size) * -2);
|
||||
left: calc(50% - var(--arrow-size));
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border-top-color: rgba(30, 30, 30, 0.7);
|
||||
border-width: 11px;
|
||||
border-top-color: var(--tooltip-color);
|
||||
border-width: var(--arrow-size);
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
#umap-tooltip-container.tooltip.tooltip-left:after {
|
||||
left: 100%;
|
||||
top: 50%;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border-color: rgba(136, 183, 213, 0);
|
||||
border-left-color: #333;
|
||||
border-width: 11px;
|
||||
margin-top: -10px;
|
||||
.tooltip-accent ul {
|
||||
padding-top: var(--small-box-padding);
|
||||
padding-bottom: var(--small-box-padding);
|
||||
}
|
||||
.tooltip-accent li {
|
||||
background-color: var(--color-light);
|
||||
color: var(--color-dark);
|
||||
padding: var(--small-box-padding);
|
||||
margin-bottom: var(--small-box-padding);
|
||||
}
|
||||
.tooltip-accent li:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -146,9 +146,8 @@ export class SyncEngine {
|
|||
updater.applyMessage(operation)
|
||||
}
|
||||
|
||||
getNumberOfConnectedPeers() {
|
||||
if (this.peers) return Object.keys(this.peers).length
|
||||
return 0
|
||||
getPeers() {
|
||||
return this.peers || {}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,7 @@ import { DomEvent } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|||
import { translate } from '../i18n.js'
|
||||
import { WithTemplate } from '../utils.js'
|
||||
import ContextMenu from './contextmenu.js'
|
||||
import * as Utils from '../utils.js'
|
||||
|
||||
const TOP_BAR_TEMPLATE = `
|
||||
<div class="umap-main-edit-toolbox with-transition dark">
|
||||
|
@ -96,17 +97,22 @@ export class TopBar extends WithTemplate {
|
|||
}
|
||||
})
|
||||
|
||||
const connectedPeers = this._umap.sync.getNumberOfConnectedPeers()
|
||||
this.elements.peers.addEventListener('mouseover', () => {
|
||||
if (!connectedPeers) return
|
||||
const connectedPeers = this._umap.sync.getPeers()
|
||||
if (!Object.keys(connectedPeers).length) return
|
||||
const ul = Utils.loadTemplate(
|
||||
`<ul>${Object.entries(connectedPeers)
|
||||
.sort((el) => el !== this._umap.user?.name)
|
||||
.map(([id, name]) => `<li>${name || translate('Anonymous')}</li>`)
|
||||
.join('')}</ul>`
|
||||
)
|
||||
this._umap.tooltip.open({
|
||||
content: translate('{connectedPeers} peer(s) currently connected to this map', {
|
||||
connectedPeers: connectedPeers,
|
||||
}),
|
||||
content: ul,
|
||||
anchor: this.elements.peers,
|
||||
position: 'bottom',
|
||||
delay: 500,
|
||||
duration: 5000,
|
||||
accent: true,
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -2,27 +2,18 @@ export class Positioned {
|
|||
openAt({ anchor, position }) {
|
||||
if (anchor && position === 'top') {
|
||||
this.anchorTop(anchor)
|
||||
} else if (anchor && position === 'left') {
|
||||
this.anchorLeft(anchor)
|
||||
} else if (anchor && position === 'bottom') {
|
||||
this.anchorBottom(anchor)
|
||||
} else {
|
||||
this.anchorAbsolute()
|
||||
}
|
||||
}
|
||||
|
||||
anchorAbsolute() {
|
||||
this.container.className = ''
|
||||
const left =
|
||||
this.parent.offsetLeft +
|
||||
this.parent.clientWidth / 2 -
|
||||
this.container.clientWidth / 2
|
||||
const top = this.parent.offsetTop + 75
|
||||
this.setPosition({ top: top, left: left })
|
||||
toggleClassPosition(position) {
|
||||
this.container.classList.toggle('tooltip-bottom', position === 'bottom')
|
||||
this.container.classList.toggle('tooltip-top', position === 'top')
|
||||
}
|
||||
|
||||
anchorTop(el) {
|
||||
this.container.className = 'tooltip-top'
|
||||
this.toggleClassPosition('top')
|
||||
const coords = this.getPosition(el)
|
||||
this.setPosition({
|
||||
left: coords.left - 10,
|
||||
|
@ -31,23 +22,15 @@ export class Positioned {
|
|||
}
|
||||
|
||||
anchorBottom(el) {
|
||||
this.container.className = 'tooltip-bottom'
|
||||
this.toggleClassPosition('bottom')
|
||||
const coords = this.getPosition(el)
|
||||
const selfCoords = this.getPosition(this.container)
|
||||
this.setPosition({
|
||||
left: coords.left,
|
||||
left: coords.left + coords.width / 2 - selfCoords.width / 2,
|
||||
top: coords.bottom + 11,
|
||||
})
|
||||
}
|
||||
|
||||
anchorLeft(el) {
|
||||
this.container.className = 'tooltip-left'
|
||||
const coords = this.getPosition(el)
|
||||
this.setPosition({
|
||||
top: coords.top,
|
||||
right: document.documentElement.offsetWidth - coords.left + 11,
|
||||
})
|
||||
}
|
||||
|
||||
getPosition(el) {
|
||||
return el.getBoundingClientRect()
|
||||
}
|
||||
|
|
|
@ -1,24 +1,32 @@
|
|||
import { DomEvent, DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
||||
import { DomEvent } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
||||
import { translate } from '../i18n.js'
|
||||
import { Positioned } from './base.js'
|
||||
import * as Utils from '../utils.js'
|
||||
|
||||
export default class Tooltip extends Positioned {
|
||||
constructor(parent) {
|
||||
super()
|
||||
this.parent = parent
|
||||
this.container = DomUtil.create('div', 'with-transition', this.parent)
|
||||
this.container.id = 'umap-tooltip-container'
|
||||
this.container = Utils.loadTemplate('<div class="umap-tooltip-container"></div>')
|
||||
this.parent.appendChild(this.container)
|
||||
DomEvent.disableClickPropagation(this.container)
|
||||
DomEvent.on(this.container, 'contextmenu', DomEvent.stopPropagation) // Do not activate our custom context menu.
|
||||
DomEvent.on(this.container, 'wheel', DomEvent.stopPropagation)
|
||||
DomEvent.on(this.container, 'MozMousePixelScroll', DomEvent.stopPropagation)
|
||||
this.container.addEventListener('contextmenu', (event) => event.stopPropagation()) // Do not activate our custom context menu.
|
||||
this.container.addEventListener('wheel', (event) => event.stopPropagation())
|
||||
this.container.addEventListener('MozMousePixelScroll', (event) =>
|
||||
event.stopPropagation()
|
||||
)
|
||||
}
|
||||
|
||||
open(opts) {
|
||||
this.container.classList.toggle('tooltip-accent', Boolean(opts.accent))
|
||||
const showIt = () => {
|
||||
if (opts.content.nodeType === 1) {
|
||||
this.container.appendChild(opts.content)
|
||||
} else {
|
||||
this.container.innerHTML = Utils.escapeHTML(opts.content)
|
||||
}
|
||||
this.parent.classList.add('umap-tooltip')
|
||||
this.openAt(opts)
|
||||
L.DomUtil.addClass(this.parent, 'umap-tooltip')
|
||||
this.container.innerHTML = U.Utils.escapeHTML(opts.content)
|
||||
}
|
||||
this.TOOLTIP_ID = window.setTimeout(L.bind(showIt, this), opts.delay || 0)
|
||||
const id = this.TOOLTIP_ID
|
||||
|
@ -26,7 +34,7 @@ export default class Tooltip extends Positioned {
|
|||
this.close(id)
|
||||
}
|
||||
if (opts.anchor) {
|
||||
L.DomEvent.once(opts.anchor, 'mouseout', closeIt)
|
||||
opts.anchor.addEventListener('mouseout', closeIt, { once: true })
|
||||
}
|
||||
if (opts.duration !== Number.POSITIVE_INFINITY) {
|
||||
window.setTimeout(closeIt, opts.duration || 3000)
|
||||
|
@ -38,9 +46,9 @@ export default class Tooltip extends Positioned {
|
|||
// in the meantime. Eg. after a mouseout from the anchor.
|
||||
window.clearTimeout(id)
|
||||
if (id && id !== this.TOOLTIP_ID) return
|
||||
this.container.className = ''
|
||||
this.toggleClassPosition()
|
||||
this.container.innerHTML = ''
|
||||
this.setPosition({})
|
||||
L.DomUtil.removeClass(this.parent, 'umap-tooltip')
|
||||
this.parent.classList.remove('umap-tooltip')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1357,7 +1357,7 @@ export default class Umap extends ServerStored {
|
|||
numberOfConnectedPeers: () => {
|
||||
Utils.eachElement('.connected-peers span', (el) => {
|
||||
if (this.sync.websocketConnected) {
|
||||
el.textContent = this.sync.getNumberOfConnectedPeers()
|
||||
el.textContent = Object.keys(this.sync.getPeers()).length
|
||||
} else {
|
||||
el.textContent = translate('Disconnected')
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
--control-size: 36px;
|
||||
--border-radius: 4px;
|
||||
--box-padding: 20px;
|
||||
--small-box-padding: 4px;
|
||||
--box-margin: 14px;
|
||||
--text-margin: 7px;
|
||||
|
||||
|
|
|
@ -484,12 +484,12 @@ def test_vertexmarker_not_shown_if_too_many(live_server, map, page, settings):
|
|||
page.get_by_role("button", name="Import data", exact=True).click()
|
||||
page.locator("path").click()
|
||||
page.get_by_role("link", name="Toggle edit mode (⇧+Click)").click()
|
||||
expect(page.locator("#umap-tooltip-container")).to_contain_text(
|
||||
expect(page.locator(".umap-tooltip-container")).to_contain_text(
|
||||
"Please zoom in to edit the geometry"
|
||||
)
|
||||
expect(page.locator(".leaflet-vertex-icon")).to_be_hidden()
|
||||
page.get_by_label("Zoom in").click()
|
||||
expect(page.locator("#umap-tooltip-container")).to_contain_text(
|
||||
expect(page.locator(".umap-tooltip-container")).to_contain_text(
|
||||
"Please zoom in to edit the geometry"
|
||||
)
|
||||
page.get_by_label("Zoom in").click()
|
||||
|
@ -497,6 +497,6 @@ def test_vertexmarker_not_shown_if_too_many(live_server, map, page, settings):
|
|||
page.get_by_label("Zoom out").click()
|
||||
page.wait_for_timeout(500)
|
||||
expect(page.locator(".leaflet-vertex-icon")).to_be_hidden()
|
||||
expect(page.locator("#umap-tooltip-container")).to_contain_text(
|
||||
expect(page.locator(".umap-tooltip-container")).to_contain_text(
|
||||
"Please zoom in to edit the geometry"
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue