Next RC #57

Merged
akinwale merged 21 commits from rc-0.9.4 into master 2019-10-17 15:10:49 +02:00
13 changed files with 197 additions and 68 deletions
Showing only changes of commit 2cb393e6ee - Show all commits

View file

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2017-2018 LBRY Inc Copyright (c) 2017-2019 LBRY Inc
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish,distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish,distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

8
package-lock.json generated
View file

@ -5640,8 +5640,8 @@
} }
}, },
"lbry-redux": { "lbry-redux": {
"version": "github:lbryio/lbry-redux#23bcde0539a27fb19bf3a7d87683279194e02046", "version": "github:lbryio/lbry-redux#f06e1e64a8587a183bd7333f628fca821fe81fa4",
"from": "github:lbryio/lbry-redux#23bcde0539a27fb19bf3a7d87683279194e02046", "from": "github:lbryio/lbry-redux#f06e1e64a8587a183bd7333f628fca821fe81fa4",
"requires": { "requires": {
"proxy-polyfill": "0.1.6", "proxy-polyfill": "0.1.6",
"reselect": "^3.0.0", "reselect": "^3.0.0",
@ -5649,8 +5649,8 @@
} }
}, },
"lbryinc": { "lbryinc": {
"version": "github:lbryio/lbryinc#67bb3e215be3f13605c5e3f9f2b0e2fb880724cf", "version": "github:lbryio/lbryinc#02d8571cd7fafd00d1a60f133d884eb8c5f1a306",
"from": "github:lbryio/lbryinc#67bb3e215be3f13605c5e3f9f2b0e2fb880724cf", "from": "github:lbryio/lbryinc#02d8571cd7fafd00d1a60f133d884eb8c5f1a306",
"requires": { "requires": {
"reselect": "^3.0.0" "reselect": "^3.0.0"
} }

View file

@ -0,0 +1,4 @@
import { connect } from 'react-redux';
import ModalSuggestedSubscriptions from './view';
export default connect()(ModalSuggestedSubscriptions);

View file

@ -0,0 +1,26 @@
import React from 'react';
import { ScrollView, Text, TouchableOpacity, View } from 'react-native';
import modalStyle from 'styles/modal';
import subscriptionsStyle from 'styles/subscriptions';
import Button from 'component/button';
import Colors from 'styles/colors';
import SuggestedSubscriptions from 'component/suggestedSubscriptions';
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
import Icon from 'react-native-vector-icons/FontAwesome5';
export default class ModalSuggestedSubcriptions extends React.PureComponent {
render() {
const { navigation, onDonePress, onOverlayPress } = this.props;
return (
<TouchableOpacity style={modalStyle.overlay} activeOpacity={1} onPress={onOverlayPress}>
<TouchableOpacity style={[modalStyle.container, subscriptionsStyle.modalContainer]} activeOpacity={1}>
<SuggestedSubscriptions inModal navigation={navigation} />
<View style={modalStyle.buttons}>
<Button style={modalStyle.doneButton} text={'Done'} onPress={onDonePress} />
</View>
</TouchableOpacity>
</TouchableOpacity>
);
}
}

View file

@ -1,6 +1,7 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doClaimSearch, selectFetchingClaimSearch, selectClaimSearchByQuery, selectFollowedTags } from 'lbry-redux'; import { doClaimSearch, selectFetchingClaimSearch, selectClaimSearchByQuery, selectFollowedTags } from 'lbry-redux';
import { selectSuggestedChannels, selectIsFetchingSuggested } from 'lbryinc'; import { selectSuggestedChannels, selectIsFetchingSuggested } from 'lbryinc';
import { selectShowNsfw } from 'redux/selectors/settings';
import SuggestedSubscriptions from './view'; import SuggestedSubscriptions from './view';
const select = state => ({ const select = state => ({
@ -8,6 +9,7 @@ const select = state => ({
suggested: selectSuggestedChannels(state), suggested: selectSuggestedChannels(state),
loading: selectIsFetchingSuggested(state) || selectFetchingClaimSearch(state), loading: selectIsFetchingSuggested(state) || selectFetchingClaimSearch(state),
claimSearchByQuery: selectClaimSearchByQuery(state), claimSearchByQuery: selectClaimSearchByQuery(state),
showNsfwContent: selectShowNsfw(state),
}); });
const perform = dispatch => ({ const perform = dispatch => ({

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { ActivityIndicator, FlatList, SectionList, Text, View } from 'react-native'; import { ActivityIndicator, SectionList, Text, View } from 'react-native';
import { createNormalizedClaimSearchKey, normalizeURI } from 'lbry-redux'; import { MATURE_TAGS, createNormalizedClaimSearchKey, normalizeURI } from 'lbry-redux';
import { __, navigateToUri } from 'utils/helper'; import { __, navigateToUri } from 'utils/helper';
import SubscribeButton from 'component/subscribeButton'; import SubscribeButton from 'component/subscribeButton';
import SuggestedSubscriptionItem from 'component/suggestedSubscriptionItem'; import SuggestedSubscriptionItem from 'component/suggestedSubscriptionItem';
@ -16,13 +16,16 @@ class SuggestedSubscriptions extends React.PureComponent {
}; };
componentDidMount() { componentDidMount() {
const { claimSearch, followedTags } = this.props; const { claimSearch, followedTags, showNsfwContent } = this.props;
const options = { const options = {
any_tags: _.shuffle(followedTags.map(tag => tag.name)).slice(0, 3), any_tags: _.shuffle(followedTags.map(tag => tag.name)).slice(0, 3),
page: 1, page: 1,
no_totals: true, no_totals: true,
claim_type: 'channel', claim_type: 'channel',
}; };
if (!showNsfwContent) {
options.not_tags = MATURE_TAGS;
}
this.setState({ options }); this.setState({ options });
claimSearch(options); claimSearch(options);
} }
@ -35,7 +38,7 @@ class SuggestedSubscriptions extends React.PureComponent {
const suggestedUris = suggested ? suggested.map(suggested => suggested.uri) : []; const suggestedUris = suggested ? suggested.map(suggested => suggested.uri) : [];
return [ return [
{ {
title: __('Tags you follow'), title: __('Suggested channels'),
data: claimSearchUris ? claimSearchUris.filter(uri => !suggestedUris.includes(uri)) : [], data: claimSearchUris ? claimSearchUris.filter(uri => !suggestedUris.includes(uri)) : [],
}, },
{ {
@ -46,7 +49,7 @@ class SuggestedSubscriptions extends React.PureComponent {
}; };
render() { render() {
const { suggested, loading, navigation } = this.props; const { suggested, inModal, loading, navigation } = this.props;
if (loading) { if (loading) {
return ( return (
@ -58,8 +61,10 @@ class SuggestedSubscriptions extends React.PureComponent {
return ( return (
<SectionList <SectionList
style={subscriptionsStyle.scrollContainer} style={inModal ? subscriptionsStyle.modalScrollContainer : subscriptionsStyle.scrollContainer}
contentContainerStyle={subscriptionsStyle.suggestedScrollPadding} contentContainerStyle={
inModal ? subscriptionsStyle.modalSuggestedScrollContent : subscriptionsStyle.suggestedScrollContent
}
renderItem={({ item, index, section }) => ( renderItem={({ item, index, section }) => (
<SuggestedSubscriptionItem key={item} uri={normalizeURI(item)} navigation={navigation} /> <SuggestedSubscriptionItem key={item} uri={normalizeURI(item)} navigation={navigation} />
)} )}

View file

@ -61,11 +61,10 @@ class DiscoverPage extends React.PureComponent {
} }
}); });
const { sortByItem, fetchRewardedContent, fetchSubscriptions, fileList, followedTags } = this.props; const { sortByItem, fetchRewardedContent, fileList, followedTags } = this.props;
this.buildTagCollection(followedTags); this.buildTagCollection(followedTags);
fetchRewardedContent(); fetchRewardedContent();
fetchSubscriptions();
fileList(); fileList();
this.handleSortByItemSelected(sortByItem); this.handleSortByItemSelected(sortByItem);
@ -88,9 +87,11 @@ class DiscoverPage extends React.PureComponent {
} }
onComponentFocused = () => { onComponentFocused = () => {
const { pushDrawerStack } = this.props; const { fetchSubscriptions, pushDrawerStack } = this.props;
// pushDrawerStack(); // pushDrawerStack();
NativeModules.Firebase.setCurrentScreen('Your tags'); NativeModules.Firebase.setCurrentScreen('Your tags').then(result => {
fetchSubscriptions();
});
}; };
handleSortByItemSelected = item => { handleSortByItemSelected = item => {
@ -127,44 +128,39 @@ class DiscoverPage extends React.PureComponent {
const { unreadSubscriptions, enabledChannelNotifications } = this.props; const { unreadSubscriptions, enabledChannelNotifications } = this.props;
const utility = NativeModules.UtilityModule; const utility = NativeModules.UtilityModule;
if (utility) { const hasUnread =
const hasUnread = prevProps.unreadSubscriptions &&
prevProps.unreadSubscriptions && prevProps.unreadSubscriptions.length !== unreadSubscriptions.length &&
prevProps.unreadSubscriptions.length !== unreadSubscriptions.length && unreadSubscriptions.length > 0;
unreadSubscriptions.length > 0;
if (hasUnread) { if (hasUnread) {
unreadSubscriptions.map(({ channel, uris }) => { unreadSubscriptions.map(({ channel, uris }) => {
const { claimName: channelName } = parseURI(channel); const { claimName: channelName } = parseURI(channel);
// check if notifications are enabled for the channel // check if notifications are enabled for the channel
if (enabledChannelNotifications.indexOf(channelName) > -1) { if (enabledChannelNotifications.includes(channelName)) {
uris.forEach(uri => { uris.forEach(uri => {
Lbry.resolve({ urls: uri }).then(result => { Lbry.resolve({ urls: uri }).then(result => {
const sub = result[uri].claim; const sub = result[uri];
if (sub && sub.value && sub.value.stream) {
let isPlayable = false; if (sub && sub.value) {
const source = sub.value.stream.source; const { source, title, thumbnail } = sub.value;
const metadata = sub.value.stream.metadata; const isPlayable =
if (source) { source && source.media_type && ['audio', 'video'].includes(source.media_type.substring(0, 5));
isPlayable = if (title) {
source.contentType && ['audio', 'video'].indexOf(source.contentType.substring(0, 5)) > -1; utility.showNotificationForContent(
} uri,
if (metadata) { title,
utility.showNotificationForContent( channelName,
uri, thumbnail ? thumbnail.url : null,
metadata.title, isPlayable
channelName, );
metadata.thumbnail,
isPlayable
);
}
} }
}); }
}); });
} });
}); }
} });
} }
} }

View file

@ -6,6 +6,7 @@ import {
Alert, Alert,
DeviceEventEmitter, DeviceEventEmitter,
Dimensions, Dimensions,
Linking,
NativeModules, NativeModules,
ScrollView, ScrollView,
StatusBar, StatusBar,
@ -968,6 +969,12 @@ class FilePage extends React.PureComponent {
onPress={this.onSaveFilePressed} onPress={this.onSaveFilePressed}
/> />
)} )}
<Button
style={[filePageStyle.actionButton, filePageStyle.reportButton]}
theme={'light'}
icon={'flag'}
onPress={() => Linking.openURL(`https://lbry.com/dmca/${claim.claim_id}`)}
/>
<Button <Button
style={[filePageStyle.actionButton, filePageStyle.tipButton]} style={[filePageStyle.actionButton, filePageStyle.tipButton]}
theme={'light'} theme={'light'}

View file

@ -12,7 +12,7 @@ import {
View, View,
} from 'react-native'; } from 'react-native';
import Colors from 'styles/colors'; import Colors from 'styles/colors';
import Constants from 'constants'; 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 firstRunStyle from 'styles/firstRun'; import firstRunStyle from 'styles/firstRun';
@ -45,8 +45,8 @@ class SkipAccountPage extends React.PureComponent {
/> />
</View> </View>
<Text style={firstRunStyle.rowParagraph}> <Text style={firstRunStyle.rowParagraph}>
I understand that by uninstalling LBRY I will lose any balances or published content with no recovery I understand that by uninstalling LBRY I will lose any balances or published content with no recovery option
option. if it is not backed up manually (see wallet page)
</Text> </Text>
</View> </View>
</View> </View>

View file

@ -25,6 +25,7 @@ import FileItem from 'component/fileItem';
import Icon from 'react-native-vector-icons/FontAwesome5'; import Icon from 'react-native-vector-icons/FontAwesome5';
import Link from 'component/link'; import Link from 'component/link';
import ModalPicker from 'component/modalPicker'; import ModalPicker from 'component/modalPicker';
import ModalSuggestedSubscriptions from 'component/modalSuggestedSubscriptions';
import SubscribedChannelList from 'component/subscribedChannelList'; import SubscribedChannelList from 'component/subscribedChannelList';
import SuggestedSubscriptions from 'component/suggestedSubscriptions'; import SuggestedSubscriptions from 'component/suggestedSubscriptions';
import UriBar from 'component/uriBar'; import UriBar from 'component/uriBar';
@ -34,6 +35,7 @@ class SubscriptionsPage extends React.PureComponent {
showingSuggestedSubs: false, showingSuggestedSubs: false,
showSortPicker: false, showSortPicker: false,
showTimePicker: false, showTimePicker: false,
showModalSuggestedSubs: false,
orderBy: ['release_time'], orderBy: ['release_time'],
filteredChannels: [], filteredChannels: [],
currentSortByItem: Constants.CLAIM_SEARCH_SORT_BY_ITEMS[1], // should always default to sorting subscriptions by new currentSortByItem: Constants.CLAIM_SEARCH_SORT_BY_ITEMS[1], // should always default to sorting subscriptions by new
@ -122,7 +124,7 @@ class SubscriptionsPage extends React.PureComponent {
unreadSubscriptions, unreadSubscriptions,
navigation, navigation,
} = this.props; } = this.props;
const { currentSortByItem, filteredChannels, showSortPicker, showTimePicker } = this.state; const { currentSortByItem, filteredChannels, showModalSuggestedSubs, showSortPicker, showTimePicker } = this.state;
const numberOfSubscriptions = subscribedChannels ? subscribedChannels.length : 0; const numberOfSubscriptions = subscribedChannels ? subscribedChannels.length : 0;
const hasSubscriptions = numberOfSubscriptions > 0; const hasSubscriptions = numberOfSubscriptions > 0;
@ -151,23 +153,31 @@ class SubscriptionsPage extends React.PureComponent {
</View> </View>
{!this.state.showingSuggestedSubs && hasSubscriptions && ( {!this.state.showingSuggestedSubs && hasSubscriptions && (
<View style={subscriptionsStyle.pickerRow}> <View style={subscriptionsStyle.pickerRow}>
<TouchableOpacity <View style={subscriptionsStyle.leftPickerRow}>
style={subscriptionsStyle.tagSortBy}
onPress={() => this.setState({ showSortPicker: true })}
>
<Text style={subscriptionsStyle.tagSortText}>{currentSortByItem.label.split(' ')[0]}</Text>
<Icon style={subscriptionsStyle.tagSortIcon} name={'sort-down'} size={14} />
</TouchableOpacity>
{Constants.SORT_BY_TOP === currentSortByItem.name && (
<TouchableOpacity <TouchableOpacity
style={subscriptionsStyle.tagSortBy} style={subscriptionsStyle.tagSortBy}
onPress={() => this.setState({ showTimePicker: true })} onPress={() => this.setState({ showSortPicker: true })}
> >
<Text style={subscriptionsStyle.tagSortText}>{timeItem.label}</Text> <Text style={subscriptionsStyle.tagSortText}>{currentSortByItem.label.split(' ')[0]}</Text>
<Icon style={subscriptionsStyle.tagSortIcon} name={'sort-down'} size={14} /> <Icon style={subscriptionsStyle.tagSortIcon} name={'sort-down'} size={14} />
</TouchableOpacity> </TouchableOpacity>
)}
{Constants.SORT_BY_TOP === currentSortByItem.name && (
<TouchableOpacity
style={subscriptionsStyle.tagSortBy}
onPress={() => this.setState({ showTimePicker: true })}
>
<Text style={subscriptionsStyle.tagSortText}>{timeItem.label}</Text>
<Icon style={subscriptionsStyle.tagSortIcon} name={'sort-down'} size={14} />
</TouchableOpacity>
)}
</View>
<Link
style={subscriptionsStyle.suggestedLink}
text={'Suggested'}
onPress={() => this.setState({ showModalSuggestedSubs: true })}
/>
</View> </View>
)} )}
{!this.state.showingSuggestedSubs && hasSubscriptions && !loading && ( {!this.state.showingSuggestedSubs && hasSubscriptions && !loading && (
@ -223,7 +233,9 @@ class SubscriptionsPage extends React.PureComponent {
</View> </View>
)} )}
{!showSortPicker && !showTimePicker && <FloatingWalletBalance navigation={navigation} />} {!showSortPicker && !showTimePicker && !showModalSuggestedSubs && (
<FloatingWalletBalance navigation={navigation} />
)}
{showSortPicker && ( {showSortPicker && (
<ModalPicker <ModalPicker
title={__('Sort content by')} title={__('Sort content by')}
@ -242,6 +254,13 @@ class SubscriptionsPage extends React.PureComponent {
items={Constants.CLAIM_SEARCH_TIME_ITEMS} items={Constants.CLAIM_SEARCH_TIME_ITEMS}
/> />
)} )}
{showModalSuggestedSubs && (
<ModalSuggestedSubscriptions
navigation={navigation}
onOverlayPress={() => this.setState({ showModalSuggestedSubs: false })}
onDonePress={() => this.setState({ showModalSuggestedSubs: false })}
/>
)}
</View> </View>
); );
} }

View file

@ -322,6 +322,9 @@ const filePageStyle = StyleSheet.create({
saveFileButton: { saveFileButton: {
marginRight: 8, marginRight: 8,
}, },
reportButton: {
marginRight: 8,
},
tagContainer: { tagContainer: {
marginLeft: 12, marginLeft: 12,
marginRight: 12, marginRight: 12,

48
src/styles/modal.js Normal file
View file

@ -0,0 +1,48 @@
import { StyleSheet } from 'react-native';
import Colors from './colors';
const modalPickerStyle = StyleSheet.create({
overlay: {
backgroundColor: '#00000055',
flex: 1,
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
zIndex: 300,
},
overlayTouchArea: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
},
container: {
position: 'absolute',
left: 8,
right: 8,
bottom: 8,
borderRadius: 8,
backgroundColor: Colors.White,
overflow: 'hidden',
},
paddedContatiner: {
padding: 12,
},
buttons: {
marginTop: 16,
left: 8,
bottom: 8,
position: 'absolute',
},
doneButton: {
alignSelf: 'flex-start',
backgroundColor: Colors.LbryGreen,
paddingLeft: 16,
paddingRight: 16,
},
});
export default modalPickerStyle;

View file

@ -13,7 +13,7 @@ const subscriptionsStyle = StyleSheet.create({
suggestedSubsContainer: { suggestedSubsContainer: {
flex: 1, flex: 1,
}, },
suggestedScrollPadding: { suggestedScrollContent: {
paddingTop: 8, paddingTop: 8,
}, },
button: { button: {
@ -159,6 +159,7 @@ const subscriptionsStyle = StyleSheet.create({
pickerRow: { pickerRow: {
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
justifyContent: 'space-between',
marginLeft: 16, marginLeft: 16,
marginRight: 16, marginRight: 16,
marginTop: 8, marginTop: 8,
@ -245,6 +246,24 @@ const subscriptionsStyle = StyleSheet.create({
marginRight: 4, marginRight: 4,
marginBottom: 4, marginBottom: 4,
}, },
leftPickerRow: {
flexDirection: 'row',
alignItems: 'center',
},
suggestedLink: {
fontFamily: 'Inter-UI-Regular',
fontSize: 14,
},
modalContainer: {
height: '80%',
backgroundColor: Colors.PageBackground,
},
modalScrollContainer: {
marginBottom: 50,
},
modalSuggestedScrollContent: {
paddingTop: 16,
},
}); });
export default subscriptionsStyle; export default subscriptionsStyle;