@@ -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(
+
+
+ {this.props.channels.map(({ name }) =>
+
+ )}
+
+
+ );
+ if (fetchingChannels) {
+ channelContent.push(
+
+ );
+ }
+ } else if (fetchingChannels) {
+ channelContent.push(
);
+ }
+
+ return (
+
+
+
{__("Identity")}
+
+ {__("Who created this content?")}
+
+
+
+ {channelContent}
+
+ {this.state.addingChannel &&
+
+
{
+ this.handleNewChannelNameChange(event);
+ }}
+ value={this.state.newChannelName}
+ />
+
+
+
+
+ }
+
+ );
+ }
+}
+
export default PublishPage;
diff --git a/ui/js/reducers/claims.js b/ui/js/reducers/claims.js
index 2172832af..233028c8c 100644
--- a/ui/js/reducers/claims.js
+++ b/ui/js/reducers/claims.js
@@ -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);