diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 891aa6df4..a7632cb33 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.17.0rc1 +current_version = 0.17.0 commit = True tag = True parse = (?P\d+)\.(?P\d+)\.(?P\d+)((?P[a-z]+)(?P\d+))? diff --git a/CHANGELOG.md b/CHANGELOG.md index 48ebd3d43..b041da113 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,43 +8,61 @@ Web UI version numbers should always match the corresponding version of LBRY App ## [Unreleased] ### Added - * Added a new search service. Significantly improved search results. - * Channels now appear in search results. Channel cards to be improved soon?. - * Add setting to automatically purchase low-cost content without a confirmation dialog. - * New custom styled scrollbar (#574) - * New tabs (#547). + * + * ### Changed - * LBRY protocol upgraded from v0.16.1 to [v0.17](https://github.com/lbryio/lbry/releases/tag/v0.17.0). Significant improvements to download performance anticipated. - * Improved Discover page load time by batching all URIs into one API call. - * Changed the File page to make it clearer how to to open the folder for a file. - * Display search bar on discover page instead of title and remove duplicated icon. - * Minor update for themes. - * There is no longer a minimum channel length (#645) - * Changed the File page to make it clearer how to to open the folder for a file - * The upgrade message is now friendlier and includes a link to the release notes. - * Local settings refactored and no longer intermixed with LBRY API library. + * + * ### Fixed - * Improve layout (and implementation) of the icon panel in file tiles and cards - * The folder icon representing a local download now shows up properly on Channel pages (#587) - * While editing a publish, the URL will no longer change if you select a new file. (#601) - * Fixed issues with opening the folder for a file (#606) - * Be consistent with the step property on credit inputs (#604) - * Fixed unresponsive header (#613) - * Fixed dark theme issues with text content. - * Minor css fixes. - * Fixed issue when file fails to download (#642) - * Fixed issue after accessing a video without enough credits (#605) - * Fixed channel fetching without claims (#634) + * + * ### Deprecated * * ### Removed - * * + * + +## [0.17.0] - 2017-10-12 + +### Added + * Added a new search service. Significantly improved search results. + * Channels now appear in search results. Channel cards to be improved soon?. + * Add setting to automatically purchase low-cost content without a confirmation dialog. + * New custom styled scrollbar (#574) + * New tabs (#576). + + +### Changed + * LBRY protocol upgraded from v0.16.1 to [v0.17](https://github.com/lbryio/lbry/releases/tag/v0.17.0). Significant improvements to download performance anticipated. + * Improved Discover page load time by batching all URIs into one API call. + * Changed the File page to make it clearer how to to open the folder for a file. + * Display search bar on discover page instead of title and remove duplicated icon. + * Minor update for themes. + * There is no longer a minimum channel length (#645) + * Changed the File page to make it clearer how to to open the folder for a file + * The upgrade message is now friendlier and includes a link to the release notes. + * Local settings refactored and no longer intermixed with LBRY API library. + + +### Fixed + * Improve layout (and implementation) of the icon panel in file tiles and cards + * The folder icon representing a local download now shows up properly on Channel pages (#587) + * While editing a publish, the URL will no longer change if you select a new file. (#601) + * Fixed issues with opening the folder for a file (#606) + * Be consistent with the step property on credit inputs (#604) + * Fixed unresponsive header (#613) + * Fixed dark theme issues with text content. + * Minor css fixes. + * Fixed issue when file fails to download (#642) + * Fixed issue after accessing a video without enough credits (#605) + * Fixed channel fetching without claims (#634) + + ## [0.16.0] - 2017-09-21 diff --git a/app/package.json b/app/package.json index 37c2f2ab3..67f399985 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "LBRY", - "version": "0.17.0rc1", + "version": "0.17.0", "main": "main.js", "description": "A browser for the LBRY network, a digital marketplace controlled by its users.", "author": { @@ -20,7 +20,7 @@ "electron-rebuild": "^1.5.11" }, "lbrySettings": { - "lbrynetDaemonVersion": "0.17.0rc13", + "lbrynetDaemonVersion": "0.17.0", "lbrynetDaemonUrlTemplate": "https://github.com/lbryio/lbry/releases/download/vDAEMONVER/lbrynet-daemon-vDAEMONVER-OSNAME.zip" }, "license": "MIT" diff --git a/ui/js/actions/content.js b/ui/js/actions/content.js index 912b06d11..a94719ac0 100644 --- a/ui/js/actions/content.js +++ b/ui/js/actions/content.js @@ -45,11 +45,17 @@ export function doResolveUris(uris) { let resolveInfo = {}; lbry.resolve({ uris: urisToResolve }).then(result => { for (let [uri, uriResolveInfo] of Object.entries(result)) { - const { claim, certificate } = uriResolveInfo || { + const fallbackResolveInfo = { claim: null, + claims_in_channel: null, certificate: null, }; - resolveInfo[uri] = { claim, certificate }; + + const { claim, certificate, claims_in_channel } = uriResolveInfo && + !uriResolveInfo.error + ? uriResolveInfo + : fallbackResolveInfo; + resolveInfo[uri] = { claim, certificate, claims_in_channel }; } dispatch({ diff --git a/ui/js/actions/search.js b/ui/js/actions/search.js index a83ce60bb..e26251e3e 100644 --- a/ui/js/actions/search.js +++ b/ui/js/actions/search.js @@ -5,11 +5,13 @@ import { doNavigate } from "actions/navigation"; import { selectCurrentPage } from "selectors/navigation"; import batchActions from "util/batchActions"; -export function doSearch(query) { +export function doSearch(rawQuery) { return function(dispatch, getState) { const state = getState(); const page = selectCurrentPage(state); + const query = rawQuery.replace(/^lbry:\/\//, ""); + if (!query) { return dispatch({ type: types.SEARCH_CANCELLED, diff --git a/ui/js/component/app/view.jsx b/ui/js/component/app/view.jsx index b349fd2de..17e0ec030 100644 --- a/ui/js/component/app/view.jsx +++ b/ui/js/component/app/view.jsx @@ -39,7 +39,7 @@ class App extends React.PureComponent { } setTitleFromProps(props) { - window.document.title = props.pageTitle; + window.document.title = props.pageTitle || "LBRY"; } render() { diff --git a/ui/js/component/channelTile/index.js b/ui/js/component/channelTile/index.js index 2e4c438f7..6cc68149f 100644 --- a/ui/js/component/channelTile/index.js +++ b/ui/js/component/channelTile/index.js @@ -1,19 +1,21 @@ import React from "react"; import { connect } from "react-redux"; -import { doFetchClaimCountByChannel } from "actions/content"; import { makeSelectClaimForUri } from "selectors/claims"; import { doNavigate } from "actions/navigation"; +import { doResolveUri } from "actions/content"; import { makeSelectTotalItemsForChannel } from "selectors/content"; +import { makeSelectIsUriResolving } from "selectors/content"; import ChannelTile from "./view"; const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), + isResolvingUri: makeSelectIsUriResolving(props.uri)(state), totalItems: makeSelectTotalItemsForChannel(props.uri)(state), }); const perform = dispatch => ({ - fetchClaimCount: uri => dispatch(doFetchClaimCountByChannel(uri)), navigate: (path, params) => dispatch(doNavigate(path, params)), + resolveUri: uri => dispatch(doResolveUri(uri)), }); export default connect(select, perform)(ChannelTile); diff --git a/ui/js/component/channelTile/view.jsx b/ui/js/component/channelTile/view.jsx index 2ee3c4069..dd8cf8899 100644 --- a/ui/js/component/channelTile/view.jsx +++ b/ui/js/component/channelTile/view.jsx @@ -1,27 +1,25 @@ import React from "react"; -import lbryuri from "lbryuri.js"; import CardMedia from "component/cardMedia"; import { TruncatedText, BusyMessage } from "component/common.js"; class ChannelTile extends React.PureComponent { componentDidMount() { - const { uri, fetchClaimCount } = this.props; + const { uri, resolveUri } = this.props; - fetchClaimCount(uri); + resolveUri(uri); } componentWillReceiveProps(nextProps) { - const { uri, fetchClaimCount } = this.props; + const { uri, resolveUri } = this.props; if (nextProps.uri != uri) { - fetchClaimCount(uri); + resolveUri(uri); } } render() { - const { navigate, totalItems, uri } = this.props; - const { name, claimId } = lbryuri.parse(uri); - + const { claim, navigate, isResolvingUri, totalItems, uri } = this.props; + let onClick = () => navigate("/show", { uri }); return ( @@ -30,21 +28,22 @@ class ChannelTile extends React.PureComponent {
-
-

