mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-20 19:08:21 +00:00
fix location in details (#7813)
Co-authored-by: zhouwenxuan <aries@Mac.local>
This commit is contained in:
@@ -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>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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 });
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -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',
|
||||||
|
Reference in New Issue
Block a user