diff --git a/CHANGELOG.md b/CHANGELOG.md index a8f4dbc9a..2a94afa13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,10 @@ Web UI version numbers should always match the corresponding version of LBRY App ## [Unreleased] ### Added - * + * File pages now show the time of a publish. * The "auth token" displayable on Help offers security warning + * Added a new component for rendering dates and times. This component can render the date and time of a block height, as well. + ### Changed * diff --git a/ui/js/actions/wallet.js b/ui/js/actions/wallet.js index e97675d18..dd48c71fa 100644 --- a/ui/js/actions/wallet.js +++ b/ui/js/actions/wallet.js @@ -33,6 +33,17 @@ export function doFetchTransactions() { }; } +export function doFetchBlock(height) { + return function(dispatch, getState) { + lbry.block_show({ height }).then(block => { + dispatch({ + type: types.FETCH_BLOCK_SUCCESS, + data: { block }, + }); + }); + }; +} + export function doGetNewAddress() { return function(dispatch, getState) { dispatch({ diff --git a/ui/js/component/dateTime/index.js b/ui/js/component/dateTime/index.js new file mode 100644 index 000000000..81ef4b165 --- /dev/null +++ b/ui/js/component/dateTime/index.js @@ -0,0 +1,17 @@ +import React from "react"; +import { connect } from "react-redux"; +import { makeSelectBlockDate } from "selectors/wallet"; +import { doFetchBlock } from "actions/wallet"; +import DateTime from "./view"; + +const select = (state, props) => ({ + date: !props.date && props.block + ? makeSelectBlockDate(props.block)(state) + : props.date, +}); + +const perform = dispatch => ({ + fetchBlock: height => dispatch(doFetchBlock(height)), +}); + +export default connect(select, perform)(DateTime); diff --git a/ui/js/component/dateTime/view.jsx b/ui/js/component/dateTime/view.jsx new file mode 100644 index 000000000..72d47c130 --- /dev/null +++ b/ui/js/component/dateTime/view.jsx @@ -0,0 +1,26 @@ +import React from "react"; + +class DateTime extends React.PureComponent { + componentWillMount() { + this.refreshDate(this.props); + } + + componentWillReceiveProps(props) { + this.refreshDate(props); + } + + refreshDate(props) { + const { block, date, fetchBlock } = props; + if (block && date === undefined) { + fetchBlock(block); + } + } + + render() { + const { date } = this.props; + + return {date && date.toLocaleString()}; + } +} + +export default DateTime; diff --git a/ui/js/constants/action_types.js b/ui/js/constants/action_types.js index 84c8e0e06..099d4c563 100644 --- a/ui/js/constants/action_types.js +++ b/ui/js/constants/action_types.js @@ -39,6 +39,7 @@ export const SET_DRAFT_TRANSACTION_ADDRESS = "SET_DRAFT_TRANSACTION_ADDRESS"; export const SEND_TRANSACTION_STARTED = "SEND_TRANSACTION_STARTED"; export const SEND_TRANSACTION_COMPLETED = "SEND_TRANSACTION_COMPLETED"; export const SEND_TRANSACTION_FAILED = "SEND_TRANSACTION_FAILED"; +export const FETCH_BLOCK_SUCCESS = "FETCH_BLOCK_SUCCESS"; // Content export const FETCH_FEATURED_CONTENT_STARTED = "FETCH_FEATURED_CONTENT_STARTED"; diff --git a/ui/js/lbry.js b/ui/js/lbry.js index f55685074..23cf16c20 100644 --- a/ui/js/lbry.js +++ b/ui/js/lbry.js @@ -482,6 +482,19 @@ lbry.claim_abandon = function(params = {}) { }); }; +lbry.block_show = function(params = {}) { + return new Promise((resolve, reject) => { + apiCall( + "block_show", + params, + block => { + resolve(block); + }, + reject + ); + }); +}; + lbry._resolveXhrs = {}; lbry.resolve = function(params = {}) { return new Promise((resolve, reject) => { diff --git a/ui/js/page/file/view.jsx b/ui/js/page/file/view.jsx index 8459ed01c..eb920a779 100644 --- a/ui/js/page/file/view.jsx +++ b/ui/js/page/file/view.jsx @@ -9,15 +9,24 @@ import FileActions from "component/fileActions"; import Link from "component/link"; import UriIndicator from "component/uriIndicator"; import IconFeatured from "component/iconFeatured"; +import DateTime from "component/dateTime"; const FormatItem = props => { - const { contentType, metadata: { language, license } } = props; + const { + publishedDate, + contentType, + claim: { height }, + metadata: { language, license }, + } = props; const mediaType = lbry.getMediaType(contentType); return (
{__("Published on")} | |
{__("Content-Type")} | {mediaType} |