@collectionspace/cspace-public-browser
Version:
CollectionSpace public browser
226 lines (222 loc) • 8.08 kB
JavaScript
"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;