Skip to content

Commit

Permalink
Add release list filters (None, on watch list, downloaded)
Browse files Browse the repository at this point in the history
  • Loading branch information
Leapward-Koex committed May 3, 2022
1 parent 0f2326c commit f2dd6b1
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 33 deletions.
8 changes: 8 additions & 0 deletions HelperFunctions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ export function humanFileSize(bytes: number, si = false, dp = 1) {
return bytes.toFixed(dp) + ' ' + units[u];
}

export async function asyncFilter<T>(
arr: T[],
predicate: (value: T) => Promise<boolean>,
) {
const results = await Promise.all(arr.map(predicate));
return arr.filter((_v, index) => results[index]);
}

interface FilePathModuleInterface {
getFolderPathFromUri(
contentUri: string,
Expand Down
121 changes: 99 additions & 22 deletions components/ReleaseHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,123 @@
import * as React from 'react';
import {View, Keyboard, useWindowDimensions} from 'react-native';
import {Appbar, Button, Searchbar} from 'react-native-paper';
import {Appbar, Button, Dialog, Portal, Searchbar} from 'react-native-paper';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import {RadioButton} from 'react-native-paper';
import AsyncStorage from '@react-native-async-storage/async-storage';

interface ReleaseTabHeaderProps {
onSearchChanged: (query: string) => void;
onSearchCancelled: () => void;
onFilterChanged: (filter: ShowFilter) => void;
}
export const ReleaseTabHeader = (props: ReleaseTabHeaderProps) => {
const {onSearchChanged, onSearchCancelled} = props;

export enum ShowFilter {
None = '0',
Downloaded = '1',
Watching = '2',
}

export const ReleaseTabHeader = ({
onSearchChanged,
onSearchCancelled,
onFilterChanged,
}: ReleaseTabHeaderProps) => {
const {width} = useWindowDimensions();
const [searchQuery, setSearchQuery] = React.useState('');
const [filterPanelShown, setFilterPanelShown] = React.useState(false);
const [checked, setChecked] = React.useState(ShowFilter.None);

const onChangeText = (query: string) => {
onSearchChanged(query);
setSearchQuery(query);
};

const onBackButtonPressed = () => {
const onBackButtonPressed = async () => {
onSearchCancelled();
setSearchQuery('');
Keyboard.dismiss();
const lastFilter = (await AsyncStorage.getItem(
'headerFilter',
)) as ShowFilter | null;
if (lastFilter) {
setChecked(lastFilter);
onFilterChanged(lastFilter);
}
};

const onFilterPressed = async (filterValue: ShowFilter) => {
setChecked(filterValue);
onFilterChanged(filterValue);
await AsyncStorage.setItem('headerFilter', filterValue);
};

const toggleFilterPanel = () => {
setFilterPanelShown(!filterPanelShown);
};

React.useEffect(() => {
(async () => {
const lastFilter = (await AsyncStorage.getItem(
'headerFilter',
)) as ShowFilter | null;
if (lastFilter) {
setChecked(lastFilter);
onFilterChanged(lastFilter);
}
})();
}, [onFilterChanged]);

return (
<Appbar.Header statusBarHeight={1}>
<View style={{display: 'flex', flexDirection: 'row'}}>
<Button
mode="text"
compact
contentStyle={{flexDirection: 'row-reverse'}}
style={{paddingTop: 5}}
onPress={onBackButtonPressed}>
<Icon name="arrow-left" size={24} color="#fff" />
</Button>
<Searchbar
placeholder="Search"
onChangeText={onChangeText}
value={searchQuery}
style={{flexGrow: 1, width: width - 50}}
/>
</View>
</Appbar.Header>
<>
<Appbar.Header statusBarHeight={1}>
<View style={{display: 'flex', flexDirection: 'row'}}>
<Button
mode="text"
compact
contentStyle={{flexDirection: 'row-reverse'}}
style={{paddingTop: 5}}
onPress={onBackButtonPressed}>
<Icon name="arrow-left" size={24} color="#fff" />
</Button>
<Searchbar
placeholder="Search"
onChangeText={onChangeText}
value={searchQuery}
style={{flexGrow: 1, width: width - 100}}
/>
<Button
mode="text"
compact
contentStyle={{flexDirection: 'row-reverse'}}
style={{paddingTop: 5}}
onPress={toggleFilterPanel}>
<Icon name="filter-variant" size={24} color="#fff" />
</Button>
</View>
</Appbar.Header>
<Portal>
<Dialog visible={filterPanelShown} onDismiss={toggleFilterPanel}>
<Dialog.Title>Filter</Dialog.Title>
<Dialog.Content>
<RadioButton.Group
onValueChange={value => onFilterPressed(value as ShowFilter)}
value={checked}>
<RadioButton.Item label="No filter" value={ShowFilter.None} />
<RadioButton.Item
label="Watching shows"
value={ShowFilter.Watching}
/>
<RadioButton.Item
label="Downloaded shows"
value={ShowFilter.Downloaded}
/>
</RadioButton.Group>
</Dialog.Content>
<Dialog.Actions>
<Button onPress={toggleFilterPanel}>Done</Button>
</Dialog.Actions>
</Dialog>
</Portal>
</>
);
};
36 changes: 34 additions & 2 deletions components/ReleasesTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import {Appearance} from 'react-native-appearance';
import {ShowInfo, WatchList} from '../models/models';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {StorageKeys} from '../enums/enum';
import {ReleaseTabHeader} from './ReleaseHeader';
import {ReleaseTabHeader, ShowFilter} from './ReleaseHeader';
import {SubsPleaseApi} from '../SubsPleaseApi';
import debounce from 'lodash.debounce';
import {downloadedShows} from '../services/DownloadedShows';
import {asyncFilter} from '../HelperFunctions';

type ReleaseTabProps = {
shows: ShowInfo[];
Expand All @@ -23,6 +25,8 @@ export const ReleasesTab = ({
const {colors} = useTheme();
const [watchList, setWatchList] = React.useState<WatchList>();
const [showList, setShowList] = React.useState(shows);
const [filteredShowList, setFilteredShowList] = React.useState(shows);
const [showFilter, setShowFilter] = React.useState(ShowFilter.None);

const scrollY = React.useRef(new Animated.Value(0)).current;
const {height} = useWindowDimensions();
Expand All @@ -44,6 +48,33 @@ export const ReleasesTab = ({
})();
}, []);

React.useEffect(() => {
(async () => {
const getFilteredList = async () => {
if (showFilter === ShowFilter.Downloaded) {
return asyncFilter(showList, async show => {
const downloadedEpisodesForSeries = await asyncFilter(
show.downloads,
async download =>
(download.res === '720' || download.res === '1080') &&
(await downloadedShows.isShowDownloaded(
show.show,
download.magnet,
)),
);
return downloadedEpisodesForSeries.length > 0;
});
} else if (showFilter === ShowFilter.Watching) {
const watchingShowNames =
watchList?.shows.map(show => show.showName) ?? [];
return showList.filter(show => watchingShowNames.includes(show.show));
}
return showList;
};
setFilteredShowList(await getFilteredList());
})();
}, [showFilter, showList, watchList?.shows]);

const onWatchListChanged = (updatedWatchList: WatchList) => {
setWatchList({...updatedWatchList});
AsyncStorage.setItem(
Expand Down Expand Up @@ -73,10 +104,11 @@ export const ReleasesTab = ({
<ReleaseTabHeader
onSearchChanged={debounceSearchHandler}
onSearchCancelled={onSearchCancelled}
onFilterChanged={filterValue => setShowFilter(filterValue)}
/>
<Animated.FlatList
style={backgroundStyle}
data={showList}
data={filteredShowList}
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {y: scrollY}}}],
{useNativeDriver: true},
Expand Down
11 changes: 2 additions & 9 deletions components/settingsPageComponents/SettingsDivider.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import * as React from 'react';
import {Animated, SafeAreaView, useWindowDimensions, View} from 'react-native';
import {Text, useTheme} from 'react-native-paper';
import {ReleaseShow} from '../ReleaseShow';
import {useWindowDimensions, View} from 'react-native';
import {useTheme} from 'react-native-paper';
import {Appearance} from 'react-native-appearance';
import {ShowInfo, WatchList} from '../../models/models';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {StorageKeys} from '../../enums/enum';
import {ReleaseTabHeader} from '../ReleaseHeader';
import {SubsPleaseApi} from '../../SubsPleaseApi';
import debounce from 'lodash.debounce';

export const SettingsDivider = () => {
const {colors} = useTheme();
Expand Down

0 comments on commit f2dd6b1

Please sign in to comment.