diff --git a/frontend/src/components/dirent-detail/dirent-details/file-details/index.js b/frontend/src/components/dirent-detail/dirent-details/file-details/index.js index f32b6bfe73..e79f086b6b 100644 --- a/frontend/src/components/dirent-detail/dirent-details/file-details/index.js +++ b/frontend/src/components/dirent-detail/dirent-details/file-details/index.js @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import PropTypes from 'prop-types'; import DetailItem from '../../detail-item'; import Collapse from './collapse'; @@ -13,7 +13,6 @@ import { useMetadataStatus } from '../../../../hooks'; import { CAPTURE_INFO_SHOW_KEY } from '../../../../constants'; import People from '../../people'; import FileTag from './file-tag'; -import Location from '../../../../metadata/components/metadata-details/location'; import './index.css'; @@ -58,7 +57,6 @@ const getImageInfoValue = (key, value) => { const FileDetails = React.memo(({ repoID, dirent, path, direntDetail, isShowRepoTags = true, repoTags, fileTagList, onFileTagChanged }) => { const [isCaptureInfoShow, setCaptureInfoShow] = useState(false); - const [currentPosition, setCurrentPosition] = useState(null); const { enableFaceRecognition, enableMetadata } = useMetadataStatus(); const { record } = useMetadataDetails(); @@ -67,10 +65,6 @@ const FileDetails = React.memo(({ repoID, dirent, path, direntDetail, isShowRepo const lastModifiedTimeField = useMemo(() => ({ type: CellType.MTIME, name: gettext('Last modified time') }), []); const tagsField = useMemo(() => ({ type: CellType.SINGLE_SELECT, name: gettext('Tags') }), []); - const onPositionChange = useCallback((position) => { - setCurrentPosition(position); - }, []); - useEffect(() => { const savedValue = window.localStorage.getItem(CAPTURE_INFO_SHOW_KEY) === 'true'; setCaptureInfoShow(savedValue); @@ -108,14 +102,7 @@ const FileDetails = React.memo(({ repoID, dirent, path, direntDetail, isShowRepo /> )} - {enableMetadata && ( -
-
- -
- -
- )} + {enableMetadata && } ); diff --git a/frontend/src/components/dirent-detail/dirent-details/index.js b/frontend/src/components/dirent-detail/dirent-details/index.js index 572433758b..44199c0719 100644 --- a/frontend/src/components/dirent-detail/dirent-details/index.js +++ b/frontend/src/components/dirent-detail/dirent-details/index.js @@ -11,6 +11,8 @@ import ObjectUtils from '../../../utils/object'; import { MetadataDetailsProvider } from '../../../metadata/hooks'; import AIIcon from '../../../metadata/components/metadata-details/ai-icon'; import SettingsIcon from '../../../metadata/components/metadata-details/settings-icon'; +import { eventBus } from '../../common/event-bus'; +import { EVENT_BUS_TYPE } from '../../../metadata/constants'; import './index.css'; @@ -53,6 +55,10 @@ class DirentDetails extends React.Component { } } + componentWillUnmount() { + eventBus.dispatch(EVENT_BUS_TYPE.CLEAR_MAP_INSTANCE); + } + renderImage = () => { const { dirent } = this.props; if (!dirent) return null; diff --git a/frontend/src/metadata/components/metadata-details/index.js b/frontend/src/metadata/components/metadata-details/index.js index 7eb5b7f1f8..f8bc984d47 100644 --- a/frontend/src/metadata/components/metadata-details/index.js +++ b/frontend/src/metadata/components/metadata-details/index.js @@ -1,5 +1,4 @@ -import React, { useEffect, useMemo } from 'react'; -import PropTypes from 'prop-types'; +import React, { useMemo } from 'react'; import CellFormatter from '../cell-formatter'; import DetailEditor from '../detail-editor'; import DetailItem from '../../../components/dirent-detail/detail-item'; @@ -10,28 +9,16 @@ import { PRIVATE_COLUMN_KEY, IMAGE_PRIVATE_COLUMN_KEYS } from '../../constants'; import { useMetadataDetails } from '../../hooks'; import { checkIsDir } from '../../utils/row'; import { FOLDER_NOT_DISPLAY_COLUMN_KEYS } from './constants'; +import Location from './location'; import './index.css'; -const MetadataDetails = ({ onPositionChange }) => { - const { isLoading, canModifyRecord, record, columns, onChange, modifyColumnData, updateFileTags } = useMetadataDetails(); +const MetadataDetails = () => { + const { canModifyRecord, record, columns, onChange, modifyColumnData, updateFileTags } = useMetadataDetails(); const displayColumns = useMemo(() => columns.filter(c => c.shown), [columns]); - useEffect(() => { - if (!record) return; - const fileName = getFileNameFromRecord(record); - const isImage = Utils.imageCheck(fileName); - - if (isImage) { - const position = getCellValueByColumn(record, { - key: PRIVATE_COLUMN_KEY.LOCATION - }); - onPositionChange?.(position); - } - }, [record, onPositionChange]); - - if (isLoading || !record || !record._id) return null; + if (!record || !record._id) return null; const fileName = getFileNameFromRecord(record); const isImageOrVideo = Utils.imageCheck(fileName) || Utils.videoCheck(fileName); @@ -43,7 +30,9 @@ const MetadataDetails = ({ onPositionChange }) => { if (isDir && FOLDER_NOT_DISPLAY_COLUMN_KEYS.includes(field.key)) return null; const value = getCellValueByColumn(record, field); - if (field.key === PRIVATE_COLUMN_KEY.LOCATION) return null; + if (field.key === PRIVATE_COLUMN_KEY.LOCATION && Utils.imageCheck(fileName) && value) { + return ; + } let canEdit = canModifyRecord && field.editable; if (!isImageOrVideo && IMAGE_PRIVATE_COLUMN_KEYS.includes(field.key)) { @@ -79,8 +68,4 @@ const MetadataDetails = ({ onPositionChange }) => { ); }; -MetadataDetails.propTypes = { - onPositionChange: PropTypes.func, -}; - export default MetadataDetails; diff --git a/frontend/src/metadata/components/metadata-details/location/index.js b/frontend/src/metadata/components/metadata-details/location/index.js index 342d68d891..2e7f96cb61 100644 --- a/frontend/src/metadata/components/metadata-details/location/index.js +++ b/frontend/src/metadata/components/metadata-details/location/index.js @@ -6,13 +6,14 @@ import { wgs84_to_gcj02, gcj02_to_bd09 } from '../../../../utils/coord-transform import { MAP_TYPE } from '../../../../constants'; import Loading from '../../../../components/loading'; import { gettext, baiduMapKey, googleMapKey, googleMapId } from '../../../../utils/constants'; -import { CellType, GEOLOCATION_FORMAT, PRIVATE_COLUMN_KEY } from '../../../constants'; +import { CellType, EVENT_BUS_TYPE, GEOLOCATION_FORMAT, PRIVATE_COLUMN_KEY } from '../../../constants'; import { getGeolocationDisplayString } from '../../../utils/cell'; import { isValidPosition } from '../../../utils/validate'; import DetailItem from '../../../../components/dirent-detail/detail-item'; import { getColumnDisplayName } from '../../../utils/column'; import { createBMapZoomControl } from '../../map-controller'; import { Utils } from '../../../../utils/utils'; +import { eventBus } from '../../../../components/common/event-bus'; import './index.css'; @@ -33,47 +34,38 @@ class Location extends React.Component { address: '', isLoading: true, }; - this.initMapTriggered = false; } componentDidMount() { - this.initMap(this.props.position); + this.initMap(); + + this.unsubscribeClearMapInstance = eventBus.subscribe(EVENT_BUS_TYPE.CLEAR_MAP_INSTANCE, () => { + window.mapInstance = null; + delete window.mapInstance; + }); } componentDidUpdate(prevProps) { - const { position: prevPosition } = prevProps; - const { position: currPosition } = this.props; - - const isSamePosition = prevPosition?.lng === currPosition?.lng && - prevPosition?.lat === currPosition?.lat; - - if (isSamePosition) return; - - const shouldUpdateMap = this.map && currPosition?.lng && currPosition?.lat; - - if (shouldUpdateMap) { - this.addMarkerByPosition(currPosition.lng, currPosition.lat); - } else if (!this.map && currPosition) { - if (!this.initMapTriggered) { - this.initMapTriggered = true; - this.initMap(currPosition); - } - } + const { position, record } = this.props; + if (!isValidPosition(position?.lng, position?.lat)) return; + if (prevProps.position?.lng === position?.lng && prevProps.position?.lat === position?.lat) return; + this.currentPosition = position; + this.addMarkerByPosition(position.lng, position.lat); + this.setState({ address: record._location_translated?.address }); } componentWillUnmount() { - if (this.map) { - if (this.mapType === MAP_TYPE.B_MAP) { - this.map.destroy(); - } else if (this.mapType === MAP_TYPE.G_MAP) { - window.google.maps.event.clearInstanceListeners(this.map); - } - } - this.map = null; + this.unsubscribeClearMapInstance(); } - initMap = (position) => { - this.setState({ isLoading: true }); + initMap = () => { + if (this.map) return; + + const { position, record } = this.props; + if (!isValidPosition(position?.lng, position?.lat)) return; + this.currentPosition = position; + + this.setState({ isLoading: true, address: record._location_translated?.address }); if (this.mapType === MAP_TYPE.B_MAP) { if (!window.BMapGL) { window.renderBaiduMap = () => this.renderBaiduMap(position); @@ -81,23 +73,17 @@ class Location extends React.Component { } else { this.renderBaiduMap(position); } - return; - } - if (this.mapType === MAP_TYPE.G_MAP) { - if (!window.google) { + } else if (this.mapType === MAP_TYPE.G_MAP) { + if (!window.google?.maps.Map) { window.renderGoogleMap = () => this.renderGoogleMap(position); loadMapSource(this.mapType, this.mapKey); } else { this.renderGoogleMap(position); } - return; } - this.setState({ isLoading: false }); }; addMarkerByPosition = (lng, lat) => { - if (!isValidPosition(lng, lat)) return; - if (this.mapType === MAP_TYPE.B_MAP) { if (this.lastLng === lng && this.lastLat === lat) return; this.lastLng = lng; @@ -105,10 +91,9 @@ class Location extends React.Component { const point = new window.BMapGL.Point(lng, lat); const marker = new window.BMapGL.Marker(point, { offset: new window.BMapGL.Size(-2, -5) }); - this.map && this.map.clearOverlays(); - this.map && this.map.addOverlay(marker); - this.map && this.map.setCenter(point); - return; + this.map.clearOverlays(); + this.map.addOverlay(marker); + this.map.setCenter(point); } if (this.mapType === MAP_TYPE.G_MAP) { if (!this.googleMarker) { @@ -126,15 +111,15 @@ class Location extends React.Component { }; renderBaiduMap = (position = {}) => { - if (this.map) return; - this.setState({ isLoading: false }, () => { if (!window.BMapGL.Map) return; - if (!isValidPosition(position?.lng, position?.lat)) return; + + window.mapInstance = new window.BMapGL.Map('sf-geolocation-map-container', { enableMapClick: false }); + this.map = window.mapInstance; + const gcPosition = wgs84_to_gcj02(position.lng, position.lat); const bdPosition = gcj02_to_bd09(gcPosition.lng, gcPosition.lat); const { lng, lat } = bdPosition; - this.map = new window.BMapGL.Map(this.ref, { enableMapClick: false }); const point = new window.BMapGL.Point(lng, lat); this.map.centerAndZoom(point, 16); this.map.disableScrollWheelZoom(true); @@ -144,22 +129,16 @@ class Location extends React.Component { const zoomControl = new ZoomControl(); this.map.addControl(zoomControl); this.addMarkerByPosition(lng, lat); - let location_translated = this.props.record._location_translated; - if (location_translated) { - this.setState({ address: location_translated.address }); - } }); }; renderGoogleMap = (position) => { - if (this.map) return; - this.setState({ isLoading: false }, () => { if (!window.google.maps.Map) return; - if (!isValidPosition(position?.lng, position?.lat)) return; + const gcPosition = wgs84_to_gcj02(position.lng, position.lat); const { lng, lat } = gcPosition || {}; - this.map = new window.google.maps.Map(this.ref, { + window.mapInstance = new window.google.maps.Map(this.ref, { zoom: 16, center: gcPosition, mapId: googleMapId, @@ -170,12 +149,10 @@ class Location extends React.Component { rotateControl: false, fullscreenControl: false }); + this.map = window.mapInstance; + this.addMarkerByPosition(lng, lat); this.map.setCenter(gcPosition); - let location_translated = this.props.record._location_translated; - if (location_translated) { - this.setState({ address: location_translated.address }); - } }); }; diff --git a/frontend/src/metadata/constants/event-bus-type.js b/frontend/src/metadata/constants/event-bus-type.js index f171f1262d..59451c5b9d 100644 --- a/frontend/src/metadata/constants/event-bus-type.js +++ b/frontend/src/metadata/constants/event-bus-type.js @@ -87,6 +87,7 @@ export const EVENT_BUS_TYPE = { // map MODIFY_MAP_TYPE: 'modify_map_type', MAP_VIEW: 'map_view', + CLEAR_MAP_INSTANCE: 'clear_map_instance', // tag file MOVE_TAG_FILE: 'move_tag_file',