diff --git a/.flowconfig b/.flowconfig
index 1eaa4969e..664b2d8de 100644
--- a/.flowconfig
+++ b/.flowconfig
@@ -20,6 +20,5 @@ module.name_mapper='^lbry\(.*\)$' -> '/src/renderer/lbry\1'
module.name_mapper='^rewards\(.*\)$' -> '/src/renderer/rewards\1'
module.name_mapper='^modal\(.*\)$' -> '/src/renderer/modal\1'
module.name_mapper='^app\(.*\)$' -> '/src/renderer/app\1'
-module.name_mapper='^native\(.*\)$' -> '/src/renderer/native\1'
[strict]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1ae61c477..61461cbf0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,7 +7,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
### Added
- * Add ability to open log file and log directory in the help page ([#1556](https://github.com/lbryio/lbry-app/issues/1556))
* Add ability to resend verification email ([#1492](https://github.com/lbryio/lbry-app/issues/1492))
* Add Narrative about Feature Request on Help Page and Report Page ([#1551](https://github.com/lbryio/lbry-app/pull/1551))
* Add keyboard shortcut to quit the app on Windows ([#1202](https://github.com/lbryio/lbry-app/pull/1202))
@@ -28,7 +27,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
* Move rewards logic to interal api ([#1509](https://github.com/lbryio/lbry-app/pull/1509))
### Fixed
- * Fixing content address extending outside of visible area. ([#741](https://github.com/lbryio/lbry-app/issues/741))
* Fix content-type not shown correctly in file description ([#863](https://github.com/lbryio/lbry-app/pull/863))
* Fix [Flow](https://flow.org/) ([#1197](https://github.com/lbryio/lbry-app/pull/1197))
* Fix black screen on macOS after maximizing LBRY and then closing ([#1235](https://github.com/lbryio/lbry-app/pull/1235))
diff --git a/src/renderer/component/app/view.jsx b/src/renderer/component/app/view.jsx
index a6a225df0..23ee922bb 100644
--- a/src/renderer/component/app/view.jsx
+++ b/src/renderer/component/app/view.jsx
@@ -84,8 +84,8 @@ class App extends React.PureComponent {
-
+
diff --git a/src/renderer/component/common/form-components/form-field.jsx b/src/renderer/component/common/form-components/form-field.jsx
index 6b0a9b234..4029cbd1e 100644
--- a/src/renderer/component/common/form-components/form-field.jsx
+++ b/src/renderer/component/common/form-components/form-field.jsx
@@ -4,7 +4,7 @@ import ReactDOMServer from 'react-dom/server';
import classnames from 'classnames';
import MarkdownPreview from 'component/common/markdown-preview';
import SimpleMDE from 'react-simplemde-editor';
-import "simplemde/dist/simplemde.min.css";
+import 'simplemde/dist/simplemde.min.css';
type Props = {
name: string,
@@ -20,6 +20,7 @@ type Props = {
placeholder?: string | number,
children?: React.Node,
stretch?: boolean,
+ affixClass?: string, // class applied to prefix/postfix label
};
export class FormField extends React.PureComponent {
@@ -35,6 +36,7 @@ export class FormField extends React.PureComponent {
type,
children,
stretch,
+ affixClass,
...inputProps
} = this.props;
@@ -55,12 +57,12 @@ export class FormField extends React.PureComponent {
{...inputProps}
type="textarea"
options={{
- hideIcons: ['heading', 'image', 'fullscreen', 'side-by-side'],
- previewRender(plainText) {
- const preview = ;
- return ReactDOMServer.renderToString(preview);
- }
- }}
+ hideIcons: ['heading', 'image', 'fullscreen', 'side-by-side'],
+ previewRender(plainText) {
+ const preview = ;
+ return ReactDOMServer.renderToString(preview);
+ },
+ }}
/>
);
@@ -92,22 +94,18 @@ export class FormField extends React.PureComponent {
})}
>
{prefix && (
-
+
{prefix}
)}
{input}
{postfix && (
-
+
{postfix}
)}
- {helper && (
-
- {helper}
-
- )}
+ {helper && {helper}
}
);
}
diff --git a/src/renderer/component/common/qr-code.jsx b/src/renderer/component/common/qr-code.jsx
index daf08d9c3..fb74c68d7 100644
--- a/src/renderer/component/common/qr-code.jsx
+++ b/src/renderer/component/common/qr-code.jsx
@@ -6,22 +6,19 @@ import classnames from 'classnames';
type Props = {
value: string,
paddingRight?: boolean,
- paddingTop?: boolean,
};
class QRCode extends React.Component {
static defaultProps = {
paddingRight: false,
- paddingTop: false,
};
render() {
- const { value, paddingRight, paddingTop } = this.props;
+ const { value, paddingRight } = this.props;
return (
diff --git a/src/renderer/component/fileList/view.jsx b/src/renderer/component/fileList/view.jsx
index 1f649f527..cf1b22ae8 100644
--- a/src/renderer/component/fileList/view.jsx
+++ b/src/renderer/component/fileList/view.jsx
@@ -171,6 +171,7 @@ class FileList extends React.PureComponent
{
{!hideFilter && (
{
return (
-
{__('LBRY')}
+
+
{__('LBRY')}
+ beta
+
{isWarning ? (
diff --git a/src/renderer/component/transactionList/view.jsx b/src/renderer/component/transactionList/view.jsx
index c0b84be33..0ab002bee 100644
--- a/src/renderer/component/transactionList/view.jsx
+++ b/src/renderer/component/transactionList/view.jsx
@@ -96,6 +96,7 @@ class TransactionList extends React.PureComponent {
type="select"
value={filter}
onChange={this.handleFilterChanged}
+ affixClass="form-field--align-center"
prefix={__('Show')}
postfix={
{
- constructor(props: Props) {
- super(props);
-
- this.state = {
- showQR: false,
- };
- }
-
- toggleQR() {
- this.setState({
- showQR: !this.state.showQR,
- });
- }
-
componentWillMount() {
const { checkAddressIsMine, receiveAddress, getNewAddress } = this.props;
if (!receiveAddress) {
@@ -38,7 +23,6 @@ class WalletAddress extends React.PureComponent {
render() {
const { receiveAddress, getNewAddress, gettingNewAddress } = this.props;
- const { showQR } = this.state;
return (
@@ -59,17 +43,7 @@ class WalletAddress extends React.PureComponent {
onClick={getNewAddress}
disabled={gettingNewAddress}
/>
-
-
-
- {showQR && }
-
-
diff --git a/src/renderer/component/walletSend/view.jsx b/src/renderer/component/walletSend/view.jsx
index 340cc483d..1d7942676 100644
--- a/src/renderer/component/walletSend/view.jsx
+++ b/src/renderer/component/walletSend/view.jsx
@@ -56,8 +56,10 @@ class WalletSend extends React.PureComponent {
label={__('Amount')}
postfix={__('LBC')}
className="input--price-amount"
+ affixClass="form-field--fix-no-height"
min="0"
step="any"
+ placeholder="12.34"
onChange={handleChange}
onBlur={handleBlur}
value={values.amount}
diff --git a/src/renderer/component/walletSendTip/view.jsx b/src/renderer/component/walletSendTip/view.jsx
index b8dad4480..477932eab 100644
--- a/src/renderer/component/walletSendTip/view.jsx
+++ b/src/renderer/component/walletSendTip/view.jsx
@@ -87,7 +87,12 @@ class WalletSendTip extends React.PureComponent {
disabled={isPending || amount <= 0 || amount > balance}
onClick={this.handleSendButtonClicked}
/>
-
+
diff --git a/src/renderer/modal/modalDownloading/view.jsx b/src/renderer/modal/modalDownloading/view.jsx
index b230731fb..9829ec99a 100644
--- a/src/renderer/modal/modalDownloading/view.jsx
+++ b/src/renderer/modal/modalDownloading/view.jsx
@@ -34,7 +34,7 @@ class ModalDownloading extends React.PureComponent {
/>
) : null}
({});
+const select = () => ({});
const perform = dispatch => ({
downloadUpgrade: () => dispatch(doDownloadUpgrade()),
- skipUpgrade: () => dispatch(doSkipUpgrade()),
+ skipUpgrade: () => {
+ dispatch(doHideNotification());
+ dispatch(doSkipUpgrade());
+ },
});
-export default connect(select, perform)(ModalUpgrade);
+export default connect(
+ select,
+ perform
+)(ModalUpgrade);
diff --git a/src/renderer/modal/modalUpgrade/view.jsx b/src/renderer/modal/modalUpgrade/view.jsx
index ced5fd808..41425b1e4 100644
--- a/src/renderer/modal/modalUpgrade/view.jsx
+++ b/src/renderer/modal/modalUpgrade/view.jsx
@@ -24,7 +24,11 @@ class ModalUpgrade extends React.PureComponent {
{__('Want to know what has changed?')} See the{' '}
- .
+ .
);
diff --git a/src/renderer/page/file/view.jsx b/src/renderer/page/file/view.jsx
index d2660beb6..83d30fb84 100644
--- a/src/renderer/page/file/view.jsx
+++ b/src/renderer/page/file/view.jsx
@@ -20,6 +20,7 @@ import * as settings from 'constants/settings';
import type { Claim } from 'types/claim';
import type { Subscription } from 'types/subscription';
import FileDownloadLink from 'component/fileDownloadLink';
+import classnames from 'classnames';
type Props = {
claim: Claim,
@@ -114,8 +115,7 @@ class FilePage extends React.Component {
const shouldObscureThumbnail = obscureNsfw && metadata.nsfw;
const { height, channel_name: channelName, value } = claim;
const mediaType = Lbry.getMediaType(contentType);
- const isPlayable =
- Object.values(player.mime).indexOf(contentType) !== -1 || mediaType === 'audio';
+ const isPlayable = Object.values(player.mime).includes(contentType) || mediaType === 'audio';
const channelClaimId =
value && value.publisherSignature && value.publisherSignature.certificateId;
let subscriptionUri;
@@ -149,11 +149,19 @@ class FilePage extends React.Component {
) : (
- {isPlayable ? (
-
- ) : (
-
- )}
+ {isPlayable && }
+ {!isPlayable &&
+ (thumbnail ? (
+
+ ) : (
+
+
{__('This content is not playable.')}
+
+ ))}
{title}
@@ -171,7 +179,6 @@ class FilePage extends React.Component
{
{metadata.nsfw && NSFW
}
-
{claimIsMine ? (
{
}}
/>
) : (
-
+
+ )}
+
+
+ {!claimIsMine ||
+ (speechSharable && (
+
+ {!claimIsMine && (
openModal({ id: MODALS.SEND_TIP }, { uri })}
/>
-
-
- )}
- {speechSharable && (
-
- )}
-
-
+ )}
+ {speechSharable && (
+
+ )}
+
+ ))}
(
+const GetCreditsPage = () => (
-
- {__('From External Wallet')}
-
-
-
-
{__('More ways to get LBRY Credits')}
diff --git a/src/renderer/page/help/index.js b/src/renderer/page/help/index.js
index cfabb784b..6a59becb9 100644
--- a/src/renderer/page/help/index.js
+++ b/src/renderer/page/help/index.js
@@ -1,14 +1,12 @@
import { connect } from 'react-redux';
import { doAuthNavigate } from 'redux/actions/navigation';
import { doFetchAccessToken } from 'redux/actions/user';
-import { selectDaemonSettings } from 'redux/selectors/settings';
import { selectAccessToken, selectUser } from 'redux/selectors/user';
import HelpPage from './view';
const select = state => ({
user: selectUser(state),
accessToken: selectAccessToken(state),
- deamonSettings: selectDaemonSettings(state),
});
const perform = dispatch => ({
@@ -16,7 +14,4 @@ const perform = dispatch => ({
fetchAccessToken: () => dispatch(doFetchAccessToken()),
});
-export default connect(
- select,
- perform
-)(HelpPage);
+export default connect(select, perform)(HelpPage);
diff --git a/src/renderer/page/help/view.jsx b/src/renderer/page/help/view.jsx
index ce92cc1e3..eb8da4aae 100644
--- a/src/renderer/page/help/view.jsx
+++ b/src/renderer/page/help/view.jsx
@@ -1,44 +1,15 @@
// @TODO: Customize advice based on OS
-// @flow
-import * as React from 'react';
-import { shell } from 'electron';
+import React from 'react';
import { Lbry } from 'lbry-redux';
import Native from 'native';
import Button from 'component/button';
import BusyIndicator from 'component/common/busy-indicator';
+import Icon from 'component/common/icon';
import Page from 'component/page';
import * as icons from 'constants/icons';
-type DeamonSettings = {
- data_dir: string | any,
-};
-
-type Props = {
- deamonSettings: DeamonSettings,
- accessToken: string,
- fetchAccessToken: () => void,
- doAuth: () => void,
- user: any,
-};
-
-type VersionInfo = {
- os_system: string,
- os_release: string,
- platform: string,
- lbrynet_version: string,
- lbryum_version: string,
-};
-
-type State = {
- versionInfo: VersionInfo | any,
- lbryId: String | any,
- uiVersion: ?string,
- upgradeAvailable: ?boolean,
- accessTokenHidden: ?boolean,
-};
-
-class HelpPage extends React.PureComponent
{
- constructor(props: Props) {
+class HelpPage extends React.PureComponent {
+ constructor(props) {
super(props);
this.state = {
@@ -49,12 +20,11 @@ class HelpPage extends React.PureComponent {
accessTokenHidden: true,
};
- (this: any).showAccessToken = this.showAccessToken.bind(this);
- (this: any).openLogFile = this.openLogFile.bind(this);
+ this.showAccessToken = this.showAccessToken.bind(this);
}
componentDidMount() {
- Native.getAppVersionInfo().then(({ localVersion, upgradeAvailable }) => {
+ Native.getAppVersionInfo().then(({ remoteVersion, localVersion, upgradeAvailable }) => {
this.setState({
uiVersion: localVersion,
upgradeAvailable,
@@ -80,24 +50,13 @@ class HelpPage extends React.PureComponent {
});
}
- openLogFile(userHomeDirectory: string) {
- const logFileName = 'lbrynet.log';
- const os = this.state.versionInfo.os_system;
- if (os === 'Darwin' || os === 'Linux') {
- shell.openItem(`${userHomeDirectory}/${logFileName}`);
- } else {
- shell.openItem(`${userHomeDirectory}\\${logFileName}`);
- }
- }
-
render() {
let ver;
let osName;
let platform;
let newVerLink;
- const { accessToken, doAuth, user, deamonSettings } = this.props;
- const { data_dir: dataDirectory } = deamonSettings;
+ const { accessToken, doAuth, user } = this.props;
if (this.state.versionInfo) {
ver = this.state.versionInfo;
@@ -149,33 +108,12 @@ class HelpPage extends React.PureComponent {
-
- {__('View your Log')}
-
- {__('Did something go wrong? Have a look in your log file, or send it to')}{' '}
- .
-
-
- this.openLogFile(dataDirectory)}
- />
- shell.showItemInFolder(dataDirectory)}
- />
-
-
-
{__('Report a Bug or Suggest a New Feature')}
{__('Did you find something wrong? Think LBRY could add something useful and cool?')}
+
{
{__('Share Diagnostic Data')}
-
-
-
+
{
@@ -317,7 +315,7 @@ class SettingsPage extends React.PureComponent {
{__('Application Cache')}
- {__("This will delete your subscriptions, and clear the app's cache")}
+ {__('This will clear the application cache. Your wallet will not be affected.')}
(dispatch: Dispatch, getState: GetS
dispatch(batchActions(...actions));
- if (!pendingPublishes.length) {
+ if (!Object.keys(pendingPublishes).length) {
clearInterval(publishCheckInterval);
}
});
diff --git a/src/renderer/redux/actions/user.js b/src/renderer/redux/actions/user.js
index 7b9e96d66..1893fb13a 100644
--- a/src/renderer/redux/actions/user.js
+++ b/src/renderer/redux/actions/user.js
@@ -1,6 +1,6 @@
import * as ACTIONS from 'constants/action_types';
import Lbryio from 'lbryio';
-import { Lbry, doNotify, MODALS } from 'lbry-redux';
+import { doNotify, MODALS } from 'lbry-redux';
import { doClaimRewardType, doRewardList } from 'redux/actions/rewards';
import {
selectEmailToVerify,
@@ -9,7 +9,6 @@ import {
} from 'redux/selectors/user';
import rewards from 'rewards';
import analytics from 'analytics';
-import pjson from 'package.json';
export function doFetchInviteStatus() {
return dispatch => {
@@ -36,19 +35,6 @@ export function doFetchInviteStatus() {
};
}
-export function doInstallNew() {
- const payload = { app_version: pjson.version };
- Lbry.status().then(status => {
- payload.app_id = status.installation_id;
- Lbry.version().then(version => {
- payload.daemon_version = version.lbrynet_version;
- payload.operating_system = version.os_system;
- payload.platform = version.platform;
- Lbryio.call('install', 'new', payload);
- });
- });
-}
-
export function doAuthenticate() {
return dispatch => {
dispatch({
@@ -63,7 +49,6 @@ export function doAuthenticate() {
});
dispatch(doRewardList());
dispatch(doFetchInviteStatus());
- doInstallNew();
})
.catch(error => {
dispatch(doNotify({ id: MODALS.AUTHENTICATION_FAILURE }));
diff --git a/src/renderer/redux/reducers/app.js b/src/renderer/redux/reducers/app.js
index 3417d55d2..c66ae24b3 100644
--- a/src/renderer/redux/reducers/app.js
+++ b/src/renderer/redux/reducers/app.js
@@ -114,7 +114,6 @@ reducers[ACTIONS.SKIP_UPGRADE] = state => {
return Object.assign({}, state, {
isUpgradeSkipped: true,
- modal: null,
});
};
diff --git a/src/renderer/scss/_gui.scss b/src/renderer/scss/_gui.scss
index 8d8bb175e..de1d5e449 100644
--- a/src/renderer/scss/_gui.scss
+++ b/src/renderer/scss/_gui.scss
@@ -121,6 +121,10 @@ input::placeholder {
opacity: 0.5;
}
+label[for] {
+ cursor: pointer;
+}
+
button + input {
margin-left: $spacing-vertical * 2/3;
}
@@ -157,7 +161,7 @@ p {
grid-template-rows: var(--header-height) calc(100vh - var(--header-height));
grid-template-columns: var(--side-nav-width) auto;
grid-template-areas:
- 'nav header'
+ 'nav content'
'nav content';
background-color: var(--color-bg);
height: 100vh;
@@ -176,7 +180,7 @@ p {
*/
.content {
grid-area: content;
- overflow: auto;
+ overflow-y: auto;
}
.main {
@@ -356,13 +360,7 @@ p {
}
.qr-code {
- border: 3px solid var(--color-white);
- height: 134px;
- width: 134px;
&.qr-code--right-padding {
- margin-right: $spacing-vertical * 2/3;
- }
- &.qr-code--top-padding {
- margin-top: $spacing-vertical * 2/3;
+ padding-right: $spacing-vertical * 2/3;
}
}
diff --git a/src/renderer/scss/_vars.scss b/src/renderer/scss/_vars.scss
index 1909e3ffe..fc2b6fe68 100644
--- a/src/renderer/scss/_vars.scss
+++ b/src/renderer/scss/_vars.scss
@@ -42,6 +42,7 @@ $large-breakpoint: 1760px;
--color-divider: #e3e3e3;
--color-help: rgba(0, 0, 0, 0.54);
--color-error: #a94442;
+ --color-nsfw: #bf4440;
--color-download: var(--color-white);
--color-download-overlay: var(--color-black);
--color-bg: #fafafa;
diff --git a/src/renderer/scss/component/_card.scss b/src/renderer/scss/component/_card.scss
index b27fdc815..6b74d12c1 100644
--- a/src/renderer/scss/component/_card.scss
+++ b/src/renderer/scss/component/_card.scss
@@ -8,10 +8,6 @@
flex-direction: column;
}
-.card > h1 {
- word-wrap: break-word;
-}
-
.card--section {
background-color: var(--card-bg);
padding: $spacing-vertical;
@@ -27,17 +23,17 @@
padding-top: var(--video-aspect-ratio);
}
- .card__media-text {
- // for the weird padding required for dynamic height
- // this lets the text sit in the middle instead of the bottom
- margin-top: calc(var(--video-aspect-ratio) * -1);
- }
-
.channel-name {
font-size: 12px;
}
}
+.card__media-text {
+ // for the weird padding required for dynamic height
+ // this lets the text sit in the middle instead of the bottom
+ margin-top: calc(var(--video-aspect-ratio) * -1);
+}
+
.card--link {
cursor: pointer;
}
@@ -244,6 +240,10 @@
right: $spacing-vertical;
}
+.card__actions--end {
+ justify-content: flex-end;
+}
+
/*
.card-row is used on the discover page
It is a list of cards that extend past the right edge of the screen
diff --git a/src/renderer/scss/component/_content.scss b/src/renderer/scss/component/_content.scss
index 89359eed1..6fe2194ee 100644
--- a/src/renderer/scss/component/_content.scss
+++ b/src/renderer/scss/component/_content.scss
@@ -78,6 +78,20 @@
color: var(--color-white);
}
+.content__empty {
+ background-color: black;
+ width: 100%;
+ padding-top: var(--video-aspect-ratio);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--color-white);
+
+ &.content__empty--nsfw {
+ background-color: var(--color-nsfw);
+ }
+}
+
img {
max-height: 100%;
max-width: 100%;
diff --git a/src/renderer/scss/component/_form-field.scss b/src/renderer/scss/component/_form-field.scss
index 9dd03b5d7..d93a1885b 100644
--- a/src/renderer/scss/component/_form-field.scss
+++ b/src/renderer/scss/component/_form-field.scss
@@ -84,7 +84,7 @@
.form-field__help {
color: var(--color-help);
- padding-top: $spacing-vertical * 1/3;
+ padding-top: $spacing-vertical * 2/3;
}
.form-field__error {
@@ -94,6 +94,14 @@
.form-field__prefix,
.form-field__postfix {
font-family: 'metropolis-medium';
+
+ &.form-field--fix-no-height {
+ line-height: 1;
+ }
+
+ &.form-field--align-center {
+ align-self: center;
+ }
}
.form-field__prefix {
diff --git a/src/renderer/scss/component/_header.scss b/src/renderer/scss/component/_header.scss
index 6df42f34e..94eb62974 100644
--- a/src/renderer/scss/component/_header.scss
+++ b/src/renderer/scss/component/_header.scss
@@ -1,11 +1,9 @@
.header {
- grid-area: header;
display: flex;
z-index: 1;
justify-content: space-between;
padding: $spacing-width $spacing-width 0 $spacing-width;
background-color: var(--color-bg);
- // height: 100px;
}
.header__actions-right {
diff --git a/src/renderer/scss/component/_load-screen.scss b/src/renderer/scss/component/_load-screen.scss
index a34dd2d89..f41b36578 100644
--- a/src/renderer/scss/component/_load-screen.scss
+++ b/src/renderer/scss/component/_load-screen.scss
@@ -10,10 +10,20 @@
justify-content: center;
}
+.load-screen__header {
+ display: flex;
+}
+
.load-screen__title {
font-family: 'metropolis-bold';
font-size: 60px;
line-height: 100px;
+ margin-left: 40px; // width of "beta" superscript
+}
+
+.load-screen__beta {
+ padding-top: 23px;
+ padding-left: 10px;
}
.load-screen__message {