opds-web-client
Version:
160 lines (159 loc) • 10.6 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var React = require("react");
require("../stylesheets/root.scss");
var react_redux_1 = require("react-redux");
var mergeRootProps_1 = require("./mergeRootProps");
var BookDetails_1 = require("./BookDetails");
var LoadingIndicator_1 = require("./LoadingIndicator");
var ErrorMessage_1 = require("./ErrorMessage");
var BasicAuthForm_1 = require("./BasicAuthForm");
var Search_1 = require("./Search");
var Breadcrumbs_1 = require("./Breadcrumbs");
var Collection_1 = require("./Collection");
var UrlForm_1 = require("./UrlForm");
var SkipNavigationLink_1 = require("./SkipNavigationLink");
var CatalogLink_1 = require("./CatalogLink");
var Root = (function (_super) {
__extends(Root, _super);
function Root() {
_super.apply(this, arguments);
}
Root.prototype.render = function () {
var BookDetailsContainer = this.props.BookDetailsContainer;
var Header = this.props.Header;
var Footer = this.props.Footer;
var collectionTitle = this.props.collectionData ? this.props.collectionData.title : null;
var bookTitle = this.props.bookData ? this.props.bookData.title : null;
var computeBreadcrumbs = this.props.computeBreadcrumbs || Breadcrumbs_1.defaultComputeBreadcrumbs;
var breadcrumbsLinks = computeBreadcrumbs(this.props.collectionData, this.props.history);
var headerTitle = this.props.headerTitle || (this.props.collectionData ? this.props.collectionData.title : null);
var showCollection = this.props.collectionData;
var showBook = this.props.bookData;
var showBookWrapper = this.props.bookUrl || this.props.bookData;
var showUrlForm = !this.props.collectionUrl && !this.props.bookUrl;
var showBreadcrumbs = showCollection && breadcrumbsLinks.length > 0;
var showFooter = showCollection && Footer;
var bodyClass = "body";
if (showBreadcrumbs) {
bodyClass += " with-breadcrumbs";
}
if (showFooter) {
bodyClass += " with-footer";
}
return (React.createElement("div", {className: "catalog"}, React.createElement(SkipNavigationLink_1.default, null), this.props.error && (!this.props.basicAuth || !this.props.basicAuth.showForm) &&
React.createElement(ErrorMessage_1.default, {message: "Could not fetch data: " + this.props.error.url, retry: this.props.retryCollectionAndBook}), this.props.isFetching &&
React.createElement(LoadingIndicator_1.default, null), this.props.basicAuth && this.props.basicAuth.showForm &&
React.createElement(BasicAuthForm_1.default, {saveCredentials: this.props.saveBasicAuthCredentials, hide: this.props.closeErrorAndHideBasicAuthForm, callback: this.props.basicAuth.callback, title: this.props.basicAuth.title, loginLabel: this.props.basicAuth.loginLabel, passwordLabel: this.props.basicAuth.passwordLabel, error: this.props.basicAuth.error}), showUrlForm &&
React.createElement(UrlForm_1.default, {collectionUrl: this.props.collectionUrl}), Header ?
React.createElement(Header, {collectionTitle: collectionTitle, bookTitle: bookTitle, loansUrl: this.props.loansUrl, isSignedIn: this.props.isSignedIn, showBasicAuthForm: this.props.showBasicAuthForm, clearBasicAuthCredentials: this.props.clearBasicAuthCredentials}, this.props.collectionData && this.props.collectionData.search &&
React.createElement(Search_1.default, {url: this.props.collectionData.search.url, searchData: this.props.collectionData.search.searchData, fetchSearchDescription: this.props.fetchSearchDescription})) :
React.createElement("nav", {className: "header navbar navbar-default navbar-fixed-top"}, React.createElement("div", {className: "container-fluid"}, React.createElement("span", {className: "navbar-brand"}, "OPDS Web Client"), this.props.loansUrl &&
React.createElement("ul", {className: "nav navbar-nav"}, React.createElement("li", null, React.createElement(CatalogLink_1.default, {collectionUrl: this.props.loansUrl, bookUrl: null}, "Loans"))), this.props.collectionData && this.props.collectionData.search &&
React.createElement(Search_1.default, {className: "navbar-form navbar-right", url: this.props.collectionData.search.url, searchData: this.props.collectionData.search.searchData, fetchSearchDescription: this.props.fetchSearchDescription}))), showBreadcrumbs &&
React.createElement("div", {className: "breadcrumbs-wrapper"}, React.createElement(Breadcrumbs_1.default, {links: breadcrumbsLinks})), React.createElement("div", {className: bodyClass}, showBookWrapper &&
React.createElement("div", {className: "book-details-wrapper"}, showBook &&
(BookDetailsContainer && (this.props.bookUrl || this.props.bookData.url) ?
React.createElement(BookDetailsContainer, {book: this.loanedBookData() || this.props.bookData, bookUrl: this.props.bookUrl || this.props.bookData.url, collectionUrl: this.props.collectionUrl, refreshCatalog: this.props.refreshCollectionAndBook}, React.createElement(BookDetails_1.default, {book: this.loanedBookData() || this.props.bookData, updateBook: this.props.updateBook, fulfillBook: this.props.fulfillBook, indirectFulfillBook: this.props.indirectFulfillBook, isSignedIn: this.props.isSignedIn})) :
React.createElement("div", {className: "without-container"}, React.createElement(BookDetails_1.default, {book: this.loanedBookData() || this.props.bookData, updateBook: this.props.updateBook, fulfillBook: this.props.fulfillBook, indirectFulfillBook: this.props.indirectFulfillBook, isSignedIn: this.props.isSignedIn})))), showCollection &&
React.createElement(Collection_1.default, {collection: this.props.collectionData, fetchPage: this.props.fetchPage, isFetching: this.props.isFetching, isFetchingPage: this.props.isFetchingPage, error: this.props.error})), showFooter &&
React.createElement("footer", null, React.createElement(Footer, {collection: this.props.collectionData}))));
};
Root.prototype.componentWillMount = function () {
var _this = this;
this.updatePageTitle(this.props);
if (this.props.basicAuthCredentials && this.props.saveBasicAuthCredentials) {
this.props.saveBasicAuthCredentials(this.props.basicAuthCredentials);
}
if (this.props.collectionUrl || this.props.bookUrl) {
return this.props.setCollectionAndBook(this.props.collectionUrl, this.props.bookUrl).then(function (_a) {
var collectionData = _a.collectionData, bookData = _a.bookData;
if (_this.props.basicAuthCredentials && collectionData.shelfUrl) {
_this.props.fetchLoans(collectionData.shelfUrl);
}
});
}
};
Root.prototype.componentDidMount = function () {
if (typeof document !== "undefined") {
document.addEventListener("keydown", this.handleKeyDown.bind(this));
}
};
Root.prototype.componentWillReceiveProps = function (nextProps) {
if (nextProps.collectionUrl !== this.props.collectionUrl || nextProps.bookUrl !== this.props.bookUrl) {
this.props.setCollectionAndBook(nextProps.collectionUrl, nextProps.bookUrl);
}
this.updatePageTitle(nextProps);
};
Root.prototype.updatePageTitle = function (props) {
if (typeof document !== "undefined" && props.pageTitleTemplate) {
var collectionTitle = props.collectionData && props.collectionData.title;
var bookTitle = props.bookData && props.bookData.title;
document.title = props.pageTitleTemplate(collectionTitle, bookTitle);
}
};
Root.prototype.handleKeyDown = function (event) {
if (!event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
// event.keyCode is deprecated but not all browsers support event.code
if (event.code === "ArrowLeft" || event.keyCode === 37) {
this.showPrevBook();
}
else if (event.code === "ArrowRight" || event.keyCode === 39) {
this.showNextBook();
}
}
};
Root.prototype.showPrevBook = function () {
this.showRelativeBook(-1);
};
Root.prototype.showNextBook = function () {
this.showRelativeBook(1);
};
Root.prototype.showRelativeBook = function (relativeIndex) {
if (this.context.router && this.props.collectionData && this.props.bookData) {
var books = this.props.collectionData.lanes.reduce(function (books, lane) {
return books.concat(lane.books);
}, this.props.collectionData.books);
var bookIds = books.map(function (book) { return book.id; });
var currentBookIndex = bookIds.indexOf(this.props.bookData.id);
if (currentBookIndex !== -1) {
// wrap index at start and end of bookIds array
var nextBookIndex = (currentBookIndex + relativeIndex + bookIds.length) % bookIds.length;
var nextBookUrl = books[nextBookIndex].url || books[nextBookIndex].id;
this.context.router.push(this.context.pathFor(this.props.collectionData.url, nextBookUrl));
}
}
};
;
Root.prototype.loanedBookData = function () {
var _this = this;
if (!this.props.loans || this.props.loans.length === 0) {
return null;
}
return this.props.loans.find(function (book) {
if (_this.props.bookData) {
return book.id === _this.props.bookData.id;
}
else if (_this.props.bookUrl) {
return book.url === _this.props.bookUrl;
}
else {
return null;
}
});
};
Root.contextTypes = {
router: React.PropTypes.object,
pathFor: React.PropTypes.func
};
return Root;
}(React.Component));
exports.Root = Root;
var connectOptions = { withRef: true, pure: false };
var ConnectedRoot = react_redux_1.connect(mergeRootProps_1.mapStateToProps, mergeRootProps_1.mapDispatchToProps, mergeRootProps_1.mergeRootProps, connectOptions)(Root);
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = ConnectedRoot;