diff --git a/CHANGELOG.md b/CHANGELOG.md index 8270fb16f..df00ba3a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,22 +8,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added * Allow typing of encryption password without clicking entry box ([#1977](https://github.com/lbryio/lbry-desktop/pull/1977)) * Focus on search bar with {cmd,ctrl} + "l" ([#2003](https://github.com/lbryio/lbry-desktop/pull/2003)) - * Add support for clickable channel names on explore page headings ([#2023](https://github.com/lbryio/lbry-desktop/pull/2023)) - * Content loading placeholder styles on FileCard/FileTile ([#2022](https://github.com/lbryio/lbry-desktop/pull/2022)) - ### Changed * Make tooltip smarter ([#1979](https://github.com/lbryio/lbry-desktop/pull/1979)) * Change channel pages to have 48 items instead of 10 ([#2002](https://github.com/lbryio/lbry-desktop/pull/2002)) * Update to https ([#2016](https://github.com/lbryio/lbry-desktop/pull/2016)) * Simplify FileCard and FileTile component styling ([#2011](https://github.com/lbryio/lbry-desktop/pull/2011)) - * Credit card verification messaging ([#2025](https://github.com/lbryio/lbry-desktop/pull/2025)) ### Fixed - * Fixed Transactions filter menu collides with transaction table ([#2005](https://github.com/lbryio/lbry-desktop/pull/2005)) * Invite table cutoff with large number of invites ([#1985](https://github.com/lbryio/lbry-desktop/pull/1985)) * History styling on large screens and link issue with claims ([#1999](https://github.com/lbryio/lbry-desktop/pull/1999)) * Satisfy console warnings in publishForm and validation messaging ([#2010](https://github.com/lbryio/lbry-desktop/pull/2010)) - * App crashing if invalid characters entered in LBRY URL ([#2026])(https://github.com/lbryio/lbry-desktop/pull/2026)) + ## [0.25.1] - 2018-09-18 diff --git a/src/renderer/component/common/tooltip.jsx b/src/renderer/component/common/tooltip.jsx index 181c792c7..c54318098 100644 --- a/src/renderer/component/common/tooltip.jsx +++ b/src/renderer/component/common/tooltip.jsx @@ -11,11 +11,7 @@ type Props = { onComponent?: boolean, // extra padding to account for button/form field size }; -type State = { - direction: string, -}; - -class ToolTip extends React.PureComponent { +class ToolTip extends React.PureComponent { static defaultProps = { direction: 'bottom', }; @@ -38,9 +34,6 @@ class ToolTip extends React.PureComponent { // 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, diff --git a/src/renderer/component/dateTime/view.jsx b/src/renderer/component/dateTime/view.jsx index 7049b223e..83f7fa755 100644 --- a/src/renderer/component/dateTime/view.jsx +++ b/src/renderer/component/dateTime/view.jsx @@ -1,15 +1,6 @@ -// @flow import React from 'react'; -import moment from 'moment'; -type Props = { - date?: number, - timeAgo?: boolean, - formatOptions: {}, - show?: string, -}; - -class DateTime extends React.PureComponent { +class DateTime extends React.PureComponent { static SHOW_DATE = 'date'; static SHOW_TIME = 'time'; static SHOW_BOTH = 'both'; @@ -38,24 +29,18 @@ class DateTime extends React.PureComponent { } render() { - const { date, formatOptions, timeAgo } = this.props; + const { date, formatOptions } = this.props; const show = this.props.show || DateTime.SHOW_BOTH; const locale = app.i18n.getLocale(); - // If !date, it's currently being fetched - - if (timeAgo) { - return date ? {moment(date).from(moment())} : ; - } - return ( {date && - (show === DateTime.SHOW_BOTH || show === DateTime.SHOW_DATE) && + (show == DateTime.SHOW_BOTH || show === DateTime.SHOW_DATE) && date.toLocaleDateString([locale, 'en-US'], formatOptions)} - {show === DateTime.SHOW_BOTH && ' '} + {show == DateTime.SHOW_BOTH && ' '} {date && - (show === DateTime.SHOW_BOTH || show === DateTime.SHOW_TIME) && + (show == DateTime.SHOW_BOTH || show === DateTime.SHOW_TIME) && date.toLocaleTimeString()} {!date && '...'} diff --git a/src/renderer/component/fileCard/index.js b/src/renderer/component/fileCard/index.js index b61ae8bb1..95a7f9a67 100644 --- a/src/renderer/component/fileCard/index.js +++ b/src/renderer/component/fileCard/index.js @@ -14,8 +14,6 @@ import { } from 'redux/selectors/content'; import { selectShowNsfw } from 'redux/selectors/settings'; import { selectPendingPublish } from 'redux/selectors/publish'; -import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions'; -import { doClearContentHistoryUri } from 'redux/actions/content'; import FileCard from './view'; const select = (state, props) => { @@ -38,7 +36,6 @@ const select = (state, props) => { ...fileCardInfo, pending: !!pendingPublish, position: makeSelectContentPositionForUri(props.uri)(state), - isSubscribed: makeSelectIsSubscribed(props.uri)(state), }; }; diff --git a/src/renderer/component/fileCard/view.jsx b/src/renderer/component/fileCard/view.jsx index bb2df3780..1d058d4ad 100644 --- a/src/renderer/component/fileCard/view.jsx +++ b/src/renderer/component/fileCard/view.jsx @@ -10,7 +10,6 @@ import * as icons from 'constants/icons'; import classnames from 'classnames'; import FilePrice from 'component/filePrice'; import { openCopyLinkMenu } from 'util/contextMenu'; -import DateTime from 'component/dateTime'; type Props = { uri: string, @@ -25,11 +24,15 @@ type Props = { /* eslint-disable react/no-unused-prop-types */ resolveUri: string => void, isResolvingUri: boolean, + showPrice: boolean, /* eslint-enable react/no-unused-prop-types */ - isSubscribed: boolean, }; class FileCard extends React.PureComponent { + static defaultProps = { + showPrice: true, + }; + componentWillMount() { this.resolve(this.props); } @@ -56,20 +59,9 @@ class FileCard extends React.PureComponent { obscureNsfw, claimIsMine, pending, - isSubscribed, + showPrice, } = this.props; - if (!claim && !pending) { - return ( -
-
-
-
-
-
- ); - } - const shouldHide = !claimIsMine && !pending && obscureNsfw && metadata && metadata.nsfw; if (shouldHide) { return null; @@ -79,7 +71,6 @@ class FileCard extends React.PureComponent { const title = metadata && metadata.title ? metadata.title : uri; const thumbnail = metadata && metadata.thumbnail ? metadata.thumbnail : null; const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id); - const height = claim && claim.height; const handleContextMenu = event => { event.preventDefault(); event.stopPropagation(); @@ -106,15 +97,10 @@ class FileCard extends React.PureComponent {
{pending ?
Pending...
: }
-
- - -
- - {isRewardContent && } - {isSubscribed && } - {fileInfo && } -
+
+ {showPrice && } + {isRewardContent && } + {fileInfo && }
); diff --git a/src/renderer/component/fileTile/index.js b/src/renderer/component/fileTile/index.js index 2b10e1356..e5e242291 100644 --- a/src/renderer/component/fileTile/index.js +++ b/src/renderer/component/fileTile/index.js @@ -11,7 +11,6 @@ import { selectShowNsfw } from 'redux/selectors/settings'; import { doNavigate } from 'redux/actions/navigation'; import { doClearPublish, doUpdatePublishForm } from 'redux/actions/publish'; import { selectRewardContentClaimIds } from 'redux/selectors/content'; -import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions'; import FileTile from './view'; const select = (state, props) => ({ @@ -22,7 +21,6 @@ const select = (state, props) => ({ rewardedContentClaimIds: selectRewardContentClaimIds(state, props), obscureNsfw: !selectShowNsfw(state), claimIsMine: makeSelectClaimIsMine(props.uri)(state), - isSubscribed: makeSelectIsSubscribed(props.uri)(state), }); const perform = dispatch => ({ diff --git a/src/renderer/component/fileTile/view.jsx b/src/renderer/component/fileTile/view.jsx index c23804b8e..1793c331c 100644 --- a/src/renderer/component/fileTile/view.jsx +++ b/src/renderer/component/fileTile/view.jsx @@ -10,9 +10,10 @@ import Button from 'component/button'; import classnames from 'classnames'; import FilePrice from 'component/filePrice'; import UriIndicator from 'component/uriIndicator'; -import DateTime from 'component/dateTime'; type Props = { + showUri: boolean, + showLocal: boolean, obscureNsfw: boolean, claimIsMine: boolean, isDownloaded: boolean, @@ -29,11 +30,12 @@ type Props = { displayHiddenMessage?: boolean, displayDescription?: boolean, size: string, - isSubscribed: boolean, }; class FileTile extends React.PureComponent { static defaultProps = { + showUri: false, + showLocal: false, displayDescription: true, size: 'regular', }; @@ -48,28 +50,18 @@ class FileTile extends React.PureComponent { if (!isResolvingUri && claim === undefined && uri) resolveUri(uri); } - renderFileProperties() { - const { isSubscribed, isDownloaded, claim, uri, rewardedContentClaimIds, size } = this.props; - const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id); - - return ( -
- - {isSubscribed && } - {isRewardContent && } - {isDownloaded && } -
- ); - } - render() { const { claim, metadata, isResolvingUri, navigate, + rewardedContentClaimIds, + showUri, obscureNsfw, claimIsMine, + showLocal, + isDownloaded, clearPublish, updatePublishForm, hideNoResult, @@ -78,24 +70,6 @@ class FileTile extends React.PureComponent { size, } = this.props; - if (!claim && isResolvingUri) { - return ( -
-
-
-
-
-
-
-
- ); - } - const shouldHide = !claimIsMine && obscureNsfw && metadata && metadata.nsfw; if (shouldHide) { return displayHiddenMessage ? ( @@ -113,12 +87,12 @@ class FileTile extends React.PureComponent { const title = isClaimed && metadata && metadata.title ? metadata.title : parseURI(uri).contentName; const thumbnail = metadata && metadata.thumbnail ? metadata.thumbnail : null; + const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id); const onClick = () => navigate('/show', { uri }); - let height; let name; if (claim) { - ({ name, height } = claim); + ({ name } = claim); } return !name && hideNoResult ? null : ( @@ -134,42 +108,43 @@ class FileTile extends React.PureComponent { >
-
- {(title || name) && ( - - )} -
-
- -
-
- - {size !== 'large' && this.renderFileProperties()} -
- {displayDescription && ( -
- -
- )} - {size === 'large' && this.renderFileProperties()} - {!name && ( + {isResolvingUri &&
{__('Loading...')}
} + {!isResolvingUri && ( - {__('This location is unused.')}{' '} -
diff --git a/src/renderer/component/recommendedContent/view.jsx b/src/renderer/component/recommendedContent/view.jsx index 4a12aecb3..902229c47 100644 --- a/src/renderer/component/recommendedContent/view.jsx +++ b/src/renderer/component/recommendedContent/view.jsx @@ -2,6 +2,7 @@ import React from 'react'; import FileTile from 'component/fileTile'; import type { Claim } from 'types/claim'; +import Spinner from 'component/spinner'; type Props = { uri: string, @@ -65,6 +66,7 @@ export default class RecommendedContent extends React.PureComponent { {recommendedContent && !recommendedContent.length && !isSearching &&
No related content found
} + {isSearching && } ); } diff --git a/src/renderer/component/userHistory/index.js b/src/renderer/component/userHistory/index.js index 01618f6be..1b77955b1 100644 --- a/src/renderer/component/userHistory/index.js +++ b/src/renderer/component/userHistory/index.js @@ -18,6 +18,7 @@ const select = state => { const perform = dispatch => ({ navigate: (path, params) => dispatch(doNavigate(path, params)), clearHistoryUri: uri => dispatch(doClearContentHistoryUri(uri)), + }); export default connect( diff --git a/src/renderer/component/userVerify/view.jsx b/src/renderer/component/userVerify/view.jsx index 468a6288b..9220095b1 100644 --- a/src/renderer/component/userVerify/view.jsx +++ b/src/renderer/component/userVerify/view.jsx @@ -43,7 +43,7 @@ class UserVerify extends React.PureComponent {

{`${__( 'If you have a valid credit or debit card, you can use it to instantly prove your humanity.' - )} ${__('LBRY does not store your credit card information. There is no charge at all for this, now or in the future.')} `} + )} ${__('There is no charge at all for this, now or in the future.')} `}

{errorMessage &&

{errorMessage}

} diff --git a/src/renderer/component/wunderbar/index.js b/src/renderer/component/wunderbar/index.js index 13dcc37d7..1bbcd3b26 100644 --- a/src/renderer/component/wunderbar/index.js +++ b/src/renderer/component/wunderbar/index.js @@ -7,7 +7,6 @@ import { doFocusSearchInput, doBlurSearchInput, doSearch, - doNotify, } from 'lbry-redux'; import { makeSelectClientSetting } from 'redux/selectors/settings'; import * as settings from 'constants/settings'; @@ -39,7 +38,6 @@ const perform = dispatch => ({ updateSearchQuery: query => dispatch(doUpdateSearchQuery(query)), doFocus: () => dispatch(doFocusSearchInput()), doBlur: () => dispatch(doBlurSearchInput()), - doShowSnackBar: (modal, props) => dispatch(doNotify(modal, props)), }); export default connect( diff --git a/src/renderer/component/wunderbar/view.jsx b/src/renderer/component/wunderbar/view.jsx index daace0ec9..1736fb1d5 100644 --- a/src/renderer/component/wunderbar/view.jsx +++ b/src/renderer/component/wunderbar/view.jsx @@ -1,7 +1,7 @@ // @flow import React from 'react'; import classnames from 'classnames'; -import { normalizeURI, SEARCH_TYPES, isURIValid } from 'lbry-redux'; +import { normalizeURI, SEARCH_TYPES } from 'lbry-redux'; import Icon from 'component/common/icon'; import { parseQueryParams } from 'util/query_params'; import * as icons from 'constants/icons'; @@ -101,16 +101,9 @@ class WunderBar extends React.PureComponent { if (suggestion.type === 'search') { onSearch(query, resultCount); } else { - if (isURIValid(query)) { - const params = getParams(); - const uri = normalizeURI(query); - onSubmit(uri, params); - } else { - this.props.doShowSnackBar({ - message: __('Invalid LBRY URL entered. Only A-Z, a-z, and - allowed.'), - displayType: ['snackbar'], - }) - } + const params = getParams(); + const uri = normalizeURI(query); + onSubmit(uri, params); } return; @@ -119,16 +112,9 @@ class WunderBar extends React.PureComponent { // Currently no suggestion is highlighted. The user may have started // typing, then lost focus and came back later on the same page try { - if (isURIValid(query)) { - const uri = normalizeURI(query); - const params = getParams(); - onSubmit(uri, params); - } else { - this.props.doShowSnackBar({ - message: __('Invalid LBRY URL entered. Only A-Z, a-z, and - allowed.'), - displayType: ['snackbar'], - }) - } + const uri = normalizeURI(query); + const params = getParams(); + onSubmit(uri, params); } catch (e) { onSearch(query, resultCount); } diff --git a/src/renderer/page/discover/view.jsx b/src/renderer/page/discover/view.jsx index 0c1e98358..4579f5394 100644 --- a/src/renderer/page/discover/view.jsx +++ b/src/renderer/page/discover/view.jsx @@ -31,20 +31,6 @@ class DiscoverPage extends React.PureComponent { this.clearContinuousFetch(); } - getCategoryLinkPartByCategory(category: string) { - const channelName = category.substr(category.indexOf('@')); - if (!channelName.includes('#')) { - return null; - } - return channelName; - } - - trimClaimIdFromCategory(category: string) { - return category.split('#')[0]; - } - - continousFetch: ?IntervalID; - clearContinuousFetch() { if (this.continousFetch) { clearInterval(this.continousFetch); @@ -52,26 +38,24 @@ class DiscoverPage extends React.PureComponent { } } + continousFetch: ?number; + render() { const { featuredUris, fetchingFeaturedUris } = this.props; const hasContent = typeof featuredUris === 'object' && Object.keys(featuredUris).length; const failedToLoad = !fetchingFeaturedUris && !hasContent; + return ( {hasContent && Object.keys(featuredUris).map( category => featuredUris[category].length ? ( - + ) : ( ) diff --git a/src/renderer/page/file/view.jsx b/src/renderer/page/file/view.jsx index db0d2adba..147a2313a 100644 --- a/src/renderer/page/file/view.jsx +++ b/src/renderer/page/file/view.jsx @@ -43,13 +43,9 @@ type Props = { fetchFileInfo: string => void, fetchCostInfo: string => void, prepareEdit: ({}, string) => void, - setViewed: string => void, - autoplay: boolean, - setClientSetting: (string, string | boolean | number) => void, - /* eslint-disable react/no-unused-prop-types */ checkSubscription: (uri: string) => void, subscriptions: Array, - /* eslint-enable react/no-unused-prop-types */ + setViewed: string => void, }; class FilePage extends React.Component { @@ -187,7 +183,7 @@ class FilePage extends React.Component { ))}
-
+

{title}

{isRewardContent && ( @@ -224,12 +220,14 @@ class FilePage extends React.Component { onClick={() => openModal({ id: MODALS.SEND_TIP }, { uri })} /> )} -
diff --git a/src/renderer/redux/actions/publish.js b/src/renderer/redux/actions/publish.js index 70a5cdcf9..2421375ab 100644 --- a/src/renderer/redux/actions/publish.js +++ b/src/renderer/redux/actions/publish.js @@ -19,13 +19,11 @@ import { doNavigate } from 'redux/actions/navigation'; import fs from 'fs'; import path from 'path'; import { CC_LICENSES, COPYRIGHT, OTHER } from 'constants/licenses'; +import type { Dispatch, GetState } from 'types/redux'; type Action = UpdatePublishFormAction | { type: ACTIONS.CLEAR_PUBLISH }; -type PromiseAction = Promise; -type Dispatch = (action: Action | PromiseAction | Array) => any; -type GetState = () => {}; -export const doResetThumbnailStatus = () => (dispatch: Dispatch): PromiseAction => { +export const doResetThumbnailStatus = () => (dispatch: Dispatch): Promise => { dispatch({ type: ACTIONS.UPDATE_PUBLISH_FORM, data: { @@ -61,20 +59,22 @@ export const doResetThumbnailStatus = () => (dispatch: Dispatch): PromiseAction ); }; -export const doClearPublish = () => (dispatch: Dispatch): PromiseAction => { +export const doClearPublish = () => (dispatch: Dispatch): Promise => { dispatch({ type: ACTIONS.CLEAR_PUBLISH }); return dispatch(doResetThumbnailStatus()); }; export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) => ( - dispatch: Dispatch + dispatch: Dispatch ): UpdatePublishFormAction => dispatch({ type: ACTIONS.UPDATE_PUBLISH_FORM, data: { ...publishFormValue }, }); -export const doUploadThumbnail = (filePath: string, nsfw: boolean) => (dispatch: Dispatch) => { +export const doUploadThumbnail = (filePath: string, nsfw: boolean) => ( + dispatch: Dispatch +) => { const thumbnail = fs.readFileSync(filePath); const fileExt = path.extname(filePath); const fileName = path.basename(filePath); @@ -128,7 +128,7 @@ export const doUploadThumbnail = (filePath: string, nsfw: boolean) => (dispatch: .catch(err => uploadError(err.message)); }; -export const doPrepareEdit = (claim: any, uri: string) => (dispatch: Dispatch) => { +export const doPrepareEdit = (claim: any, uri: string) => (dispatch: Dispatch) => { const { name, amount, @@ -189,7 +189,10 @@ export const doPrepareEdit = (claim: any, uri: string) => (dispatch: Dispatch) = dispatch({ type: ACTIONS.DO_PREPARE_EDIT, data: publishData }); }; -export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getState: () => {}) => { +export const doPublish = (params: PublishParams) => ( + dispatch: Dispatch, + getState: () => {} +) => { const state = getState(); const myChannels = selectMyChannelClaims(state); @@ -265,7 +268,7 @@ export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getStat }; // Calls claim_list_mine until any pending publishes are confirmed -export const doCheckPendingPublishes = () => (dispatch: Dispatch, getState: GetState) => { +export const doCheckPendingPublishes = () => (dispatch: Dispatch, getState: GetState) => { const state = getState(); const pendingPublishes = selectPendingPublishes(state); diff --git a/src/renderer/redux/actions/shape_shift.js b/src/renderer/redux/actions/shape_shift.js index c2aecefba..5e66e6255 100644 --- a/src/renderer/redux/actions/shape_shift.js +++ b/src/renderer/redux/actions/shape_shift.js @@ -14,6 +14,7 @@ import type { GetActiveShiftFail, } from 'redux/reducers/shape_shift'; import type { FormikActions } from 'types/common'; +import type { Dispatch, ThunkAction } from 'types/redux'; // use promise chains instead of callbacks for shapeshift api const shapeShift = Promise.promisifyAll(require('shapeshift.io')); @@ -38,9 +39,6 @@ export type Action = // Basic thunk types // It would be nice to import these from types/common // Not sure how that would work since they rely on the Action type -type PromiseAction = Promise; -export type Dispatch = (action: Action | PromiseAction | Array) => any; -type ThunkAction = (dispatch: Dispatch) => any; // ShapeShift form values export type ShapeShiftFormValues = { @@ -49,7 +47,7 @@ export type ShapeShiftFormValues = { receiveAddress: string, }; -export const getCoinStats = (coin: string) => (dispatch: Dispatch): ThunkAction => { +export const getCoinStats = (coin: string) => (dispatch: Dispatch): ThunkAction => { const pair = `${coin.toLowerCase()}_lbc`; dispatch({ type: ACTIONS.GET_COIN_STATS_START, data: coin }); @@ -60,7 +58,7 @@ export const getCoinStats = (coin: string) => (dispatch: Dispatch): ThunkAction .catch(err => dispatch({ type: ACTIONS.GET_COIN_STATS_FAIL, data: err })); }; -export const shapeShiftInit = () => (dispatch: Dispatch): ThunkAction => { +export const shapeShiftInit = () => (dispatch: Dispatch): ThunkAction => { dispatch({ type: ACTIONS.GET_SUPPORTED_COINS_START }); return shapeShift @@ -94,8 +92,8 @@ export const shapeShiftInit = () => (dispatch: Dispatch): ThunkAction => { }; export const createShapeShift = (values: ShapeShiftFormValues, actions: FormikActions) => ( - dispatch: Dispatch -): ThunkAction => { + dispatch: Dispatch +): ThunkAction => { const { originCoin, returnAddress, receiveAddress: withdrawalAddress } = values; const pair = `${originCoin.toLowerCase()}_lbc`; @@ -114,7 +112,9 @@ export const createShapeShift = (values: ShapeShiftFormValues, actions: FormikAc }); }; -export const getActiveShift = (depositAddress: string) => (dispatch: Dispatch): ThunkAction => { +export const getActiveShift = (depositAddress: string) => ( + dispatch: Dispatch +): ThunkAction => { dispatch({ type: ACTIONS.GET_ACTIVE_SHIFT_START }); return shapeShift @@ -123,5 +123,5 @@ export const getActiveShift = (depositAddress: string) => (dispatch: Dispatch): .catch(err => dispatch({ type: ACTIONS.GET_ACTIVE_SHIFT_FAIL, data: err })); }; -export const clearShapeShift = () => (dispatch: Dispatch): Action => +export const clearShapeShift = () => (dispatch: Dispatch): Action => dispatch({ type: ACTIONS.CLEAR_SHAPE_SHIFT }); diff --git a/src/renderer/redux/reducers/subscriptions.js b/src/renderer/redux/reducers/subscriptions.js index 348528007..0ccfbd7db 100644 --- a/src/renderer/redux/reducers/subscriptions.js +++ b/src/renderer/redux/reducers/subscriptions.js @@ -3,6 +3,7 @@ import * as ACTIONS from 'constants/action_types'; import * as NOTIFICATION_TYPES from 'constants/notification_types'; import { handleActions } from 'util/redux-utils'; import type { Subscription } from 'types/subscription'; +import type { Dispatch as ReduxDispatch } from 'types/redux'; export type NotificationType = | NOTIFICATION_TYPES.DOWNLOADING @@ -79,7 +80,7 @@ export type Action = | CheckSubscriptionStarted | CheckSubscriptionCompleted | Function; -export type Dispatch = (action: Action) => any; +export type Dispatch = ReduxDispatch; const defaultState = { subscriptions: [], diff --git a/src/renderer/redux/selectors/subscriptions.js b/src/renderer/redux/selectors/subscriptions.js index 1931c1671..12c35ae74 100644 --- a/src/renderer/redux/selectors/subscriptions.js +++ b/src/renderer/redux/selectors/subscriptions.js @@ -3,7 +3,6 @@ import { selectAllClaimsByChannel, selectClaimsById, selectAllFetchingChannelClaims, - makeSelectClaimForUri, } from 'lbry-redux'; // get the entire subscriptions state @@ -72,13 +71,3 @@ export const selectSubscriptionsBeingFetched = createSelector( return fetchingSubscriptionMap; } ); - -export const makeSelectIsSubscribed = uri => - createSelector(selectSubscriptions, makeSelectClaimForUri(uri), (subscriptions, claim) => { - if (!claim || !claim.channel_name) { - return false; - } - - const channelUri = `${claim.channel_name}#${claim.value.publisherSignature.certificateId}`; - return subscriptions.some(sub => sub.uri === channelUri); - }); diff --git a/src/renderer/scss/all.scss b/src/renderer/scss/all.scss index 370cebd3f..30a4dc9f5 100644 --- a/src/renderer/scss/all.scss +++ b/src/renderer/scss/all.scss @@ -32,4 +32,3 @@ @import 'component/_item-list.scss'; @import 'component/_time.scss'; @import 'component/_icon.scss'; -@import 'component/_placeholder.scss'; diff --git a/src/renderer/scss/component/_card.scss b/src/renderer/scss/component/_card.scss index 69ef64ba6..c202974ae 100644 --- a/src/renderer/scss/component/_card.scss +++ b/src/renderer/scss/component/_card.scss @@ -88,16 +88,20 @@ // FileCard is slightly different where the title is only slightly bigger than the subtitle // Slightly bigger than 2 lines for consistent channel placement font-size: 1.1em; - height: 3.3em; + height: 4em; @media only screen and (min-width: $large-breakpoint) { font-size: 1.3em; } } -.card--space-between { +.card__title__space-between { display: flex; justify-content: space-between; + + .icon { + margin: 0 $spacing-vertical * 1/3; + } } .card__title-identity-icons { @@ -110,7 +114,6 @@ color: var(--card-text-color); font-size: 1em; line-height: 1em; - padding-top: $spacing-vertical * 1/3; @media (min-width: $large-breakpoint) { font-size: 1.2em; @@ -121,13 +124,12 @@ font-size: 1.1em; &:not(:first-of-type) { - padding-top: $spacing-vertical * 3/2; + margin-top: $spacing-vertical * 3/2; } } .card__subtext { font-size: 0.85em; - padding-top: $spacing-vertical * 1/3; } .card__meta { @@ -140,11 +142,8 @@ .card__file-properties { display: flex; align-items: center; + padding-top: $spacing-vertical * 1/3; color: var(--card-text-color); - - .icon + .icon { - margin-left: $spacing-vertical * 1/3; - } } // .card-media__internal__links should always be inside a card @@ -197,8 +196,9 @@ } .card__actions-top-corner { - display: flex; - justify-content: flex-end; + position: absolute; + top: $spacing-vertical; + right: $spacing-vertical; } .card__actions-bottom-corner { diff --git a/src/renderer/scss/component/_file-list.scss b/src/renderer/scss/component/_file-list.scss index e62b4df5c..666046341 100644 --- a/src/renderer/scss/component/_file-list.scss +++ b/src/renderer/scss/component/_file-list.scss @@ -45,7 +45,6 @@ } .file-tile__title { - font-size: 1.1em; } .file-tile--small { @@ -66,7 +65,6 @@ .file-tile__info { display: flex; - flex: 1; flex-direction: column; margin-left: $spacing-vertical * 2/3; max-width: 500px; diff --git a/src/renderer/scss/component/_placeholder.scss b/src/renderer/scss/component/_placeholder.scss deleted file mode 100644 index e66418137..000000000 --- a/src/renderer/scss/component/_placeholder.scss +++ /dev/null @@ -1,40 +0,0 @@ -@keyframes pulse { - 0% { - opacity: 1; - } - 50% { - opacity: 0.7; - } - 100% { - opacity: 1; - } -} - -.card--placeholder { - animation: pulse 2s infinite ease-in-out; - background: var(--color-placeholder); -} - -// Individual items we need a placeholder for -// FileCard -.placeholder__title { - margin-top: $spacing-vertical * 1/3; - height: 3em; -} - -.placeholder__channel { - margin-top: $spacing-vertical * 1/3; - height: 1em; - width: 70%; -} - -.placeholder__date { - height: 1em; - margin-top: $spacing-vertical * 1/3; - width: 50%; -} - -// FileTile -.placeholder__title--tile { - height: 3em; -} diff --git a/src/renderer/types/redux.js b/src/renderer/types/redux.js new file mode 100644 index 000000000..e198e51b3 --- /dev/null +++ b/src/renderer/types/redux.js @@ -0,0 +1,6 @@ +// @flow + +// eslint-disable-next-line no-use-before-define +export type Dispatch = (action: T | Promise | Array | ThunkAction) => any; // Need to refer to ThunkAction +export type GetState = () => {}; +export type ThunkAction = (dispatch: Dispatch, getState: GetState) => any; diff --git a/yarn.lock b/yarn.lock index ff1003b87..9298e7f8c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5662,9 +5662,9 @@ lbry-redux@lbryio/lbry-redux: proxy-polyfill "0.1.6" reselect "^3.0.0" -lbry-redux@lbryio/lbry-redux#4ee6c376e5f2c3e3e96d199a56970e2621a84af1: +lbry-redux@lbryio/lbry-redux#c079b108c3bc4ba2b4fb85fb112b52cfc040c301: version "0.0.1" - resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/4ee6c376e5f2c3e3e96d199a56970e2621a84af1" + resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/c079b108c3bc4ba2b4fb85fb112b52cfc040c301" dependencies: proxy-polyfill "0.1.6" reselect "^3.0.0"