0.8.2 rc (#28)
* enable deletion of downloads on the Library page * tweak suggested subscriptions and library page * pin lbryinc commit hash
This commit is contained in:
parent
a2ee73e23e
commit
4287793d3f
10 changed files with 180 additions and 58 deletions
8
package-lock.json
generated
8
package-lock.json
generated
|
@ -5562,8 +5562,8 @@
|
|||
}
|
||||
},
|
||||
"lbry-redux": {
|
||||
"version": "github:lbryio/lbry-redux#06b65b5bb474bd61aa4a6bcff2047a71575a17b0",
|
||||
"from": "github:lbryio/lbry-redux#06b65b5bb474bd61aa4a6bcff2047a71575a17b0",
|
||||
"version": "github:lbryio/lbry-redux#4f812db1c7cdb4c08c5426d4d3f83023de5d655f",
|
||||
"from": "github:lbryio/lbry-redux#4f812db1c7cdb4c08c5426d4d3f83023de5d655f",
|
||||
"requires": {
|
||||
"proxy-polyfill": "0.1.6",
|
||||
"reselect": "^3.0.0",
|
||||
|
@ -5571,8 +5571,8 @@
|
|||
}
|
||||
},
|
||||
"lbryinc": {
|
||||
"version": "github:lbryio/lbryinc#430c280789a5031c2e49ca5bf8a7d90ccccc4cdb",
|
||||
"from": "github:lbryio/lbryinc#430c280789a5031c2e49ca5bf8a7d90ccccc4cdb",
|
||||
"version": "github:lbryio/lbryinc#17868d948a160af27a375956226f8dd23fa2c37d",
|
||||
"from": "github:lbryio/lbryinc#17868d948a160af27a375956226f8dd23fa2c37d",
|
||||
"requires": {
|
||||
"reselect": "^3.0.0"
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
"base-64": "^0.1.0",
|
||||
"@expo/vector-icons": "^8.1.0",
|
||||
"gfycat-style-urls": "^1.0.3",
|
||||
"lbry-redux": "lbryio/lbry-redux#f6ba006cccf64b059ff9d10b9bd9796383caff98",
|
||||
"lbryinc": "lbryio/lbryinc#430c280789a5031c2e49ca5bf8a7d90ccccc4cdb",
|
||||
"lbry-redux": "lbryio/lbry-redux#4f812db1c7cdb4c08c5426d4d3f83023de5d655f",
|
||||
"lbryinc": "lbryio/lbryinc#17868d948a160af27a375956226f8dd23fa2c37d",
|
||||
"lodash": ">=4.17.11",
|
||||
"merge": ">=1.2.1",
|
||||
"moment": "^2.22.1",
|
||||
|
|
|
@ -38,12 +38,7 @@ export default class Button extends React.PureComponent {
|
|||
);
|
||||
if (solid) {
|
||||
renderIcon = (
|
||||
<Icon
|
||||
name={icon}
|
||||
size={16}
|
||||
color={iconColor || (theme === 'light' ? Colors.DarkGrey : Colors.White)}
|
||||
solid
|
||||
/>
|
||||
<Icon name={icon} size={16} color={iconColor || (theme === 'light' ? Colors.DarkGrey : Colors.White)} solid />
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ class ClaimList extends React.PureComponent {
|
|||
/>
|
||||
{loading && (
|
||||
<View style={claimListStyle.verticalLoading}>
|
||||
<ActivityIndicator size={'small'} color={Colors.LbryGreen} />
|
||||
<ActivityIndicator size={'small'} color={Colors.NextLbryGreen} />
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
@ -240,7 +240,7 @@ class ClaimList extends React.PureComponent {
|
|||
if (loading) {
|
||||
return (
|
||||
<View style={discoverStyle.listLoading}>
|
||||
<ActivityIndicator size={'small'} color={Colors.LbryGreen} />
|
||||
<ActivityIndicator size={'small'} color={Colors.NextLbryGreen} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -65,7 +65,8 @@ class StorageStatsCard extends React.PureComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
if (this.state.totalBytes == 0) {
|
||||
const { fileInfos } = this.props;
|
||||
if (fileInfos.length === 0 || this.state.totalBytes === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class SuggestedSubscriptions extends React.PureComponent {
|
|||
componentDidMount() {
|
||||
const { claimSearch, followedTags } = this.props;
|
||||
const options = {
|
||||
any_tags: followedTags.map(tag => tag.name),
|
||||
any_tags: _.shuffle(followedTags.map(tag => tag.name)).slice(0, 3),
|
||||
page: 1,
|
||||
no_totals: true,
|
||||
claim_type: 'channel',
|
||||
|
@ -34,14 +34,14 @@ class SuggestedSubscriptions extends React.PureComponent {
|
|||
|
||||
const suggestedUris = suggested ? suggested.map(suggested => suggested.uri) : [];
|
||||
return [
|
||||
{
|
||||
title: __('You might like'),
|
||||
data: suggestedUris,
|
||||
},
|
||||
{
|
||||
title: __('Tags you follow'),
|
||||
data: claimSearchUris ? claimSearchUris.filter(uri => !suggestedUris.includes(uri)) : [],
|
||||
},
|
||||
{
|
||||
title: __('You might also like'),
|
||||
data: _.shuffle(suggestedUris),
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
selectIsFetchingFileList,
|
||||
} from 'lbry-redux';
|
||||
import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
|
||||
import { doDeleteFile } from 'redux/actions/file';
|
||||
import { selectCurrentRoute } from 'redux/selectors/drawer';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import DownloadsPage from './view';
|
||||
|
@ -22,6 +23,9 @@ const select = state => ({
|
|||
});
|
||||
|
||||
const perform = dispatch => ({
|
||||
deleteFile: (fileInfo, deleteFromDevice, abandonClaim) => {
|
||||
dispatch(doDeleteFile(fileInfo, deleteFromDevice, abandonClaim));
|
||||
},
|
||||
fetchMyClaims: () => dispatch(doFetchClaimListMine()),
|
||||
fileList: () => dispatch(doFileList()),
|
||||
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_MY_LBRY)),
|
||||
|
|
|
@ -1,7 +1,17 @@
|
|||
import React from 'react';
|
||||
import { Lbry, buildURI, normalizeURI } from 'lbry-redux';
|
||||
import { ActivityIndicator, Button, FlatList, NativeModules, Text, TextInput, View, ScrollView } from 'react-native';
|
||||
import { navigateToUri, uriFromFileInfo } from 'utils/helper';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Alert,
|
||||
Button,
|
||||
FlatList,
|
||||
NativeModules,
|
||||
Text,
|
||||
TextInput,
|
||||
View,
|
||||
ScrollView,
|
||||
} from 'react-native';
|
||||
import { __, navigateToUri, uriFromFileInfo } from 'utils/helper';
|
||||
import Colors from 'styles/colors';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import PageHeader from 'component/pageHeader';
|
||||
|
@ -17,6 +27,12 @@ class DownloadsPage extends React.PureComponent {
|
|||
title: 'Downloads',
|
||||
};
|
||||
|
||||
state = {
|
||||
selectionMode: false,
|
||||
selectedUris: [],
|
||||
selectedClaimsMap: {},
|
||||
};
|
||||
|
||||
didFocusListener;
|
||||
|
||||
componentWillMount() {
|
||||
|
@ -58,40 +74,127 @@ class DownloadsPage extends React.PureComponent {
|
|||
return downloadedUris.filter(uri => !claimUris.includes(uri));
|
||||
};
|
||||
|
||||
getFilteredFileInfos = () => {
|
||||
const { claims, fileInfos } = this.props;
|
||||
const claimUris = claims.map(claim => normalizeURI(`${claim.name}#${claim.claim_id}`));
|
||||
return fileInfos.filter(
|
||||
fileInfo => !claimUris.includes(normalizeURI(`${fileInfo.claim_name}#${fileInfo.claim_id}`))
|
||||
);
|
||||
};
|
||||
|
||||
addOrRemoveItem = (uri, claim) => {
|
||||
const { selectedClaimsMap } = this.state;
|
||||
let selectedUris = [...this.state.selectedUris];
|
||||
|
||||
if (selectedUris.includes(uri)) {
|
||||
delete selectedClaimsMap[uri];
|
||||
selectedUris.splice(selectedUris.indexOf(uri), 1);
|
||||
} else {
|
||||
selectedClaimsMap[uri] = claim;
|
||||
selectedUris.push(uri);
|
||||
}
|
||||
|
||||
this.setState({ selectionMode: selectedUris.length > 0, selectedUris, selectedClaimsMap });
|
||||
};
|
||||
|
||||
handleSelectItem = (uri, claim) => {
|
||||
this.addOrRemoveItem(uri, claim);
|
||||
};
|
||||
|
||||
handleItemLongPress = (uri, claim) => {
|
||||
this.addOrRemoveItem(uri, claim);
|
||||
};
|
||||
|
||||
onExitSelectionMode = () => {
|
||||
this.setState({ selectionMode: false, selectedUris: [], selectedClaimsMap: {} });
|
||||
};
|
||||
|
||||
onDeleteActionPressed = () => {
|
||||
const { deleteFile, fileList } = this.props;
|
||||
const { selectedClaimsMap } = this.state;
|
||||
|
||||
// show confirm alert
|
||||
Alert.alert(
|
||||
__('Delete files'),
|
||||
__('Are you sure you want to delete the selected content?'),
|
||||
[
|
||||
{ text: __('No') },
|
||||
{
|
||||
text: __('Yes'),
|
||||
onPress: () => {
|
||||
const uris = Object.keys(selectedClaimsMap);
|
||||
uris.forEach(uri => {
|
||||
const { txid, nout } = selectedClaimsMap[uri];
|
||||
deleteFile(`${txid}:${nout}`, true);
|
||||
});
|
||||
this.onExitSelectionMode();
|
||||
fileList();
|
||||
},
|
||||
},
|
||||
],
|
||||
{
|
||||
cancelable: true,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { fetching, claims, downloadedUris, fileInfos, navigation } = this.props;
|
||||
const { selectionMode, selectedUris } = this.state;
|
||||
const filteredUris = this.getFilteredUris();
|
||||
const hasDownloads = filteredUris && filteredUris.length > 0;
|
||||
|
||||
return (
|
||||
<View style={downloadsStyle.container}>
|
||||
<UriBar navigation={navigation} />
|
||||
{!fetching && !hasDownloads && (
|
||||
<View style={downloadsStyle.busyContainer}>
|
||||
<Text style={downloadsStyle.noDownloadsText}>
|
||||
You have not watched or downloaded any content from LBRY yet.
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
{fetching && (
|
||||
<View style={downloadsStyle.busyContainer}>
|
||||
<ActivityIndicator size="large" color={Colors.NextLbryGreen} style={downloadsStyle.loading} />
|
||||
</View>
|
||||
)}
|
||||
{!fetching && hasDownloads && (
|
||||
<View style={downloadsStyle.subContainer}>
|
||||
<StorageStatsCard fileInfos={fileInfos} />
|
||||
<UriBar
|
||||
navigation={navigation}
|
||||
selectionMode={selectionMode}
|
||||
selectedItemCount={selectedUris.length}
|
||||
onExitSelectionMode={this.onExitSelectionMode}
|
||||
onDeleteActionPressed={this.onDeleteActionPressed}
|
||||
/>
|
||||
|
||||
<View style={downloadsStyle.subContainer}>
|
||||
{hasDownloads && <StorageStatsCard fileInfos={this.getFilteredFileInfos()} />}
|
||||
{fetching && (
|
||||
<View style={downloadsStyle.busyContainer}>
|
||||
<ActivityIndicator size="large" color={Colors.NextLbryGreen} style={downloadsStyle.loading} />
|
||||
</View>
|
||||
)}
|
||||
{!fetching && !hasDownloads && (
|
||||
<View style={downloadsStyle.busyContainer}>
|
||||
<Text style={downloadsStyle.noDownloadsText}>You do not have any downloaded content on this device.</Text>
|
||||
</View>
|
||||
)}
|
||||
{!fetching && hasDownloads && (
|
||||
<FlatList
|
||||
extraData={this.state}
|
||||
style={downloadsStyle.scrollContainer}
|
||||
contentContainerStyle={downloadsStyle.scrollPadding}
|
||||
renderItem={({ item }) => (
|
||||
<FileListItem style={fileListStyle.item} uri={item} navigation={navigation} autoplay />
|
||||
<FileListItem
|
||||
autoplay
|
||||
key={item}
|
||||
uri={item}
|
||||
style={fileListStyle.item}
|
||||
selected={selectedUris.includes(item)}
|
||||
onPress={claim => {
|
||||
if (selectionMode) {
|
||||
this.handleSelectItem(item, claim);
|
||||
} else {
|
||||
// TODO: when shortUrl is available for my claims, navigate to that URL instead
|
||||
navigateToUri(navigation, item, { autoplay: true });
|
||||
}
|
||||
}}
|
||||
onLongPress={claim => this.handleItemLongPress(item, claim)}
|
||||
navigation={navigation}
|
||||
/>
|
||||
)}
|
||||
data={downloadedUris}
|
||||
keyExtractor={(item, index) => item}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
)}
|
||||
</View>
|
||||
<FloatingWalletBalance navigation={navigation} />
|
||||
</View>
|
||||
);
|
||||
|
|
|
@ -498,9 +498,23 @@ class FilePage extends React.PureComponent {
|
|||
return;
|
||||
}
|
||||
|
||||
sendTip(tipAmount, claim.claim_id, uri, () => {
|
||||
this.setState({ tipAmount: 0, showTipView: false });
|
||||
});
|
||||
const suffix = 'credit' + (tipAmount === 1 ? '' : 's');
|
||||
Alert.alert(
|
||||
'Send tip',
|
||||
`Are you sure you want to tip ${tipAmount} ${suffix}?`,
|
||||
[
|
||||
{ text: 'No' },
|
||||
{
|
||||
text: 'Yes',
|
||||
onPress: () => {
|
||||
sendTip(tipAmount, claim.claim_id, false, () => {
|
||||
this.setState({ tipAmount: 0, showTipView: false });
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
{ cancelable: true }
|
||||
);
|
||||
};
|
||||
|
||||
renderTags = tags => {
|
||||
|
|
|
@ -75,20 +75,25 @@ class PublishesPage extends React.PureComponent {
|
|||
const { selectedClaimsMap } = this.state;
|
||||
|
||||
// show confirm alert
|
||||
Alert.alert(__('Unpublish'), __('Are you sure you want to unpublish the selected content?'), [
|
||||
{ text: __('No') },
|
||||
{
|
||||
text: __('Yes'),
|
||||
onPress: () => {
|
||||
const uris = Object.keys(selectedClaimsMap);
|
||||
uris.forEach(uri => {
|
||||
const { txid, nout } = selectedClaimsMap[uri];
|
||||
abandonClaim(txid, nout);
|
||||
});
|
||||
this.onExitSelectionMode();
|
||||
Alert.alert(
|
||||
__('Unpublish'),
|
||||
__('Are you sure you want to unpublish the selected content?'),
|
||||
[
|
||||
{ text: __('No') },
|
||||
{
|
||||
text: __('Yes'),
|
||||
onPress: () => {
|
||||
const uris = Object.keys(selectedClaimsMap);
|
||||
uris.forEach(uri => {
|
||||
const { txid, nout } = selectedClaimsMap[uri];
|
||||
abandonClaim(txid, nout);
|
||||
});
|
||||
this.onExitSelectionMode();
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
],
|
||||
{ cancelable: true }
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
|
@ -106,7 +111,7 @@ class PublishesPage extends React.PureComponent {
|
|||
/>
|
||||
{fetching && (
|
||||
<View style={publishStyle.centered}>
|
||||
<ActivityIndicator size={'small'} color={Colors.LbryGreen} />
|
||||
<ActivityIndicator size={'large'} color={Colors.NextLbryGreen} />
|
||||
</View>
|
||||
)}
|
||||
|
||||
|
|
Loading…
Reference in a new issue