- {name} -

-
-
- {isNaN(totalItems) && - } - {totalItems > 0 && - - This is a channel with over {totalItems} items inside of it. - } - {totalItems === 0 && - This is an empty channel.} -
+
+

+ {uri} +

+
+
+ {isResolvingUri && + } + {totalItems > 0 && + + This is a channel with {totalItems}{" "} + {totalItems === 1 ? " item" : " items"} inside of it. + } + {!isResolvingUri && + !totalItems && + This is an empty channel.}
diff --git a/ui/js/component/publishForm/view.jsx b/ui/js/component/publishForm/view.jsx index 3a2416644..7d034922d 100644 --- a/ui/js/component/publishForm/view.jsx +++ b/ui/js/component/publishForm/view.jsx @@ -173,7 +173,7 @@ class PublishForm extends React.PureComponent { topClaimValue() { if (!this.claim()) return null; - return parseFloat(this.claim().amount); + return parseFloat(this.claim().effective_amount); } myClaimExists() { diff --git a/ui/js/page/show/view.jsx b/ui/js/page/show/view.jsx index 3dd48a705..8b1e05789 100644 --- a/ui/js/page/show/view.jsx +++ b/ui/js/page/show/view.jsx @@ -6,15 +6,17 @@ import FilePage from "page/file"; class ShowPage extends React.PureComponent { componentWillMount() { - const { resolveUri, uri } = this.props; + const { isResolvingUri, resolveUri, uri } = this.props; - resolveUri(uri); + if (!isResolvingUri) resolveUri(uri); } componentWillReceiveProps(nextProps) { - const { resolveUri, uri } = nextProps; + const { isResolvingUri, resolveUri, claim, uri } = nextProps; - resolveUri(uri); + if (!isResolvingUri && claim === undefined && uri) { + resolveUri(uri); + } } render() { diff --git a/ui/js/reducers/content.js b/ui/js/reducers/content.js index 5afb2790a..0d2b8cd09 100644 --- a/ui/js/reducers/content.js +++ b/ui/js/reducers/content.js @@ -4,7 +4,7 @@ const reducers = {}; const defaultState = { playingUri: null, rewardedContentClaimIds: [], - channelPages: {}, + channelClaimCounts: {}, }; reducers[types.FETCH_FEATURED_CONTENT_STARTED] = function(state, action) { @@ -48,31 +48,38 @@ reducers[types.RESOLVE_URIS_STARTED] = function(state, action) { }); }; +reducers[types.RESOLVE_URIS_COMPLETED] = function(state, action) { + const { resolveInfo } = action.data; + const channelClaimCounts = Object.assign({}, state.channelClaimCounts); + + for (let [uri, { certificate, claims_in_channel }] of Object.entries( + resolveInfo + )) { + if (certificate && !isNaN(claims_in_channel)) { + channelClaimCounts[uri] = claims_in_channel; + } + } + + return Object.assign({}, state, { + channelClaimCounts, + resolvingUris: (state.resolvingUris || []).filter(uri => !resolveInfo[uri]), + }); +}; + reducers[types.SET_PLAYING_URI] = (state, action) => { return Object.assign({}, state, { playingUri: action.data.uri, }); }; -// reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) { -// const channelPages = Object.assign({}, state.channelPages); -// const { uri, claims } = action.data; -// -// channelPages[uri] = totalPages; -// -// return Object.assign({}, state, { -// channelPages, -// }); -// }; - reducers[types.FETCH_CHANNEL_CLAIM_COUNT_COMPLETED] = function(state, action) { - const channelPages = Object.assign({}, state.channelPages); + const channelClaimCounts = Object.assign({}, state.channelClaimCounts); const { uri, totalClaims } = action.data; - channelPages[uri] = Math.ceil(totalClaims / 10); + channelClaimCounts[uri] = totalClaims; return Object.assign({}, state, { - channelPages, + channelClaimCounts, }); }; diff --git a/ui/js/selectors/content.js b/ui/js/selectors/content.js index 8e083ca93..a1c98f049 100644 --- a/ui/js/selectors/content.js +++ b/ui/js/selectors/content.js @@ -29,20 +29,20 @@ export const makeSelectIsUriResolving = uri => { ); }; -export const selectChannelPages = createSelector( +export const selectChannelClaimCounts = createSelector( _selectState, - state => state.channelPages || {} + state => state.channelClaimCounts || {} ); export const makeSelectTotalItemsForChannel = uri => { - return createSelector( - selectChannelPages, - byUri => (byUri && byUri[uri]) * 10 - ); + return createSelector(selectChannelClaimCounts, byUri => byUri && byUri[uri]); }; export const makeSelectTotalPagesForChannel = uri => { - return createSelector(selectChannelPages, byUri => byUri && byUri[uri]); + return createSelector( + selectChannelClaimCounts, + byUri => byUri && byUri[uri] && Math.ceil(byUri[uri] / 10) + ); }; export const selectRewardContentClaimIds = createSelector( diff --git a/ui/js/selectors/search.js b/ui/js/selectors/search.js index 09468a43c..b1792c4a0 100644 --- a/ui/js/selectors/search.js +++ b/ui/js/selectors/search.js @@ -24,7 +24,11 @@ export const selectSearchUrisByQuery = createSelector( ); export const makeSelectSearchUris = query => { - return createSelector(selectSearchUrisByQuery, byQuery => byQuery[query]); + //replace statement below is kind of ugly, and repeated in doSearch action + return createSelector( + selectSearchUrisByQuery, + byQuery => byQuery[query ? query.replace(/^lbry:\/\//, "") : query] + ); }; export const selectWunderBarAddress = createSelector( diff --git a/ui/package.json b/ui/package.json index e392ac16a..e63403aa1 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "lbry-web-ui", - "version": "0.17.0rc1", + "version": "0.17.0", "description": "LBRY UI", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", diff --git a/ui/scss/component/_form-field.scss b/ui/scss/component/_form-field.scss index 0021efe86..9880a599a 100644 --- a/ui/scss/component/_form-field.scss +++ b/ui/scss/component/_form-field.scss @@ -129,7 +129,7 @@ input[readonly]:focus { display: block; } -.form-field__label { +.form-field__label, .form-row__label { color: var(--color-help); &[for] { cursor: pointer; } > input[type="checkbox"], input[type="radio"] {