Merge branch 'master' into release-0.28.0

This commit is contained in:
Sean Yesmunt 2019-01-31 16:25:58 -05:00
commit e77d735111
22 changed files with 231 additions and 316 deletions

View file

@ -8,18 +8,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added
- Support for sandbox applications ([#2178](https://github.com/lbryio/lbry-desktop/pull/2178))
- Support for sandbox games and applications ([#2178](https://github.com/lbryio/lbry-desktop/pull/2178))
- CTA to invite page on first run ([#2221](https://github.com/lbryio/lbry-desktop/pull/2221))
- Responsive related content list ([#2226](https://github.com/lbryio/lbry-desktop/pull/2226))
- Autoplay content in list of related files ([#2235](https://github.com/lbryio/lbry-desktop/pull/2235))
- Support for back/forward mouse navigation on Windows ([#2250](https://github.com/lbryio/lbry-desktop/pull/2250))
### Changed
- Less intrusive first run flow ([#2210](https://github.com/lbryio/lbry-desktop/pull/2210))
- Add icon for your own publishes on cards/tiles ([#2249](https://github.com/lbryio/lbry-desktop/pull/2249))
### Fixed
- Flow errors ([#2213](https://github.com/lbryio/lbry-desktop/pull/2213))
- Video position on previously viewed files ([#2240](https://github.com/lbryio/lbry-desktop/pull/2240))
## [0.27.1] - 2018-01-22

21
azure-pipelines.yml Normal file
View file

@ -0,0 +1,21 @@
# Node.js
# Build a general Node.js project with npm.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
trigger:
- release
pool:
vmImage: 'vs2017-win2016'
steps:
- task: NodeTool@0
inputs:
versionSpec: '9.x'
displayName: 'Install Node.js'
- script: |
yarn install
yarn build --publish onTag
displayName: 'yarn install and build'

View file

@ -52,7 +52,7 @@
"hast-util-sanitize": "^1.1.2",
"keytar": "^4.2.1",
"lbry-format": "https://github.com/lbryio/lbry-format.git",
"lbry-redux": "lbryio/lbry-redux#2ff9f70a3d765946a1c83c8e7eee7d81c96c1345",
"lbry-redux": "lbryio/lbry-redux#e94de324876185561b4f38b18fabb2aa58b8e3ed",
"lbryinc": "lbryio/lbryinc#83c275da7a44f346ce9e796d06f30126f02b4c63",
"localforage": "^1.7.1",
"mammoth": "^1.4.6",
@ -62,8 +62,8 @@
"node-fetch": "^2.3.0",
"qrcode.react": "^0.8.0",
"rc-progress": "^2.0.6",
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react": "^16.6.0",
"react-dom": "^16.6.0",
"react-feather": "^1.0.8",
"react-modal": "^3.1.7",
"react-paginate": "^5.2.1",
@ -71,9 +71,7 @@
"react-redux": "^5.0.3",
"react-simplemde-editor": "^3.6.16",
"react-toggle": "^4.0.2",
"react-transition-group": "1.x",
"redux": "^3.6.0",
"redux-logger": "^3.0.1",
"redux-persist": "^4.8.0",
"redux-persist-transform-compress": "^4.2.0",
"redux-persist-transform-filter": "0.0.16",
@ -84,7 +82,6 @@
"render-media": "^3.1.0",
"reselect": "^3.0.0",
"semver": "^5.3.0",
"shapeshift.io": "^1.3.1",
"source-map-support": "^0.5.4",
"stream-to-blob-url": "^2.1.1",
"three": "^0.93.0",
@ -143,4 +140,4 @@
"lbrynetDaemonDir": "static/daemon",
"lbrynetDaemonFileName": "lbrynet"
}
}
}

View file

@ -73,6 +73,19 @@ export default appState => {
setupBarMenu();
// Windows back/forward mouse navigation
window.on('app-command', (e, cmd) => {
switch (cmd) {
case 'browser-backward':
window.webContents.send('navigate-backward', null);
break;
case 'browser-forward':
window.webContents.send('navigate-forward', null);
break;
default: // Do nothing
}
});
window.on('close', event => {
if (!appState.isQuitting && !appState.autoUpdateAccepted) {
event.preventDefault();

View file

@ -24,5 +24,5 @@ export default async function startSandbox() {
});
// eslint-disable-next-line no-console
sandbox.listen(port, () => console.log(`Sandbox listening on port ${port}.`));
sandbox.listen(port, 'localhost', () => console.log(`Sandbox listening on port ${port}.`));
}

View file

@ -1,20 +1,24 @@
import { connect } from 'react-redux';
import { doFetchClaimsByChannel } from 'redux/actions/content';
import { makeSelectCategoryListUris } from 'redux/selectors/content';
import {
makeSelectClaimsInChannelForCurrentPage,
makeSelectFetchingChannelClaims,
doResolveUris,
selectActiveHistoryEntry,
} from 'lbry-redux';
import { selectShowNsfw } from 'redux/selectors/settings';
import CategoryList from './view';
const select = (state, props) => ({
channelClaims: makeSelectClaimsInChannelForCurrentPage(props.categoryLink)(state),
urisInList: makeSelectCategoryListUris(props.uris, props.categoryLink)(state),
fetching: makeSelectFetchingChannelClaims(props.categoryLink)(state),
obscureNsfw: !selectShowNsfw(state),
currentPageAttributes: selectActiveHistoryEntry(state),
});
const perform = dispatch => ({
fetchChannel: channel => dispatch(doFetchClaimsByChannel(channel)),
resolveUris: uris => dispatch(doResolveUris(uris, true)),
});
export default connect(

View file

@ -1,5 +1,4 @@
// @flow
import type { Claim } from 'types/claim';
import * as ICONS from 'constants/icons';
import React, { PureComponent, createRef } from 'react';
import { normalizeURI } from 'lbry-redux';
@ -11,12 +10,13 @@ import throttle from 'util/throttle';
type Props = {
category: string,
names: ?Array<string>,
categoryLink: ?string,
fetching: boolean,
channelClaims: ?Array<Claim>,
fetchChannel: string => void,
obscureNsfw: boolean,
currentPageAttributes: { scrollY: number },
fetchChannel: string => void,
urisInList: ?Array<string>,
resolveUris: (Array<string>) => void,
};
type State = {
@ -26,9 +26,11 @@ type State = {
class CategoryList extends PureComponent<Props, State> {
static defaultProps = {
categoryLink: '',
categoryLink: undefined,
};
scrollWrapper: { current: null | HTMLUListElement };
constructor() {
super();
@ -40,23 +42,55 @@ class CategoryList extends PureComponent<Props, State> {
(this: any).handleScrollNext = this.handleScrollNext.bind(this);
(this: any).handleScrollPrevious = this.handleScrollPrevious.bind(this);
(this: any).handleArrowButtonsOnScroll = this.handleArrowButtonsOnScroll.bind(this);
(this: any).handleResolveOnScroll = this.handleResolveOnScroll.bind(this);
this.scrollWrapper = createRef();
}
componentDidMount() {
const { fetching, categoryLink, fetchChannel } = this.props;
if (!fetching && categoryLink) {
const { fetching, categoryLink, fetchChannel, resolveUris, urisInList } = this.props;
if (!fetching && categoryLink && (!urisInList || urisInList.length)) {
// Only fetch the channels claims if no urisInList are specifically passed in
// This allows setting a channel link and and passing in a custom list of urisInList (featured content usually works this way)
fetchChannel(categoryLink);
}
const scrollWrapper = this.scrollWrapper.current;
if (scrollWrapper) {
scrollWrapper.addEventListener('scroll', throttle(this.handleArrowButtonsOnScroll, 500));
if (urisInList && window.innerHeight > scrollWrapper.offsetTop) {
resolveUris(urisInList);
}
}
}
scrollWrapper: { current: null | HTMLUListElement };
componentDidUpdate(prevProps: Props) {
const { scrollY: previousScrollY } = prevProps.currentPageAttributes;
const { scrollY } = this.props.currentPageAttributes;
if (scrollY > previousScrollY) {
this.handleResolveOnScroll();
}
}
handleResolveOnScroll() {
const {
urisInList,
resolveUris,
currentPageAttributes: { scrollY },
} = this.props;
const scrollWrapper = this.scrollWrapper.current;
if (!scrollWrapper) {
return;
}
const shouldResolve = window.innerHeight > scrollWrapper.offsetTop - scrollY;
if (shouldResolve && urisInList) {
resolveUris(urisInList);
}
}
handleArrowButtonsOnScroll() {
// Determine if the arrow buttons should be disabled
@ -212,7 +246,7 @@ class CategoryList extends PureComponent<Props, State> {
}
render() {
const { category, categoryLink, names, channelClaims, obscureNsfw } = this.props;
const { category, categoryLink, urisInList, obscureNsfw } = this.props;
const { canScrollNext, canScrollPrevious } = this.state;
const isCommunityTopBids = category.match(/^community/i);
const showScrollButtons = isCommunityTopBids ? !obscureNsfw : true;
@ -241,6 +275,7 @@ class CategoryList extends PureComponent<Props, State> {
)}
{isCommunityTopBids && (
<ToolTip
direction="top"
label={__("What's this?")}
body={__(
'Community Content is a public space where anyone can share content with the rest of the LBRY community. Bid on the names from "one" to "ten" to put your content here!'
@ -272,30 +307,18 @@ class CategoryList extends PureComponent<Props, State> {
</p>
) : (
<ul className="media-scrollhouse" ref={this.scrollWrapper}>
{names &&
names.length &&
names.map(name => (
<FileCard showSubscribedLogo key={name} uri={normalizeURI(name)} />
{urisInList &&
urisInList.map(uri => (
<FileCard
placeholder
preventResolve
showSubscribedLogo
key={uri}
uri={normalizeURI(uri)}
/>
))}
{channelClaims &&
channelClaims.length &&
channelClaims
// Only show the first 10 claims, regardless of the amount we have on a channel page
.slice(0, 10)
.map(claim => (
<FileCard
showSubcribedLogo
key={claim.claim_id}
uri={`lbry://${claim.name}#${claim.claim_id}`}
/>
))}
{/*
If there aren't any uris passed in, create an empty array and render placeholder cards
channelClaims or names are being fetched
*/}
{!channelClaims &&
!names &&
{!urisInList &&
/* eslint-disable react/no-array-index-key */
new Array(10).fill(1).map((x, i) => <FileCard placeholder key={i} />)
/* eslint-enable react/no-array-index-key */

View file

@ -29,63 +29,6 @@ class ToolTip extends React.PureComponent<Props, State> {
};
}
componentDidMount() {
this.handleVisibility();
}
getVisibility = () => {
if (!this.tooltip) {
return;
}
const node = this.tooltip;
const rect = node.getBoundingClientRect();
// Get parent-container
const viewport = document.getElementById('content');
if (!viewport) {
throw Error('Document must contain parent div with #content');
}
const visibility = {
top: rect.top >= 0,
left: rect.left >= 0,
right: rect.right <= viewport.offsetWidth,
bottom: rect.bottom <= viewport.offsetHeight,
};
return visibility;
};
invertDirection = () => {
// Get current direction
const { direction } = this.state;
// Inverted directions
const directions = {
top: 'bottom',
left: 'right',
right: 'left',
bottom: 'top',
};
const inverted = directions[direction];
// Update direction
if (inverted) {
this.setState({ direction: inverted });
}
};
handleVisibility = () => {
const { direction } = this.state;
const visibility = this.getVisibility();
// Invert direction if tooltip is outside viewport bounds
if (!visibility || !visibility[direction]) {
this.invertDirection();
}
};
tooltip: ?HTMLSpanElement;
render() {
@ -98,8 +41,6 @@ class ToolTip extends React.PureComponent<Props, State> {
return (
<span
onFocus={this.handleVisibility}
onMouseOver={this.handleVisibility}
className={classnames('tooltip', {
'tooltip--label': label && !icon,
'tooltip--icon': icon,

View file

@ -1,10 +1,10 @@
// @flow
import React from 'react';
import * as React from 'react';
import Native from 'native';
type Props = {
title: string,
subtitle: string,
subtitle: string | React.Node,
type: string,
};

View file

@ -29,19 +29,25 @@ type Props = {
isSubscribed: boolean,
isNew: boolean,
placeholder: boolean,
preventResolve: boolean,
};
class FileCard extends React.PureComponent<Props> {
static defaultProps = {
placeholder: false,
preventResolve: false,
};
componentWillMount() {
this.resolve(this.props);
componentDidMount() {
if (!this.props.preventResolve) {
this.resolve(this.props);
}
}
componentWillReceiveProps(nextProps: Props) {
this.resolve(nextProps);
componentDidUpdate() {
if (!this.props.preventResolve) {
this.resolve(this.props);
}
}
resolve = (props: Props) => {
@ -74,7 +80,7 @@ class FileCard extends React.PureComponent<Props> {
return null;
}
if ((!claim && !pending) || placeholder) {
if (!claim && (!pending || placeholder)) {
return (
<li className="media-card media--placeholder">
<div className="media__thumb media__thumb--placeholder" />
@ -133,7 +139,8 @@ class FileCard extends React.PureComponent<Props> {
<FilePrice hideFree uri={uri} />
{isRewardContent && <Icon iconColor="red" icon={icons.FEATURED} />}
{isSubscribed && <Icon icon={icons.SUBSCRIPTION} />}
{fileInfo && <Icon icon={icons.LOCAL} />}
{claimIsMine && <Icon icon={icons.PUBLISHED} />}
{!claimIsMine && fileInfo && <Icon icon={icons.LOCAL} />}
{isNew && <span className="badge badge--alert">{__('NEW')}</span>}
</div>
</li>

View file

@ -59,6 +59,7 @@ class FileTile extends React.PureComponent<Props> {
rewardedContentClaimIds,
size,
isNew,
claimIsMine,
} = this.props;
const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id);
@ -67,12 +68,15 @@ class FileTile extends React.PureComponent<Props> {
}
return (
// TODO: turn this into it's own component and share it with FileCard
// The only issue is icon placement on the search page
<div className={classnames('media__properties', { card__subtitle: size === 'large' })}>
<FilePrice hideFree uri={uri} />
{isNew && <span className="badge badge--alert icon">{__('NEW')}</span>}
{isSubscribed && <Icon icon={ICONS.SUBSCRIPTION} />}
{isRewardContent && <Icon iconColor="red" icon={ICONS.FEATURED} />}
{isDownloaded && <Icon icon={ICONS.LOCAL} />}
{!claimIsMine && isDownloaded && <Icon icon={ICONS.LOCAL} />}
{claimIsMine && <Icon icon={ICONS.PUBLISHED} />}
</div>
);
}

View file

@ -48,6 +48,7 @@ class MediaPlayer extends React.PureComponent {
claim,
onStartCb,
onFinishCb,
savePosition,
} = this.props;
const loadedMetadata = () => {
@ -95,13 +96,7 @@ class MediaPlayer extends React.PureComponent {
if (position) {
mediaElement.currentTime = position;
}
mediaElement.addEventListener('timeupdate', () =>
this.props.savePosition(
claim.claim_id,
`${claim.txid}:${claim.nout}`,
mediaElement.currentTime
)
);
mediaElement.addEventListener('timeupdate', () => savePosition(mediaElement.currentTime));
mediaElement.addEventListener('click', this.togglePlayListener);
mediaElement.addEventListener('loadedmetadata', loadedMetadata.bind(this), {
once: true,
@ -110,6 +105,7 @@ class MediaPlayer extends React.PureComponent {
if (onFinishCb) {
onFinishCb();
}
savePosition(0);
});
mediaElement.addEventListener('webkitfullscreenchange', win32FullScreenChange.bind(this));
mediaElement.addEventListener('volumechange', () => {

View file

@ -18,6 +18,7 @@ type Props = {
written_bytes: number,
download_path: string,
completed: boolean,
blobs_completed: number,
},
fileInfoErrors: ?{
[string]: boolean,
@ -259,7 +260,9 @@ class FileViewer extends React.PureComponent<Props> {
downloadCompleted={fileInfo.completed}
changeVolume={changeVolume}
volume={volume}
savePosition={savePosition}
savePosition={newPosition =>
savePosition(claim.claim_id, `${claim.txid}:${claim.nout}`, newPosition)
}
claim={claim}
uri={uri}
position={position}

View file

@ -101,7 +101,7 @@ export default class FirstRun extends PureComponent<Props> {
<h1 className="card__title">{__('You Are Awesome!')}</h1>
</header>
<div className="card__content">
<p>{__("Check out some of the neat files below me. I'll see you around!")}</p>
<p>{__("Check out some of the neat content below me. I'll see you around!")}</p>
<div className="card__actions">
<Button button="primary" onClick={completeFirstRun} label={__('See You Later')} />
</div>

View file

@ -17,8 +17,8 @@ import {
doOpenModal,
doHideModal,
} from 'redux/actions/app';
import { doToast, doBlackListedOutpointsSubscribe, isURIValid } from 'lbry-redux';
import { doNavigate } from 'redux/actions/navigation';
import { doToast, doBlackListedOutpointsSubscribe, isURIValid, setSearchApi } from 'lbry-redux';
import { doNavigate, doHistoryBack, doHistoryForward } from 'redux/actions/navigation';
import { doDownloadLanguages, doUpdateIsNightAsync } from 'redux/actions/settings';
import { doAuthenticate, Lbryio, rewards } from 'lbryinc';
import 'scss/all.scss';
@ -37,6 +37,18 @@ if (process.env.LBRY_API_URL) {
Lbryio.setLocalApi(process.env.LBRY_API_URL);
}
if (process.env.SEARCH_API_URL) {
setSearchApi(process.env.SEARCH_API_URL);
}
ipcRenderer.on('navigate-backward', () => {
app.store.dispatch(doHistoryBack());
});
ipcRenderer.on('navigate-forward', () => {
app.store.dispatch(doHistoryForward());
});
// We need to override Lbryio for getting/setting the authToken
// We interect with ipcRenderer to get the auth key from a users keyring
// We keep a local variable for authToken beacuse `ipcRenderer.send` does not

View file

@ -9,7 +9,7 @@ const select = state => ({
});
const perform = dispatch => ({
fetchFeaturedUris: () => dispatch(doFetchFeaturedUris()),
fetchFeaturedUris: () => dispatch(doFetchFeaturedUris(true)),
fetchRewardedContent: () => dispatch(doFetchRewardedContent()),
fetchRewards: () => dispatch(doRewardList()),
});

View file

@ -18,7 +18,7 @@ class DiscoverPage extends React.PureComponent<Props> {
this.continousFetch = undefined;
}
componentWillMount() {
componentDidMount() {
const { fetchFeaturedUris, fetchRewardedContent, fetchRewards } = this.props;
fetchFeaturedUris();
fetchRewardedContent();
@ -59,27 +59,19 @@ class DiscoverPage extends React.PureComponent<Props> {
const { featuredUris, fetchingFeaturedUris } = this.props;
const hasContent = typeof featuredUris === 'object' && Object.keys(featuredUris).length;
const failedToLoad = !fetchingFeaturedUris && !hasContent;
return (
<Page noPadding isLoading={!hasContent && fetchingFeaturedUris}>
<FirstRun />
{hasContent &&
Object.keys(featuredUris).map(
category =>
featuredUris[category].length ? (
<CategoryList
key={category}
category={this.trimClaimIdFromCategory(category)}
names={featuredUris[category]}
categoryLink={this.getCategoryLinkPartByCategory(category)}
/>
) : (
<CategoryList
key={category}
category={this.trimClaimIdFromCategory(category)}
categoryLink={category}
/>
)
)}
Object.keys(featuredUris).map(category => (
<CategoryList
key={category}
category={this.trimClaimIdFromCategory(category)}
uris={featuredUris[category]}
categoryLink={this.getCategoryLinkPartByCategory(category)}
/>
))}
{failedToLoad && <div className="empty">{__('Failed to load landing content.')}</div>}
</Page>
);

View file

@ -1,8 +1,8 @@
// @flow
import React, { Fragment } from 'react';
import Native from 'native';
import Button from 'component/button';
import SuggestedSubscriptions from 'component/subscribeSuggested';
import Yrbl from 'component/common/yrbl';
type Props = {
showSuggested: boolean,
@ -23,40 +23,37 @@ export default (props: Props) => {
return (
<Fragment>
<div className="yrbl-wrap">
<img
alt="Friendly gerbil"
className="subscriptions__gerbil"
src={Native.imagePath('gerbil-happy.png')}
/>
<div className="card__content">
<h2 className="card__title">
{numberOfSubscriptions > 0 ? __('Woohoo!') : __('No subscriptions... yet.')}
</h2>
<p className="card__subtitle">
{showSuggested
? __('I hear these channels are pretty good.')
: __("I'll tell you where the good channels are if you find me a wheel.")}
</p>
{!showSuggested && (
<div className="card__actions">
<Button button="primary" label={__('Explore')} onClick={doShowSuggestedSubs} />
</div>
)}
{showSuggested &&
numberOfSubscriptions > 0 && (
<Yrbl
title={numberOfSubscriptions > 0 ? __('Woohoo!') : __('No subscriptions... yet.')}
subtitle={
<React.Fragment>
<p>
{showSuggested
? __('I hear these channels are pretty good.')
: __("I'll tell you where the good channels are if you find me a wheel.")}
</p>
{!showSuggested && (
<div className="card__actions">
<Button
button="primary"
onClick={onFinish}
label={`${__('View your')} ${numberOfSubscriptions} ${
numberOfSubscriptions > 1 ? __('subscribed channels') : __('subscribed channel')
}`}
/>
<Button button="primary" label={__('Explore')} onClick={doShowSuggestedSubs} />
</div>
)}
</div>
</div>
{showSuggested &&
numberOfSubscriptions > 0 && (
<div className="card__actions">
<Button
button="primary"
onClick={onFinish}
label={`${__('View your')} ${numberOfSubscriptions} ${
numberOfSubscriptions > 1
? __('subscribed channels')
: __('subscribed channel')
}`}
/>
</div>
)}
</React.Fragment>
}
/>
{showSuggested && !loadingSuggested && <SuggestedSubscriptions />}
</Fragment>
);

View file

@ -1,8 +1,13 @@
// @flow
import { createSelector } from 'reselect';
import { makeSelectClaimForUri, selectClaimsByUri } from 'lbry-redux';
import {
makeSelectClaimForUri,
selectClaimsByUri,
makeSelectClaimsInChannelForCurrentPage,
} from 'lbry-redux';
import { HISTORY_ITEMS_PER_PAGE } from 'constants/content';
export const selectState = state => state.content || {};
export const selectState = (state: any) => state.content || {};
export const selectPlayingUri = createSelector(selectState, state => state.playingUri);
@ -11,7 +16,7 @@ export const selectChannelClaimCounts = createSelector(
state => state.channelClaimCounts || {}
);
export const makeSelectTotalItemsForChannel = uri =>
export const makeSelectTotalItemsForChannel = (uri: string) =>
createSelector(selectChannelClaimCounts, byUri => byUri && byUri[uri]);
export const selectRewardContentClaimIds = createSelector(
@ -19,7 +24,7 @@ export const selectRewardContentClaimIds = createSelector(
state => state.rewardedContentClaimIds
);
export const makeSelectContentPositionForUri = uri =>
export const makeSelectContentPositionForUri = (uri: string) =>
createSelector(selectState, makeSelectClaimForUri(uri), (state, claim) => {
if (!claim) {
return null;
@ -33,7 +38,7 @@ export const selectHistoryPageCount = createSelector(selectState, state =>
Math.ceil(state.history.length / HISTORY_ITEMS_PER_PAGE)
);
export const makeSelectHistoryForPage = page =>
export const makeSelectHistoryForPage = (page: number) =>
createSelector(selectState, selectClaimsByUri, (state, claimsByUri) => {
const left = page * HISTORY_ITEMS_PER_PAGE;
const historyItems = state.history.slice(left, left + HISTORY_ITEMS_PER_PAGE);
@ -51,5 +56,19 @@ export const makeSelectHistoryForPage = page =>
});
});
export const makeSelectHistoryForUri = uri =>
export const makeSelectHistoryForUri = (uri: string) =>
createSelector(selectState, state => state.history.find(i => i.uri === uri));
export const makeSelectCategoryListUris = (uris: Array<string> = [], channel: string) =>
createSelector(makeSelectClaimsInChannelForCurrentPage(channel), channelClaims => {
if (uris) return uris;
if (channelClaims) {
const CATEGORY_LIST_SIZE = 10;
return channelClaims
.slice(0, CATEGORY_LIST_SIZE)
.map(({ name, claim_id: claimId }) => `${name}#${claimId}`);
}
return null;
});

View file

@ -96,7 +96,7 @@
}
.media__properties {
bottom: -5rem;
bottom: -4.5rem;
left: -20rem;
position: absolute;
}

View file

@ -1,4 +1,3 @@
import { createLogger } from 'redux-logger';
import appReducer from 'redux/reducers/app';
import availabilityReducer from 'redux/reducers/availability';
import contentReducer from 'redux/reducers/content';
@ -75,13 +74,6 @@ const reducers = combineReducers({
const bulkThunk = createBulkThunkMiddleware();
const middleware = [thunk, bulkThunk];
if (app.env === 'development') {
const logger = createLogger({
collapsed: true,
});
middleware.push(logger);
}
// eslint-disable-next-line no-underscore-dangle
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

149
yarn.lock
View file

@ -1793,10 +1793,6 @@ center-align@^0.1.1:
align-text "^0.1.3"
lazy-cache "^1.0.3"
chain-function@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.0.tgz#0d4ab37e7e18ead0bdc47b920764118ce58733dc"
chainsaw@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98"
@ -2659,10 +2655,6 @@ dedent@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
deep-diff@^0.3.5:
version "0.3.8"
resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84"
deep-equal@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
@ -2859,10 +2851,6 @@ dom-converter@~0.1:
dependencies:
utila "~0.3"
dom-helpers@^3.2.0:
version "3.3.1"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.3.1.tgz#fc1a4e15ffdf60ddde03a480a9c0fece821dd4a6"
dom-scroll-into-view@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz#e8f36732dd089b0201a88d7815dc3f88e6d66c7e"
@ -2874,10 +2862,6 @@ dom-serializer@0, dom-serializer@~0.1.0:
domelementtype "~1.1.1"
entities "~1.1.1"
dom-walk@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
domain-browser@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
@ -3969,18 +3953,6 @@ fbjs@^0.6.1:
ua-parser-js "^0.7.9"
whatwg-fetch "^0.9.0"
fbjs@^0.8.16:
version "0.8.17"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
dependencies:
core-js "^1.0.0"
isomorphic-fetch "^2.1.1"
loose-envify "^1.0.0"
object-assign "^4.1.0"
promise "^7.1.1"
setimmediate "^1.0.5"
ua-parser-js "^0.7.18"
fd-slicer@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65"
@ -4185,12 +4157,6 @@ follow-redirects@^1.0.0:
dependencies:
debug "^3.1.0"
for-each@^0.3.2:
version "0.3.3"
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
dependencies:
is-callable "^1.1.3"
for-in@^0.1.3:
version "0.1.8"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
@ -4482,13 +4448,6 @@ global-dirs@^0.1.0:
dependencies:
ini "^1.3.4"
global@~4.3.0:
version "4.3.2"
resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f"
dependencies:
min-document "^2.19.0"
process "~0.5.1"
globals@^11.0.1, globals@^11.1.0:
version "11.7.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673"
@ -5244,10 +5203,6 @@ is-fullwidth-code-point@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
is-function@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5"
is-glob@^2.0.0, is-glob@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
@ -5471,13 +5426,6 @@ isobject@^3.0.0, isobject@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
isomorphic-fetch@^2.1.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
dependencies:
node-fetch "^1.0.1"
whatwg-fetch ">=0.10.0"
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
@ -5723,17 +5671,17 @@ lazy-val@^1.0.3:
tar-stream "^1.6.2"
zstd-codec "^0.1.1"
lbry-redux@lbryio/lbry-redux#2ff9f70a3d765946a1c83c8e7eee7d81c96c1345:
lbry-redux@lbryio/lbry-redux#84b7d396934d57a37802aadbef71db91230a9404:
version "0.0.1"
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/2ff9f70a3d765946a1c83c8e7eee7d81c96c1345"
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/84b7d396934d57a37802aadbef71db91230a9404"
dependencies:
proxy-polyfill "0.1.6"
reselect "^3.0.0"
uuid "^3.3.2"
lbry-redux@lbryio/lbry-redux#84b7d396934d57a37802aadbef71db91230a9404:
lbry-redux@lbryio/lbry-redux#e94de324876185561b4f38b18fabb2aa58b8e3ed:
version "0.0.1"
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/84b7d396934d57a37802aadbef71db91230a9404"
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/e94de324876185561b4f38b18fabb2aa58b8e3ed"
dependencies:
proxy-polyfill "0.1.6"
reselect "^3.0.0"
@ -6375,12 +6323,6 @@ mimic-response@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
min-document@^2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
dependencies:
dom-walk "^0.1.0"
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
@ -6643,7 +6585,7 @@ node-emoji@^1.4.1:
dependencies:
lodash.toarray "^4.4.0"
node-fetch@^1.0.1, node-fetch@^1.3.3:
node-fetch@^1.3.3:
version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
dependencies:
@ -7199,13 +7141,6 @@ parse-glob@^3.0.4:
is-extglob "^1.0.0"
is-glob "^2.0.0"
parse-headers@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.1.tgz#6ae83a7aa25a9d9b700acc28698cd1f1ed7e9536"
dependencies:
for-each "^0.3.2"
trim "0.0.1"
parse-json@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
@ -7726,10 +7661,6 @@ process@^0.11.0, process@^0.11.10:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
process@~0.5.1:
version "0.5.2"
resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
progress-stream@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/progress-stream/-/progress-stream-1.2.0.tgz#2cd3cfea33ba3a89c9c121ec3347abe9ab125f77"
@ -7751,7 +7682,7 @@ promise@^7.0.3, promise@^7.1.1:
dependencies:
asap "~2.0.3"
prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2:
prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2:
version "15.6.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102"
dependencies:
@ -7948,14 +7879,14 @@ rc@^1.0.1, rc@^1.1.2, rc@^1.1.6, rc@^1.2.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
react-dom@^16.3.0:
version "16.4.1"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.4.1.tgz#7f8b0223b3a5fbe205116c56deb85de32685dad6"
react-dom@^16.6.0:
version "16.7.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0.tgz#a17b2a7ca89ee7390bc1ed5eb81783c7461748b8"
dependencies:
fbjs "^0.8.16"
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.0"
prop-types "^15.6.2"
scheduler "^0.12.0"
react-feather@^1.0.8:
version "1.1.1"
@ -8025,16 +7956,6 @@ react-toggle@^4.0.2:
dependencies:
classnames "^2.2.5"
react-transition-group@1.x:
version "1.2.1"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.1.tgz#e11f72b257f921b213229a774df46612346c7ca6"
dependencies:
chain-function "^1.0.0"
dom-helpers "^3.2.0"
loose-envify "^1.3.1"
prop-types "^15.5.6"
warning "^3.0.0"
react@^0.14.5:
version "0.14.9"
resolved "https://registry.yarnpkg.com/react/-/react-0.14.9.tgz#9110a6497c49d44ba1c0edd317aec29c2e0d91d1"
@ -8042,14 +7963,14 @@ react@^0.14.5:
envify "^3.0.0"
fbjs "^0.6.1"
react@^16.3.0:
version "16.6.1"
resolved "https://registry.yarnpkg.com/react/-/react-16.6.1.tgz#ee2aef4f0a09e494594882029821049772f915fe"
react@^16.6.0:
version "16.7.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.7.0.tgz#b674ec396b0a5715873b350446f7ea0802ab6381"
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "^0.11.0"
scheduler "^0.12.0"
read-config-file@3.1.0, read-config-file@^3.0.0:
version "3.1.0"
@ -8185,12 +8106,6 @@ reduce-function-call@^1.0.1:
dependencies:
balanced-match "^0.4.2"
redux-logger@^3.0.1:
version "3.0.6"
resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-3.0.6.tgz#f7555966f3098f3c88604c449cf0baf5778274bf"
dependencies:
deep-diff "^0.3.5"
redux-persist-transform-compress@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/redux-persist-transform-compress/-/redux-persist-transform-compress-4.2.0.tgz#5089e299df7130878fca45f97ffe82888ba02690"
@ -8415,7 +8330,7 @@ replace-ext@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb"
request@^2.45.0, request@^2.55.0:
request@^2.45.0:
version "2.87.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e"
dependencies:
@ -8640,9 +8555,9 @@ sax@~1.1.1:
version "1.1.6"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.1.6.tgz#5d616be8a5e607d54e114afae55b7eaf2fcc3240"
scheduler@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.0.tgz#def1f1bfa6550cc57981a87106e65e8aea41a6b5"
scheduler@^0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.12.0.tgz#8ab17699939c0aedc5a196a657743c496538647b"
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
@ -8780,7 +8695,7 @@ set-value@^2.0.0:
is-plain-object "^2.0.3"
split-string "^3.0.1"
setimmediate@^1.0.4, setimmediate@^1.0.5, setimmediate@~1.0.4:
setimmediate@^1.0.4, setimmediate@~1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
@ -8811,13 +8726,6 @@ shallow-clone@^1.0.0:
kind-of "^5.0.0"
mixin-object "^2.0.1"
shapeshift.io@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/shapeshift.io/-/shapeshift.io-1.3.1.tgz#939f7d89e6a93fad4b556567d3fcdab45d5cc021"
dependencies:
request "^2.55.0"
xhr "^2.0.1"
shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
@ -9731,10 +9639,6 @@ typo-js@*:
version "1.0.3"
resolved "https://registry.yarnpkg.com/typo-js/-/typo-js-1.0.3.tgz#54d8ebc7949f1a7810908b6002c6841526c99d5a"
ua-parser-js@^0.7.18:
version "0.7.19"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.19.tgz#94151be4c0a7fb1d001af7022fdaca4642659e4b"
ua-parser-js@^0.7.9:
version "0.7.18"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.18.tgz#a7bfd92f56edfb117083b69e31d2aa8882d4b1ed"
@ -10319,10 +10223,6 @@ websocket-extensions@>=0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
whatwg-fetch@>=0.10.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"
whatwg-fetch@^0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-0.9.0.tgz#0e3684c6cb9995b43efc9df03e4c365d95fd9cc0"
@ -10424,15 +10324,6 @@ xdg-basedir@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
xhr@^2.0.1:
version "2.5.0"
resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd"
dependencies:
global "~4.3.0"
is-function "^1.0.1"
parse-headers "^2.0.0"
xtend "^4.0.0"
xml2js@0.4.17:
version "0.4.17"
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.17.tgz#17be93eaae3f3b779359c795b419705a8817e868"