void,
diff --git a/ui/page/publish/view.jsx b/ui/page/publish/view.jsx
index d802a84a1..6a850215d 100644
--- a/ui/page/publish/view.jsx
+++ b/ui/page/publish/view.jsx
@@ -6,7 +6,6 @@ import YrblWalletEmpty from 'component/yrblWalletEmpty';
type Props = {
balance: number,
- totalRewardValue: number,
};
function PublishPage(props: Props) {
diff --git a/ui/page/repost/index.js b/ui/page/repost/index.js
new file mode 100644
index 000000000..30aae741e
--- /dev/null
+++ b/ui/page/repost/index.js
@@ -0,0 +1,15 @@
+import { connect } from 'react-redux';
+
+import { doResolveUri, selectBalance } from 'lbry-redux';
+
+import RepostPage from './view';
+
+const select = (state, props) => ({
+ balance: selectBalance(state),
+});
+
+const perform = dispatch => ({
+ resolveUri: uri => dispatch(doResolveUri(uri)),
+});
+
+export default connect(select, perform)(RepostPage);
diff --git a/ui/page/repost/view.jsx b/ui/page/repost/view.jsx
new file mode 100644
index 000000000..b1e2e1023
--- /dev/null
+++ b/ui/page/repost/view.jsx
@@ -0,0 +1,77 @@
+// @flow
+import React from 'react';
+import Page from 'component/page';
+import { useHistory } from 'react-router';
+import RepostCreate from 'component/repostCreate';
+import YrblWalletEmpty from 'component/yrblWalletEmpty';
+import useThrottle from 'effects/use-throttle';
+import classnames from 'classnames';
+
+type Props = {
+ balance: number,
+ resolveUri: string => void,
+};
+function RepostPage(props: Props) {
+ const { balance, resolveUri } = props;
+
+ const REPOST_FROM = 'from';
+ const REPOST_TO = 'to';
+ const REDIRECT = 'redirect';
+ const {
+ location: { search },
+ } = useHistory();
+
+ const urlParams = new URLSearchParams(search);
+ const repostFrom = urlParams.get(REPOST_FROM);
+ const redirectUri = urlParams.get(REDIRECT);
+ const repostTo = urlParams.get(REPOST_TO);
+ const [contentUri, setContentUri] = React.useState('');
+ const [repostUri, setRepostUri] = React.useState('');
+ const throttledContentValue = useThrottle(contentUri, 500);
+ const throttledRepostValue = useThrottle(repostUri, 500);
+
+ React.useEffect(() => {
+ if (throttledContentValue) {
+ resolveUri(throttledContentValue);
+ }
+ }, [throttledContentValue, resolveUri]);
+
+ React.useEffect(() => {
+ if (throttledRepostValue) {
+ resolveUri(throttledRepostValue);
+ }
+ }, [throttledRepostValue, resolveUri]);
+
+ React.useEffect(() => {
+ if (repostTo) {
+ resolveUri(repostTo);
+ }
+ }, [repostTo, resolveUri]);
+
+ const decodedFrom = repostFrom && decodeURIComponent(repostFrom);
+ return (
+
+ {balance === 0 && }
+
+
+
+
+ );
+}
+
+export default RepostPage;
diff --git a/ui/page/search/view.jsx b/ui/page/search/view.jsx
index f8b4124a7..8a38e03fa 100644
--- a/ui/page/search/view.jsx
+++ b/ui/page/search/view.jsx
@@ -11,6 +11,7 @@ import Ads from 'web/component/ads';
import SearchTopClaim from 'component/searchTopClaim';
import { formatLbryUrlForWeb } from 'util/url';
import { useHistory } from 'react-router';
+import ClaimPreview from 'component/claimPreview';
type AdditionalOptions = {
isBackgroundSearch: boolean,
@@ -97,7 +98,6 @@ export default function SearchPage(props: Props) {
{urlQuery && (
<>
{isValid &&
}
-
}
/>
+ {isSearching && new Array(5).fill(1).map((x, i) =>
)}
{__('These search results are provided by LBRY, Inc.')}
>
diff --git a/ui/page/top/index.js b/ui/page/top/index.js
index 0960e95d8..16130d033 100644
--- a/ui/page/top/index.js
+++ b/ui/page/top/index.js
@@ -1,5 +1,8 @@
import { connect } from 'react-redux';
import TopPage from './view';
+import { doClearPublish, doPrepareEdit, doResolveUris } from 'lbry-redux';
+import { push } from 'connected-react-router';
+import * as PAGES from 'constants/pages';
const select = (state, props) => {
const { search } = props.location;
@@ -11,4 +14,13 @@ const select = (state, props) => {
};
};
-export default connect(select)(TopPage);
+const perform = dispatch => ({
+ beginPublish: name => {
+ dispatch(doClearPublish());
+ dispatch(doPrepareEdit({ name }));
+ dispatch(push(`/$/${PAGES.UPLOAD}`));
+ },
+ doResolveUris: uris => dispatch(doResolveUris(uris)),
+});
+
+export default connect(select, perform)(TopPage);
diff --git a/ui/page/top/view.jsx b/ui/page/top/view.jsx
index 6149ac029..e004efa7d 100644
--- a/ui/page/top/view.jsx
+++ b/ui/page/top/view.jsx
@@ -7,22 +7,42 @@ import ClaimEffectiveAmount from 'component/claimEffectiveAmount';
import SearchTopClaim from 'component/searchTopClaim';
import { ORDER_BY_TOP, FRESH_ALL } from 'constants/claim_search';
import Button from 'component/button';
+import I18nMessage from 'component/i18nMessage';
+import * as PAGES from 'constants/pages';
type Props = {
name: string,
+ beginPublish: string => void,
};
function TopPage(props: Props) {
- const { name } = props;
+ const { name, beginPublish } = props;
const [channelActive, setChannelActive] = React.useState(false);
-
+ // if the query was actually '@name', still offer repost for 'name'
+ const queryName = name[0] === '@' ? name.slice(1) : name;
return (
+ ),
+ publish: