UNPKG

opds-web-client

Version:
160 lines (159 loc) 10.6 kB
"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;