UNPKG

@collectionspace/cspace-public-browser

Version:
226 lines (222 loc) 8.08 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _reactIntl = require("react-intl"); var _cspaceRefname = require("cspace-refname"); var _immutable = _interopRequireDefault(require("immutable")); var _urlHelpers = require("../../../helpers/urlHelpers"); var _config = _interopRequireDefault(require("../../../config")); var _SearchResultImage = _interopRequireDefault(require("../../../../styles/cspace/SearchResultImage.css")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } /* global fetch, window, AbortController */ const propTypes = { gatewayUrl: _propTypes.default.string.isRequired, holdingInstitutions: _propTypes.default.instanceOf(_immutable.default.List), loadImageImmediately: _propTypes.default.bool, mediaCsid: _propTypes.default.string, referenceValue: _propTypes.default.string.isRequired }; const defaultProps = { holdingInstitutions: _immutable.default.List(), loadImageImmediately: false, mediaCsid: undefined }; const messages = (0, _reactIntl.defineMessages)({ noimage: { "id": "searchResultImage.noimage", "defaultMessage": "no image available" } }); class SearchResultImage extends _react.Component { constructor(props) { super(); this.handleScroll = this.handleScroll.bind(this); this.ref = /*#__PURE__*/_react.default.createRef(); this.state = { gatewayUrl: props.gatewayUrl }; if (AbortController) { this.abortController = new AbortController(); } } componentDidMount() { const { holdingInstitutions, loadImageImmediately, mediaCsid, referenceValue } = this.props; window.setTimeout(() => { if (this.isInView()) { this.init(referenceValue, mediaCsid, holdingInstitutions); } else { window.addEventListener('scroll', this.handleScroll); } }, loadImageImmediately ? 0 : _config.default.get('imageLoadDelay')); } componentDidUpdate(prevProps) { const { gatewayUrl: prevGatewayUrl, mediaCsid: prevMediaCsid, referenceValue: prevReferenceValue } = prevProps; const { holdingInstitutions, gatewayUrl, mediaCsid, referenceValue } = this.props; if (mediaCsid !== prevMediaCsid || gatewayUrl !== prevGatewayUrl || referenceValue !== prevReferenceValue) { // FIXME: Make this component stateless. // eslint-disable-next-line react/no-did-update-set-state this.setState({ gatewayUrl }); this.init(referenceValue, mediaCsid, holdingInstitutions); } } componentWillUnmount() { if (this.abortController) { this.abortController.abort(); } window.removeEventListener('scroll', this.handleScroll); } handleScroll() { if (this.isInView()) { window.setTimeout(() => { if (this.isInView()) { const { holdingInstitutions, mediaCsid, referenceValue } = this.props; window.removeEventListener('scroll', this.handleScroll); this.init(referenceValue, mediaCsid, holdingInstitutions); } }, _config.default.get('imageLoadDelay')); } } getMediaCsid(gatewayUrl, indexName, referenceValue) { const url = `${gatewayUrl}/es/doc/_search`; const referenceField = _config.default.get('referenceField'); const query = { _source: 'collectionspace_denorm:mediaCsid', query: { term: { [referenceField]: referenceValue } }, size: 1, terminate_after: 1 }; return fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(query), signal: this.abortController ? this.abortController.signal : undefined }).then(response => response.json()) // eslint-disable-next-line no-underscore-dangle .then(data => data.hits.hits[0]._source['collectionspace_denorm:mediaCsid'][0]).catch(() => undefined); } init(referenceValue, mediaCsid, holdingInstitutions) { if (typeof mediaCsid !== 'undefined') { this.setState({ mediaCsid }); return; } // Attempt to resove a mediaCsid from holding instutitions. This is really only used by the // materials browser. In other profiles, the media csid will have been received in the search // result. const cachedGatewayMediaCsid = window.sessionStorage.getItem(`image-${referenceValue}`); if (cachedGatewayMediaCsid) { const [cachedGatewayUrl, cachedMediaCsid] = cachedGatewayMediaCsid.split(','); this.setState({ gatewayUrl: cachedGatewayUrl, mediaCsid: cachedMediaCsid }); return; } const institutions = holdingInstitutions.filter(value => !!value); if (institutions.size === 0) { this.setState({ mediaCsid: null }); return; } const findImage = institutions.reduce((promise, institution) => promise.catch(() => { const instShortId = (0, _cspaceRefname.getItemShortID)(institution); const instGatewayUrl = _config.default.get(['institutions', instShortId, 'gatewayUrl']); const instIndexName = _config.default.get(['institutions', instShortId, 'esIndexName']); if (!instGatewayUrl) { return Promise.reject(); } return this.getMediaCsid(instGatewayUrl, instIndexName, referenceValue).then(instMediaCsid => { if (!instMediaCsid) { return Promise.reject(); } return Promise.resolve({ instGatewayUrl, instMediaCsid }); }); }), Promise.reject()); findImage.then(({ instGatewayUrl, instMediaCsid }) => { try { window.sessionStorage.setItem(`image-${referenceValue}`, `${instGatewayUrl},${instMediaCsid}`); } catch (err) { // Ignore storage error. } this.setState({ gatewayUrl: instGatewayUrl, mediaCsid: instMediaCsid }); }).catch(() => {}); } isInView() { const domNode = this.ref.current; if (domNode) { const rect = domNode.getBoundingClientRect(); return rect.top >= 0 && rect.top < window.innerHeight; } return false; } render() { const { gatewayUrl, mediaCsid } = this.state; if (mediaCsid === null) { return /*#__PURE__*/_react.default.createElement("div", { "aria-hidden": true, className: _SearchResultImage.default.noimage }, /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, messages.noimage)); } const imageUrl = mediaCsid && (0, _urlHelpers.blobUrl)(gatewayUrl, mediaCsid, _config.default.get('searchResultImageDerivative')); let style; if (imageUrl) { style = { backgroundImage: `url(${imageUrl})` }; } return /*#__PURE__*/_react.default.createElement("div", { className: _SearchResultImage.default.common, style: style, ref: this.ref }); } } exports.default = SearchResultImage; SearchResultImage.propTypes = propTypes; SearchResultImage.defaultProps = defaultProps;