1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-21 03:18:23 +00:00

fix location in details (#7813)

Co-authored-by: zhouwenxuan <aries@Mac.local>
This commit is contained in:
Aries
2025-05-13 15:37:54 +08:00
committed by GitHub
parent 5851acf764
commit 1586ffd448
5 changed files with 53 additions and 97 deletions

View File

@@ -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 PropTypes from 'prop-types';
import DetailItem from '../../detail-item'; import DetailItem from '../../detail-item';
import Collapse from './collapse'; import Collapse from './collapse';
@@ -13,7 +13,6 @@ import { useMetadataStatus } from '../../../../hooks';
import { CAPTURE_INFO_SHOW_KEY } from '../../../../constants'; import { CAPTURE_INFO_SHOW_KEY } from '../../../../constants';
import People from '../../people'; import People from '../../people';
import FileTag from './file-tag'; import FileTag from './file-tag';
import Location from '../../../../metadata/components/metadata-details/location';
import './index.css'; 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 FileDetails = React.memo(({ repoID, dirent, path, direntDetail, isShowRepoTags = true, repoTags, fileTagList, onFileTagChanged }) => {
const [isCaptureInfoShow, setCaptureInfoShow] = useState(false); const [isCaptureInfoShow, setCaptureInfoShow] = useState(false);
const [currentPosition, setCurrentPosition] = useState(null);
const { enableFaceRecognition, enableMetadata } = useMetadataStatus(); const { enableFaceRecognition, enableMetadata } = useMetadataStatus();
const { record } = useMetadataDetails(); 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 lastModifiedTimeField = useMemo(() => ({ type: CellType.MTIME, name: gettext('Last modified time') }), []);
const tagsField = useMemo(() => ({ type: CellType.SINGLE_SELECT, name: gettext('Tags') }), []); const tagsField = useMemo(() => ({ type: CellType.SINGLE_SELECT, name: gettext('Tags') }), []);
const onPositionChange = useCallback((position) => {
setCurrentPosition(position);
}, []);
useEffect(() => { useEffect(() => {
const savedValue = window.localStorage.getItem(CAPTURE_INFO_SHOW_KEY) === 'true'; const savedValue = window.localStorage.getItem(CAPTURE_INFO_SHOW_KEY) === 'true';
setCaptureInfoShow(savedValue); setCaptureInfoShow(savedValue);
@@ -108,14 +102,7 @@ const FileDetails = React.memo(({ repoID, dirent, path, direntDetail, isShowRepo
/> />
</DetailItem> </DetailItem>
)} )}
{enableMetadata && ( {enableMetadata && <MetadataDetails />}
<div className="sf-metadata-details-wrapper">
<div className="sf-metadata-details-map-container">
<Location key="singleton-map" position={currentPosition} record={record} />
</div>
<MetadataDetails onPositionChange={onPositionChange} />
</div>
)}
</> </>
); );

View File

@@ -11,6 +11,8 @@ import ObjectUtils from '../../../utils/object';
import { MetadataDetailsProvider } from '../../../metadata/hooks'; import { MetadataDetailsProvider } from '../../../metadata/hooks';
import AIIcon from '../../../metadata/components/metadata-details/ai-icon'; import AIIcon from '../../../metadata/components/metadata-details/ai-icon';
import SettingsIcon from '../../../metadata/components/metadata-details/settings-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'; import './index.css';
@@ -53,6 +55,10 @@ class DirentDetails extends React.Component {
} }
} }
componentWillUnmount() {
eventBus.dispatch(EVENT_BUS_TYPE.CLEAR_MAP_INSTANCE);
}
renderImage = () => { renderImage = () => {
const { dirent } = this.props; const { dirent } = this.props;
if (!dirent) return null; if (!dirent) return null;

View File

@@ -1,5 +1,4 @@
import React, { useEffect, useMemo } from 'react'; import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import CellFormatter from '../cell-formatter'; import CellFormatter from '../cell-formatter';
import DetailEditor from '../detail-editor'; import DetailEditor from '../detail-editor';
import DetailItem from '../../../components/dirent-detail/detail-item'; 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 { useMetadataDetails } from '../../hooks';
import { checkIsDir } from '../../utils/row'; import { checkIsDir } from '../../utils/row';
import { FOLDER_NOT_DISPLAY_COLUMN_KEYS } from './constants'; import { FOLDER_NOT_DISPLAY_COLUMN_KEYS } from './constants';
import Location from './location';
import './index.css'; import './index.css';
const MetadataDetails = ({ onPositionChange }) => { const MetadataDetails = () => {
const { isLoading, canModifyRecord, record, columns, onChange, modifyColumnData, updateFileTags } = useMetadataDetails(); const { canModifyRecord, record, columns, onChange, modifyColumnData, updateFileTags } = useMetadataDetails();
const displayColumns = useMemo(() => columns.filter(c => c.shown), [columns]); const displayColumns = useMemo(() => columns.filter(c => c.shown), [columns]);
useEffect(() => { if (!record || !record._id) return null;
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;
const fileName = getFileNameFromRecord(record); const fileName = getFileNameFromRecord(record);
const isImageOrVideo = Utils.imageCheck(fileName) || Utils.videoCheck(fileName); 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; if (isDir && FOLDER_NOT_DISPLAY_COLUMN_KEYS.includes(field.key)) return null;
const value = getCellValueByColumn(record, field); 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 <Location key={field.key} position={value} record={record} />;
}
let canEdit = canModifyRecord && field.editable; let canEdit = canModifyRecord && field.editable;
if (!isImageOrVideo && IMAGE_PRIVATE_COLUMN_KEYS.includes(field.key)) { if (!isImageOrVideo && IMAGE_PRIVATE_COLUMN_KEYS.includes(field.key)) {
@@ -79,8 +68,4 @@ const MetadataDetails = ({ onPositionChange }) => {
); );
}; };
MetadataDetails.propTypes = {
onPositionChange: PropTypes.func,
};
export default MetadataDetails; export default MetadataDetails;

View File

@@ -6,13 +6,14 @@ import { wgs84_to_gcj02, gcj02_to_bd09 } from '../../../../utils/coord-transform
import { MAP_TYPE } from '../../../../constants'; import { MAP_TYPE } from '../../../../constants';
import Loading from '../../../../components/loading'; import Loading from '../../../../components/loading';
import { gettext, baiduMapKey, googleMapKey, googleMapId } from '../../../../utils/constants'; 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 { getGeolocationDisplayString } from '../../../utils/cell';
import { isValidPosition } from '../../../utils/validate'; import { isValidPosition } from '../../../utils/validate';
import DetailItem from '../../../../components/dirent-detail/detail-item'; import DetailItem from '../../../../components/dirent-detail/detail-item';
import { getColumnDisplayName } from '../../../utils/column'; import { getColumnDisplayName } from '../../../utils/column';
import { createBMapZoomControl } from '../../map-controller'; import { createBMapZoomControl } from '../../map-controller';
import { Utils } from '../../../../utils/utils'; import { Utils } from '../../../../utils/utils';
import { eventBus } from '../../../../components/common/event-bus';
import './index.css'; import './index.css';
@@ -33,47 +34,38 @@ class Location extends React.Component {
address: '', address: '',
isLoading: true, isLoading: true,
}; };
this.initMapTriggered = false;
} }
componentDidMount() { 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) { componentDidUpdate(prevProps) {
const { position: prevPosition } = prevProps; const { position, record } = this.props;
const { position: currPosition } = this.props; if (!isValidPosition(position?.lng, position?.lat)) return;
if (prevProps.position?.lng === position?.lng && prevProps.position?.lat === position?.lat) return;
const isSamePosition = prevPosition?.lng === currPosition?.lng && this.currentPosition = position;
prevPosition?.lat === currPosition?.lat; this.addMarkerByPosition(position.lng, position.lat);
this.setState({ address: record._location_translated?.address });
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);
}
}
} }
componentWillUnmount() { componentWillUnmount() {
if (this.map) { this.unsubscribeClearMapInstance();
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;
} }
initMap = (position) => { initMap = () => {
this.setState({ isLoading: true }); 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 (this.mapType === MAP_TYPE.B_MAP) {
if (!window.BMapGL) { if (!window.BMapGL) {
window.renderBaiduMap = () => this.renderBaiduMap(position); window.renderBaiduMap = () => this.renderBaiduMap(position);
@@ -81,23 +73,17 @@ class Location extends React.Component {
} else { } else {
this.renderBaiduMap(position); this.renderBaiduMap(position);
} }
return; } else if (this.mapType === MAP_TYPE.G_MAP) {
} if (!window.google?.maps.Map) {
if (this.mapType === MAP_TYPE.G_MAP) {
if (!window.google) {
window.renderGoogleMap = () => this.renderGoogleMap(position); window.renderGoogleMap = () => this.renderGoogleMap(position);
loadMapSource(this.mapType, this.mapKey); loadMapSource(this.mapType, this.mapKey);
} else { } else {
this.renderGoogleMap(position); this.renderGoogleMap(position);
} }
return;
} }
this.setState({ isLoading: false });
}; };
addMarkerByPosition = (lng, lat) => { addMarkerByPosition = (lng, lat) => {
if (!isValidPosition(lng, lat)) return;
if (this.mapType === MAP_TYPE.B_MAP) { if (this.mapType === MAP_TYPE.B_MAP) {
if (this.lastLng === lng && this.lastLat === lat) return; if (this.lastLng === lng && this.lastLat === lat) return;
this.lastLng = lng; this.lastLng = lng;
@@ -105,10 +91,9 @@ class Location extends React.Component {
const point = new window.BMapGL.Point(lng, lat); const point = new window.BMapGL.Point(lng, lat);
const marker = new window.BMapGL.Marker(point, { offset: new window.BMapGL.Size(-2, -5) }); const marker = new window.BMapGL.Marker(point, { offset: new window.BMapGL.Size(-2, -5) });
this.map && this.map.clearOverlays(); this.map.clearOverlays();
this.map && this.map.addOverlay(marker); this.map.addOverlay(marker);
this.map && this.map.setCenter(point); this.map.setCenter(point);
return;
} }
if (this.mapType === MAP_TYPE.G_MAP) { if (this.mapType === MAP_TYPE.G_MAP) {
if (!this.googleMarker) { if (!this.googleMarker) {
@@ -126,15 +111,15 @@ class Location extends React.Component {
}; };
renderBaiduMap = (position = {}) => { renderBaiduMap = (position = {}) => {
if (this.map) return;
this.setState({ isLoading: false }, () => { this.setState({ isLoading: false }, () => {
if (!window.BMapGL.Map) return; 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 gcPosition = wgs84_to_gcj02(position.lng, position.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;
this.map = new window.BMapGL.Map(this.ref, { enableMapClick: false });
const point = new window.BMapGL.Point(lng, lat); const point = new window.BMapGL.Point(lng, lat);
this.map.centerAndZoom(point, 16); this.map.centerAndZoom(point, 16);
this.map.disableScrollWheelZoom(true); this.map.disableScrollWheelZoom(true);
@@ -144,22 +129,16 @@ class Location extends React.Component {
const zoomControl = new ZoomControl(); const zoomControl = new ZoomControl();
this.map.addControl(zoomControl); this.map.addControl(zoomControl);
this.addMarkerByPosition(lng, lat); this.addMarkerByPosition(lng, lat);
let location_translated = this.props.record._location_translated;
if (location_translated) {
this.setState({ address: location_translated.address });
}
}); });
}; };
renderGoogleMap = (position) => { renderGoogleMap = (position) => {
if (this.map) return;
this.setState({ isLoading: false }, () => { this.setState({ isLoading: false }, () => {
if (!window.google.maps.Map) return; if (!window.google.maps.Map) return;
if (!isValidPosition(position?.lng, position?.lat)) return;
const gcPosition = wgs84_to_gcj02(position.lng, position.lat); const gcPosition = wgs84_to_gcj02(position.lng, position.lat);
const { lng, lat } = gcPosition || {}; const { lng, lat } = gcPosition || {};
this.map = new window.google.maps.Map(this.ref, { window.mapInstance = new window.google.maps.Map(this.ref, {
zoom: 16, zoom: 16,
center: gcPosition, center: gcPosition,
mapId: googleMapId, mapId: googleMapId,
@@ -170,12 +149,10 @@ class Location extends React.Component {
rotateControl: false, rotateControl: false,
fullscreenControl: false fullscreenControl: false
}); });
this.map = window.mapInstance;
this.addMarkerByPosition(lng, lat); this.addMarkerByPosition(lng, lat);
this.map.setCenter(gcPosition); this.map.setCenter(gcPosition);
let location_translated = this.props.record._location_translated;
if (location_translated) {
this.setState({ address: location_translated.address });
}
}); });
}; };

View File

@@ -87,6 +87,7 @@ export const EVENT_BUS_TYPE = {
// map // map
MODIFY_MAP_TYPE: 'modify_map_type', MODIFY_MAP_TYPE: 'modify_map_type',
MAP_VIEW: 'map_view', MAP_VIEW: 'map_view',
CLEAR_MAP_INSTANCE: 'clear_map_instance',
// tag file // tag file
MOVE_TAG_FILE: 'move_tag_file', MOVE_TAG_FILE: 'move_tag_file',