Compare commits
6 commits
master
...
product-re
Author | SHA1 | Date | |
---|---|---|---|
|
c84f6db099 | ||
|
085c613040 | ||
|
4d181000b0 | ||
|
c3a431b40c | ||
|
9157b18f45 | ||
|
4712b3581b |
14 changed files with 259 additions and 37 deletions
|
@ -214,7 +214,7 @@ const drawer = createDrawerNavigator(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
drawerWidth: 280,
|
drawerWidth: 300,
|
||||||
drawerBackgroundColor: 'transparent',
|
drawerBackgroundColor: 'transparent',
|
||||||
headerMode: 'none',
|
headerMode: 'none',
|
||||||
backBehavior: 'none',
|
backBehavior: 'none',
|
||||||
|
|
|
@ -1,4 +1,18 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { doFetchChannelListMine, selectMyChannelClaims } from 'lbry-redux';
|
||||||
|
import { selectUser } from 'lbryinc';
|
||||||
import DrawerContent from './view';
|
import DrawerContent from './view';
|
||||||
|
|
||||||
export default connect()(DrawerContent);
|
const select = state => ({
|
||||||
|
channels: selectMyChannelClaims(state),
|
||||||
|
user: selectUser(state),
|
||||||
|
});
|
||||||
|
|
||||||
|
const perform = dispatch => ({
|
||||||
|
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(DrawerContent);
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { DrawerItems, SafeAreaView } from 'react-navigation';
|
import { DrawerItems, SafeAreaView } from 'react-navigation';
|
||||||
import { ScrollView, Text, TouchableOpacity, View } from 'react-native';
|
import { Image, ScrollView, Text, TouchableOpacity, View } from 'react-native';
|
||||||
|
import Button from 'component/button';
|
||||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||||
import Icon from 'react-native-vector-icons/FontAwesome5';
|
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||||
|
import channelIconStyle from 'styles/channelIcon';
|
||||||
import discoverStyle from 'styles/discover';
|
import discoverStyle from 'styles/discover';
|
||||||
|
|
||||||
const groupedMenuItems = {
|
const groupedMenuItems = {
|
||||||
|
@ -30,14 +32,73 @@ const groupedMenuItems = {
|
||||||
const groupNames = Object.keys(groupedMenuItems);
|
const groupNames = Object.keys(groupedMenuItems);
|
||||||
|
|
||||||
class DrawerContent extends React.PureComponent {
|
class DrawerContent extends React.PureComponent {
|
||||||
|
componentDidMount() {
|
||||||
|
const { fetchChannelListMine } = this.props;
|
||||||
|
fetchChannelListMine();
|
||||||
|
}
|
||||||
|
|
||||||
|
getAvatarImageUrl = () => {
|
||||||
|
const { channels = [] } = this.props;
|
||||||
|
if (channels) {
|
||||||
|
// get the first channel thumbnail found. In the future, allow the user to select a default channel thumbnail?
|
||||||
|
for (let i = 0; i < channels.length; i++) {
|
||||||
|
if (channels[i].value && channels[i].value.thumbnail) {
|
||||||
|
return channels[i].value.thumbnail.url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
launchSignInFlow = () => {
|
||||||
|
// for now, sync flow (email, then password input) will be the default sign in flow
|
||||||
|
const { navigation } = this.props;
|
||||||
|
navigation.navigate({ routeName: 'Verification', key: 'verification', params: { syncFlow: true } });
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { activeTintColor, navigation, onItemPress } = this.props;
|
const { activeTintColor, navigation, user, onItemPress } = this.props;
|
||||||
const { state } = navigation;
|
const { state } = navigation;
|
||||||
|
|
||||||
const activeItemKey = state.routes[state.index] ? state.routes[state.index].key : null;
|
const activeItemKey = state.routes[state.index] ? state.routes[state.index].key : null;
|
||||||
|
const signedIn = user && user.has_verified_email;
|
||||||
|
const avatarImageUrl = this.getAvatarImageUrl();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={discoverStyle.drawerContentArea}>
|
<View style={discoverStyle.drawerContentArea}>
|
||||||
|
<View style={discoverStyle.signInContainer}>
|
||||||
|
{!signedIn && (
|
||||||
|
<Button
|
||||||
|
style={discoverStyle.signInButton}
|
||||||
|
theme={'light'}
|
||||||
|
text={'Sign in'}
|
||||||
|
onPress={this.launchSignInFlow}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{signedIn && (
|
||||||
|
<View style={discoverStyle.signedIn}>
|
||||||
|
<View style={discoverStyle.signedInAvatar}>
|
||||||
|
{avatarImageUrl && (
|
||||||
|
<Image
|
||||||
|
style={discoverStyle.signedInAvatarImage}
|
||||||
|
resizeMode={'cover'}
|
||||||
|
source={{ uri: avatarImageUrl }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{!avatarImageUrl && (
|
||||||
|
<Text style={channelIconStyle.autothumbCharacter}>
|
||||||
|
{user.primary_email.substring(0, 1).toUpperCase()}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
<Text style={discoverStyle.signedInEmail} numberOfLines={1}>
|
||||||
|
{user.primary_email}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
|
||||||
<ScrollView contentContainerStyle={discoverStyle.menuScrollContent}>
|
<ScrollView contentContainerStyle={discoverStyle.menuScrollContent}>
|
||||||
<SafeAreaView
|
<SafeAreaView
|
||||||
style={discoverStyle.drawerContentContainer}
|
style={discoverStyle.drawerContentContainer}
|
||||||
|
|
|
@ -32,7 +32,7 @@ class RewardEnrolment extends React.Component {
|
||||||
const { fetching, navigation, unclaimedRewardAmount, user } = this.props;
|
const { fetching, navigation, unclaimedRewardAmount, user } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={rewardStyle.enrollContainer} onPress>
|
<View style={rewardStyle.enrollContainer}>
|
||||||
<View style={rewardStyle.summaryRow}>
|
<View style={rewardStyle.summaryRow}>
|
||||||
<Icon name="award" size={36} color={Colors.White} />
|
<Icon name="award" size={36} color={Colors.White} />
|
||||||
<Text style={rewardStyle.summaryText}>{unclaimedRewardAmount} available credits</Text>
|
<Text style={rewardStyle.summaryText}>{unclaimedRewardAmount} available credits</Text>
|
||||||
|
|
19
src/component/walletSignIn/index.js
Normal file
19
src/component/walletSignIn/index.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { doToast } from 'lbry-redux';
|
||||||
|
import { doSetClientSetting } from 'redux/actions/settings';
|
||||||
|
import { selectUser } from 'lbryinc';
|
||||||
|
import WalletSignIn from './view';
|
||||||
|
|
||||||
|
const select = state => ({
|
||||||
|
user: selectUser(state),
|
||||||
|
});
|
||||||
|
|
||||||
|
const perform = dispatch => ({
|
||||||
|
notify: data => dispatch(doToast(data)),
|
||||||
|
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(WalletSignIn);
|
47
src/component/walletSignIn/view.js
Normal file
47
src/component/walletSignIn/view.js
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Linking, NativeModules, Text, TouchableOpacity, View } from 'react-native';
|
||||||
|
import AsyncStorage from '@react-native-community/async-storage';
|
||||||
|
import Button from 'component/button';
|
||||||
|
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||||
|
import Link from 'component/link';
|
||||||
|
import Colors from 'styles/colors';
|
||||||
|
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||||
|
import walletStyle from 'styles/wallet';
|
||||||
|
|
||||||
|
class WalletSignIn extends React.Component {
|
||||||
|
onContinuePressed = () => {
|
||||||
|
const { navigation, setClientSetting } = this.props;
|
||||||
|
setClientSetting(Constants.SETTING_ALPHA_UNDERSTANDS_RISKS, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
onSignInPressed = () => {
|
||||||
|
const { navigation } = this.props;
|
||||||
|
navigation.navigate({ routeName: 'Verification', key: 'verification', params: { syncFlow: true } });
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { navigation, user } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={walletStyle.signInContainer}>
|
||||||
|
<View style={walletStyle.signInSummaryRow}>
|
||||||
|
<Text style={walletStyle.signInTitle}>Sign in</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={walletStyle.onboarding}>
|
||||||
|
<Text style={walletStyle.onboardingText}>
|
||||||
|
An account will allow you to earn rewards and keep your account and settings synced.{'\n\n'}
|
||||||
|
Without an account, you will not receive rewards, sync and backup services, or security updates.{'\n\n'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={walletStyle.buttonRow}>
|
||||||
|
<Link style={walletStyle.continueLink} text={'Continue anyway'} onPress={this.onContinuePressed} />
|
||||||
|
<Button style={walletStyle.signInButton} theme={'light'} text={'Sign in'} onPress={this.onSignInPressed} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WalletSignIn;
|
|
@ -140,6 +140,8 @@ const Constants = {
|
||||||
TRUE_STRING: 'true',
|
TRUE_STRING: 'true',
|
||||||
|
|
||||||
MINIMUM_TRANSACTION_BALANCE: 0.1,
|
MINIMUM_TRANSACTION_BALANCE: 0.1,
|
||||||
|
|
||||||
|
SHARE_BASE_URL: 'https://open.lbry.com',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Constants;
|
export default Constants;
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { TabView, SceneMap } from 'react-native-tab-view';
|
import { TabView, SceneMap } from 'react-native-tab-view';
|
||||||
import { normalizeURI } from 'lbry-redux';
|
import { normalizeURI } from 'lbry-redux';
|
||||||
import { navigateBack, getOrderBy } from 'utils/helper';
|
import { navigateBack, getOrderBy, formatLbryUrlForWeb } from 'utils/helper';
|
||||||
import ChannelIconItem from 'component/channelIconItem';
|
import ChannelIconItem from 'component/channelIconItem';
|
||||||
import ClaimList from 'component/claimList';
|
import ClaimList from 'component/claimList';
|
||||||
import Colors from 'styles/colors';
|
import Colors from 'styles/colors';
|
||||||
|
@ -172,6 +172,15 @@ class ChannelPage extends React.PureComponent {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onSharePressed = () => {
|
||||||
|
const { claim } = this.props;
|
||||||
|
if (claim) {
|
||||||
|
const { canonical_url: canonicalUrl, short_url: shortUrl, permanent_url: permanentUrl } = claim;
|
||||||
|
const url = Constants.SHARE_BASE_URL + formatLbryUrlForWeb(canonicalUrl || shortUrl || permanentUrl);
|
||||||
|
NativeModules.UtilityModule.shareUrl(url);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
onDeletePressed = () => {
|
onDeletePressed = () => {
|
||||||
const { abandonClaim, claim, navigation } = this.props;
|
const { abandonClaim, claim, navigation } = this.props;
|
||||||
if (claim) {
|
if (claim) {
|
||||||
|
@ -274,6 +283,12 @@ class ChannelPage extends React.PureComponent {
|
||||||
onPress={this.onDeletePressed}
|
onPress={this.onDeletePressed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<Button
|
||||||
|
style={[channelPageStyle.actionButton, channelPageStyle.shareButton]}
|
||||||
|
theme={'light'}
|
||||||
|
icon={'share-alt'}
|
||||||
|
onPress={this.onSharePressed}
|
||||||
|
/>
|
||||||
{!ownedChannel && <SubscribeButton style={channelPageStyle.subscribeButton} uri={fullUri} name={name} />}
|
{!ownedChannel && <SubscribeButton style={channelPageStyle.subscribeButton} uri={fullUri} name={name} />}
|
||||||
{!ownedChannel && (
|
{!ownedChannel && (
|
||||||
<SubscribeNotificationButton
|
<SubscribeNotificationButton
|
||||||
|
|
|
@ -19,7 +19,7 @@ import {
|
||||||
WebView,
|
WebView,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { NavigationEvents } from 'react-navigation';
|
import { NavigationEvents } from 'react-navigation';
|
||||||
import { navigateBack, navigateToUri } from 'utils/helper';
|
import { navigateBack, navigateToUri, formatLbryUrlForWeb } from 'utils/helper';
|
||||||
import Icon from 'react-native-vector-icons/FontAwesome5';
|
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||||
import ImageViewer from 'react-native-image-zoom-viewer';
|
import ImageViewer from 'react-native-image-zoom-viewer';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
@ -508,16 +508,11 @@ class FilePage extends React.PureComponent {
|
||||||
this.setState({ fileViewLogged: true });
|
this.setState({ fileViewLogged: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Move this to lbry-redux
|
|
||||||
formatLbryUrlForWeb = url => {
|
|
||||||
return url.replace('lbry://', '/').replace(/#/g, ':');
|
|
||||||
};
|
|
||||||
|
|
||||||
handleSharePress = () => {
|
handleSharePress = () => {
|
||||||
const { claim, notify } = this.props;
|
const { claim, notify } = this.props;
|
||||||
if (claim) {
|
if (claim) {
|
||||||
const { canonical_url: canonicalUrl, short_url: shortUrl, permanent_url: permanentUrl } = claim;
|
const { canonical_url: canonicalUrl, short_url: shortUrl, permanent_url: permanentUrl } = claim;
|
||||||
const url = 'https://open.lbry.com' + this.formatLbryUrlForWeb(canonicalUrl || shortUrl || permanentUrl);
|
const url = Constants.SHARE_BASE_URL + formatLbryUrlForWeb(canonicalUrl || shortUrl || permanentUrl);
|
||||||
NativeModules.UtilityModule.shareUrl(url);
|
NativeModules.UtilityModule.shareUrl(url);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,6 +5,7 @@ import WalletAddress from 'component/walletAddress';
|
||||||
import WalletBalance from 'component/walletBalance';
|
import WalletBalance from 'component/walletBalance';
|
||||||
import WalletSend from 'component/walletSend';
|
import WalletSend from 'component/walletSend';
|
||||||
import WalletRewardsDriver from 'component/walletRewardsDriver';
|
import WalletRewardsDriver from 'component/walletRewardsDriver';
|
||||||
|
import WalletSignIn from 'component/walletSignIn';
|
||||||
import WalletSyncDriver from 'component/walletSyncDriver';
|
import WalletSyncDriver from 'component/walletSyncDriver';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import Link from 'component/link';
|
import Link from 'component/link';
|
||||||
|
@ -66,33 +67,15 @@ class WalletPage extends React.PureComponent {
|
||||||
understandsRisks,
|
understandsRisks,
|
||||||
setClientSetting,
|
setClientSetting,
|
||||||
navigation,
|
navigation,
|
||||||
|
user,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (!understandsRisks) {
|
const signedIn = user && user.has_verified_email;
|
||||||
|
if (!signedIn && !understandsRisks) {
|
||||||
return (
|
return (
|
||||||
<View>
|
<View style={walletStyle.container}>
|
||||||
<UriBar navigation={navigation} />
|
<UriBar navigation={navigation} />
|
||||||
<View style={walletStyle.warning}>
|
<WalletSignIn navigation={navigation} />
|
||||||
<Text style={walletStyle.warningParagraph}>
|
|
||||||
This is beta software. You may lose any credits that you send to your wallet due to software bugs, deleted
|
|
||||||
files, or malicious third-party software. You should not use this wallet as your primary wallet.
|
|
||||||
</Text>
|
|
||||||
{!hasSyncedWallet && (
|
|
||||||
<Text style={walletStyle.warningParagraph}>
|
|
||||||
Since you are not using the LBRY sync service, you will lose all of your credits if you uninstall this
|
|
||||||
application. Instructions on how to enroll as well as how to backup your wallet manually are available
|
|
||||||
on the next page.
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
<Text style={walletStyle.warningText}>
|
|
||||||
If you understand the risks and you wish to continue, please tap the button below.
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
<Button
|
|
||||||
text={'I understand the risks'}
|
|
||||||
style={[walletStyle.button, walletStyle.understand]}
|
|
||||||
onPress={() => setClientSetting(Constants.SETTING_ALPHA_UNDERSTANDS_RISKS, true)}
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,6 +172,10 @@ const channelPageStyle = StyleSheet.create({
|
||||||
deleteButton: {
|
deleteButton: {
|
||||||
marginLeft: 8,
|
marginLeft: 8,
|
||||||
},
|
},
|
||||||
|
shareButton: {
|
||||||
|
marginLeft: 8,
|
||||||
|
marginRight: 8,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default channelPageStyle;
|
export default channelPageStyle;
|
||||||
|
|
|
@ -296,7 +296,7 @@ const discoverStyle = StyleSheet.create({
|
||||||
marginRight: 6,
|
marginRight: 6,
|
||||||
},
|
},
|
||||||
menuScrollContent: {
|
menuScrollContent: {
|
||||||
paddingTop: 16,
|
paddingTop: 12,
|
||||||
},
|
},
|
||||||
menuGroup: {
|
menuGroup: {
|
||||||
marginTop: 8,
|
marginTop: 8,
|
||||||
|
@ -336,6 +336,37 @@ const discoverStyle = StyleSheet.create({
|
||||||
fontFamily: 'Inter-UI-Regular',
|
fontFamily: 'Inter-UI-Regular',
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
},
|
},
|
||||||
|
signInContainer: {
|
||||||
|
backgroundColor: Colors.LbryGreen,
|
||||||
|
height: 140,
|
||||||
|
padding: 16,
|
||||||
|
},
|
||||||
|
signInButton: {
|
||||||
|
backgroundColor: Colors.White,
|
||||||
|
alignSelf: 'flex-start',
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: 16,
|
||||||
|
left: 16,
|
||||||
|
},
|
||||||
|
signedInEmail: {
|
||||||
|
fontFamily: 'Inter-UI-SemiBold',
|
||||||
|
fontSize: 15,
|
||||||
|
color: Colors.White,
|
||||||
|
},
|
||||||
|
signedInAvatar: {
|
||||||
|
backgroundColor: Colors.NextLbryGreen,
|
||||||
|
width: 80,
|
||||||
|
height: 80,
|
||||||
|
marginBottom: 12,
|
||||||
|
borderRadius: 160,
|
||||||
|
overflow: 'hidden',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
signedInAvatarImage: {
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default discoverStyle;
|
export default discoverStyle;
|
||||||
|
|
|
@ -305,6 +305,52 @@ const walletStyle = StyleSheet.create({
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
marginLeft: 8,
|
marginLeft: 8,
|
||||||
},
|
},
|
||||||
|
buttonRow: {
|
||||||
|
width: '100%',
|
||||||
|
position: 'absolute',
|
||||||
|
alignItems: 'center',
|
||||||
|
left: 24,
|
||||||
|
bottom: 24,
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
},
|
||||||
|
continueLink: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
color: Colors.White,
|
||||||
|
},
|
||||||
|
learnMoreLink: {
|
||||||
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
color: Colors.NextLbryGreen,
|
||||||
|
},
|
||||||
|
signInButton: {
|
||||||
|
backgroundColor: Colors.White,
|
||||||
|
paddingLeft: 16,
|
||||||
|
paddingRight: 16,
|
||||||
|
},
|
||||||
|
signInContainer: {
|
||||||
|
flex: 1,
|
||||||
|
marginTop: 60,
|
||||||
|
padding: 24,
|
||||||
|
backgroundColor: Colors.LbryGreen,
|
||||||
|
},
|
||||||
|
onboarding: {
|
||||||
|
marginTop: 36,
|
||||||
|
},
|
||||||
|
onboardingText: {
|
||||||
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
fontSize: 18,
|
||||||
|
lineHeight: 28,
|
||||||
|
color: Colors.White,
|
||||||
|
},
|
||||||
|
signInSummaryRow: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
},
|
||||||
|
signInTitle: {
|
||||||
|
color: Colors.White,
|
||||||
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
fontSize: 28,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default walletStyle;
|
export default walletStyle;
|
||||||
|
|
|
@ -346,3 +346,8 @@ export function uploadImageAsset(filePath, success, failure) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Move this to lbry-redux
|
||||||
|
export function formatLbryUrlForWeb(url) {
|
||||||
|
return url.replace('lbry://', '/').replace(/#/g, ':');
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue