diff --git a/app/src/component/AppNavigator.js b/app/src/component/AppNavigator.js
index 92bc1e60..266683d6 100644
--- a/app/src/component/AppNavigator.js
+++ b/app/src/component/AppNavigator.js
@@ -66,6 +66,7 @@ const discoverStack = createStackNavigator({
navigationOptions: ({ navigation }) => ({
title: 'Discover',
headerLeft: menuNavigationButton(navigation),
+ headerTitleStyle: discoverStyle.titleText
})
},
File: {
@@ -78,7 +79,8 @@ const discoverStack = createStackNavigator({
Search: {
screen: SearchPage,
navigationOptions: ({ navigation }) => ({
- drawerLockMode: 'locked-closed'
+ drawerLockMode: 'locked-closed',
+ headerTitleStyle: discoverStyle.titleText
})
}
}, {
@@ -91,6 +93,7 @@ const trendingStack = createStackNavigator({
navigationOptions: ({ navigation }) => ({
title: 'Trending',
headerLeft: menuNavigationButton(navigation),
+ headerTitleStyle: discoverStyle.titleText
})
}
});
@@ -101,6 +104,7 @@ const myLbryStack = createStackNavigator({
navigationOptions: ({ navigation }) => ({
title: 'My LBRY',
headerLeft: menuNavigationButton(navigation),
+ headerTitleStyle: discoverStyle.titleText
})
}
});
@@ -111,6 +115,7 @@ const rewardsStack = createStackNavigator({
navigationOptions: ({ navigation }) => ({
title: 'Rewards',
headerLeft: menuNavigationButton(navigation),
+ headerTitleStyle: discoverStyle.titleText
})
}
});
@@ -121,13 +126,15 @@ const walletStack = createStackNavigator({
navigationOptions: ({ navigation }) => ({
title: 'Wallet',
headerLeft: menuNavigationButton(navigation),
+ headerTitleStyle: discoverStyle.titleText
})
},
TransactionHistory: {
screen: TransactionHistoryPage,
navigationOptions: {
title: 'Transaction History',
- drawerLockMode: 'locked-closed'
+ drawerLockMode: 'locked-closed',
+ headerTitleStyle: discoverStyle.titleText
}
}
}, {
@@ -162,7 +169,8 @@ const drawer = createDrawerNavigator({
drawerWidth: 300,
headerMode: 'none',
contentOptions: {
- activeTintColor: Colors.LbryGreen
+ activeTintColor: Colors.LbryGreen,
+ labelStyle: discoverStyle.menuText
}
});
diff --git a/app/src/component/walletSend/index.js b/app/src/component/walletSend/index.js
index e57233ea..080f0a66 100644
--- a/app/src/component/walletSend/index.js
+++ b/app/src/component/walletSend/index.js
@@ -8,15 +8,15 @@ import {
} from 'lbry-redux';
import WalletSend from './view';
-const perform = dispatch => ({
- sendToAddress: (address, amount) => dispatch(doSendDraftTransaction(address, amount)),
- notify: (data) => dispatch(doToast(data))
-});
-
const select = state => ({
balance: selectBalance(state),
draftTransaction: selectDraftTransaction(state),
transactionError: selectDraftTransactionError(state),
});
+const perform = dispatch => ({
+ sendToAddress: (address, amount) => dispatch(doSendDraftTransaction(address, amount)),
+ notify: (data) => dispatch(doToast(data))
+});
+
export default connect(select, perform)(WalletSend);
diff --git a/app/src/constants.js b/app/src/constants.js
index 003ec2d0..47645200 100644
--- a/app/src/constants.js
+++ b/app/src/constants.js
@@ -6,6 +6,11 @@ const Constants = {
ACTION_DELETE_COMPLETED_BLOBS: "DELETE_COMPLETED_BLOBS",
ACTION_FIRST_RUN_PAGE_CHANGED: "FIRST_RUN_PAGE_CHANGED",
+
+ PAGE_REWARDS: 'rewards',
+ PAGE_SETTINGS: 'settings',
+ PAGE_TRENDING: 'trending',
+ PAGE_WALLET: 'wallet'
};
export default Constants;
diff --git a/app/src/page/about/index.js b/app/src/page/about/index.js
index e389db20..fd767ed9 100644
--- a/app/src/page/about/index.js
+++ b/app/src/page/about/index.js
@@ -1,4 +1,5 @@
import { connect } from 'react-redux';
+import { doToast } from 'lbry-redux';
import { doFetchAccessToken, selectAccessToken, selectUserEmail } from 'lbryinc';
import AboutPage from './view';
@@ -9,6 +10,7 @@ const select = state => ({
const perform = dispatch => ({
fetchAccessToken: () => dispatch(doFetchAccessToken()),
+ notify: data => dispatch(doToast(data)),
});
export default connect(select, perform)(AboutPage);
\ No newline at end of file
diff --git a/app/src/page/about/view.js b/app/src/page/about/view.js
index 190fe3f1..d67b586a 100644
--- a/app/src/page/about/view.js
+++ b/app/src/page/about/view.js
@@ -33,7 +33,7 @@ class AboutPage extends React.PureComponent {
}
render() {
- const { accessToken, navigation, userEmail } = this.props;
+ const { accessToken, navigation, notify, userEmail } = this.props;
const loading = 'Loading...';
const ver = this.state.versionInfo ? this.state.versionInfo : null;
@@ -75,7 +75,7 @@ class AboutPage extends React.PureComponent {
@@ -102,6 +102,21 @@ class AboutPage extends React.PureComponent {
{this.state.lbryId ? this.state.lbryId : loading}
+
+
+ Logs
+
+ {
+ if (NativeModules.UtilityModule) {
+ NativeModules.UtilityModule.shareLogFile((error) => {
+ if (error) {
+ notify(error);
+ }
+ });
+ }
+ }} />
+
+
);
diff --git a/app/src/page/file/index.js b/app/src/page/file/index.js
index 36256b1b..888a2695 100644
--- a/app/src/page/file/index.js
+++ b/app/src/page/file/index.js
@@ -3,6 +3,7 @@ import {
doFetchFileInfo,
doFetchCostInfoForUri,
doResolveUri,
+ doSendTip,
doToast,
makeSelectIsUriResolving,
makeSelectCostInfoForUri,
@@ -10,6 +11,7 @@ import {
makeSelectClaimForUri,
makeSelectContentTypeForUri,
makeSelectMetadataForUri,
+ selectBalance,
selectBlackListedOutpoints,
} from 'lbry-redux';
import { selectRewardContentClaimIds } from 'lbryinc';
@@ -19,6 +21,7 @@ import FilePage from './view';
const select = (state, props) => {
const selectProps = { uri: props.navigation.state.params.uri };
return {
+ balance: selectBalance(state),
blackListedOutpoints: selectBlackListedOutpoints(state),
claim: makeSelectClaimForUri(selectProps.uri)(state),
isResolvingUri: makeSelectIsUriResolving(selectProps.uri)(state),
@@ -40,6 +43,7 @@ const perform = dispatch => ({
fetchCostInfo: uri => dispatch(doFetchCostInfoForUri(uri)),
notify: data => dispatch(doToast(data)),
resolveUri: uri => dispatch(doResolveUri(uri)),
+ sendTip: (amount, claimId, uri, successCallback, errorCallback) => dispatch(doSendTip(amount, claimId, uri, successCallback, errorCallback)),
stopDownload: (uri, fileInfo) => dispatch(doStopDownloadingFile(uri, fileInfo)),
});
diff --git a/app/src/page/file/view.js b/app/src/page/file/view.js
index b6f2d928..66dd066c 100644
--- a/app/src/page/file/view.js
+++ b/app/src/page/file/view.js
@@ -37,6 +37,8 @@ class FilePage extends React.PureComponent {
title: ''
};
+ tipAmountInput = null;
+
playerBackground = null;
startTime = null;
@@ -55,8 +57,10 @@ class FilePage extends React.PureComponent {
pageSuspended: false,
showImageViewer: false,
showWebView: false,
+ showTipView: false,
playerBgHeight: 0,
playerHeight: 0,
+ tipAmount: null,
uri: null,
stopDownloadConfirmed: false
};
@@ -310,6 +314,21 @@ class FilePage extends React.PureComponent {
this.setState({ fileViewLogged: true });
}
+ handleSendTip = () => {
+ const { claim, balance, navigation, notify, sendTip } = this.props;
+ const { uri } = navigation.state.params;
+ const { tipAmount } = this.state;
+
+ if (tipAmount > balance) {
+ notify({
+ message: 'Insufficient credits',
+ });
+ return;
+ }
+
+ sendTip(tipAmount, claim.claim_id, uri, () => { this.setState({ tipAmount: 0, showTipView: false }) });
+ }
+
render() {
const {
claim,
@@ -378,12 +397,12 @@ class FilePage extends React.PureComponent {
const mediaType = Lbry.getMediaType(contentType);
const isPlayable = mediaType === 'video' || mediaType === 'audio';
const { height, channel_name: channelName, value } = claim;
- const showActions = !this.state.fullscreenMode &&
- !this.state.showImageViewer &&
- !this.state.showWebView &&
- (completed || (fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes));
+ const showActions = !this.state.fullscreenMode && !this.state.showImageViewer && !this.state.showWebView;
+ const showFileActions = (completed || (fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes));
const channelClaimId =
value && value.publisherSignature && value.publisherSignature.certificateId;
+ const canSendTip = this.state.tipAmount > 0;
+
const playerStyle = [filePageStyle.player,
this.state.isLandscape ? filePageStyle.containedPlayerLandscape :
@@ -473,21 +492,29 @@ class FilePage extends React.PureComponent {
onPlaybackStarted={this.onPlaybackStarted}
/>}
- {fileInfo && showActions &&
+ {showActions &&
- {completed && }
- {!completed && fileInfo && !fileInfo.stopped &&
- fileInfo.written_bytes < fileInfo.total_bytes &&
- !this.state.stopDownloadConfirmed &&
-
- }
+ {}
+ {this.state.showTipView &&
+
+
+ this.tipAmountInput = ref}
+ onChangeText={value => this.setState({tipAmount: value})}
+ keyboardType={'numeric'}
+ value={this.state.tipAmount}
+ style={[filePageStyle.input, filePageStyle.tipAmountInput]} />
+ LBC
+
+ this.setState({ showTipView: false })} />
+
+
+ }
)}
{!this.state.fullscreenMode && }
diff --git a/app/src/styles/about.js b/app/src/styles/about.js
index 784bb72f..d5765b77 100644
--- a/app/src/styles/about.js
+++ b/app/src/styles/about.js
@@ -56,7 +56,7 @@ const aboutStyle = StyleSheet.create({
fontSize: 16,
marginBottom: 24
},
- emailPreferencesLink: {
+ listLink: {
color: Colors.LbryGreen,
fontFamily: 'Metropolis-Regular',
fontSize: 15,
diff --git a/app/src/styles/discover.js b/app/src/styles/discover.js
index f18b49e4..c1be9747 100644
--- a/app/src/styles/discover.js
+++ b/app/src/styles/discover.js
@@ -127,6 +127,13 @@ const discoverStyle = StyleSheet.create({
},
rewardTitle: {
flex: 0.9
+ },
+ menuText: {
+ fontFamily: 'Metropolis-Regular',
+ fontSize: 16
+ },
+ titleText: {
+ fontFamily: 'Metropolis-Regular'
}
});
diff --git a/app/src/styles/filePage.js b/app/src/styles/filePage.js
index 76a6955f..5ced62e4 100644
--- a/app/src/styles/filePage.js
+++ b/app/src/styles/filePage.js
@@ -142,6 +142,8 @@ const filePageStyle = StyleSheet.create({
color: '#0c604b'
},
actions: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
paddingLeft: 16,
paddingRight: 16,
paddingTop: 16,
@@ -149,6 +151,9 @@ const filePageStyle = StyleSheet.create({
marginTop: -14,
width: '100%',
},
+ fileActions: {
+ alignSelf: 'flex-end'
+ },
actionButton: {
alignSelf: 'flex-start',
backgroundColor: Colors.White,
@@ -200,10 +205,57 @@ const filePageStyle = StyleSheet.create({
zIndex: 100
},
link: {
- color: Colors.LbryGreen
+ color: Colors.Grey
},
linkTapped: {
color: "rgba(64, 184, 154, .2)"
+ },
+ tipCard: {
+ backgroundColor: Colors.White,
+ position: 'absolute',
+ top: containedMediaHeightWithControls - 16,
+ width: '100%',
+ paddingTop: 8,
+ paddingBottom: 8,
+ paddingLeft: 16,
+ paddingRight: 16
+ },
+ row: {
+ flexDirection: 'row',
+ flex: 1,
+ justifyContent: 'space-between'
+ },
+ amountRow: {
+ flexDirection: 'row',
+ flex: 0.75
+ },
+ button: {
+ backgroundColor: Colors.LbryGreen,
+ alignSelf: 'flex-end',
+ marginBottom: 6
+ },
+ cancelTipLink: {
+ alignSelf: 'flex-end',
+ marginBottom: 14
+ },
+ input: {
+ fontFamily: 'Metropolis-Regular',
+ fontSize: 14
+ },
+ tipAmountInput: {
+ alignSelf: 'flex-start',
+ width: 80,
+ fontSize: 16,
+ letterSpacing: 1
+ },
+ currency: {
+ alignSelf: 'flex-start',
+ marginTop: 17
+ },
+ text: {
+ fontFamily: 'Metropolis-Regular',
+ fontSize: 16,
+ lineHeight: 24
}
});
diff --git a/app/src/styles/pageHeader.js b/app/src/styles/pageHeader.js
index 5a29ff63..44422689 100644
--- a/app/src/styles/pageHeader.js
+++ b/app/src/styles/pageHeader.js
@@ -42,6 +42,7 @@ const pageHeaderStyle = StyleSheet.create({
flexDirection: 'row',
},
titleText: {
+ fontFamily: 'Metropolis-Regular',
fontSize: Platform.OS === 'ios' ? 17 : 20,
fontWeight: Platform.OS === 'ios' ? '700' : '500',
color: 'rgba(0, 0, 0, .9)',
diff --git a/app/src/utils/helper.js b/app/src/utils/helper.js
index 2807e1a7..126b9c8e 100644
--- a/app/src/utils/helper.js
+++ b/app/src/utils/helper.js
@@ -1,6 +1,27 @@
import { NavigationActions, StackActions } from 'react-navigation';
+import Constants from '../constants';
+
+function getRouteForSpecialUri(uri) {
+ let targetRoute;
+ const page = uri.substring(8).trim(); // 'lbry://?'.length == 8
+
+ switch (page) {
+ case Constants.PAGE_REWARDS: targetRoute = 'Rewards'; break;
+ case Constants.PAGE_SETTINGS: targetRoute = 'Settings'; break;
+ case Constants.PAGE_TRENDING: targetRoute = 'TrendingStack'; break;
+ case Constants.PAGE_WALLET: targetRoute = 'WalletStack'; break;
+ default: targetRoute = 'DiscoverStack'; break;
+ }
+
+ return targetRoute;
+}
export function dispatchNavigateToUri(dispatch, nav, uri) {
+ if (uri.startsWith('lbry://?')) {
+ dispatch(NavigationActions.navigate({ routeName: getRouteForSpecialUri(uri) }));
+ return;
+ }
+
const params = { uri };
if (nav && nav.routes && nav.routes.length > 0 && 'Main' === nav.routes[0].routeName) {
const mainRoute = nav.routes[0];
@@ -48,6 +69,11 @@ export function navigateToUri(navigation, uri, additionalParams) {
return;
}
+ if (uri.startsWith('lbry://?')) {
+ navigation.navigate({ routeName: getRouteForSpecialUri(uri) });
+ return;
+ }
+
const params = Object.assign({ uri }, additionalParams);
if ('File' === navigation.state.routeName) {
const stackAction = StackActions.replace({ routeName: 'File', newKey: uri, params });
diff --git a/buildozer.spec.sample b/buildozer.spec.sample
index f35c3755..69e8b9af 100644
--- a/buildozer.spec.sample
+++ b/buildozer.spec.sample
@@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
# (list) Application requirements
# comma seperated e.g. requirements = sqlite3,kivy
-requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, miniupnpc==1.9, gmpy, appdirs==1.4.3, argparse==1.2.1, docopt, base58==1.0.0, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2, pyyaml, qrcode==5.2.2, requests, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, txJSON-RPC, zope.interface==4.3.3, protobuf==3.6.1, keyring==10.4.0, txupnp, git+https://github.com/lbryio/lbryschema.git#egg=lbryschema, git+https://github.com/lbryio/lbry.git@remove-android-helpers#egg=lbrynet, git+https://github.com/lbryio/aioupnp.git#egg=aioupnp, asn1crypto, treq==17.8.0, funcsigs, mock, pbr, pyopenssl, twisted, idna, Automat, hyperlink, PyHamcrest, netifaces, cryptography, aiohttp, multidict==4.5.2, idna_ssl==1.1.0, typing_extensions==3.6.5, yarl, chardet==3.0.4, async_timeout==3.0.1, aiorpcX==0.9.0, asyncio, git+https://github.com/lbryio/torba@997b573aa4223ec6c8c01948cd2df0c6475b5f42#egg=torba, coincurve
+requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, miniupnpc==1.9, gmpy, appdirs==1.4.3, argparse==1.2.1, docopt, base58==1.0.0, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2, pyyaml, qrcode==5.2.2, requests, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, txJSON-RPC, zope.interface==4.3.3, protobuf==3.6.1, keyring==10.4.0, txupnp, git+https://github.com/lbryio/lbryschema.git#egg=lbryschema, git+https://github.com/lbryio/lbry.git@v0.30.4#egg=lbrynet, git+https://github.com/lbryio/aioupnp.git#egg=aioupnp, asn1crypto, treq==17.8.0, funcsigs, mock, pbr, pyopenssl, twisted, idna, Automat, hyperlink, PyHamcrest, netifaces, cryptography, aiohttp, multidict==4.5.2, idna_ssl==1.1.0, typing_extensions==3.6.5, yarl, chardet==3.0.4, async_timeout==3.0.1, aiorpcX==0.9.0, asyncio, git+https://github.com/lbryio/torba#egg=torba, coincurve
# (str) Custom source folders for requirements
# Sets custom source for any requirements with recipes
diff --git a/buildozer.spec.travis b/buildozer.spec.travis
index f35c3755..69e8b9af 100644
--- a/buildozer.spec.travis
+++ b/buildozer.spec.travis
@@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
# (list) Application requirements
# comma seperated e.g. requirements = sqlite3,kivy
-requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, miniupnpc==1.9, gmpy, appdirs==1.4.3, argparse==1.2.1, docopt, base58==1.0.0, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2, pyyaml, qrcode==5.2.2, requests, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, txJSON-RPC, zope.interface==4.3.3, protobuf==3.6.1, keyring==10.4.0, txupnp, git+https://github.com/lbryio/lbryschema.git#egg=lbryschema, git+https://github.com/lbryio/lbry.git@remove-android-helpers#egg=lbrynet, git+https://github.com/lbryio/aioupnp.git#egg=aioupnp, asn1crypto, treq==17.8.0, funcsigs, mock, pbr, pyopenssl, twisted, idna, Automat, hyperlink, PyHamcrest, netifaces, cryptography, aiohttp, multidict==4.5.2, idna_ssl==1.1.0, typing_extensions==3.6.5, yarl, chardet==3.0.4, async_timeout==3.0.1, aiorpcX==0.9.0, asyncio, git+https://github.com/lbryio/torba@997b573aa4223ec6c8c01948cd2df0c6475b5f42#egg=torba, coincurve
+requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, miniupnpc==1.9, gmpy, appdirs==1.4.3, argparse==1.2.1, docopt, base58==1.0.0, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2, pyyaml, qrcode==5.2.2, requests, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, txJSON-RPC, zope.interface==4.3.3, protobuf==3.6.1, keyring==10.4.0, txupnp, git+https://github.com/lbryio/lbryschema.git#egg=lbryschema, git+https://github.com/lbryio/lbry.git@v0.30.4#egg=lbrynet, git+https://github.com/lbryio/aioupnp.git#egg=aioupnp, asn1crypto, treq==17.8.0, funcsigs, mock, pbr, pyopenssl, twisted, idna, Automat, hyperlink, PyHamcrest, netifaces, cryptography, aiohttp, multidict==4.5.2, idna_ssl==1.1.0, typing_extensions==3.6.5, yarl, chardet==3.0.4, async_timeout==3.0.1, aiorpcX==0.9.0, asyncio, git+https://github.com/lbryio/torba#egg=torba, coincurve
# (str) Custom source folders for requirements
# Sets custom source for any requirements with recipes
diff --git a/buildozer.spec.vagrant b/buildozer.spec.vagrant
index 073218f5..812ba239 100644
--- a/buildozer.spec.vagrant
+++ b/buildozer.spec.vagrant
@@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
# (list) Application requirements
# comma seperated e.g. requirements = sqlite3,kivy
-requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, miniupnpc==1.9, gmpy, appdirs==1.4.3, argparse==1.2.1, docopt, base58==1.0.0, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2, pyyaml, qrcode==5.2.2, requests, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, txJSON-RPC, zope.interface==4.3.3, protobuf==3.6.1, keyring==10.4.0, txupnp, git+https://github.com/lbryio/lbryschema.git#egg=lbryschema, git+https://github.com/lbryio/lbry.git#egg=lbrynet, git+https://github.com/lbryio/aioupnp.git#egg=aioupnp, asn1crypto, treq==17.8.0, funcsigs, mock, pbr, pyopenssl, twisted, idna, Automat, hyperlink, PyHamcrest, netifaces, cryptography, aiohttp, aiorpcX==0.9.0, asyncio, git+https://github.com/lbryio/torba#egg=torba, coincurve
+requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, miniupnpc==1.9, gmpy, appdirs==1.4.3, argparse==1.2.1, docopt, base58==1.0.0, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2, pyyaml, qrcode==5.2.2, requests, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, txJSON-RPC, zope.interface==4.3.3, protobuf==3.6.1, keyring==10.4.0, txupnp, git+https://github.com/lbryio/lbryschema.git#egg=lbryschema, git+https://github.com/lbryio/lbry.git#egg=lbrynet, git+https://github.com/lbryio/aioupnp.git#egg=aioupnp, asn1crypto, treq==17.8.0, funcsigs, mock, pbr, pyopenssl, twisted, idna, Automat, hyperlink, PyHamcrest, netifaces, cryptography, aiohttp, aiorpcX==0.9.0, asyncio, git+https://github.com/lbryio/torba@997b573aa4223ec6c8c01948cd2df0c6475b5f42#egg=torba, coincurve
# (str) Custom source folders for requirements
# Sets custom source for any requirements with recipes
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/templates/AndroidManifest.tmpl.xml b/p4a/pythonforandroid/bootstraps/lbry/build/templates/AndroidManifest.tmpl.xml
index 198f4a4d..f96f8d87 100644
--- a/p4a/pythonforandroid/bootstraps/lbry/build/templates/AndroidManifest.tmpl.xml
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/templates/AndroidManifest.tmpl.xml
@@ -140,6 +140,16 @@
{% endif %}
+
+
+
+
diff --git a/src/main/java/io/lbry/browser/reactmodules/UtilityModule.java b/src/main/java/io/lbry/browser/reactmodules/UtilityModule.java
index 84dee733..39ad8143 100644
--- a/src/main/java/io/lbry/browser/reactmodules/UtilityModule.java
+++ b/src/main/java/io/lbry/browser/reactmodules/UtilityModule.java
@@ -2,21 +2,30 @@ package io.lbry.browser.reactmodules;
import android.app.Activity;
import android.content.Context;
+import android.content.Intent;
import android.content.SharedPreferences;
import android.Manifest;
+import android.net.Uri;
import android.os.Build;
+import android.support.v4.content.FileProvider;
import android.telephony.TelephonyManager;
import android.view.View;
import android.view.WindowManager;
+import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
+import java.io.File;
+
import io.lbry.browser.MainActivity;
+import io.lbry.browser.Utils;
public class UtilityModule extends ReactContextBaseJavaModule {
+ private static final String FILE_PROVIDER = "io.lbry.browser.fileprovider";
+
private Context context;
public UtilityModule(ReactApplicationContext reactContext) {
@@ -139,6 +148,30 @@ public class UtilityModule extends ReactContextBaseJavaModule {
}
}
+ @ReactMethod
+ public void shareLogFile(Callback errorCallback) {
+ String logFileName = "lbrynet.log";
+ File logFile = new File(String.format("%s/%s", Utils.getAppInternalStorageDir(context), "lbrynet"), logFileName);
+ if (!logFile.exists()) {
+ errorCallback.invoke("The lbrynet.log file could not be found.");
+ return;
+ }
+
+ try {
+ Uri fileUri = FileProvider.getUriForFile(context, FILE_PROVIDER, logFile);
+ if (fileUri != null) {
+ Intent shareIntent = new Intent();
+ shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ shareIntent.setAction(Intent.ACTION_SEND);
+ shareIntent.setType("text/plain");
+ shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
+ context.startActivity(Intent.createChooser(shareIntent, "Send LBRY log"));
+ }
+ } catch (IllegalArgumentException e) {
+ errorCallback.invoke("The lbrynet.log file cannot be shared due to permission restrictions.");
+ }
+ }
+
private static boolean isEmulator() {
String buildModel = Build.MODEL.toLowerCase();
return (// Check FINGERPRINT
diff --git a/src/main/python/lbrynetservice.py b/src/main/python/lbrynetservice.py
index bb8a1d90..312c56d6 100644
--- a/src/main/python/lbrynetservice.py
+++ b/src/main/python/lbrynetservice.py
@@ -1,14 +1,17 @@
import keyring
-from keyring.backend import KeyringBackend
+import platform
from jnius import autoclass
-from lbrynet.extras.cli import start_daemon
+from keyring.backend import KeyringBackend
+from lbrynet import build_type
+from lbrynet.extras.cli import conf, log_support, check_connection, Daemon, reactor
from lbrynet.extras.daemon.Components import DHT_COMPONENT, HASH_ANNOUNCER_COMPONENT, PEER_PROTOCOL_SERVER_COMPONENT
from lbrynet.extras.daemon.Components import REFLECTOR_COMPONENT
lbrynet_android_utils = autoclass('io.lbry.browser.Utils')
service = autoclass('io.lbry.browser.LbrynetService').serviceInstance
-
+platform.platform = lambda: 'Android %s (API %s)' % (lbrynet_utils.getAndroidRelease(), lbrynet_utils.getAndroidSdk())
+build_type.BUILD = 'dev' if lbrynet_android_utils.isDebug() else 'release'
# Keyring backend
class LbryAndroidKeyring(KeyringBackend):
@@ -34,18 +37,30 @@ def start():
keyring.set_keyring(LbryAndroidKeyring())
private_storage_dir = lbrynet_android_utils.getAppInternalStorageDir(service.getApplicationContext())
- data_dir = f'{private_storage_dir}/lbrynet'
- wallet_dir = f'{private_storage_dir}/lbryum'
- download_dir = f'{lbrynet_android_utils.getInternalStorageDir(service.getApplicationContext())}/Download'
-
- return start_daemon(settings={
- 'components_to_skip': [DHT_COMPONENT, HASH_ANNOUNCER_COMPONENT, PEER_PROTOCOL_SERVER_COMPONENT,
- REFLECTOR_COMPONENT],
+ conf.initialize_settings(
+ data_dir=f'{private_storage_dir}/lbrynet',
+ wallet_dir=f'{private_storage_dir}/lbryum',
+ download_dir=f'{lbrynet_android_utils.getAppExternalStorageDir(service.getApplicationContext())}/Download'
+ )
+ conf.settings.update({
+ 'components_to_skip': [
+ DHT_COMPONENT, HASH_ANNOUNCER_COMPONENT, PEER_PROTOCOL_SERVER_COMPONENT,
+ REFLECTOR_COMPONENT
+ ],
'use_upnp': False,
- # 'use_https': False,
+ # 'use_https': True, # TODO: does this work on android?
# 'use_auth_http': True
- }, data_dir=data_dir, wallet_dir=wallet_dir, download_dir=download_dir)
+ })
+ log_support.configure_logging(conf.settings.get_log_filename(), True, [])
+ log_support.configure_loggly_handler()
+
+ if check_connection():
+ daemon = Daemon()
+ daemon.start_listening()
+ reactor.run()
+ else:
+ print("Not connected to internet, unable to start")
if __name__ == '__main__':
start()
diff --git a/src/main/res/xml/filepaths.xml b/src/main/res/xml/filepaths.xml
new file mode 100644
index 00000000..6c65d1c7
--- /dev/null
+++ b/src/main/res/xml/filepaths.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file