Progress towards working publish
This commit is contained in:
parent
df954882bc
commit
8325828f6e
11 changed files with 1399 additions and 159 deletions
|
@ -15,6 +15,7 @@ import { selectBadgeNumber } from "selectors/app";
|
||||||
import { selectTotalDownloadProgress } from "selectors/file_info";
|
import { selectTotalDownloadProgress } from "selectors/file_info";
|
||||||
import setBadge from "util/setBadge";
|
import setBadge from "util/setBadge";
|
||||||
import setProgressBar from "util/setProgressBar";
|
import setProgressBar from "util/setProgressBar";
|
||||||
|
import { doFileList } from "actions/file_info";
|
||||||
import batchActions from "util/batchActions";
|
import batchActions from "util/batchActions";
|
||||||
|
|
||||||
const { ipcRenderer } = require("electron");
|
const { ipcRenderer } = require("electron");
|
||||||
|
@ -356,3 +357,92 @@ export function doFetchChannelListMine() {
|
||||||
lbry.channel_list_mine().then(callback);
|
lbry.channel_list_mine().then(callback);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function doCreateChannel(name, amount) {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
dispatch({
|
||||||
|
type: types.CREATE_CHANNEL_STARTED,
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
lbry
|
||||||
|
.channel_new({
|
||||||
|
channel_name: name,
|
||||||
|
amount: parseFloat(amount),
|
||||||
|
})
|
||||||
|
.then(
|
||||||
|
channelClaim => {
|
||||||
|
channelClaim.name = name;
|
||||||
|
dispatch({
|
||||||
|
type: types.CREATE_CHANNEL_COMPLETED,
|
||||||
|
data: { channelClaim },
|
||||||
|
});
|
||||||
|
resolve(channelClaim);
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
resolve(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doPublish(params) {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
let uri;
|
||||||
|
const { name, channel_name } = params;
|
||||||
|
if (channel_name) {
|
||||||
|
uri = lbryuri.build({ name: channel_name, path: name }, false);
|
||||||
|
} else {
|
||||||
|
uri = lbryuri.build({ name: name }, false);
|
||||||
|
}
|
||||||
|
const pendingPublish = {
|
||||||
|
name,
|
||||||
|
channel_name,
|
||||||
|
claim_id: "pending_claim_" + uri,
|
||||||
|
txid: "pending_" + uri,
|
||||||
|
nout: 0,
|
||||||
|
outpoint: "pending_" + uri + ":0",
|
||||||
|
time: Date.now(),
|
||||||
|
};
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.PUBLISH_STARTED,
|
||||||
|
data: {
|
||||||
|
params,
|
||||||
|
pendingPublish,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const success = claim => {
|
||||||
|
claim.name = params.name;
|
||||||
|
claim.channel_name = params.channel_name;
|
||||||
|
dispatch({
|
||||||
|
type: types.PUBLISH_COMPLETED,
|
||||||
|
data: {
|
||||||
|
claim,
|
||||||
|
uri,
|
||||||
|
pendingPublish,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
dispatch(doFileList());
|
||||||
|
resolve(claim);
|
||||||
|
};
|
||||||
|
const failure = error => {
|
||||||
|
dispatch({
|
||||||
|
type: types.PUBLISH_FAILED,
|
||||||
|
data: {
|
||||||
|
error,
|
||||||
|
params,
|
||||||
|
uri,
|
||||||
|
pendingPublish,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
reject(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
lbry.publish(params).then(success, failure);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -42,6 +42,40 @@ export class TruncatedText extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class TruncatedMarkdown extends React.PureComponent {
|
||||||
|
static propTypes = {
|
||||||
|
lines: React.PropTypes.number,
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
lines: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
transformMarkdown(text) {
|
||||||
|
// render markdown to html string then trim html tag
|
||||||
|
let htmlString = ReactDOMServer.renderToStaticMarkup(
|
||||||
|
<ReactMarkdown source={this.props.children} />
|
||||||
|
);
|
||||||
|
var txt = document.createElement("textarea");
|
||||||
|
txt.innerHTML = htmlString;
|
||||||
|
return txt.value.replace(/<(?:.|\n)*?>/gm, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let content = this.props.children && typeof this.props.children === "string"
|
||||||
|
? this.transformMarkdown(this.props.children)
|
||||||
|
: this.props.children;
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className="truncated-text"
|
||||||
|
style={{ WebkitLineClamp: this.props.lines }}
|
||||||
|
>
|
||||||
|
{content}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class BusyMessage extends React.PureComponent {
|
export class BusyMessage extends React.PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
message: React.PropTypes.string,
|
message: React.PropTypes.string,
|
||||||
|
|
|
@ -68,6 +68,11 @@ export const FETCH_CHANNEL_LIST_MINE_STARTED =
|
||||||
"FETCH_CHANNEL_LIST_MINE_STARTED";
|
"FETCH_CHANNEL_LIST_MINE_STARTED";
|
||||||
export const FETCH_CHANNEL_LIST_MINE_COMPLETED =
|
export const FETCH_CHANNEL_LIST_MINE_COMPLETED =
|
||||||
"FETCH_CHANNEL_LIST_MINE_COMPLETED";
|
"FETCH_CHANNEL_LIST_MINE_COMPLETED";
|
||||||
|
export const CREATE_CHANNEL_STARTED = "CREATE_CHANNEL_STARTED";
|
||||||
|
export const CREATE_CHANNEL_COMPLETED = "CREATE_CHANNEL_COMPLETED";
|
||||||
|
export const PUBLISH_STARTED = "PUBLISH_STARTED";
|
||||||
|
export const PUBLISH_COMPLETED = "PUBLISH_COMPLETED";
|
||||||
|
export const PUBLISH_FAILED = "PUBLISH_FAILED";
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
export const SEARCH_STARTED = "SEARCH_STARTED";
|
export const SEARCH_STARTED = "SEARCH_STARTED";
|
||||||
|
|
|
@ -203,6 +203,8 @@ lbryuri.build = function(uriObj, includeProto = true, allowExtraProps = false) {
|
||||||
/* Takes a parseable LBRY URI and converts it to standard, canonical format (currently this just
|
/* Takes a parseable LBRY URI and converts it to standard, canonical format (currently this just
|
||||||
* consists of adding the lbry:// prefix if needed) */
|
* consists of adding the lbry:// prefix if needed) */
|
||||||
lbryuri.normalize = function(uri) {
|
lbryuri.normalize = function(uri) {
|
||||||
|
if (uri.match(/pending_claim/)) return uri;
|
||||||
|
|
||||||
const { name, path, bidPosition, claimSequence, claimId } = lbryuri.parse(
|
const { name, path, bidPosition, claimSequence, claimId } = lbryuri.parse(
|
||||||
uri
|
uri
|
||||||
);
|
);
|
||||||
|
|
|
@ -13,6 +13,8 @@ import {
|
||||||
doFetchClaimListMine,
|
doFetchClaimListMine,
|
||||||
doFetchChannelListMine,
|
doFetchChannelListMine,
|
||||||
doResolveUri,
|
doResolveUri,
|
||||||
|
doCreateChannel,
|
||||||
|
doPublish,
|
||||||
} from "actions/content";
|
} from "actions/content";
|
||||||
import rewards from "rewards";
|
import rewards from "rewards";
|
||||||
import PublishPage from "./view";
|
import PublishPage from "./view";
|
||||||
|
@ -33,6 +35,8 @@ const perform = dispatch => ({
|
||||||
dispatch(doClaimRewardType(rewards.TYPE_FIRST_CHANNEL)),
|
dispatch(doClaimRewardType(rewards.TYPE_FIRST_CHANNEL)),
|
||||||
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
|
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
|
||||||
resolveUri: uri => dispatch(doResolveUri(uri)),
|
resolveUri: uri => dispatch(doResolveUri(uri)),
|
||||||
|
createChannel: (name, amount) => dispatch(doCreateChannel(name, amount)),
|
||||||
|
publish: params => dispatch(doPublish(params)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(PublishPage);
|
export default connect(select, perform)(PublishPage);
|
||||||
|
|
|
@ -125,16 +125,11 @@ class PublishPage extends React.PureComponent {
|
||||||
publishArgs.file_path = this.refs.file.getValue();
|
publishArgs.file_path = this.refs.file.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
lbry.publishDeprecated(
|
const success = claim => {};
|
||||||
publishArgs,
|
const failure = error => this.handlePublishError(error);
|
||||||
message => {
|
|
||||||
this.handlePublishStarted();
|
this.handlePublishStarted();
|
||||||
},
|
this.props.publish(publishArgs).then(success, failure);
|
||||||
null,
|
|
||||||
error => {
|
|
||||||
this.handlePublishError(error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.state.isFee) {
|
if (this.state.isFee) {
|
||||||
|
@ -216,6 +211,10 @@ class PublishPage extends React.PureComponent {
|
||||||
handleNameChange(event) {
|
handleNameChange(event) {
|
||||||
var rawName = event.target.value;
|
var rawName = event.target.value;
|
||||||
|
|
||||||
|
this.nameChanged(rawName);
|
||||||
|
}
|
||||||
|
|
||||||
|
nameChanged(rawName) {
|
||||||
if (!rawName) {
|
if (!rawName) {
|
||||||
this.setState({
|
this.setState({
|
||||||
rawName: "",
|
rawName: "",
|
||||||
|
@ -233,15 +232,26 @@ class PublishPage extends React.PureComponent {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let channel = "";
|
||||||
|
if (this.state.channel !== "anonymous") channel = this.state.channel;
|
||||||
|
|
||||||
const name = rawName.toLowerCase();
|
const name = rawName.toLowerCase();
|
||||||
const uri = lbryuri.normalize(name);
|
const uri = lbryuri.build({ contentName: name, channelName: channel });
|
||||||
this.setState({
|
this.setState({
|
||||||
rawName: rawName,
|
rawName: rawName,
|
||||||
name: name,
|
name: name,
|
||||||
uri,
|
uri,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.props.resolveUri(uri);
|
if (this.resolveUriTimeout) {
|
||||||
|
clearTimeout(this.resolveUriTimeout);
|
||||||
|
this.resolveUriTimeout = undefined;
|
||||||
|
}
|
||||||
|
const resolve = () => this.props.resolveUri(uri);
|
||||||
|
|
||||||
|
this.resolveUriTimeout = setTimeout(resolve.bind(this), 500, {
|
||||||
|
once: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleBidChange(event) {
|
handleBidChange(event) {
|
||||||
|
@ -302,40 +312,12 @@ class PublishPage extends React.PureComponent {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChannelChange(event) {
|
handleChannelChange(channelName) {
|
||||||
const channel = event.target.value;
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
channel: channel,
|
channel: channelName,
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleNewChannelNameChange(event) {
|
|
||||||
const newChannelName = event.target.value.startsWith("@")
|
|
||||||
? event.target.value
|
|
||||||
: "@" + event.target.value;
|
|
||||||
|
|
||||||
if (
|
|
||||||
newChannelName.length > 1 &&
|
|
||||||
!lbryuri.isValidName(newChannelName.substr(1), false)
|
|
||||||
) {
|
|
||||||
this.refs.newChannelName.showError(
|
|
||||||
__("LBRY channel names must contain only letters, numbers and dashes.")
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
this.refs.newChannelName.clearError();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
newChannelName: newChannelName,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleNewChannelBidChange(event) {
|
|
||||||
this.setState({
|
|
||||||
newChannelBid: event.target.value,
|
|
||||||
});
|
});
|
||||||
|
const nameChanged = () => this.nameChanged(this.state.rawName);
|
||||||
|
setTimeout(nameChanged.bind(this), 500, { once: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTOSChange(event) {
|
handleTOSChange(event) {
|
||||||
|
@ -413,19 +395,26 @@ class PublishPage extends React.PureComponent {
|
||||||
getNameBidHelpText() {
|
getNameBidHelpText() {
|
||||||
if (
|
if (
|
||||||
this.state.uri &&
|
this.state.uri &&
|
||||||
this.props.resolvingUris.indexOf(this.state.uri) !== -1
|
this.props.resolvingUris.indexOf(this.state.uri) !== -1 &&
|
||||||
|
this.claim() === undefined
|
||||||
) {
|
) {
|
||||||
return <BusyMessage />;
|
return <BusyMessage />;
|
||||||
} else if (!this.state.name) {
|
} else if (!this.state.name) {
|
||||||
return __("Select a URL for this publish.");
|
return __("Select a URL for this publish.");
|
||||||
} else if (!this.claim()) {
|
} else if (!this.claim()) {
|
||||||
return __("This URL is unused.");
|
return __("This URL is unused.");
|
||||||
} else if (this.myClaimExists()) {
|
} else if (this.myClaimExists() && !this.state.prefillDone) {
|
||||||
return __(
|
return (
|
||||||
"You have already used this URL. Publishing to it again will update your previous publish."
|
<Notice>
|
||||||
|
{__("You already have a claim with this name.")}{" "}
|
||||||
|
<Link
|
||||||
|
label={__("Use data from my existing claim")}
|
||||||
|
onClick={() => this.handlePrefillClicked()}
|
||||||
|
/>
|
||||||
|
</Notice>
|
||||||
);
|
);
|
||||||
} else if (this.state.topClaimValue) {
|
} else if (this.claim()) {
|
||||||
if (this.state.topClaimValue === 1) {
|
if (this.topClaimValue() === 1) {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
{__(
|
{__(
|
||||||
|
@ -439,7 +428,7 @@ class PublishPage extends React.PureComponent {
|
||||||
<span>
|
<span>
|
||||||
{__(
|
{__(
|
||||||
'A deposit of at least "%s" credits is required to win "%s". However, you can still get a permanent URL for any amount.',
|
'A deposit of at least "%s" credits is required to win "%s". However, you can still get a permanent URL for any amount.',
|
||||||
this.state.topClaimValue,
|
this.topClaimValue(),
|
||||||
this.state.name
|
this.state.name
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
|
@ -709,77 +698,11 @@ class PublishPage extends React.PureComponent {
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="card">
|
<ChannelSection
|
||||||
<div className="card__title-primary">
|
{...this.props}
|
||||||
<h4>{__("Identity")}</h4>
|
handleChannelChange={this.handleChannelChange.bind(this)}
|
||||||
<div className="card__subtitle">
|
channel={this.state.channel}
|
||||||
{__("Who created this content?")}
|
/>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="card__content">
|
|
||||||
{this.props.fetchingChannels
|
|
||||||
? <BusyMessage message="Fetching identities" />
|
|
||||||
: <FormRow
|
|
||||||
type="select"
|
|
||||||
tabIndex="1"
|
|
||||||
onChange={event => {
|
|
||||||
this.handleChannelChange(event);
|
|
||||||
}}
|
|
||||||
value={this.state.channel}
|
|
||||||
>
|
|
||||||
<option key="anonymous" value="anonymous">
|
|
||||||
{__("Anonymous")}
|
|
||||||
</option>
|
|
||||||
{this.props.channels.map(({ name }) =>
|
|
||||||
<option key={name} value={name}>{name}</option>
|
|
||||||
)}
|
|
||||||
<option key="new" value="new">
|
|
||||||
{__("New identity...")}
|
|
||||||
</option>
|
|
||||||
</FormRow>}
|
|
||||||
</div>
|
|
||||||
{this.state.channel == "new"
|
|
||||||
? <div className="card__content">
|
|
||||||
<FormRow
|
|
||||||
label={__("Name")}
|
|
||||||
type="text"
|
|
||||||
onChange={event => {
|
|
||||||
this.handleNewChannelNameChange(event);
|
|
||||||
}}
|
|
||||||
ref={newChannelName => {
|
|
||||||
this.refs.newChannelName = newChannelName;
|
|
||||||
}}
|
|
||||||
value={this.state.newChannelName}
|
|
||||||
/>
|
|
||||||
<FormRow
|
|
||||||
label={__("Deposit")}
|
|
||||||
postfix={__("LBC")}
|
|
||||||
step="0.01"
|
|
||||||
min="0"
|
|
||||||
type="number"
|
|
||||||
helper={lbcInputHelp}
|
|
||||||
onChange={event => {
|
|
||||||
this.handleNewChannelBidChange(event);
|
|
||||||
}}
|
|
||||||
value={this.state.newChannelBid}
|
|
||||||
/>
|
|
||||||
<div className="form-row-submit">
|
|
||||||
<Link
|
|
||||||
button="primary"
|
|
||||||
label={
|
|
||||||
!this.state.creatingChannel
|
|
||||||
? __("Create identity")
|
|
||||||
: __("Creating identity...")
|
|
||||||
}
|
|
||||||
onClick={event => {
|
|
||||||
this.handleCreateChannelClick(event);
|
|
||||||
}}
|
|
||||||
disabled={this.state.creatingChannel}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
: null}
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section className="card">
|
<section className="card">
|
||||||
<div className="card__title-primary">
|
<div className="card__title-primary">
|
||||||
|
@ -795,7 +718,9 @@ class PublishPage extends React.PureComponent {
|
||||||
</div>
|
</div>
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
<FormRow
|
<FormRow
|
||||||
prefix="lbry://"
|
prefix={`lbry://${this.state.channel === "anonymous"
|
||||||
|
? ""
|
||||||
|
: `${this.state.channel}/`}`}
|
||||||
type="text"
|
type="text"
|
||||||
ref="name"
|
ref="name"
|
||||||
placeholder="myname"
|
placeholder="myname"
|
||||||
|
@ -907,4 +832,177 @@ class PublishPage extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ChannelSection extends React.PureComponent {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
newChannelName: "@",
|
||||||
|
newChannelBid: 10,
|
||||||
|
addingChannel: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChannelChange(event) {
|
||||||
|
const channel = event.target.value;
|
||||||
|
if (channel === "new") this.setState({ addingChannel: true });
|
||||||
|
else {
|
||||||
|
this.setState({ addingChannel: false });
|
||||||
|
this.props.handleChannelChange(event.target.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNewChannelNameChange(event) {
|
||||||
|
const newChannelName = event.target.value.startsWith("@")
|
||||||
|
? event.target.value
|
||||||
|
: "@" + event.target.value;
|
||||||
|
|
||||||
|
if (
|
||||||
|
newChannelName.length > 1 &&
|
||||||
|
!lbryuri.isValidName(newChannelName.substr(1), false)
|
||||||
|
) {
|
||||||
|
this.refs.newChannelName.showError(
|
||||||
|
__("LBRY channel names must contain only letters, numbers and dashes.")
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.refs.newChannelName.clearError();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
newChannelName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNewChannelBidChange(event) {
|
||||||
|
this.setState({
|
||||||
|
newChannelBid: event.target.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCreateChannelClick(event) {
|
||||||
|
if (this.state.newChannelName.length < 5) {
|
||||||
|
this.refs.newChannelName.showError(
|
||||||
|
__("LBRY channel names must be at least 4 characters in length.")
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
creatingChannel: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const newChannelName = this.state.newChannelName;
|
||||||
|
const amount = parseFloat(this.state.newChannelBid);
|
||||||
|
this.setState({
|
||||||
|
creatingChannel: true,
|
||||||
|
});
|
||||||
|
const success = (() => {
|
||||||
|
this.setState({
|
||||||
|
creatingChannel: false,
|
||||||
|
addingChannel: false,
|
||||||
|
channel: newChannelName,
|
||||||
|
});
|
||||||
|
this.props.handleChannelChange(newChannelName);
|
||||||
|
}).bind(this);
|
||||||
|
const failure = (err => {
|
||||||
|
this.setState({
|
||||||
|
creatingChannel: false,
|
||||||
|
});
|
||||||
|
this.refs.newChannelName.showError(
|
||||||
|
__("Unable to create channel due to an internal error.")
|
||||||
|
);
|
||||||
|
}).bind(this);
|
||||||
|
this.props.createChannel(newChannelName, amount).then(success, failure);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const lbcInputHelp = __(
|
||||||
|
"This LBC remains yours and the deposit can be undone at any time."
|
||||||
|
);
|
||||||
|
|
||||||
|
const { fetchingChannels, channels } = this.props;
|
||||||
|
|
||||||
|
let channelContent = [];
|
||||||
|
if (channels.length > 0) {
|
||||||
|
channelContent.push(
|
||||||
|
<FormRow
|
||||||
|
key="channel"
|
||||||
|
type="select"
|
||||||
|
tabIndex="1"
|
||||||
|
onChange={this.handleChannelChange.bind(this)}
|
||||||
|
value={this.props.channel}
|
||||||
|
>
|
||||||
|
<option key="anonymous" value="anonymous">
|
||||||
|
{__("Anonymous")}
|
||||||
|
</option>
|
||||||
|
{this.props.channels.map(({ name }) =>
|
||||||
|
<option key={name} value={name}>{name}</option>
|
||||||
|
)}
|
||||||
|
<option key="new" value="new">
|
||||||
|
{__("New identity...")}
|
||||||
|
</option>
|
||||||
|
</FormRow>
|
||||||
|
);
|
||||||
|
if (fetchingChannels) {
|
||||||
|
channelContent.push(
|
||||||
|
<BusyMessage message="Updating channels" key="loading" />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (fetchingChannels) {
|
||||||
|
channelContent.push(
|
||||||
|
<BusyMessage message="Loading channels" key="loading" />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="card">
|
||||||
|
<div className="card__title-primary">
|
||||||
|
<h4>{__("Identity")}</h4>
|
||||||
|
<div className="card__subtitle">
|
||||||
|
{__("Who created this content?")}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="card__content">
|
||||||
|
{channelContent}
|
||||||
|
</div>
|
||||||
|
{this.state.addingChannel &&
|
||||||
|
<div className="card__content">
|
||||||
|
<FormRow
|
||||||
|
label={__("Name")}
|
||||||
|
type="text"
|
||||||
|
onChange={event => {
|
||||||
|
this.handleNewChannelNameChange(event);
|
||||||
|
}}
|
||||||
|
value={this.state.newChannelName}
|
||||||
|
/>
|
||||||
|
<FormRow
|
||||||
|
label={__("Deposit")}
|
||||||
|
postfix="LBC"
|
||||||
|
step="0.1"
|
||||||
|
min="0"
|
||||||
|
type="number"
|
||||||
|
helper={lbcInputHelp}
|
||||||
|
ref="newChannelName"
|
||||||
|
onChange={this.handleNewChannelBidChange.bind(this)}
|
||||||
|
value={this.state.newChannelBid}
|
||||||
|
/>
|
||||||
|
<div className="form-row-submit">
|
||||||
|
<Link
|
||||||
|
button="primary"
|
||||||
|
label={
|
||||||
|
!this.state.creatingChannel
|
||||||
|
? __("Create identity")
|
||||||
|
: __("Creating identity...")
|
||||||
|
}
|
||||||
|
onClick={this.handleCreateChannelClick.bind(this)}
|
||||||
|
disabled={this.state.creatingChannel}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>}
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default PublishPage;
|
export default PublishPage;
|
||||||
|
|
|
@ -15,7 +15,13 @@ reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) {
|
||||||
byUri[uri] = claim.claim_id;
|
byUri[uri] = claim.claim_id;
|
||||||
} else if (claim === undefined && certificate !== undefined) {
|
} else if (claim === undefined && certificate !== undefined) {
|
||||||
byId[certificate.claim_id] = certificate;
|
byId[certificate.claim_id] = certificate;
|
||||||
byUri[uri] = certificate.claim_id;
|
// Don't point URI at the channel certificate unless it actually is
|
||||||
|
// a channel URI. This is brittle.
|
||||||
|
if (!uri.split(certificate.name)[1].match(/\//)) {
|
||||||
|
byUri[uri] = certificate.claim_id;
|
||||||
|
} else {
|
||||||
|
byUri[uri] = null;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
byUri[uri] = null;
|
byUri[uri] = null;
|
||||||
}
|
}
|
||||||
|
@ -108,6 +114,34 @@ reducers[types.ABANDON_CLAIM_COMPLETED] = function(state, action) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
reducers[types.CREATE_CHANNEL_COMPLETED] = function(state, action) {
|
||||||
|
const { channelClaim } = action.data;
|
||||||
|
const byId = Object.assign({}, state.byId);
|
||||||
|
const myChannelClaims = new Set(state.myChannelClaims);
|
||||||
|
|
||||||
|
byId[channelClaim.claim_id] = channelClaim;
|
||||||
|
myChannelClaims.add(channelClaim.claim_id);
|
||||||
|
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
byId,
|
||||||
|
myChannelClaims,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
reducers[types.PUBLISH_COMPLETED] = function(state, action) {
|
||||||
|
const { claim } = action.data;
|
||||||
|
const byId = Object.assign({}, state.byId);
|
||||||
|
const myClaims = new Set(state.myClaims);
|
||||||
|
|
||||||
|
byId[claim.claim_id] = claim;
|
||||||
|
myClaims.add(claim.claim_id);
|
||||||
|
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
byId,
|
||||||
|
myClaims,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export default function reducer(state = defaultState, action) {
|
export default function reducer(state = defaultState, action) {
|
||||||
const handler = reducers[action.type];
|
const handler = reducers[action.type];
|
||||||
if (handler) return handler(state, action);
|
if (handler) return handler(state, action);
|
||||||
|
|
|
@ -12,8 +12,9 @@ reducers[types.FILE_LIST_STARTED] = function(state, action) {
|
||||||
|
|
||||||
reducers[types.FILE_LIST_COMPLETED] = function(state, action) {
|
reducers[types.FILE_LIST_COMPLETED] = function(state, action) {
|
||||||
const { fileInfos } = action.data;
|
const { fileInfos } = action.data;
|
||||||
|
|
||||||
const newByOutpoint = Object.assign({}, state.byOutpoint);
|
const newByOutpoint = Object.assign({}, state.byOutpoint);
|
||||||
|
const pendingByOutpoint = Object.assign({}, state.pendingByOutpoint);
|
||||||
|
|
||||||
fileInfos.forEach(fileInfo => {
|
fileInfos.forEach(fileInfo => {
|
||||||
const { outpoint } = fileInfo;
|
const { outpoint } = fileInfo;
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ reducers[types.FILE_LIST_COMPLETED] = function(state, action) {
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
isFileListPending: false,
|
isFileListPending: false,
|
||||||
byOutpoint: newByOutpoint,
|
byOutpoint: newByOutpoint,
|
||||||
|
pendingByOutpoint,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -136,6 +138,61 @@ reducers[types.LOADING_VIDEO_FAILED] = function(state, action) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
reducers[types.PUBLISH_STARTED] = function(state, action) {
|
||||||
|
const { pendingPublish } = action.data;
|
||||||
|
const pendingByOutpoint = Object.assign({}, state.pendingByOutpoint);
|
||||||
|
|
||||||
|
pendingByOutpoint[pendingPublish.outpoint] = pendingPublish;
|
||||||
|
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
pendingByOutpoint,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
reducers[types.PUBLISH_COMPLETED] = function(state, action) {
|
||||||
|
const { pendingPublish } = action.data;
|
||||||
|
const pendingByOutpoint = Object.assign({}, state.pendingByOutpoint);
|
||||||
|
|
||||||
|
delete pendingByOutpoint[pendingPublish.outpoint];
|
||||||
|
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
pendingByOutpoint,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
reducers[types.PUBLISH_FAILED] = function(state, action) {
|
||||||
|
const { pendingPublish } = action.data;
|
||||||
|
const pendingByOutpoint = Object.assign({}, state.pendingByOutpoint);
|
||||||
|
|
||||||
|
delete pendingByOutpoint[pendingPublish.outpoint];
|
||||||
|
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
pendingByOutpoint,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// reducers[types.PUBLISH_COMPLETED] = function(state, action) {
|
||||||
|
// const { claim } = action.data;
|
||||||
|
// const uri = lbryuri.build({
|
||||||
|
// txid: claim.txId
|
||||||
|
// })
|
||||||
|
// const newPendingPublish = {
|
||||||
|
// name,
|
||||||
|
// channel_name,
|
||||||
|
// claim_id: "pending_claim_" + uri,
|
||||||
|
// txid: "pending_" + uri,
|
||||||
|
// nout: 0,
|
||||||
|
// outpoint: "pending_" + uri + ":0",
|
||||||
|
// time: Date.now(),
|
||||||
|
// };
|
||||||
|
// const fileInfos = Object.assign({}, state.fileInfos)
|
||||||
|
// fileInfos[newPendingPublish.outpoint] = newPendingPublish
|
||||||
|
|
||||||
|
// return Object.assign({}, state, {
|
||||||
|
// fileInfos,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
export default function reducer(state = defaultState, action) {
|
export default function reducer(state = defaultState, action) {
|
||||||
const handler = reducers[action.type];
|
const handler = reducers[action.type];
|
||||||
if (handler) return handler(state, action);
|
if (handler) return handler(state, action);
|
||||||
|
|
|
@ -69,6 +69,11 @@ export const makeSelectLoadingForUri = () => {
|
||||||
return createSelector(selectLoadingForUri, loading => !!loading);
|
return createSelector(selectLoadingForUri, loading => !!loading);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const selectFileInfosPendingPublish = createSelector(
|
||||||
|
_selectState,
|
||||||
|
state => Object.values(state.pendingByOutpoint || {})
|
||||||
|
);
|
||||||
|
|
||||||
export const selectFileInfosDownloaded = createSelector(
|
export const selectFileInfosDownloaded = createSelector(
|
||||||
selectFileInfosByOutpoint,
|
selectFileInfosByOutpoint,
|
||||||
selectMyClaimsOutpoints,
|
selectMyClaimsOutpoints,
|
||||||
|
@ -87,24 +92,17 @@ export const selectFileInfosDownloaded = createSelector(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectFileInfosPendingPublish = createSelector(
|
|
||||||
_selectState,
|
|
||||||
state => {
|
|
||||||
return lbry.getPendingPublishes();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectFileInfosPublished = createSelector(
|
export const selectFileInfosPublished = createSelector(
|
||||||
selectFileInfosByOutpoint,
|
selectFileInfosByOutpoint,
|
||||||
selectFileInfosPendingPublish,
|
|
||||||
selectMyClaimsOutpoints,
|
selectMyClaimsOutpoints,
|
||||||
(byOutpoint, pendingFileInfos, outpoints) => {
|
selectFileInfosPendingPublish,
|
||||||
|
(byOutpoint, outpoints, pendingPublish) => {
|
||||||
const fileInfos = [];
|
const fileInfos = [];
|
||||||
outpoints.forEach(outpoint => {
|
outpoints.forEach(outpoint => {
|
||||||
const fileInfo = byOutpoint[outpoint];
|
const fileInfo = byOutpoint[outpoint];
|
||||||
if (fileInfo) fileInfos.push(fileInfo);
|
if (fileInfo) fileInfos.push(fileInfo);
|
||||||
});
|
});
|
||||||
return [...fileInfos, ...pendingFileInfos];
|
return fileInfos;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -133,7 +131,6 @@ export const selectFileInfosByUri = createSelector(
|
||||||
if (fileInfo) fileInfos[uri] = fileInfo;
|
if (fileInfo) fileInfos[uri] = fileInfo;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return fileInfos;
|
return fileInfos;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -92,12 +92,16 @@ const saveClaimsFilter = createFilter("claims", [
|
||||||
"myClaims",
|
"myClaims",
|
||||||
"myChannelClaims",
|
"myChannelClaims",
|
||||||
]);
|
]);
|
||||||
|
const saveFileInfosFilter = createFilter("fileInfo", [
|
||||||
|
"fileInfos",
|
||||||
|
"pendingByOutpoint",
|
||||||
|
]);
|
||||||
|
|
||||||
const persistOptions = {
|
const persistOptions = {
|
||||||
whitelist: ["claims"],
|
whitelist: ["claims", "fileInfo"],
|
||||||
// Order is important. Needs to be compressed last or other transforms can't
|
// Order is important. Needs to be compressed last or other transforms can't
|
||||||
// read the data
|
// read the data
|
||||||
transforms: [saveClaimsFilter, compressor],
|
transforms: [saveClaimsFilter, saveFileInfosFilter, compressor],
|
||||||
debounce: 1000,
|
debounce: 1000,
|
||||||
storage: localForage,
|
storage: localForage,
|
||||||
};
|
};
|
||||||
|
|
957
ui/yarn.lock
957
ui/yarn.lock
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue