mirror of
https://github.com/umap-project/umap.git
synced 2025-04-29 20:02:36 +02:00
feat(sync): Display the state of the connection to the users
This commit is contained in:
parent
6643fe0a2b
commit
aac5185b16
5 changed files with 64 additions and 31 deletions
|
@ -48,7 +48,7 @@ const MAX_RECONNECT_DELAY = 32000;
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export class SyncEngine {
|
export class SyncEngine {
|
||||||
constructor(map, urls, server) {
|
constructor(map, websocketTokenURI, websocketURI, server) {
|
||||||
this.updaters = {
|
this.updaters = {
|
||||||
map: new MapUpdater(map),
|
map: new MapUpdater(map),
|
||||||
feature: new FeatureUpdater(map),
|
feature: new FeatureUpdater(map),
|
||||||
|
@ -58,14 +58,12 @@ export class SyncEngine {
|
||||||
this._operations = new Operations()
|
this._operations = new Operations()
|
||||||
this._server = server
|
this._server = server
|
||||||
|
|
||||||
// Store URIs to avoid persisting the map
|
this._websocketTokenURI = websocketTokenURI
|
||||||
// mainly to ensure separation of concerns.
|
this._websocketURI = websocketURI
|
||||||
this._websocketTokenURI = urls.get('map_websocket_auth_token', {
|
|
||||||
map_id: map.options.umap_id,
|
|
||||||
})
|
|
||||||
this._websocketURI = map.options.websocketURI
|
|
||||||
this._reconnectTimeout = null;
|
this._reconnectTimeout = null;
|
||||||
this._reconnectDelay = RECONNECT_DELAY;
|
this._reconnectDelay = RECONNECT_DELAY;
|
||||||
|
this.websocketConnected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,9 +90,13 @@ export class SyncEngine {
|
||||||
onConnection() {
|
onConnection() {
|
||||||
this._reconnectTimeout = null;
|
this._reconnectTimeout = null;
|
||||||
this._reconnectDelay = RECONNECT_DELAY;
|
this._reconnectDelay = RECONNECT_DELAY;
|
||||||
|
this.websocketConnected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
reconnect() {
|
reconnect() {
|
||||||
|
this.websocketConnected = false;
|
||||||
|
this.updaters.map.update({ key: 'numberOfConnectedPeers' })
|
||||||
|
|
||||||
console.log("reconnecting in ", this._reconnectDelay, " ms")
|
console.log("reconnecting in ", this._reconnectDelay, " ms")
|
||||||
this._reconnectTimeout = setTimeout(() => {
|
this._reconnectTimeout = setTimeout(() => {
|
||||||
if (this._reconnectDelay < MAX_RECONNECT_DELAY) {
|
if (this._reconnectDelay < MAX_RECONNECT_DELAY) {
|
||||||
|
|
|
@ -661,30 +661,43 @@ const ControlsMixin = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.options.syncEnabled) {
|
||||||
const connectedPeers = this.sync.getNumberOfConnectedPeers()
|
const connectedPeers = this.sync.getNumberOfConnectedPeers()
|
||||||
if (connectedPeers !== 0) {
|
let hoverMessage = ''
|
||||||
|
|
||||||
|
if (connectedPeers !== 0 || !this.sync.websocketConnected) {
|
||||||
const connectedPeersCount = L.DomUtil.createButton(
|
const connectedPeersCount = L.DomUtil.createButton(
|
||||||
'leaflet-control-connected-peers',
|
'leaflet-control-connected-peers',
|
||||||
rightContainer,
|
rightContainer,
|
||||||
''
|
''
|
||||||
)
|
)
|
||||||
|
if (this.sync.websocketConnected) {
|
||||||
|
connectedPeersCount.innerHTML =
|
||||||
|
'<span>' + this.sync.getNumberOfConnectedPeers() + '</span>'
|
||||||
|
hoverMessage = L._(
|
||||||
|
'{connectedPeers} peer(s) currently connected to this map',
|
||||||
|
{
|
||||||
|
connectedPeers: connectedPeers,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
connectedPeersCount.innerHTML = '<span>' + L._('Disconnected') + '</span>'
|
||||||
|
connectedPeersCount.classList.add('disconnected')
|
||||||
|
hoverMessage = L._('Reconnecting in {seconds} seconds', {
|
||||||
|
seconds: this.sync._reconnectDelay / 1000,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
L.DomEvent.on(connectedPeersCount, 'mouseover', () => {
|
L.DomEvent.on(connectedPeersCount, 'mouseover', () => {
|
||||||
this.tooltip.open({
|
this.tooltip.open({
|
||||||
content: L._('{connectedPeers} peer(s) currently connected to this map', {
|
content: hoverMessage,
|
||||||
connectedPeers: connectedPeers,
|
|
||||||
}),
|
|
||||||
anchor: connectedPeersCount,
|
anchor: connectedPeersCount,
|
||||||
position: 'bottom',
|
position: 'bottom',
|
||||||
delay: 500,
|
delay: 500,
|
||||||
duration: 5000,
|
duration: 5000,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const updateConnectedPeersCount = () => {
|
|
||||||
connectedPeersCount.innerHTML =
|
|
||||||
'<span>' + this.sync.getNumberOfConnectedPeers() + '</span>'
|
|
||||||
}
|
}
|
||||||
updateConnectedPeersCount()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.help.getStartedLink(rightContainer)
|
this.help.getStartedLink(rightContainer)
|
||||||
|
|
|
@ -68,7 +68,14 @@ U.Map = L.Map.extend({
|
||||||
this.server = new U.ServerRequest()
|
this.server = new U.ServerRequest()
|
||||||
this.request = new U.Request()
|
this.request = new U.Request()
|
||||||
|
|
||||||
this.sync_engine = new U.SyncEngine(this, this.urls, this.server)
|
// Store URIs to avoid persisting the map
|
||||||
|
// mainly to ensure separation of concerns.
|
||||||
|
const websocketTokenURI = this.urls.get('map_websocket_auth_token', {
|
||||||
|
map_id: this.options.umap_id,
|
||||||
|
})
|
||||||
|
const websocketURI = this.options.websocketURI
|
||||||
|
|
||||||
|
this.sync_engine = new U.SyncEngine(this, websocketTokenURI, websocketURI, this.server)
|
||||||
this.sync = this.sync_engine.proxy(this)
|
this.sync = this.sync_engine.proxy(this)
|
||||||
|
|
||||||
this.initLoader()
|
this.initLoader()
|
||||||
|
@ -206,7 +213,9 @@ U.Map = L.Map.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
initSyncEngine: async function () {
|
initSyncEngine: async function () {
|
||||||
|
// This.options.websocketEnabled is set by the server admin
|
||||||
if (this.options.websocketEnabled === false) return
|
if (this.options.websocketEnabled === false) return
|
||||||
|
// This.options.syncEnabled is set by the user in the map settings
|
||||||
if (this.options.syncEnabled !== true) {
|
if (this.options.syncEnabled !== true) {
|
||||||
this.sync.stop()
|
this.sync.stop()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -518,6 +518,12 @@ ul.photon-autocomplete {
|
||||||
background-color: var(--color-lightCyan);
|
background-color: var(--color-lightCyan);
|
||||||
color: var(--color-dark);
|
color: var(--color-dark);
|
||||||
}
|
}
|
||||||
|
.leaflet-container .leaflet-control-connected-peers.disconnected,
|
||||||
|
.leaflet-container .leaflet-control-connected-peers.disconnected:hover
|
||||||
|
{
|
||||||
|
background-color: var(--color-red);
|
||||||
|
color: var(--color-darkGray);
|
||||||
|
}
|
||||||
|
|
||||||
.leaflet-container .leaflet-control-edit-disable:before,
|
.leaflet-container .leaflet-control-edit-disable:before,
|
||||||
.leaflet-container .leaflet-control-edit-save:before,
|
.leaflet-container .leaflet-control-edit-save:before,
|
||||||
|
|
|
@ -8,8 +8,11 @@ import { MapUpdater } from '../js/modules/sync/updaters.js'
|
||||||
import { SyncEngine, Operations } from '../js/modules/sync/engine.js'
|
import { SyncEngine, Operations } from '../js/modules/sync/engine.js'
|
||||||
|
|
||||||
describe('SyncEngine', () => {
|
describe('SyncEngine', () => {
|
||||||
|
const websocketTokenURI = 'http://localhost:8000/api/v1/maps/1/websocket_auth_token/'
|
||||||
|
const websocketURI = 'ws://localhost:8000/ws/maps/1/'
|
||||||
|
|
||||||
it('should initialize methods even before start', () => {
|
it('should initialize methods even before start', () => {
|
||||||
const engine = new SyncEngine({})
|
const engine = new SyncEngine({}, websocketTokenURI, websocketURI, {})
|
||||||
engine.upsert()
|
engine.upsert()
|
||||||
engine.update()
|
engine.update()
|
||||||
engine.delete()
|
engine.delete()
|
||||||
|
|
Loading…
Reference in a new issue