Compare commits
11 commits
master
...
channel-cr
Author | SHA1 | Date | |
---|---|---|---|
|
78f2b4f3be | ||
|
0fe32e1a36 | ||
|
f008d95aa6 | ||
|
c4218d9f8b | ||
|
e95786b904 | ||
|
f02fdd9979 | ||
|
563a9135ce | ||
|
39eb2b1a96 | ||
|
2f0014be08 | ||
|
27c0ac7585 | ||
|
44856e1ba1 |
27 changed files with 1703 additions and 35 deletions
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -5574,8 +5574,8 @@
|
|||
}
|
||||
},
|
||||
"lbry-redux": {
|
||||
"version": "github:lbryio/lbry-redux#362d764c4c0de23032b6871b4d54207dc548028c",
|
||||
"from": "github:lbryio/lbry-redux#362d764c4c0de23032b6871b4d54207dc548028c",
|
||||
"version": "github:lbryio/lbry-redux#3133ea60b0302c162f7b6f67cc858997f1d2ab52",
|
||||
"from": "github:lbryio/lbry-redux#3133ea60b0302c162f7b6f67cc858997f1d2ab52",
|
||||
"requires": {
|
||||
"proxy-polyfill": "0.1.6",
|
||||
"reselect": "^3.0.0",
|
||||
|
@ -8039,11 +8039,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"react-native-document-picker": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react-native-document-picker/-/react-native-document-picker-3.2.4.tgz",
|
||||
"integrity": "sha512-5l0/fkgasUZdIk9jUUkReDtNCQn2yg1+BrMPHMt45c/NVmE15ThnhIuDj8/n8h1F1RlhUb3SzF86ANK4OdZAiQ=="
|
||||
},
|
||||
"react-native-exception-handler": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-exception-handler/-/react-native-exception-handler-2.9.0.tgz",
|
||||
|
@ -9124,6 +9119,11 @@
|
|||
"object-assign": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"seedrandom": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.3.tgz",
|
||||
"integrity": "sha512-PJLhhxIMjlMJaiIRtqiVW061EZn3cS+waZkbFe7eCa2R3g88HbNdWmw4NTFG1w5unxd0GeNaUUxZJP7gPAzSDQ=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"base-64": "^0.1.0",
|
||||
"@expo/vector-icons": "^8.1.0",
|
||||
"gfycat-style-urls": "^1.0.3",
|
||||
"lbry-redux": "lbryio/lbry-redux#362d764c4c0de23032b6871b4d54207dc548028c",
|
||||
"lbry-redux": "lbryio/lbry-redux#3133ea60b0302c162f7b6f67cc858997f1d2ab52",
|
||||
"lbryinc": "lbryio/lbryinc#b9f354ae50bd57691765a7d042c5054167878bf4",
|
||||
"lodash": ">=4.17.11",
|
||||
"merge": ">=1.2.1",
|
||||
|
@ -22,7 +22,6 @@
|
|||
"@react-native-community/async-storage": "^1.5.1",
|
||||
"react-native-camera": "^2.11.1",
|
||||
"react-native-country-picker-modal": "^0.6.2",
|
||||
"react-native-document-picker": "^3.2.4",
|
||||
"react-native-exception-handler": "2.9.0",
|
||||
"react-native-fast-image": "^6.1.1",
|
||||
"react-native-fs": "^2.13.3",
|
||||
|
@ -44,7 +43,8 @@
|
|||
"redux-persist-transform-compress": "^4.2.0",
|
||||
"redux-persist-transform-filter": "0.0.18",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"rn-fetch-blob": "0.10.15"
|
||||
"rn-fetch-blob": "0.10.15",
|
||||
"seedrandom": "3.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.5.4",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import AboutPage from 'page/about';
|
||||
import ChannelCreatorPage from 'page/channelCreator';
|
||||
import DiscoverPage from 'page/discover';
|
||||
import DownloadsPage from 'page/downloads';
|
||||
import DrawerContent from 'component/drawerContent';
|
||||
|
@ -159,6 +160,12 @@ const drawer = createDrawerNavigator(
|
|||
drawerIcon: ({ tintColor }) => <Icon name="wallet" size={drawerIconSize} style={{ color: tintColor }} />,
|
||||
},
|
||||
},
|
||||
ChannelCreator: {
|
||||
screen: ChannelCreatorPage,
|
||||
navigationOptions: {
|
||||
drawerIcon: ({ tintColor }) => <Icon name="at" size={drawerIconSize} style={{ color: tintColor }} />,
|
||||
},
|
||||
},
|
||||
Publish: {
|
||||
screen: PublishPage,
|
||||
navigationOptions: {
|
||||
|
|
|
@ -13,10 +13,15 @@ export default class ChannelIconItem extends React.PureComponent {
|
|||
autothumbStyle.autothumbBlue,
|
||||
autothumbStyle.autothumbLightBlue,
|
||||
autothumbStyle.autothumbCyan,
|
||||
autothumbStyle.autothumbTeal,
|
||||
autothumbStyle.autothumbGreen,
|
||||
autothumbStyle.autothumbYellow,
|
||||
autothumbStyle.autothumbOrange,
|
||||
autothumbStyle.autothumbDeepPurple,
|
||||
autothumbStyle.autothumbAmber,
|
||||
autothumbStyle.autothumbLime,
|
||||
autothumbStyle.autothumbLightGreen,
|
||||
autothumbStyle.autothumbDeepOrange,
|
||||
autothumbStyle.autothumbBrown,
|
||||
];
|
||||
|
||||
state = {
|
||||
|
|
|
@ -204,7 +204,11 @@ class ClaimList extends React.PureComponent {
|
|||
|
||||
const options = this.buildClaimSearchOptions();
|
||||
const claimSearchKey = createNormalizedClaimSearchKey(options);
|
||||
const uris = claimSearchByQuery[claimSearchKey];
|
||||
let uris = claimSearchByQuery[claimSearchKey];
|
||||
|
||||
if (uris) {
|
||||
uris = uris.filter(uri => uri && uri.length > 0);
|
||||
}
|
||||
|
||||
if (Constants.ORIENTATION_VERTICAL === orientation) {
|
||||
return (
|
||||
|
|
|
@ -12,6 +12,7 @@ const groupedMenuItems = {
|
|||
{ icon: 'globe-americas', label: 'All content', route: Constants.DRAWER_ROUTE_TRENDING },
|
||||
],
|
||||
'Your content': [
|
||||
{ icon: 'at', label: 'Channels', route: Constants.DRAWER_ROUTE_CHANNEL_CREATOR },
|
||||
{ icon: 'download', label: 'Library', route: Constants.DRAWER_ROUTE_MY_LBRY },
|
||||
{ icon: 'cloud-upload-alt', label: 'Publishes', route: Constants.DRAWER_ROUTE_PUBLISHES },
|
||||
{ icon: 'upload', label: 'New publish', route: Constants.DRAWER_ROUTE_PUBLISH },
|
||||
|
|
|
@ -67,11 +67,12 @@ export default class TagSearch extends React.PureComponent {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { name, style, type, selectedTags = [], showNsfwTags } = this.props;
|
||||
const { editable, name, style, type, selectedTags = [], showNsfwTags } = this.props;
|
||||
|
||||
return (
|
||||
<View>
|
||||
<TextInput
|
||||
editable={editable}
|
||||
style={tagStyle.searchInput}
|
||||
placeholder={'Search for more tags'}
|
||||
underlineColorAndroid={Colors.NextLbryGreen}
|
||||
|
|
|
@ -25,6 +25,9 @@ const Constants = {
|
|||
PHASE_DETAILS: 'details',
|
||||
PHASE_PUBLISH: 'publish',
|
||||
|
||||
PHASE_LIST: 'list',
|
||||
PHASE_NEW: 'create',
|
||||
|
||||
CONTENT_TAB: 'content',
|
||||
ABOUT_TAB: 'about',
|
||||
|
||||
|
@ -56,6 +59,11 @@ const Constants = {
|
|||
ACTION_SORT_BY_ITEM_CHANGED: 'SORT_BY_ITEM_CHANGED',
|
||||
ACTION_TIME_ITEM_CHANGED: 'TIME_ITEM_CHANGED',
|
||||
|
||||
ACTION_UPDATE_PUBLISH_FORM_STATE: 'UPDATE_PUBLISH_FORM_STATE',
|
||||
ACTION_UPDATE_CHANNEL_FORM_STATE: 'UPDATE_CHANNEL_FORM_STATE',
|
||||
ACTION_CLEAR_PUBLISH_FORM_STATE: 'CLEAR_PUBLISH_FORM_STATE',
|
||||
ACTION_CLEAR_CHANNEL_FORM_STATE: 'CLEAR_CHANNEL_FORM_STATE',
|
||||
|
||||
ORIENTATION_HORIZONTAL: 'horizontal',
|
||||
ORIENTATION_VERTICAL: 'vertical',
|
||||
|
||||
|
@ -69,6 +77,7 @@ const Constants = {
|
|||
DRAWER_ROUTE_SUBSCRIPTIONS: 'Subscriptions',
|
||||
DRAWER_ROUTE_MY_LBRY: 'Downloads',
|
||||
DRAWER_ROUTE_PUBLISH: 'Publish',
|
||||
DRAWER_ROUTE_PUBLISH_FORM: 'PublishForm',
|
||||
DRAWER_ROUTE_PUBLISHES: 'Publishes',
|
||||
DRAWER_ROUTE_REWARDS: 'Rewards',
|
||||
DRAWER_ROUTE_WALLET: 'Wallet',
|
||||
|
@ -77,6 +86,8 @@ const Constants = {
|
|||
DRAWER_ROUTE_SEARCH: 'Search',
|
||||
DRAWER_ROUTE_TRANSACTION_HISTORY: 'TransactionHistory',
|
||||
DRAWER_ROUTE_TAG: 'Tag',
|
||||
DRAWER_ROUTE_CHANNEL_CREATOR: 'ChannelCreator',
|
||||
DRAWER_ROUTE_CHANNEL_CREATOR_FORM: 'ChannnelCreatorForm',
|
||||
|
||||
FULL_ROUTE_NAME_DISCOVER: 'DiscoverStack',
|
||||
FULL_ROUTE_NAME_WALLET: 'WalletStack',
|
||||
|
@ -146,4 +157,8 @@ export const DrawerRoutes = [
|
|||
Constants.DRAWER_ROUTE_ABOUT,
|
||||
Constants.DRAWER_ROUTE_SEARCH,
|
||||
Constants.DRAWER_ROUTE_TRANSACTION_HISTORY,
|
||||
Constants.DRAWER_ROUTE_CHANNEL_CREATOR,
|
||||
];
|
||||
|
||||
// sub-pages for main routes
|
||||
export const InnerDrawerRoutes = [Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM, Constants.DRAWER_ROUTE_PUBLISH_FORM];
|
||||
|
|
|
@ -37,6 +37,7 @@ import FilesystemStorage from 'redux-persist-filesystem-storage';
|
|||
import createCompressor from 'redux-persist-transform-compress';
|
||||
import createFilter from 'redux-persist-transform-filter';
|
||||
import moment from 'moment';
|
||||
import formReducer from 'redux/reducers/form';
|
||||
import drawerReducer from 'redux/reducers/drawer';
|
||||
import settingsReducer from 'redux/reducers/settings';
|
||||
import thunk from 'redux-thunk';
|
||||
|
@ -109,6 +110,7 @@ const reducers = persistCombineReducers(persistOptions, {
|
|||
file: fileReducer,
|
||||
fileInfo: fileInfoReducer,
|
||||
filtered: filteredReducer,
|
||||
form: formReducer,
|
||||
homepage: homepageReducer,
|
||||
nav: navigatorReducer,
|
||||
notifications: notificationsReducer,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { doFetchClaimsByChannel, makeSelectClaimForUri } from 'lbry-redux';
|
||||
import { makeSelectClaimForUri, selectMyChannelClaims } from 'lbry-redux';
|
||||
import { doPopDrawerStack } from 'redux/actions/drawer';
|
||||
import { doSetSortByItem, doSetTimeItem } from 'redux/actions/settings';
|
||||
import { selectDrawerStack } from 'redux/selectors/drawer';
|
||||
|
@ -7,6 +7,7 @@ import { selectSortByItem, selectTimeItem } from 'redux/selectors/settings';
|
|||
import ChannelPage from './view';
|
||||
|
||||
const select = (state, props) => ({
|
||||
channels: selectMyChannelClaims(state),
|
||||
claim: makeSelectClaimForUri(props.uri)(state),
|
||||
drawerStack: selectDrawerStack(state),
|
||||
sortByItem: selectSortByItem(state),
|
||||
|
@ -14,7 +15,6 @@ const select = (state, props) => ({
|
|||
});
|
||||
|
||||
const perform = dispatch => ({
|
||||
fetchClaims: (uri, page) => dispatch(doFetchClaimsByChannel(uri, page)),
|
||||
popDrawerStack: () => dispatch(doPopDrawerStack()),
|
||||
setSortByItem: item => dispatch(doSetSortByItem(item)),
|
||||
setTimeItem: item => dispatch(doSetTimeItem(item)),
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Alert,
|
||||
Dimensions,
|
||||
Image,
|
||||
NativeModules,
|
||||
|
@ -159,10 +160,46 @@ class ChannelPage extends React.PureComponent {
|
|||
);
|
||||
};
|
||||
|
||||
onEditPressed = () => {
|
||||
const { claim, navigation } = this.props;
|
||||
if (claim) {
|
||||
const { permanent_url: permanentUrl } = claim;
|
||||
navigation.navigate({
|
||||
routeName: Constants.DRAWER_ROUTE_CHANNEL_CREATOR,
|
||||
params: { editChannelUrl: permanentUrl },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onDeletePressed = () => {
|
||||
const { abandonClaim, claim, navigation } = this.props;
|
||||
if (claim) {
|
||||
const { txid, nout } = claim;
|
||||
|
||||
// show confirm alert
|
||||
Alert.alert(
|
||||
__('Delete channel'),
|
||||
__('Are you sure you want to delete this channel?'),
|
||||
[
|
||||
{ text: __('No') },
|
||||
{
|
||||
text: __('Yes'),
|
||||
onPress: () => {
|
||||
abandonClaim(txid, nout);
|
||||
navigation.navigate({ routeName: Constants.DRAWER_ROUTE_CHANNEL_CREATOR });
|
||||
},
|
||||
},
|
||||
],
|
||||
{ cancelable: true }
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { claim, navigation, uri, drawerStack, popDrawerStack, sortByItem, timeItem } = this.props;
|
||||
const { channels, claim, navigation, uri, drawerStack, popDrawerStack, sortByItem, timeItem } = this.props;
|
||||
const { name, permanent_url: permanentUrl } = claim;
|
||||
const { autoStyle, showSortPicker, showTimePicker } = this.state;
|
||||
const ownedChannel = channels ? channels.map(channel => channel.permanent_url).includes(permanentUrl) : false;
|
||||
|
||||
let thumbnailUrl,
|
||||
coverUrl,
|
||||
|
@ -218,12 +255,32 @@ class ChannelPage extends React.PureComponent {
|
|||
</View>
|
||||
|
||||
<View style={channelPageStyle.subscribeButtonContainer}>
|
||||
<SubscribeButton style={channelPageStyle.subscribeButton} uri={fullUri} name={name} />
|
||||
<SubscribeNotificationButton
|
||||
style={[channelPageStyle.subscribeButton, channelPageStyle.bellButton]}
|
||||
uri={fullUri}
|
||||
name={name}
|
||||
/>
|
||||
{ownedChannel && (
|
||||
<Button
|
||||
style={channelPageStyle.actionButton}
|
||||
theme={'light'}
|
||||
icon={'edit'}
|
||||
text={'Edit'}
|
||||
onPress={this.onEditPressed}
|
||||
/>
|
||||
)}
|
||||
{ownedChannel && (
|
||||
<Button
|
||||
style={channelPageStyle.deleteButton}
|
||||
theme={'light'}
|
||||
icon={'trash-alt'}
|
||||
text={'Delete'}
|
||||
onPress={this.onDeletePressed}
|
||||
/>
|
||||
)}
|
||||
{!ownedChannel && <SubscribeButton style={channelPageStyle.subscribeButton} uri={fullUri} name={name} />}
|
||||
{!ownedChannel && (
|
||||
<SubscribeNotificationButton
|
||||
style={[channelPageStyle.subscribeButton, channelPageStyle.bellButton]}
|
||||
uri={fullUri}
|
||||
name={name}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
|
|
49
src/page/channelCreator/index.js
Normal file
49
src/page/channelCreator/index.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
import { connect } from 'react-redux';
|
||||
import {
|
||||
selectAbandoningIds,
|
||||
selectBalance,
|
||||
selectMyChannelClaims,
|
||||
selectFetchingMyChannels,
|
||||
selectUpdatingChannel,
|
||||
selectUpdateChannelError,
|
||||
doAbandonClaim,
|
||||
doFetchChannelListMine,
|
||||
doCreateChannel,
|
||||
doUpdateChannel,
|
||||
doToast,
|
||||
} from 'lbry-redux';
|
||||
import { doPushDrawerStack, doPopDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
|
||||
import { doUpdateChannelFormState, doClearChannelFormState } from 'redux/actions/form';
|
||||
import { selectDrawerStack } from 'redux/selectors/drawer';
|
||||
import { selectChannelFormState } from 'redux/selectors/form';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import ChannelCreator from './view';
|
||||
|
||||
const select = state => ({
|
||||
abandoningClaimIds: selectAbandoningIds(state),
|
||||
channels: selectMyChannelClaims(state),
|
||||
channelFormState: selectChannelFormState(state),
|
||||
drawerStack: selectDrawerStack(state),
|
||||
fetchingChannels: selectFetchingMyChannels(state),
|
||||
balance: selectBalance(state),
|
||||
updatingChannel: selectUpdatingChannel(state),
|
||||
updateChannelError: selectUpdateChannelError(state),
|
||||
});
|
||||
|
||||
const perform = dispatch => ({
|
||||
abandonClaim: (txid, nout) => dispatch(doAbandonClaim(txid, nout)),
|
||||
notify: data => dispatch(doToast(data)),
|
||||
clearChannelFormState: () => dispatch(doClearChannelFormState()),
|
||||
createChannel: (name, amount, optionalParams) => dispatch(doCreateChannel(name, amount, optionalParams)),
|
||||
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
|
||||
updateChannel: params => dispatch(doUpdateChannel(params)),
|
||||
updateChannelFormState: data => dispatch(doUpdateChannelFormState(data)),
|
||||
pushDrawerStack: (routeName, params) => dispatch(doPushDrawerStack(routeName, params)),
|
||||
popDrawerStack: () => dispatch(doPopDrawerStack()),
|
||||
setPlayerVisible: () => dispatch(doSetPlayerVisible(false)),
|
||||
});
|
||||
|
||||
export default connect(
|
||||
select,
|
||||
perform
|
||||
)(ChannelCreator);
|
1042
src/page/channelCreator/view.js
Normal file
1042
src/page/channelCreator/view.js
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,7 @@
|
|||
import { connect } from 'react-redux';
|
||||
import {
|
||||
doFetchFileInfo,
|
||||
doFetchChannelListMine,
|
||||
doFetchClaimListMine,
|
||||
doFileGet,
|
||||
doPurchaseUri,
|
||||
|
@ -19,6 +20,7 @@ import {
|
|||
makeSelectThumbnailForUri,
|
||||
makeSelectTitleForUri,
|
||||
selectBalance,
|
||||
selectMyChannelClaims,
|
||||
selectMyClaimUrisWithoutChannels,
|
||||
selectPurchasedUris,
|
||||
selectFailedPurchaseUris,
|
||||
|
@ -46,6 +48,7 @@ const select = (state, props) => {
|
|||
return {
|
||||
balance: selectBalance(state),
|
||||
blackListedOutpoints: selectBlackListedOutpoints(state),
|
||||
channels: selectMyChannelClaims(state),
|
||||
claim: makeSelectClaimForUri(selectProps.uri)(state),
|
||||
drawerStack: selectDrawerStack(state),
|
||||
isResolvingUri: makeSelectIsUriResolving(selectProps.uri)(state),
|
||||
|
@ -75,6 +78,7 @@ const perform = dispatch => ({
|
|||
fetchFileInfo: uri => dispatch(doFetchFileInfo(uri)),
|
||||
fetchCostInfo: uri => dispatch(doFetchCostInfoForUri(uri)),
|
||||
fetchMyClaims: () => dispatch(doFetchClaimListMine()),
|
||||
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
|
||||
fileGet: (uri, saveFile) => dispatch(doFileGet(uri, saveFile)),
|
||||
notify: data => dispatch(doToast(data)),
|
||||
popDrawerStack: () => dispatch(doPopDrawerStack()),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Lbry, normalizeURI } from 'lbry-redux';
|
||||
import { Lbry, normalizeURI, parseURI } from 'lbry-redux';
|
||||
import { Lbryio } from 'lbryinc';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
|
@ -100,7 +100,7 @@ class FilePage extends React.PureComponent {
|
|||
DeviceEventEmitter.addListener('onDownloadUpdated', this.handleDownloadUpdated);
|
||||
DeviceEventEmitter.addListener('onDownloadCompleted', this.handleDownloadCompleted);
|
||||
|
||||
const { fileInfo, isResolvingUri, resolveUri, navigation } = this.props;
|
||||
const { fetchChannelListMine, fileInfo, isResolvingUri, resolveUri, navigation } = this.props;
|
||||
const { uri, uriVars } = navigation.state.params;
|
||||
this.setState({ uri, uriVars });
|
||||
|
||||
|
@ -108,6 +108,7 @@ class FilePage extends React.PureComponent {
|
|||
|
||||
this.fetchFileInfo(this.props);
|
||||
this.fetchCostInfo(this.props);
|
||||
fetchChannelListMine();
|
||||
|
||||
if (NativeModules.Firebase) {
|
||||
NativeModules.Firebase.track('open_file_page', { uri: uri });
|
||||
|
@ -567,6 +568,7 @@ class FilePage extends React.PureComponent {
|
|||
const {
|
||||
balance,
|
||||
claim,
|
||||
channels,
|
||||
channelUri,
|
||||
costInfo,
|
||||
fileInfo,
|
||||
|
@ -585,6 +587,10 @@ class FilePage extends React.PureComponent {
|
|||
} = this.props;
|
||||
const { uri, autoplay } = navigation.state.params;
|
||||
|
||||
const myChannelUris = channels ? channels.map(channel => channel.permanent_url) : [];
|
||||
const ownedClaim = myClaimUris.includes(uri) || myChannelUris.includes(uri);
|
||||
const { isChannel } = parseURI(uri);
|
||||
|
||||
let innerContent = null;
|
||||
if ((isResolvingUri && !claim) || !claim) {
|
||||
return (
|
||||
|
@ -597,7 +603,14 @@ class FilePage extends React.PureComponent {
|
|||
)}
|
||||
{claim === null && !isResolvingUri && (
|
||||
<View style={filePageStyle.container}>
|
||||
<Text style={filePageStyle.emptyClaimText}>There's nothing at this location.</Text>
|
||||
{ownedClaim && (
|
||||
<Text style={filePageStyle.emptyClaimText}>
|
||||
{isChannel
|
||||
? 'It looks like you just created this channel. It will appear in a few minutes.'
|
||||
: 'It looks you just published this content. It will appear in a few minutes.'}
|
||||
</Text>
|
||||
)}
|
||||
{!ownedClaim && <Text style={filePageStyle.emptyClaimText}>There's nothing at this location.</Text>}
|
||||
</View>
|
||||
)}
|
||||
<UriBar value={uri} navigation={navigation} />
|
||||
|
@ -606,7 +619,7 @@ class FilePage extends React.PureComponent {
|
|||
}
|
||||
|
||||
if (claim) {
|
||||
if (claim && claim.name.length && claim.name[0] === '@') {
|
||||
if (isChannel) {
|
||||
return <ChannelPage uri={uri} navigation={navigation} />;
|
||||
}
|
||||
|
||||
|
|
|
@ -523,6 +523,8 @@ class PublishPage extends React.PureComponent {
|
|||
});
|
||||
};
|
||||
|
||||
handleUploadPressed = () => {};
|
||||
|
||||
getRandomFileId = () => {
|
||||
// generate a random id for a photo or recorded video between 1 and 20 (for creating thumbnails)
|
||||
const id = Math.floor(Math.random() * (20 - 2)) + 1;
|
||||
|
@ -824,6 +826,7 @@ class PublishPage extends React.PureComponent {
|
|||
)}
|
||||
<TextInput
|
||||
editable={this.state.canPublish && !this.state.publishStarted}
|
||||
multiline
|
||||
placeholder={this.state.descriptionFocused ? '' : 'Description'}
|
||||
style={publishStyle.inputText}
|
||||
value={this.state.description}
|
||||
|
|
|
@ -33,6 +33,15 @@ class PublishesPage extends React.PureComponent {
|
|||
this.onComponentFocused();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const { currentRoute } = nextProps;
|
||||
const { currentRoute: prevRoute } = this.props;
|
||||
|
||||
if (Constants.DRAWER_ROUTE_PUBLISHES === currentRoute && currentRoute !== prevRoute) {
|
||||
this.onComponentFocused();
|
||||
}
|
||||
}
|
||||
|
||||
onComponentFocused = () => {
|
||||
const { checkPendingPublishes, fetchMyClaims, pushDrawerStack, setPlayerVisible } = this.props;
|
||||
pushDrawerStack();
|
||||
|
|
23
src/redux/actions/form.js
Normal file
23
src/redux/actions/form.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
|
||||
export const doUpdatePublishFormState = publishFormValue => dispatch =>
|
||||
dispatch({
|
||||
type: Constants.ACTION_UPDATE_PUBLISH_FORM_STATE,
|
||||
data: { ...publishFormValue },
|
||||
});
|
||||
|
||||
export const doUpdateChannelFormState = channelFormValue => dispatch =>
|
||||
dispatch({
|
||||
type: Constants.ACTION_UPDATE_CHANNEL_FORM_STATE,
|
||||
data: { ...channelFormValue },
|
||||
});
|
||||
|
||||
export const doClearPublishFormState = () => dispatch =>
|
||||
dispatch({
|
||||
type: Constants.ACTION_CLEAR_PUBLISH_FORM_STATE,
|
||||
});
|
||||
|
||||
export const doClearChannelFormState = () => dispatch =>
|
||||
dispatch({
|
||||
type: Constants.ACTION_CLEAR_CHANNEL_FORM_STATE,
|
||||
});
|
|
@ -16,7 +16,19 @@ reducers[Constants.ACTION_PUSH_DRAWER_STACK] = (state, action) => {
|
|||
const { routeName, params } = action.data;
|
||||
const newStack = state.stack.slice();
|
||||
|
||||
if (routeName !== newStack[newStack.length - 1].route) {
|
||||
const lastRoute = newStack[newStack.length - 1].route;
|
||||
let canPushStack = routeName !== lastRoute;
|
||||
if (
|
||||
lastRoute === Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM &&
|
||||
routeName === Constants.DRAWER_ROUTE_CHANNEL_CREATOR
|
||||
) {
|
||||
canPushStack = false;
|
||||
}
|
||||
if (lastRoute === Constants.DRAWER_ROUTE_PUBLISH_FORM && routeName === Constants.DRAWER_ROUTE_PUBLISH) {
|
||||
canPushStack = false;
|
||||
}
|
||||
|
||||
if (canPushStack) {
|
||||
newStack.push({ route: routeName, params });
|
||||
}
|
||||
|
||||
|
|
49
src/redux/reducers/form.js
Normal file
49
src/redux/reducers/form.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
|
||||
const reducers = {};
|
||||
const defaultState = {
|
||||
channelFormValues: {},
|
||||
publishFormValues: {},
|
||||
};
|
||||
|
||||
reducers[Constants.ACTION_UPDATE_PUBLISH_FORM_STATE] = (state, action) => {
|
||||
const { data } = action;
|
||||
const publishFormValues = Object.assign({}, state.publishFormValues);
|
||||
const newPublishFormValues = Object.assign(publishFormValues, data);
|
||||
|
||||
return {
|
||||
...state,
|
||||
publishFormValues: newPublishFormValues,
|
||||
};
|
||||
};
|
||||
|
||||
reducers[Constants.ACTION_UPDATE_CHANNEL_FORM_STATE] = (state, action) => {
|
||||
const { data } = action;
|
||||
const channelFormValues = Object.assign({}, state.channelFormValues);
|
||||
const newChannelFormValues = Object.assign(channelFormValues, data);
|
||||
|
||||
return {
|
||||
...state,
|
||||
channelFormValues: newChannelFormValues,
|
||||
};
|
||||
};
|
||||
|
||||
reducers[Constants.ACTION_CLEAR_PUBLISH_FORM_STATE] = state => {
|
||||
return {
|
||||
...state,
|
||||
publishFormValues: {},
|
||||
};
|
||||
};
|
||||
|
||||
reducers[Constants.ACTION_CLEAR_CHANNEL_FORM_STATE] = state => {
|
||||
return {
|
||||
...state,
|
||||
channelFormValues: {},
|
||||
};
|
||||
};
|
||||
|
||||
export default function reducer(state = defaultState, action) {
|
||||
const handler = reducers[action.type];
|
||||
if (handler) return handler(state, action);
|
||||
return state;
|
||||
}
|
13
src/redux/selectors/form.js
Normal file
13
src/redux/selectors/form.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { createSelector } from 'reselect';
|
||||
|
||||
export const selectState = state => state.form || {};
|
||||
|
||||
export const selectPublishFormState = createSelector(
|
||||
selectState,
|
||||
state => state.publishFormValues || {}
|
||||
);
|
||||
|
||||
export const selectChannelFormState = createSelector(
|
||||
selectState,
|
||||
state => state.channelFormValues || {}
|
||||
);
|
|
@ -4,6 +4,9 @@ const autothumbStyle = StyleSheet.create({
|
|||
autothumbPurple: {
|
||||
backgroundColor: '#9c27b0',
|
||||
},
|
||||
autothumbDeepPurple: {
|
||||
backgroundColor: '#5e35b1',
|
||||
},
|
||||
autothumbRed: {
|
||||
backgroundColor: '#e53935',
|
||||
},
|
||||
|
@ -34,6 +37,21 @@ const autothumbStyle = StyleSheet.create({
|
|||
autothumbOrange: {
|
||||
backgroundColor: '#ffa726',
|
||||
},
|
||||
autothumbAmber: {
|
||||
backgroundColor: '#ffb300',
|
||||
},
|
||||
autothumbLime: {
|
||||
backgroundColor: '#c0ca33',
|
||||
},
|
||||
autothumbLightGreen: {
|
||||
backgroundColor: '#7cb342',
|
||||
},
|
||||
autothumbDeepOrange: {
|
||||
backgroundColor: '#f4511e',
|
||||
},
|
||||
autothumbBrown: {
|
||||
backgroundColor: '#6d4c41',
|
||||
},
|
||||
});
|
||||
|
||||
export default autothumbStyle;
|
||||
|
|
261
src/styles/channelCreator.js
Normal file
261
src/styles/channelCreator.js
Normal file
|
@ -0,0 +1,261 @@
|
|||
import { Dimensions, StyleSheet } from 'react-native';
|
||||
import Colors from './colors';
|
||||
|
||||
const screenDimension = Dimensions.get('window');
|
||||
const screenWidth = screenDimension.width;
|
||||
|
||||
const channelCreatorStyle = StyleSheet.create({
|
||||
card: {
|
||||
backgroundColor: Colors.White,
|
||||
marginTop: 16,
|
||||
marginLeft: 16,
|
||||
marginRight: 16,
|
||||
padding: 16,
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: Colors.PageBackground,
|
||||
},
|
||||
channelPicker: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 16,
|
||||
height: 52,
|
||||
width: '100%',
|
||||
},
|
||||
bidRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
label: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 16,
|
||||
},
|
||||
channelNameInput: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 16,
|
||||
paddingLeft: 20,
|
||||
},
|
||||
bidAmountInput: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 16,
|
||||
marginLeft: 16,
|
||||
textAlign: 'right',
|
||||
width: 80,
|
||||
},
|
||||
helpText: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 12,
|
||||
},
|
||||
channelTitleInput: {
|
||||
marginBottom: 4,
|
||||
},
|
||||
createChannelContainer: {
|
||||
marginTop: 60,
|
||||
flex: 1,
|
||||
},
|
||||
channelAt: {
|
||||
position: 'absolute',
|
||||
left: 4,
|
||||
top: 13,
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 16,
|
||||
},
|
||||
buttonContainer: {
|
||||
marginTop: 24,
|
||||
marginBottom: 16,
|
||||
},
|
||||
buttons: {
|
||||
marginLeft: 16,
|
||||
marginRight: 16,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
cancelLink: {
|
||||
marginRight: 16,
|
||||
},
|
||||
createButton: {
|
||||
backgroundColor: Colors.LbryGreen,
|
||||
alignSelf: 'flex-end',
|
||||
},
|
||||
inlineError: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 12,
|
||||
color: Colors.Red,
|
||||
marginTop: 2,
|
||||
},
|
||||
imageSelectors: {
|
||||
width: '100%',
|
||||
height: 160,
|
||||
},
|
||||
coverImageTouchArea: {
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
coverImage: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
avatarImageContainer: {
|
||||
position: 'absolute',
|
||||
left: screenWidth / 2 - 80 / 2,
|
||||
bottom: -16,
|
||||
width: 80,
|
||||
height: 80,
|
||||
borderRadius: 160,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
avatarTouchArea: {
|
||||
width: 80,
|
||||
height: 80,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
avatarImage: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
listFooter: {
|
||||
marginTop: 24,
|
||||
},
|
||||
createChannelButton: {
|
||||
backgroundColor: Colors.LbryGreen,
|
||||
alignSelf: 'flex-start',
|
||||
},
|
||||
scrollContainer: {
|
||||
marginTop: 60,
|
||||
marginLeft: 16,
|
||||
marginRight: 16,
|
||||
},
|
||||
scrollPadding: {
|
||||
paddingTop: 16,
|
||||
},
|
||||
channelListItem: {
|
||||
flexDirection: 'row',
|
||||
marginBottom: 16,
|
||||
alignItems: 'center',
|
||||
},
|
||||
channelListTitle: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 18,
|
||||
marginBottom: 4,
|
||||
},
|
||||
channelListName: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 14,
|
||||
},
|
||||
channelListAvatar: {
|
||||
marginRight: 16,
|
||||
width: 80,
|
||||
height: 80,
|
||||
borderRadius: 160,
|
||||
overflow: 'hidden',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
selectedOverlay: {
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: 80,
|
||||
height: 80,
|
||||
borderRadius: 160,
|
||||
overflow: 'hidden',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: '#000000aa',
|
||||
},
|
||||
listHeader: {
|
||||
alignItems: 'center',
|
||||
marginTop: 16,
|
||||
marginBottom: 16,
|
||||
},
|
||||
textInputLayout: {
|
||||
marginBottom: 4,
|
||||
},
|
||||
textInputTitle: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 12,
|
||||
marginBottom: -10,
|
||||
marginLeft: 4,
|
||||
},
|
||||
inputText: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 16,
|
||||
},
|
||||
toggleContainer: {
|
||||
marginTop: 24,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
modeLink: {
|
||||
color: Colors.LbryGreen,
|
||||
alignSelf: 'flex-end',
|
||||
marginRight: 16,
|
||||
},
|
||||
cardTitle: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 20,
|
||||
marginBottom: 8,
|
||||
},
|
||||
tag: {
|
||||
marginRight: 4,
|
||||
marginBottom: 4,
|
||||
},
|
||||
tagList: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
},
|
||||
editOverlay: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
borderRadius: 24,
|
||||
position: 'absolute',
|
||||
padding: 8,
|
||||
left: 4,
|
||||
bottom: 4,
|
||||
backgroundColor: '#00000077',
|
||||
},
|
||||
thumbnailEditOverlay: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
borderRadius: 24,
|
||||
position: 'absolute',
|
||||
padding: 8,
|
||||
left: 80 / 2 - 32 / 2,
|
||||
bottom: 4,
|
||||
backgroundColor: '#00000077',
|
||||
},
|
||||
editIcon: {
|
||||
color: Colors.White,
|
||||
fontFamily: 'Inter-UI-SemiBold',
|
||||
fontSize: 12,
|
||||
},
|
||||
uploadProgress: {
|
||||
alignItems: 'center',
|
||||
borderRadius: 16,
|
||||
flexDirection: 'row',
|
||||
position: 'absolute',
|
||||
top: 8,
|
||||
right: 8,
|
||||
backgroundColor: '#00000077',
|
||||
paddingLeft: 8,
|
||||
paddingRight: 8,
|
||||
paddingTop: 4,
|
||||
paddingBottom: 4,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
uploadText: {
|
||||
color: Colors.White,
|
||||
fontFamily: 'Inter-UI-SemiBold',
|
||||
fontSize: 12,
|
||||
marginLeft: 4,
|
||||
},
|
||||
});
|
||||
|
||||
export default channelCreatorStyle;
|
|
@ -31,6 +31,7 @@ const channelPageStyle = StyleSheet.create({
|
|||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
padding: 24,
|
||||
},
|
||||
infoText: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
|
@ -165,6 +166,9 @@ const channelPageStyle = StyleSheet.create({
|
|||
claimListContent: {
|
||||
paddingTop: 16,
|
||||
},
|
||||
actionButton: {
|
||||
backgroundColor: Colors.White,
|
||||
},
|
||||
});
|
||||
|
||||
export default channelPageStyle;
|
||||
|
|
|
@ -41,8 +41,8 @@ const filePageStyle = StyleSheet.create({
|
|||
fontFamily: 'Inter-UI-Regular',
|
||||
textAlign: 'center',
|
||||
fontSize: 20,
|
||||
marginLeft: 16,
|
||||
marginRight: 16,
|
||||
marginLeft: 24,
|
||||
marginRight: 24,
|
||||
},
|
||||
scrollContainer: {
|
||||
flex: 1,
|
||||
|
|
|
@ -156,6 +156,10 @@ const publishStyle = StyleSheet.create({
|
|||
fontSize: 16,
|
||||
marginLeft: 8,
|
||||
},
|
||||
listEmptyText: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 14,
|
||||
},
|
||||
titleRow: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { NavigationActions, StackActions } from 'react-navigation';
|
||||
import { buildURI, isURIValid, normalizeURI } from 'lbry-redux';
|
||||
import { doPopDrawerStack, doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
|
||||
import Constants, { DrawerRoutes } from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import Constants, { DrawerRoutes, InnerDrawerRoutes } from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
|
||||
const tagNameLength = 10;
|
||||
|
||||
|
@ -156,10 +156,26 @@ export function navigateBack(navigation, drawerStack, popDrawerStack) {
|
|||
const target = drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0];
|
||||
const { route, params } = target;
|
||||
navigation.goBack(navigation.state.key);
|
||||
if (DrawerRoutes.indexOf(route) === -1 && isURIValid(route)) {
|
||||
if (!DrawerRoutes.includes(route) && !InnerDrawerRoutes.includes(route) && isURIValid(route)) {
|
||||
navigateToUri(navigation, route, null, true);
|
||||
} else {
|
||||
navigation.navigate({ routeName: route, params });
|
||||
let targetRoute = route;
|
||||
let targetParams = params;
|
||||
if (InnerDrawerRoutes.includes(route)) {
|
||||
if (Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM === route) {
|
||||
targetRoute = Constants.DRAWER_ROUTE_CHANNEL_CREATOR;
|
||||
} else if (Constants.DRAWER_ROUTE_PUBLISH_FORM === route) {
|
||||
targetRoute = Constants.DRAWER_ROUTE_PUBLISH_FORM;
|
||||
}
|
||||
|
||||
if (targetParams) {
|
||||
targetParams.displayForm = true;
|
||||
} else {
|
||||
targetParams = { displayForm: true };
|
||||
}
|
||||
}
|
||||
|
||||
navigation.navigate({ routeName: targetRoute, targetParams });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,14 +185,31 @@ export function dispatchNavigateBack(dispatch, nav, drawerStack) {
|
|||
const target = drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0];
|
||||
const { route } = target;
|
||||
dispatch(NavigationActions.back());
|
||||
if (DrawerRoutes.indexOf(route) === -1 && isURIValid(route)) {
|
||||
if (!DrawerRoutes.includes(route) && !InnerDrawerRoutes.includes(route) && isURIValid(route)) {
|
||||
dispatchNavigateToUri(dispatch, nav, route, true);
|
||||
} else {
|
||||
const newTarget = drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0];
|
||||
let targetRoute = newTarget.route;
|
||||
let targetParams = newTarget.params;
|
||||
if (InnerDrawerRoutes.includes(targetRoute)) {
|
||||
if (Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM === route) {
|
||||
targetRoute = Constants.DRAWER_ROUTE_CHANNEL_CREATOR;
|
||||
} else if (Constants.DRAWER_ROUTE_PUBLISH_FORM === route) {
|
||||
targetRoute = Constants.DRAWER_ROUTE_PUBLISH_FORM;
|
||||
}
|
||||
|
||||
if (targetParams) {
|
||||
targetParams.displayForm = true;
|
||||
} else {
|
||||
targetParams = { displayForm: true };
|
||||
}
|
||||
}
|
||||
|
||||
const navigateAction = NavigationActions.navigate({
|
||||
routeName: newTarget.route,
|
||||
params: newTarget.params,
|
||||
routeName: targetRoute,
|
||||
params: targetParams,
|
||||
});
|
||||
|
||||
dispatch(navigateAction);
|
||||
}
|
||||
}
|
||||
|
@ -256,3 +289,42 @@ export function transformUrl(url) {
|
|||
export function __(str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
export function uploadImageAsset(filePath, success, failure) {
|
||||
const makeid = () => {
|
||||
let text = '';
|
||||
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
for (let i = 0; i < 24; i += 1) text += possible.charAt(Math.floor(Math.random() * 62));
|
||||
return text;
|
||||
};
|
||||
|
||||
const fileName = filePath.substring(filePath.lastIndexOf('/') + 1);
|
||||
let fileExt = fileName.indexOf('.') > -1 ? fileName.substring(fileName.lastIndexOf('.') + 1).trim() : 0;
|
||||
if (!fileExt) {
|
||||
fileExt = 'jpg'; // default to jpg
|
||||
}
|
||||
const fileType = `image/${fileExt}`;
|
||||
|
||||
const data = new FormData();
|
||||
const name = makeid();
|
||||
data.append('name', name);
|
||||
data.append('file', { uri: 'file://' + filePath, type: fileType, name: fileName });
|
||||
|
||||
return fetch('https://spee.ch/api/claim/publish', {
|
||||
method: 'POST',
|
||||
body: data,
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
if (json.success) {
|
||||
if (success) {
|
||||
success({ url: `${json.data.url}.${fileExt}` });
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
if (failure) {
|
||||
failure(err.message ? err.message : 'The image failed to upload.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue