diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9a6a82780..3269d2934 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,6 +25,8 @@ Web UI version numbers should always match the corresponding version of LBRY App
* Fixed inappropriate text showing on searches
* Stop discover page from pushing jumping vertically while loading
* Restored feedback on claim amounts
+ * Fixed hiding price input when Free is checked on publish form
+ * Fixed hiding new identity fields on publish form
### Deprecated
*
diff --git a/app/main.js b/app/main.js
index 35a50f224..69fad7d92 100644
--- a/app/main.js
+++ b/app/main.js
@@ -27,7 +27,7 @@ const {version: localVersion} = require(app.getAppPath() + '/package.json');
const VERSION_CHECK_INTERVAL = 30 * 60 * 1000;
const LATEST_RELEASE_API_URL = 'https://api.github.com/repos/lbryio/lbry-app/releases/latest';
-
+const DAEMON_PATH = process.env.LBRY_DAEMON || path.join(__dirname, 'dist', 'lbrynet-daemon');
let client = jayson.client.http({
host: 'localhost',
@@ -207,13 +207,8 @@ function handleDaemonSubprocessExited() {
function launchDaemon() {
assert(!daemonSubprocess, 'Tried to launch daemon twice');
- if (process.env.LBRY_DAEMON) {
- executable = process.env.LBRY_DAEMON;
- } else {
- executable = path.join(__dirname, 'dist', 'lbrynet-daemon');
- }
- console.log('Launching daemon:', executable)
- daemonSubprocess = child_process.spawn(executable)
+ console.log('Launching daemon:', DAEMON_PATH)
+ daemonSubprocess = child_process.spawn(DAEMON_PATH)
// Need to handle the data event instead of attaching to
// process.stdout because the latter doesn't work. I believe on
// windows it buffers stdout and we don't get any meaningful output
diff --git a/app/package.json b/app/package.json
index aee4e6085..ced806d22 100644
--- a/app/package.json
+++ b/app/package.json
@@ -18,5 +18,8 @@
},
"devDependencies": {
"electron-rebuild": "^1.5.11"
+ },
+ "lbrySettings": {
+ "lbrynetDaemonVersion": "0.14.1"
}
}
diff --git a/build/DAEMON_URL b/build/DAEMON_URL
deleted file mode 100644
index e7d65abfa..000000000
--- a/build/DAEMON_URL
+++ /dev/null
@@ -1 +0,0 @@
-https://github.com/lbryio/lbry/releases/download/v0.14.1/lbrynet-daemon-v0.14.1-OSNAME.zip
diff --git a/build/build.sh b/build/build.sh
index c5ccba34f..9fa139877 100755
--- a/build/build.sh
+++ b/build/build.sh
@@ -79,11 +79,14 @@ if $OSX; then
else
OSNAME="linux"
fi
-DAEMON_URL="$(cat "$BUILD_DIR/DAEMON_URL" | sed "s/OSNAME/${OSNAME}/")"
+DAEMON_VER=$(node -e "console.log(require(\"$ROOT/app/package.json\").lbrySettings.lbrynetDaemonVersion)")
+DAEMON_URL="https://github.com/lbryio/lbry/releases/download/v${DAEMON_VER}/lbrynet-daemon-v${DAEMON_VER}-${OSNAME}.zip"
wget --quiet "$DAEMON_URL" -O "$BUILD_DIR/daemon.zip"
unzip "$BUILD_DIR/daemon.zip" -d "$ROOT/app/dist/"
rm "$BUILD_DIR/daemon.zip"
+
+
###################
# Build the app #
###################
diff --git a/ui/js/actions/app.js b/ui/js/actions/app.js
index f50ea9467..c3f23a3a5 100644
--- a/ui/js/actions/app.js
+++ b/ui/js/actions/app.js
@@ -16,9 +16,9 @@ import { doFileList } from "actions/file_info";
const { remote, ipcRenderer, shell } = require("electron");
const path = require("path");
-const app = require("electron").remote.app;
const { download } = remote.require("electron-dl");
const fs = remote.require("fs");
+const { lbrySettings: config } = require("../../../app/package.json");
const queryStringFromParams = params => {
return Object.keys(params).map(key => `${key}=${params[key]}`).join("&");
@@ -33,7 +33,7 @@ export function doNavigate(path, params = {}) {
const state = getState();
const pageTitle = selectPageTitle(state);
- dispatch(doHistoryPush(params, pageTitle, url));
+ dispatch(doHistoryPush({ params }, pageTitle, url));
};
}
@@ -51,7 +51,7 @@ export function doAuthNavigate(pathAfterAuth = null, params = {}) {
};
}
-export function doChangePath(path) {
+export function doChangePath(path, options = {}) {
return function(dispatch, getState) {
dispatch({
type: types.CHANGE_PATH,
@@ -62,8 +62,12 @@ export function doChangePath(path) {
const state = getState();
const pageTitle = selectPageTitle(state);
+ const scrollY = options.scrollY;
+
window.document.title = pageTitle;
- window.scrollTo(0, 0);
+
+ if (scrollY) window.scrollTo(0, scrollY);
+ else window.scrollTo(0, 0);
const currentPage = selectCurrentPage(state);
if (currentPage === "search") {
@@ -81,10 +85,26 @@ export function doHistoryBack() {
};
}
-export function doHistoryPush(params, title, relativeUrl) {
+export function doHistoryPush(currentState, title, relativeUrl) {
return function(dispatch, getState) {
title += " - LBRY";
- history.pushState(params, title, `#${relativeUrl}`);
+ history.pushState(currentState, title, `#${relativeUrl}`);
+ };
+}
+
+export function doRecordScroll(scroll) {
+ return function(dispatch, getState) {
+ const state = getState();
+ const historyState = history.state;
+
+ if (!historyState) return;
+
+ historyState.scrollY = scroll;
+ history.replaceState(
+ historyState,
+ document.title,
+ `#${state.app.currentPath}`
+ );
};
}
@@ -131,8 +151,9 @@ export function doDownloadUpgrade() {
return function(dispatch, getState) {
const state = getState();
// Make a new directory within temp directory so the filename is guaranteed to be available
- const dir = fs.mkdtempSync(app.getPath("temp") + require("path").sep);
- const upgradeFilename = selectUpgradeFilename(state);
+ const dir = fs.mkdtempSync(
+ remote.app.getPath("temp") + require("path").sep
+ );
let options = {
onProgress: p => dispatch(doUpdateDownloadProgress(Math.round(p * 100))),
@@ -216,6 +237,18 @@ export function doCheckUpgradeAvailable() {
};
}
+export function doCheckDaemonVersion() {
+ return function(dispatch, getState) {
+ lbry.version().then(({ lbrynet_version }) => {
+ dispatch({
+ type: config.lbrynetDaemonVersion == lbrynet_version
+ ? types.DAEMON_VERSION_MATCH
+ : types.DAEMON_VERSION_MISMATCH,
+ });
+ });
+ };
+}
+
export function doAlertError(errorList) {
return function(dispatch, getState) {
const state = getState();
@@ -232,7 +265,8 @@ export function doAlertError(errorList) {
}
export function doDaemonReady() {
- return function(dispatch) {
+ return function(dispatch, getState) {
+ history.replaceState({}, document.title, `#/discover`);
dispatch(doAuthenticate());
dispatch({
type: types.DAEMON_READY,
@@ -262,3 +296,10 @@ export function doClearCache() {
return Promise.resolve();
};
}
+
+export function doQuitAndLaunchDaemonHelp() {
+ return function(dispatch, getState) {
+ shell.openExternal("https://lbry.io/faq/incompatible-protocol-version");
+ remote.app.quit();
+ };
+}
diff --git a/ui/js/actions/user.js b/ui/js/actions/user.js
index 0ca9bc8ee..799bc8cbc 100644
--- a/ui/js/actions/user.js
+++ b/ui/js/actions/user.js
@@ -159,22 +159,22 @@ export function doUserIdentityVerify(stripeToken) {
}
})
.catch(error => {
- let user = selectUser(getState());
- user.is_identity_verified = true;
- if (user.is_identity_verified) {
- dispatch({
- type: types.USER_IDENTITY_VERIFY_SUCCESS,
- data: { user },
- });
- } else {
- throw new Error(
- "Your identity is still not verified. This should not happen."
- ); //shouldn't happen
- }
- // dispatch({
- // type: types.USER_IDENTITY_VERIFY_FAILURE,
- // data: { error: error.toString() },
- // });
+ // let user = selectUser(getState());
+ // user.is_identity_verified = true;
+ // if (user.is_identity_verified) {
+ // dispatch({
+ // type: types.USER_IDENTITY_VERIFY_SUCCESS,
+ // data: { user },
+ // });
+ // } else {
+ // throw new Error(
+ // "Your identity is still not verified. This should not happen."
+ // ); //shouldn't happen
+ // }
+ dispatch({
+ type: types.USER_IDENTITY_VERIFY_FAILURE,
+ data: { error: error.toString() },
+ });
});
};
}
diff --git a/ui/js/app.js b/ui/js/app.js
index 41701ee18..c5bfdcfbd 100644
--- a/ui/js/app.js
+++ b/ui/js/app.js
@@ -2,7 +2,9 @@ import store from "store.js";
import lbry from "./lbry.js";
const env = ENV;
-const config = require(`./config/${env}`);
+const config = {
+ ...require(`./config/${env}`),
+};
const language = lbry.getClientSetting("language")
? lbry.getClientSetting("language")
: "en";
diff --git a/ui/js/component/app/index.js b/ui/js/component/app/index.js
index 0d4e1c093..ff4940f88 100644
--- a/ui/js/component/app/index.js
+++ b/ui/js/component/app/index.js
@@ -5,6 +5,7 @@ import {
doCheckUpgradeAvailable,
doOpenModal,
doAlertError,
+ doRecordScroll,
} from "actions/app";
import { doUpdateBalance } from "actions/wallet";
import { selectWelcomeModalAcknowledged } from "selectors/app";
@@ -36,6 +37,7 @@ const perform = dispatch => ({
checkUpgradeAvailable: () => dispatch(doCheckUpgradeAvailable()),
openWelcomeModal: () => dispatch(doOpenModal(modals.WELCOME)),
updateBalance: balance => dispatch(doUpdateBalance(balance)),
+ recordScroll: scrollPosition => dispatch(doRecordScroll(scrollPosition)),
});
export default connect(select, perform)(App);
diff --git a/ui/js/component/app/view.jsx b/ui/js/component/app/view.jsx
index 7c6b17eca..c4b857a8b 100644
--- a/ui/js/component/app/view.jsx
+++ b/ui/js/component/app/view.jsx
@@ -26,6 +26,10 @@ class App extends React.PureComponent {
});
this.showWelcome(this.props);
+
+ this.scrollListener = () => this.props.recordScroll(window.scrollY);
+
+ window.addEventListener("scroll", this.scrollListener);
}
componentWillReceiveProps(nextProps) {
@@ -50,6 +54,10 @@ class App extends React.PureComponent {
}
}
+ componentWillUnmount() {
+ window.removeEventListener("scroll", this.scrollListener);
+ }
+
render() {
const { modal } = this.props;
diff --git a/ui/js/component/fileCard/view.jsx b/ui/js/component/fileCard/view.jsx
index 5a35d740d..cb57a4308 100644
--- a/ui/js/component/fileCard/view.jsx
+++ b/ui/js/component/fileCard/view.jsx
@@ -78,10 +78,11 @@ class FileCard extends React.PureComponent {
onClick={() => navigate("/show", { uri })}
className="card__link"
>
+
-
+
{title}
-
+
@@ -92,7 +93,6 @@ class FileCard extends React.PureComponent {
-
{description}
diff --git a/ui/js/component/link/view.jsx b/ui/js/component/link/view.jsx
index 2f9c7478e..a39e9947c 100644
--- a/ui/js/component/link/view.jsx
+++ b/ui/js/component/link/view.jsx
@@ -11,7 +11,6 @@ const Link = props => {
icon,
badge,
button,
- hidden,
disabled,
children,
} = props;
diff --git a/ui/js/component/modal-page.js b/ui/js/component/modal-page.js
deleted file mode 100644
index f63d120f5..000000000
--- a/ui/js/component/modal-page.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from "react";
-import ReactModal from "react-modal";
-
-export class ModalPage extends React.PureComponent {
- render() {
- return (
-
-
- {this.props.children}
-
-
- );
- }
-}
-
-export default ModalPage;
diff --git a/ui/js/component/modalIncompatibleDaemon/index.jsx b/ui/js/component/modalIncompatibleDaemon/index.jsx
new file mode 100644
index 000000000..27ddecd8d
--- /dev/null
+++ b/ui/js/component/modalIncompatibleDaemon/index.jsx
@@ -0,0 +1,13 @@
+import React from "react";
+import { connect } from "react-redux";
+import { doQuit, doSkipWrongDaemonNotice } from "actions/app";
+import { doQuitAndLaunchDaemonHelp } from "actions/app";
+import ModalIncompatibleDaemon from "./view";
+
+const select = state => ({});
+
+const perform = dispatch => ({
+ quitAndLaunchDaemonHelp: () => dispatch(doQuitAndLaunchDaemonHelp()),
+});
+
+export default connect(select, perform)(ModalIncompatibleDaemon);
diff --git a/ui/js/component/modalIncompatibleDaemon/view.jsx b/ui/js/component/modalIncompatibleDaemon/view.jsx
new file mode 100644
index 000000000..851a2ec88
--- /dev/null
+++ b/ui/js/component/modalIncompatibleDaemon/view.jsx
@@ -0,0 +1,24 @@
+import React from "react";
+import { Modal } from "component/modal";
+
+class ModalIncompatibleDaemon extends React.PureComponent {
+ render() {
+ const { quitAndLaunchDaemonHelp } = this.props;
+
+ return (
+
+ {__(
+ "This browser is running with an incompatible version of the LBRY protocol and your install must be repaired."
+ )}
+
+ );
+ }
+}
+
+export default ModalIncompatibleDaemon;
diff --git a/ui/js/component/modalWelcome/index.js b/ui/js/component/modalWelcome/index.js
index b41d17013..00a50c86b 100644
--- a/ui/js/component/modalWelcome/index.js
+++ b/ui/js/component/modalWelcome/index.js
@@ -1,7 +1,7 @@
import React from "react";
import rewards from "rewards";
import { connect } from "react-redux";
-import { doCloseModal, doNavigate } from "actions/app";
+import { doCloseModal, doAuthNavigate } from "actions/app";
import { doSetClientSetting } from "actions/settings";
import { selectUserIsRewardApproved } from "selectors/user";
import {
@@ -30,7 +30,7 @@ const perform = dispatch => () => {
return {
verifyAccount: () => {
closeModal();
- dispatch(doNavigate("/auth"));
+ dispatch(doAuthNavigate("/rewards"));
},
closeModal: closeModal,
};
diff --git a/ui/js/component/publishForm/internal/channelSection.jsx b/ui/js/component/publishForm/internal/channelSection.jsx
index 6c7802625..4e598a9de 100644
--- a/ui/js/component/publishForm/internal/channelSection.jsx
+++ b/ui/js/component/publishForm/internal/channelSection.jsx
@@ -93,6 +93,7 @@ class ChannelSection extends React.PureComponent {
"This LBC remains yours and the deposit can be undone at any time."
);
+ const channel = this.state.addingChannel ? "new" : this.props.channel;
const { fetchingChannels, channels = [] } = this.props;
let channelContent = [];
@@ -102,7 +103,7 @@ class ChannelSection extends React.PureComponent {
type="select"
tabIndex="1"
onChange={this.handleChannelChange.bind(this)}
- value={this.props.channel}
+ value={channel}
>
{__("Anonymous")}
@@ -111,7 +112,7 @@ class ChannelSection extends React.PureComponent {
{name}
)}
- {__("New identity...")}
+ {__("New channel...")}
);
@@ -124,9 +125,10 @@ class ChannelSection extends React.PureComponent {
return (
-
{__("Identity")}
+
{__("Channel Name")}
- {__("Who created this content?")}
+ {__("This is the channel that broadcasts your content.")}
+ {__("Ex. @Marvel, @TheBeatles, @BooksByJoe")}
@@ -137,9 +139,7 @@ class ChannelSection extends React.PureComponent {
{
- this.handleNewChannelNameChange(event);
- }}
+ onChange={this.handleNewChannelNameChange.bind(this)}
value={this.state.newChannelName}
/>
{
- this.handleFeePrefChange(false);
- }}
- defaultChecked={!this.state.isFee}
+ onChange={() => this.handleFeePrefChange(false)}
+ checked={!this.state.isFee}
/>
{
this.handleFeePrefChange(true);
}}
- defaultChecked={this.state.isFee}
+ checked={this.state.isFee}
/>
-
{__("Address")}
+
{__("Content URL")}
- {__("Where should this content permanently reside?")}
+ {__(
+ "This is the exact address where people find your content (ex. lbry://myvideo)."
+ )}
{" "}
.
diff --git a/ui/js/component/splash/index.js b/ui/js/component/splash/index.js
new file mode 100644
index 000000000..1a87f476b
--- /dev/null
+++ b/ui/js/component/splash/index.js
@@ -0,0 +1,19 @@
+import React from "react";
+import { connect } from "react-redux";
+
+import { selectCurrentModal, selectDaemonVersionMatched } from "selectors/app";
+import { doCheckDaemonVersion } from "actions/app";
+import SplashScreen from "./view";
+
+const select = state => {
+ return {
+ modal: selectCurrentModal(state),
+ daemonVersionMatched: selectDaemonVersionMatched(state),
+ };
+};
+
+const perform = dispatch => ({
+ checkDaemonVersion: () => dispatch(doCheckDaemonVersion()),
+});
+
+export default connect(select, perform)(SplashScreen);
diff --git a/ui/js/component/splash.js b/ui/js/component/splash/view.jsx
similarity index 59%
rename from ui/js/component/splash.js
rename to ui/js/component/splash/view.jsx
index eb67340e1..7cccd5bf0 100644
--- a/ui/js/component/splash.js
+++ b/ui/js/component/splash/view.jsx
@@ -1,6 +1,9 @@
import React from "react";
-import lbry from "../lbry.js";
-import LoadScreen from "./load_screen.js";
+import lbry from "../../lbry.js";
+import LoadScreen from "../load_screen.js";
+import ModalIncompatibleDaemon from "../modalIncompatibleDaemon";
+import ModalUpgrade from "component/modalUpgrade";
+import ModalDownloading from "component/modalDownloading";
export class SplashScreen extends React.PureComponent {
static propTypes = {
@@ -14,6 +17,7 @@ export class SplashScreen extends React.PureComponent {
this.state = {
details: __("Starting daemon"),
message: __("Connecting"),
+ isRunning: false,
isLagging: false,
};
}
@@ -35,10 +39,16 @@ export class SplashScreen extends React.PureComponent {
message: __("Testing Network"),
details: __("Waiting for name resolution"),
isLagging: false,
+ isRunning: true,
});
lbry.resolve({ uri: "lbry://one" }).then(() => {
- this.props.onLoadDone();
+ // Only leave the load screen if the daemon version matched;
+ // otherwise we'll notify the user at the end of the load screen.
+
+ if (this.props.daemonVersionMatched) {
+ this.props.onReadyToLaunch();
+ }
});
return;
}
@@ -54,6 +64,7 @@ export class SplashScreen extends React.PureComponent {
componentDidMount() {
lbry
.connect()
+ .then(this.props.checkDaemonVersion)
.then(() => {
this.updateStatus();
})
@@ -69,12 +80,24 @@ export class SplashScreen extends React.PureComponent {
}
render() {
+ const { modal } = this.props;
+
return (
-
+
+
+ {/* Temp hack: don't show any modals on splash screen daemon is running;
+ daemon doesn't let you quit during startup, so the "Quit" buttons
+ in the modals won't work. */}
+ {modal == "incompatibleDaemon" &&
+ this.state.isRunning &&
+ }
+ {modal == "upgrade" && this.state.isRunning && }
+ {modal == "downloading" && this.state.isRunning && }
+
);
}
}
diff --git a/ui/js/component/userVerify/view.jsx b/ui/js/component/userVerify/view.jsx
index 1596b3726..705ee424c 100644
--- a/ui/js/component/userVerify/view.jsx
+++ b/ui/js/component/userVerify/view.jsx
@@ -25,15 +25,13 @@ class UserVerify extends React.PureComponent {
const { errorMessage, isPending, reward } = this.props;
return (
-
-
+ {(!reward || !reward.transaction_id) &&
+
Please link a credit card to confirm your identity and receive{" "}
-
- {reward
- ?
- : your reward }
- {"."}
-
+ {reward
+ ?
+ :
your reward }
+ }
{__("This is to prevent abuse. You will not be charged.")}
{errorMessage &&
{errorMessage}
}
{
if (hash !== "") {
const url = hash.split("#")[1];
- const params = event.state;
+ const { params, scrollY } = event.state || {};
const queryString = toQueryString(params);
- app.store.dispatch(doChangePath(`${url}?${queryString}`));
+ app.store.dispatch(doChangePath(`${url}?${queryString}`, { scrollY }));
} else {
app.store.dispatch(doChangePath("/discover"));
}
@@ -111,7 +111,12 @@ var init = function() {
if (window.sessionStorage.getItem("loaded") == "y") {
onDaemonReady();
} else {
- ReactDOM.render( , canvas);
+ ReactDOM.render(
+
+
+ ,
+ canvas
+ );
}
};
diff --git a/ui/js/page/filePage/index.js b/ui/js/page/filePage/index.js
index f6629214c..ec151ab50 100644
--- a/ui/js/page/filePage/index.js
+++ b/ui/js/page/filePage/index.js
@@ -25,7 +25,7 @@ const makeSelect = () => {
contentType: selectContentType(state, props),
costInfo: selectCostInfo(state, props),
metadata: selectMetadata(state, props),
- showNsfw: !selectShowNsfw(state),
+ obscureNsfw: !selectShowNsfw(state),
fileInfo: selectFileInfo(state, props),
});
diff --git a/ui/js/page/rewards/index.js b/ui/js/page/rewards/index.js
index 52e18250a..ce24ce6e7 100644
--- a/ui/js/page/rewards/index.js
+++ b/ui/js/page/rewards/index.js
@@ -6,11 +6,11 @@ import {
selectRewards,
} from "selectors/rewards";
import {
- selectUserIsRewardEligible,
+ selectUser,
selectUserHasEmail,
selectUserIsVerificationCandidate,
} from "selectors/user";
-import { doAuthNavigate } from "actions/app";
+import { doAuthNavigate, doNavigate } from "actions/app";
import { doRewardList } from "actions/rewards";
import rewards from "rewards";
import RewardsPage from "./view";
@@ -21,15 +21,14 @@ const select = (state, props) => {
return {
fetching: selectFetchingRewards(state),
rewards: selectRewards(state),
- hasEmail: selectUserHasEmail(state),
- isEligible: selectUserIsRewardEligible(state),
- isVerificationCandidate: selectUserIsVerificationCandidate(state),
newUserReward: selectReward(state, { reward_type: rewards.TYPE_NEW_USER }),
+ user: selectUser(state),
};
};
const perform = dispatch => ({
fetchRewards: () => dispatch(doRewardList()),
+ navigate: path => dispatch(doNavigate(path)),
doAuth: () => {
dispatch(doAuthNavigate("/rewards"));
},
diff --git a/ui/js/page/rewards/view.jsx b/ui/js/page/rewards/view.jsx
index 842f90685..e590d5895 100644
--- a/ui/js/page/rewards/view.jsx
+++ b/ui/js/page/rewards/view.jsx
@@ -45,39 +45,11 @@ class RewardsPage extends React.PureComponent {
}
render() {
- const {
- doAuth,
- fetching,
- isEligible,
- isVerificationCandidate,
- hasEmail,
- rewards,
- newUserReward,
- } = this.props;
+ const { doAuth, fetching, navigate, rewards, user } = this.props;
- let content,
- isCard = false;
+ let content, cardHeader;
- if (!hasEmail || isVerificationCandidate) {
- content = (
-
-
-
{__("Only verified accounts are eligible to earn rewards.")}
-
-
-
-
-
- );
- isCard = true;
- } else if (!isEligible) {
- isCard = true;
- content = (
-
-
{__("You are not eligible to claim rewards.")}
-
- );
- } else if (fetching) {
+ if (fetching) {
content = (
@@ -99,10 +71,54 @@ class RewardsPage extends React.PureComponent {
);
}
+ if (
+ user &&
+ (!user.has_email ||
+ !user.has_verified_email ||
+ !user.is_identity_verified)
+ ) {
+ cardHeader = (
+
+
+
{__("Only verified accounts are eligible to earn rewards.")}
+
+
+
+
+
+ );
+ } else if (user && !user.is_reward_approved) {
+ cardHeader = (
+
+
+ {__(
+ "This account must undergo review before you can participate in the rewards program."
+ )}
+ {" "}
+ {__("This can take anywhere from several minutes to several days.")}
+
+
+ {__("You will receive an email when this process is complete.")}
+
+
+ {__("Please enjoy free content in the meantime!")}
+
+
+ navigate("/discover")}
+ button="primary"
+ label="Return Home"
+ />
+
+
+ );
+ }
+
return (
- {isCard ? : content}
+ {cardHeader && }
+ {content}
);
}
diff --git a/ui/js/reducers/app.js b/ui/js/reducers/app.js
index bc24ac85e..6ee007b86 100644
--- a/ui/js/reducers/app.js
+++ b/ui/js/reducers/app.js
@@ -1,4 +1,5 @@
import * as types from "constants/action_types";
+import * as modalTypes from "constants/modal_types";
import lbry from "lbry";
const currentPath = () => {
@@ -18,6 +19,7 @@ const defaultState = {
pathAfterAuth: "/discover",
platform: process.platform,
upgradeSkipped: sessionStorage.getItem("upgradeSkipped"),
+ daemonVersionMatched: null,
daemonReady: false,
hasSignature: false,
badgeNumber: 0,
@@ -29,6 +31,19 @@ reducers[types.DAEMON_READY] = function(state, action) {
});
};
+reducers[types.DAEMON_VERSION_MATCH] = function(state, action) {
+ return Object.assign({}, state, {
+ daemonVersionMatched: true,
+ });
+};
+
+reducers[types.DAEMON_VERSION_MISMATCH] = function(state, action) {
+ return Object.assign({}, state, {
+ daemonVersionMatched: false,
+ modal: modalTypes.INCOMPATIBLE_DAEMON,
+ });
+};
+
reducers[types.CHANGE_PATH] = function(state, action) {
return Object.assign({}, state, {
currentPath: action.data.path,
diff --git a/ui/js/selectors/app.js b/ui/js/selectors/app.js
index b70fbbdce..3951a8216 100644
--- a/ui/js/selectors/app.js
+++ b/ui/js/selectors/app.js
@@ -177,6 +177,11 @@ export const selectDaemonReady = createSelector(
state => state.daemonReady
);
+export const selectDaemonVersionMatched = createSelector(
+ _selectState,
+ state => state.daemonVersionMatched
+);
+
export const selectSnackBar = createSelector(
_selectState,
state => state.snackBar || {}
diff --git a/ui/js/selectors/user.js b/ui/js/selectors/user.js
index a4f266ff0..6ade78efe 100644
--- a/ui/js/selectors/user.js
+++ b/ui/js/selectors/user.js
@@ -30,11 +30,6 @@ export const selectUserHasEmail = createSelector(
(user, email) => (user && user.has_email) || !!email
);
-export const selectUserIsRewardEligible = createSelector(
- selectUser,
- user => user && user.is_reward_eligible
-);
-
export const selectUserIsRewardApproved = createSelector(
selectUser,
user => user && user.is_reward_approved
diff --git a/ui/js/utils.js b/ui/js/utils.js
index b41a2e0d4..18e4ca21e 100644
--- a/ui/js/utils.js
+++ b/ui/js/utils.js
@@ -1,3 +1,5 @@
+const { remote } = require("electron");
+
/**
* Thin wrapper around localStorage.getItem(). Parses JSON and returns undefined if the value
* is not set yet.
diff --git a/ui/scss/all.scss b/ui/scss/all.scss
index 6b421196a..61612d7df 100644
--- a/ui/scss/all.scss
+++ b/ui/scss/all.scss
@@ -15,7 +15,6 @@
@import "component/_channel-indicator.scss";
@import "component/_notice.scss";
@import "component/_modal.scss";
-@import "component/_modal-page.scss";
@import "component/_snack-bar.scss";
@import "component/_video.scss";
@import "page/_developer.scss";
diff --git a/ui/scss/component/_card.scss b/ui/scss/component/_card.scss
index e5126d6e7..d8416d226 100644
--- a/ui/scss/component/_card.scss
+++ b/ui/scss/component/_card.scss
@@ -19,18 +19,29 @@ $padding-card-horizontal: $spacing-vertical * 2/3;
.card--obscured .card__inner {
filter: blur($blur-intensity-nsfw);
}
-.card__title-primary {
+.card__title-primary,
+.card__title-identity,
+.card__actions,
+.card__content,
+.card__subtext {
padding: 0 $padding-card-horizontal;
+}
+.card--small {
+ .card__title-primary,
+ .card__title-identity,
+ .card__actions,
+ .card__content,
+ .card__subtext {
+ padding: 0 $padding-card-horizontal / 2;
+ }
+}
+.card__title-primary {
margin-top: $spacing-vertical * 2/3;
}
.card__title-identity {
- padding: 0 $padding-card-horizontal;
margin-top: $spacing-vertical * 1/3;
margin-bottom: $spacing-vertical * 1/3;
}
-.card__actions {
- padding: 0 $padding-card-horizontal;
-}
.card__actions {
margin-top: $spacing-vertical * 2/3;
}
@@ -45,21 +56,18 @@ $padding-card-horizontal: $spacing-vertical * 2/3;
.card__content {
margin-top: $spacing-vertical * 2/3;
margin-bottom: $spacing-vertical * 2/3;
- padding: 0 $padding-card-horizontal;
}
.card__subtext {
- color: #444;
- margin-top: 12px;
- font-size: 0.9em;
- margin-top: $spacing-vertical * 2/3;
- margin-bottom: $spacing-vertical * 2/3;
- padding: 0 $padding-card-horizontal;
+ color: $color-meta-light;
+ font-size: 0.82em;
+ margin-top: $spacing-vertical * 1/3;
+ margin-bottom: $spacing-vertical * 1/3;
}
.card__subtext--allow-newlines {
white-space: pre-wrap;
}
.card__subtext--two-lines {
- height: $font-size * 0.9 * $font-line-height * 2;
+ height: $font-size * 0.82 * $font-line-height * 2; /*this is so one line text still has the proper height*/
}
.card-overlay {
position: absolute;
@@ -144,7 +152,7 @@ $card-link-scaling: 1.1;
top: 36%
}
-$width-card-small: $spacing-vertical * 12;
+$width-card-small: $spacing-vertical * 10;
$height-card-small: $spacing-vertical * 15;
.card--small {
diff --git a/ui/scss/component/_modal-page.scss b/ui/scss/component/_modal-page.scss
deleted file mode 100644
index ada366f61..000000000
--- a/ui/scss/component/_modal-page.scss
+++ /dev/null
@@ -1,54 +0,0 @@
-@import "../global";
-
-.modal-page {
- position: fixed;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
-
- border: 1px solid rgb(204, 204, 204);
- background: rgb(255, 255, 255);
- overflow: auto;
-}
-
-.modal-page--full {
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- .modal-page__content {
- max-width: 500px;
- }
-}
-
-/*
-.modal-page {
- position: fixed;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
-
- border: 1px solid rgb(204, 204, 204);
- background: rgb(255, 255, 255);
- overflow: auto;
- border-radius: 4px;
- outline: none;
- padding: 36px;
-
- top: 25px;
- left: 25px;
- right: 25px;
- bottom: 25px;
-}
-*/
-
-.modal-page__content {
- h1, h2 {
- margin-bottom: $spacing-vertical / 2;
- }
- h3, h4 {
- margin-bottom: $spacing-vertical / 4;
- }
-}
\ No newline at end of file