Progress towards working publish
This commit is contained in:
parent
3d3b739387
commit
54a0c95e16
5 changed files with 253 additions and 107 deletions
|
@ -301,3 +301,32 @@ export function doFetchChannelListMine() {
|
|||
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);
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
@ -64,6 +64,8 @@ export const FETCH_CHANNEL_LIST_MINE_STARTED =
|
|||
"FETCH_CHANNEL_LIST_MINE_STARTED";
|
||||
export const 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";
|
||||
|
||||
// Search
|
||||
export const SEARCH_STARTED = "SEARCH_STARTED";
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
doFetchClaimListMine,
|
||||
doFetchChannelListMine,
|
||||
doResolveUri,
|
||||
doCreateChannel,
|
||||
} from "actions/content";
|
||||
import rewards from "rewards";
|
||||
import PublishPage from "./view";
|
||||
|
@ -33,6 +34,7 @@ const perform = dispatch => ({
|
|||
dispatch(doClaimRewardType(rewards.TYPE_FIRST_CHANNEL)),
|
||||
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
|
||||
resolveUri: uri => dispatch(doResolveUri(uri)),
|
||||
createChannel: (name, amount) => dispatch(doCreateChannel(name, amount)),
|
||||
});
|
||||
|
||||
export default connect(select, perform)(PublishPage);
|
||||
|
|
|
@ -216,6 +216,10 @@ class PublishPage extends React.PureComponent {
|
|||
handleNameChange(event) {
|
||||
var rawName = event.target.value;
|
||||
|
||||
this.nameChanged(rawName);
|
||||
}
|
||||
|
||||
nameChanged(rawName) {
|
||||
if (!rawName) {
|
||||
this.setState({
|
||||
rawName: "",
|
||||
|
@ -233,15 +237,26 @@ class PublishPage extends React.PureComponent {
|
|||
return;
|
||||
}
|
||||
|
||||
let channel = "";
|
||||
if (this.state.channel !== "anonymous") channel = this.state.channel;
|
||||
|
||||
const name = rawName.toLowerCase();
|
||||
const uri = lbryuri.normalize(name);
|
||||
const uri = lbryuri.build({ contentName: name, channelName: channel });
|
||||
this.setState({
|
||||
rawName: rawName,
|
||||
name: name,
|
||||
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) {
|
||||
|
@ -302,40 +317,12 @@ class PublishPage extends React.PureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
handleChannelChange(event) {
|
||||
const channel = event.target.value;
|
||||
|
||||
handleChannelChange(channelName) {
|
||||
this.setState({
|
||||
channel: channel,
|
||||
});
|
||||
}
|
||||
|
||||
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,
|
||||
channel: channelName,
|
||||
});
|
||||
const nameChanged = () => this.nameChanged(this.state.rawName);
|
||||
setTimeout(nameChanged.bind(this), 500, { once: true });
|
||||
}
|
||||
|
||||
handleTOSChange(event) {
|
||||
|
@ -413,7 +400,8 @@ class PublishPage extends React.PureComponent {
|
|||
getNameBidHelpText() {
|
||||
if (
|
||||
this.state.uri &&
|
||||
this.props.resolvingUris.indexOf(this.state.uri) !== -1
|
||||
this.props.resolvingUris.indexOf(this.state.uri) !== -1 &&
|
||||
this.claim() === undefined
|
||||
) {
|
||||
return <BusyMessage />;
|
||||
} else if (!this.state.name) {
|
||||
|
@ -700,77 +688,11 @@ class PublishPage extends React.PureComponent {
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<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">
|
||||
{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>
|
||||
<ChannelSection
|
||||
{...this.props}
|
||||
handleChannelChange={this.handleChannelChange.bind(this)}
|
||||
channel={this.state.channel}
|
||||
/>
|
||||
|
||||
<section className="card">
|
||||
<div className="card__title-primary">
|
||||
|
@ -898,4 +820,175 @@ 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={this.props.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="something" />
|
||||
);
|
||||
}
|
||||
} else if (fetchingChannels) {
|
||||
channelContent.push(<BusyMessage message="Loading channels" />);
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -15,7 +15,13 @@ reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) {
|
|||
byUri[uri] = claim.claim_id;
|
||||
} else if (claim === undefined && certificate !== undefined) {
|
||||
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 {
|
||||
byUri[uri] = null;
|
||||
}
|
||||
|
@ -85,6 +91,20 @@ reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) {
|
|||
});
|
||||
};
|
||||
|
||||
reducers[types.CREATE_CHANNEL_COMPLETED] = function(state, action) {
|
||||
const { channelClaim } = action.data;
|
||||
const { byId } = state;
|
||||
const myChannelClaims = new Set(state.myChannelClaims);
|
||||
|
||||
byId[channelClaim.claim_id] = channelClaim;
|
||||
myChannelClaims.add(channelClaim.claim_id);
|
||||
|
||||
return Object.assign({}, state, {
|
||||
byId,
|
||||
myChannelClaims,
|
||||
});
|
||||
};
|
||||
|
||||
export default function reducer(state = defaultState, action) {
|
||||
const handler = reducers[action.type];
|
||||
if (handler) return handler(state, action);
|
||||
|
|
Loading…
Reference in a new issue