mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-14 14:21:23 +00:00
optimize
This commit is contained in:
@@ -623,22 +623,6 @@ class Store {
|
|||||||
this.applyOperation(operation);
|
this.applyOperation(operation);
|
||||||
};
|
};
|
||||||
|
|
||||||
// map
|
|
||||||
deleteLocationPhotos = (rows_ids) => {
|
|
||||||
if (!Array.isArray(rows_ids) || rows_ids.length === 0) return;
|
|
||||||
|
|
||||||
const type = OPERATION_TYPE.DELETE_LOCATION_PHOTOS;
|
|
||||||
const valid_rows_ids = rows_ids.filter((rowId) => {
|
|
||||||
const row = getRowById(this.data, rowId);
|
|
||||||
return row && this.context.canModifyRow(row);
|
|
||||||
});
|
|
||||||
const deleted_rows = valid_rows_ids.map((rowId) => getRowById(this.data, rowId));
|
|
||||||
const operation = this.createOperation({
|
|
||||||
type, repo_id: this.repoId, rows_ids, deleted_rows
|
|
||||||
});
|
|
||||||
this.applyOperation(operation);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Store;
|
export default Store;
|
||||||
|
@@ -335,21 +335,6 @@ export default function apply(data, operation) {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// map
|
|
||||||
case OPERATION_TYPE.DELETE_LOCATION_PHOTOS: {
|
|
||||||
const { rows_ids } = operation;
|
|
||||||
const idNeedDeletedMap = rows_ids.reduce((currIdNeedDeletedMap, rowId) => ({ ...currIdNeedDeletedMap, [rowId]: true }), {});
|
|
||||||
data.rows = data.rows.filter((row) => !idNeedDeletedMap[row._id]);
|
|
||||||
data.recordsCount = data.rows.length;
|
|
||||||
// delete rows in id_row_map
|
|
||||||
rows_ids.forEach(rowId => {
|
|
||||||
delete data.id_row_map[rowId];
|
|
||||||
});
|
|
||||||
|
|
||||||
data.row_ids = data.row_ids.filter(row_id => !idNeedDeletedMap[row_id]);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@@ -34,9 +34,6 @@ export const OPERATION_TYPE = {
|
|||||||
|
|
||||||
// tag
|
// tag
|
||||||
UPDATE_FILE_TAGS: 'update_file_tags',
|
UPDATE_FILE_TAGS: 'update_file_tags',
|
||||||
|
|
||||||
// map
|
|
||||||
DELETE_LOCATION_PHOTOS: 'delete_location_photos',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const COLUMN_DATA_OPERATION_TYPE = {
|
export const COLUMN_DATA_OPERATION_TYPE = {
|
||||||
@@ -77,8 +74,6 @@ export const OPERATION_ATTRIBUTES = {
|
|||||||
[OPERATION_TYPE.MODIFY_SETTINGS]: ['repo_id', 'view_id', 'settings'],
|
[OPERATION_TYPE.MODIFY_SETTINGS]: ['repo_id', 'view_id', 'settings'],
|
||||||
|
|
||||||
[OPERATION_TYPE.UPDATE_FILE_TAGS]: ['repo_id', 'file_tags_data'],
|
[OPERATION_TYPE.UPDATE_FILE_TAGS]: ['repo_id', 'file_tags_data'],
|
||||||
|
|
||||||
[OPERATION_TYPE.DELETE_LOCATION_PHOTOS]: ['repo_id', 'rows_ids', 'deleted_rows'],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const UNDO_OPERATION_TYPE = [
|
export const UNDO_OPERATION_TYPE = [
|
||||||
|
@@ -1,114 +1,43 @@
|
|||||||
import React, { useCallback, useEffect, useState } from 'react';
|
import React, { useCallback, useEffect, useMemo } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import deepCopy from 'deep-copy';
|
import deepCopy from 'deep-copy';
|
||||||
import { CenteredLoading } from '@seafile/sf-metadata-ui-component';
|
|
||||||
import Gallery from '../../gallery/main';
|
import Gallery from '../../gallery/main';
|
||||||
import { gettext } from '../../../../utils/constants';
|
import { gettext } from '../../../../utils/constants';
|
||||||
import { EVENT_BUS_TYPE, PER_LOAD_NUMBER } from '../../../constants';
|
import { EVENT_BUS_TYPE } from '../../../constants';
|
||||||
import metadataAPI from '../../../api';
|
import metadataAPI from '../../../api';
|
||||||
import { normalizeColumns } from '../../../utils/column';
|
|
||||||
import Metadata from '../../../model/metadata';
|
|
||||||
import { Utils } from '../../../../utils/utils';
|
import { Utils } from '../../../../utils/utils';
|
||||||
import toaster from '../../../../components/toast';
|
import toaster from '../../../../components/toast';
|
||||||
import { useMetadataView } from '../../../hooks/metadata-view';
|
import { useMetadataView } from '../../../hooks/metadata-view';
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
const ClusterPhotos = ({ view, markerIds, onClose, onDelete }) => {
|
const ClusterPhotos = ({ metadata, markerIds, onClose }) => {
|
||||||
const [isLoading, setLoading] = useState(true);
|
const { store, duplicateRecord, addFolder } = useMetadataView();
|
||||||
const [metadata, setMetadata] = useState({ rows: [] });
|
|
||||||
|
|
||||||
const { deleteFilesCallback } = useMetadataView();
|
|
||||||
|
|
||||||
const repoID = window.sfMetadataContext.getSetting('repoID');
|
const repoID = window.sfMetadataContext.getSetting('repoID');
|
||||||
|
|
||||||
const loadData = useCallback((view) => {
|
const clusterMetadata = useMemo(() => {
|
||||||
setLoading(true);
|
const filteredRows = metadata.rows.filter(row => markerIds.includes(row._id));
|
||||||
const params = {
|
|
||||||
view_id: view._id,
|
|
||||||
start: 0,
|
|
||||||
limit: PER_LOAD_NUMBER,
|
|
||||||
};
|
|
||||||
metadataAPI.getMetadata(repoID, params).then(res => {
|
|
||||||
const rows = res?.data?.results || [];
|
|
||||||
const filteredRows = rows.filter(row => markerIds.includes(row._id));
|
|
||||||
const columns = normalizeColumns(res?.data?.metadata);
|
|
||||||
const metadata = new Metadata({ rows: filteredRows, columns, view });
|
|
||||||
metadata.hasMore = rows.length >= PER_LOAD_NUMBER;
|
|
||||||
setMetadata(metadata);
|
|
||||||
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.MAP_VIEW, metadata.view);
|
|
||||||
setLoading(false);
|
|
||||||
}).catch(error => {
|
|
||||||
const errorMessage = Utils.getErrorMsg(error);
|
|
||||||
toaster.danger(errorMessage);
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
}, [repoID, markerIds]);
|
|
||||||
|
|
||||||
const deletedByIds = useCallback((ids) => {
|
|
||||||
if (!Array.isArray(ids) || ids.length === 0) return;
|
|
||||||
const newMetadata = deepCopy(metadata);
|
const newMetadata = deepCopy(metadata);
|
||||||
const idNeedDeletedMap = ids.reduce((currIdNeedDeletedMap, rowId) => ({ ...currIdNeedDeletedMap, [rowId]: true }), {});
|
newMetadata.rows = filteredRows;
|
||||||
newMetadata.rows = newMetadata.rows.filter((row) => !idNeedDeletedMap[row._id]);
|
return newMetadata;
|
||||||
newMetadata.row_ids = newMetadata.row_ids.filter((id) => !idNeedDeletedMap[id]);
|
}, [metadata, markerIds]);
|
||||||
|
|
||||||
// delete rows in id_row_map
|
|
||||||
ids.forEach(rowId => {
|
|
||||||
delete newMetadata.id_row_map[rowId];
|
|
||||||
});
|
|
||||||
newMetadata.recordsCount = newMetadata.row_ids.length;
|
|
||||||
setMetadata(newMetadata);
|
|
||||||
|
|
||||||
if (newMetadata.rows.length === 0) {
|
|
||||||
onClose && onClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
onDelete(ids);
|
|
||||||
}, [metadata, onClose, onDelete]);
|
|
||||||
|
|
||||||
const handelDelete = useCallback((deletedImages, { success_callback } = {}) => {
|
const handelDelete = useCallback((deletedImages, { success_callback } = {}) => {
|
||||||
if (!deletedImages.length) return;
|
if (!deletedImages.length) return;
|
||||||
let recordIds = [];
|
let recordIds = [];
|
||||||
let paths = [];
|
deletedImages.forEach((record) => recordIds.push(record.id));
|
||||||
let fileNames = [];
|
store.deleteRecords(recordIds, { success_callback });
|
||||||
deletedImages.forEach((record) => {
|
}, [store]);
|
||||||
const { id, parentDir, name } = record || {};
|
|
||||||
if (parentDir && name) {
|
|
||||||
const path = Utils.joinPath(parentDir, name);
|
|
||||||
paths.push(path);
|
|
||||||
fileNames.push(name);
|
|
||||||
recordIds.push(id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
window.sfMetadataContext.batchDeleteFiles(repoID, paths).then(res => {
|
|
||||||
deletedByIds(recordIds);
|
|
||||||
deleteFilesCallback(paths, fileNames);
|
|
||||||
let msg = fileNames.length > 1
|
|
||||||
? gettext('Successfully deleted {name} and {n} other items')
|
|
||||||
: gettext('Successfully deleted {name}');
|
|
||||||
msg = msg.replace('{name}', fileNames[0])
|
|
||||||
.replace('{n}', fileNames.length - 1);
|
|
||||||
toaster.success(msg);
|
|
||||||
success_callback && success_callback();
|
|
||||||
}).catch(error => {
|
|
||||||
toaster.danger(gettext('Failed to delete records'));
|
|
||||||
});
|
|
||||||
}, [deleteFilesCallback, repoID, deletedByIds]);
|
|
||||||
|
|
||||||
const handleViewChange = useCallback((update) => {
|
const handleViewChange = useCallback((update) => {
|
||||||
metadataAPI.modifyView(repoID, view._id, update).then(res => {
|
metadataAPI.modifyView(repoID, metadata.view._id, update).then(res => {
|
||||||
const newView = { ...view, ...update };
|
|
||||||
loadData(newView);
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
const errorMessage = Utils.getErrorMsg(error);
|
const errorMessage = Utils.getErrorMsg(error);
|
||||||
toaster.danger(errorMessage);
|
toaster.danger(errorMessage);
|
||||||
});
|
});
|
||||||
}, [view, repoID, loadData]);
|
}, [metadata, repoID,]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
loadData({ _id: view._id, sorts: view.sorts });
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unsubscribeViewChange = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.MAP_GALLERY_VIEW_CHANGE, handleViewChange);
|
const unsubscribeViewChange = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.MAP_GALLERY_VIEW_CHANGE, handleViewChange);
|
||||||
@@ -119,27 +48,22 @@ const ClusterPhotos = ({ view, markerIds, onClose, onDelete }) => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
isLoading ? (
|
|
||||||
<CenteredLoading />
|
|
||||||
) : (
|
|
||||||
<div className="sf-metadata-view-map sf-metadata-map-photos-container">
|
<div className="sf-metadata-view-map sf-metadata-map-photos-container">
|
||||||
<div className="sf-metadata-map-photos-header" onClick={onClose}>
|
<div className="sf-metadata-map-photos-header">
|
||||||
<div className="sf-metadata-map-photos-header-back">
|
<div className="sf-metadata-map-photos-header-back" onClick={onClose}>
|
||||||
<i className="sf3-font sf3-font-arrow rotate-180"></i>
|
<i className="sf3-font sf3-font-arrow rotate-180"></i>
|
||||||
</div>
|
</div>
|
||||||
<div className="sf-metadata-map-location">{gettext('Location')}</div>
|
<div className="sf-metadata-map-location">{gettext('Location')}</div>
|
||||||
</div>
|
</div>
|
||||||
<Gallery metadata={metadata} onDelete={handelDelete} />
|
<Gallery metadata={clusterMetadata} onDelete={handelDelete} duplicateRecord={duplicateRecord} onAddFolder={addFolder} />
|
||||||
</div>
|
</div>
|
||||||
)
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
ClusterPhotos.propTypes = {
|
ClusterPhotos.propTypes = {
|
||||||
view: PropTypes.object,
|
metadata: PropTypes.object,
|
||||||
markerIds: PropTypes.array,
|
markerIds: PropTypes.array,
|
||||||
onClose: PropTypes.func,
|
onClose: PropTypes.func,
|
||||||
onDelete: PropTypes.func,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ClusterPhotos;
|
export default ClusterPhotos;
|
||||||
|
@@ -14,7 +14,7 @@ import './index.css';
|
|||||||
const Map = () => {
|
const Map = () => {
|
||||||
const [showGallery, setShowGallery] = useState(false);
|
const [showGallery, setShowGallery] = useState(false);
|
||||||
const [markerIds, setMarkerIds] = useState([]);
|
const [markerIds, setMarkerIds] = useState([]);
|
||||||
const { metadata, store } = useMetadataView();
|
const { metadata } = useMetadataView();
|
||||||
|
|
||||||
const repoID = window.sfMetadataContext.getSetting('repoID');
|
const repoID = window.sfMetadataContext.getSetting('repoID');
|
||||||
|
|
||||||
@@ -51,10 +51,6 @@ const Map = () => {
|
|||||||
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.TOGGLE_MAP_VIEW_TOOLBAR, false);
|
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.TOGGLE_MAP_VIEW_TOOLBAR, false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onDeleteLocationPhotos = useCallback((ids) => {
|
|
||||||
store.deleteLocationPhotos(ids);
|
|
||||||
}, [store]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.MAP_VIEW, metadata.view);
|
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.MAP_VIEW, metadata.view);
|
||||||
}, [metadata.view]);
|
}, [metadata.view]);
|
||||||
@@ -62,7 +58,7 @@ const Map = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{showGallery ? (
|
{showGallery ? (
|
||||||
<ClusterPhotos view={metadata.view} markerIds={markerIds} onClose={closeGallery} onDelete={onDeleteLocationPhotos} />
|
<ClusterPhotos metadata={metadata} markerIds={markerIds} onClose={closeGallery} />
|
||||||
) : (
|
) : (
|
||||||
<Main validImages={validImages} onOpen={openGallery} />
|
<Main validImages={validImages} onOpen={openGallery} />
|
||||||
)}
|
)}
|
||||||
|
@@ -71,10 +71,26 @@ const Main = ({ validImages, onOpen }) => {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const saveMapState = useCallback(() => {
|
||||||
|
if (!mapRef.current) return;
|
||||||
|
const point = mapRef.current.getCenter && mapRef.current.getCenter();
|
||||||
|
const zoom = mapRef.current.getZoom && mapRef.current.getZoom();
|
||||||
|
window.sfMetadataContext.localStorage.setItem('map-center', point);
|
||||||
|
window.sfMetadataContext.localStorage.setItem('map-zoom', zoom);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const loadMapState = useCallback(() => {
|
||||||
|
const savedCenter = window.sfMetadataContext.localStorage.getItem('map-center') || DEFAULT_POSITION;
|
||||||
|
const savedZoom = window.sfMetadataContext.localStorage.getItem('map-zoom') || DEFAULT_ZOOM;
|
||||||
|
return { center: savedCenter, zoom: savedZoom };
|
||||||
|
}, []);
|
||||||
|
|
||||||
const onClickMarker = useCallback((e, markers) => {
|
const onClickMarker = useCallback((e, markers) => {
|
||||||
|
saveMapState();
|
||||||
|
|
||||||
const imageIds = markers.map(marker => marker._imageId);
|
const imageIds = markers.map(marker => marker._imageId);
|
||||||
onOpen(imageIds);
|
onOpen(imageIds);
|
||||||
}, [onOpen]);
|
}, [onOpen, saveMapState]);
|
||||||
|
|
||||||
const renderMarkersBatch = useCallback(() => {
|
const renderMarkersBatch = useCallback(() => {
|
||||||
if (!validImages.length || !clusterRef.current) return;
|
if (!validImages.length || !clusterRef.current) return;
|
||||||
@@ -110,23 +126,23 @@ const Main = ({ validImages, onOpen }) => {
|
|||||||
|
|
||||||
const renderBaiduMap = useCallback(() => {
|
const renderBaiduMap = useCallback(() => {
|
||||||
if (!mapRef.current || !window.BMap.Map) return;
|
if (!mapRef.current || !window.BMap.Map) return;
|
||||||
let mapCenter = window.sfMetadataContext.localStorage.getItem('map-center') || DEFAULT_POSITION;
|
let { center, zoom } = loadMapState();
|
||||||
// ask for user location
|
// ask for user location
|
||||||
if (navigator.geolocation) {
|
if (navigator.geolocation) {
|
||||||
navigator.geolocation.getCurrentPosition((userInfo) => {
|
navigator.geolocation.getCurrentPosition((userInfo) => {
|
||||||
mapCenter = { lng: userInfo.coords.longitude, lat: userInfo.coords.latitude };
|
center = { lng: userInfo.coords.longitude, lat: userInfo.coords.latitude };
|
||||||
window.sfMetadataContext.localStorage.setItem('map-center', mapCenter);
|
window.sfMetadataContext.localStorage.setItem('map-center', center);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!isValidPosition(mapCenter?.lng, mapCenter?.lat)) return;
|
if (!isValidPosition(center?.lng, center?.lat)) return;
|
||||||
|
|
||||||
const gcPosition = wgs84_to_gcj02(mapCenter.lng, mapCenter.lat);
|
const gcPosition = wgs84_to_gcj02(center.lng, center.lat);
|
||||||
const bdPosition = gcj02_to_bd09(gcPosition.lng, gcPosition.lat);
|
const bdPosition = gcj02_to_bd09(gcPosition.lng, gcPosition.lat);
|
||||||
const { lng, lat } = bdPosition;
|
const { lng, lat } = bdPosition;
|
||||||
|
|
||||||
mapRef.current = new window.BMap.Map('sf-metadata-map-container', { enableMapClick: false });
|
mapRef.current = new window.BMap.Map('sf-metadata-map-container', { enableMapClick: false });
|
||||||
const point = new window.BMap.Point(lng, lat);
|
const point = new window.BMap.Point(lng, lat);
|
||||||
mapRef.current.centerAndZoom(point, DEFAULT_ZOOM);
|
mapRef.current.centerAndZoom(point, zoom);
|
||||||
mapRef.current.enableScrollWheelZoom(true);
|
mapRef.current.enableScrollWheelZoom(true);
|
||||||
|
|
||||||
const savedValue = window.sfMetadataContext.localStorage.getItem('map-type');
|
const savedValue = window.sfMetadataContext.localStorage.getItem('map-type');
|
||||||
@@ -138,7 +154,7 @@ const Main = ({ validImages, onOpen }) => {
|
|||||||
|
|
||||||
batchIndexRef.current = 0;
|
batchIndexRef.current = 0;
|
||||||
renderMarkersBatch();
|
renderMarkersBatch();
|
||||||
}, [addMapController, initializeClusterer, initializeUserMarker, renderMarkersBatch, getMapType]);
|
}, [addMapController, initializeClusterer, initializeUserMarker, renderMarkersBatch, getMapType, loadMapState]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const switchMapTypeSubscribe = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.SWITCH_MAP_TYPE, (newType) => {
|
const switchMapTypeSubscribe = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.SWITCH_MAP_TYPE, (newType) => {
|
||||||
@@ -150,7 +166,7 @@ const Main = ({ validImages, onOpen }) => {
|
|||||||
switchMapTypeSubscribe();
|
switchMapTypeSubscribe();
|
||||||
};
|
};
|
||||||
|
|
||||||
}, [getMapType]);
|
}, [getMapType, saveMapState]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (mapInfo.type === MAP_PROVIDER.B_MAP) {
|
if (mapInfo.type === MAP_PROVIDER.B_MAP) {
|
||||||
|
@@ -30,13 +30,30 @@ const customImageOverlay = (center, image, callback) => {
|
|||||||
this._div.append(label);
|
this._div.append(label);
|
||||||
|
|
||||||
const eventHandler = (event) => {
|
const eventHandler = (event) => {
|
||||||
event.stopPropagation();
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this._callback && this._callback(event, [{ _imageId: this._imageId }]);
|
this._callback && this._callback(event, [{ _imageId: this._imageId }]);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Utils.isDesktop()) {
|
if (Utils.isDesktop()) {
|
||||||
this._div.addEventListener('click', eventHandler);
|
let clickTimeout;
|
||||||
|
this._div.addEventListener('click', (event) => {
|
||||||
|
if (clickTimeout) {
|
||||||
|
clearTimeout(clickTimeout);
|
||||||
|
clickTimeout = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clickTimeout = setTimeout(() => {
|
||||||
|
eventHandler(event);
|
||||||
|
clickTimeout = null;
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
this._div.addEventListener('dblclick', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (clickTimeout) {
|
||||||
|
clearTimeout(clickTimeout);
|
||||||
|
clickTimeout = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this._div.addEventListener('touchend', eventHandler);
|
this._div.addEventListener('touchend', eventHandler);
|
||||||
}
|
}
|
||||||
|
@@ -580,14 +580,29 @@ var BMapLib = window.BMapLib = BMapLib || {};
|
|||||||
|
|
||||||
var thatMap = this._map;
|
var thatMap = this._map;
|
||||||
var thatBounds = this.getBounds();
|
var thatBounds = this.getBounds();
|
||||||
|
let clickTimeout;
|
||||||
this._clusterMarker.addEventListener("click", (event) => {
|
this._clusterMarker.addEventListener("click", (event) => {
|
||||||
// thatMap.setViewport(thatBounds);
|
if (clickTimeout) {
|
||||||
|
clearTimeout(clickTimeout);
|
||||||
|
clickTimeout = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clickTimeout = setTimeout(() => {
|
||||||
if (this._markerClusterer && typeof this._markerClusterer.getCallback() === 'function') {
|
if (this._markerClusterer && typeof this._markerClusterer.getCallback() === 'function') {
|
||||||
const markers = this._markers;
|
const markers = this._markers;
|
||||||
this._markerClusterer.getCallback()(event, markers);
|
this._markerClusterer.getCallback()(event, markers);
|
||||||
}
|
}
|
||||||
|
clickTimeout = null;
|
||||||
|
}, 300); // Delay to differentiate between single and double click
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this._clusterMarker.addEventListener("dblclick", (event) => {
|
||||||
|
if (clickTimeout) {
|
||||||
|
clearTimeout(clickTimeout);
|
||||||
|
clickTimeout = null;
|
||||||
|
}
|
||||||
|
// Do nothing on double click
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user