Compare commits
2 commits
0e9f53a9b9
...
b45fc9a025
Author | SHA1 | Date | |
---|---|---|---|
b45fc9a025 | |||
c615b2e0c1 |
3 changed files with 55 additions and 22 deletions
|
@ -21,19 +21,8 @@ function Remote() {
|
||||||
export default function ComicList() {
|
export default function ComicList() {
|
||||||
return (
|
return (
|
||||||
<Tab.Navigator
|
<Tab.Navigator
|
||||||
screenOptions={({ navigation, route }) => {
|
screenOptions={({ route }) => {
|
||||||
return {
|
return {
|
||||||
headerRight: () => (
|
|
||||||
<View style={styles.padding}>
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={() => {
|
|
||||||
navigation.push("OldHome");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<MaterialCommunityIcons name="cog" size={24} style={{ color: "black" }} />
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
),
|
|
||||||
tabBarIcon: (({ focused, size, color }) => {
|
tabBarIcon: (({ focused, size, color }) => {
|
||||||
const iconName = route.name === 'Local'
|
const iconName = route.name === 'Local'
|
||||||
? (focused ? 'download' : 'download-outline')
|
? (focused ? 'download' : 'download-outline')
|
||||||
|
@ -48,9 +37,3 @@ export default function ComicList() {
|
||||||
</Tab.Navigator>
|
</Tab.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
padding: {
|
|
||||||
paddingEnd: 16,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { FC } from "react"
|
import { FC, useEffect } from "react"
|
||||||
import { ActivityIndicator, FlatList, StyleSheet, Text, View } from "react-native"
|
import { ActivityIndicator, FlatList, StyleSheet, Text, TouchableOpacity, View } from "react-native"
|
||||||
import Touchable from "../../components/Touchable";
|
import Touchable from "../../components/Touchable";
|
||||||
import ComicCard from '../../components/ComicCard';
|
import ComicCard from '../../components/ComicCard';
|
||||||
import { ComicMetadata, useLocalComics } from "../../provider"
|
import { ComicMetadata, useLocalComics } from "../../provider"
|
||||||
|
@ -9,6 +9,8 @@ import { TabParamList } from "../comiclist";
|
||||||
import { NativeStackNavigationProp } from "@react-navigation/native-stack";
|
import { NativeStackNavigationProp } from "@react-navigation/native-stack";
|
||||||
import { RootStackParamList } from "../../../App";
|
import { RootStackParamList } from "../../../App";
|
||||||
import { LocalComicId } from "../../provider/local";
|
import { LocalComicId } from "../../provider/local";
|
||||||
|
import { useQueryClient } from "react-query";
|
||||||
|
import { MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons";
|
||||||
|
|
||||||
export type ComicListNavigationProp = CompositeNavigationProp<
|
export type ComicListNavigationProp = CompositeNavigationProp<
|
||||||
BottomTabNavigationProp<TabParamList, 'Local'>,
|
BottomTabNavigationProp<TabParamList, 'Local'>,
|
||||||
|
@ -24,9 +26,36 @@ const Comic: FC<ComicMetadata & { onClick: () => void }> = (props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function LocalComicList() {
|
export default function LocalComicList() {
|
||||||
|
const client = useQueryClient();
|
||||||
|
const navigator = useNavigation<ComicListNavigationProp>();
|
||||||
const { data, error, isLoading } = useLocalComics();
|
const { data, error, isLoading } = useLocalComics();
|
||||||
const navigation = useNavigation<ComicListNavigationProp>();
|
const navigation = useNavigation<ComicListNavigationProp>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
navigator.setOptions({
|
||||||
|
headerRight: () => <View style={styles.iconRow}>
|
||||||
|
<View style={styles.padding}>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => {
|
||||||
|
navigation.push("OldHome");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MaterialCommunityIcons name="cog" size={24} style={{ color: "black" }} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
<View style={styles.padding}>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => {
|
||||||
|
client.invalidateQueries('localComics');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MaterialCommunityIcons name="refresh" size={24} style={{ color: "black" }} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
});
|
||||||
|
}, [client]);
|
||||||
|
|
||||||
if (isLoading) return <ActivityIndicator />;
|
if (isLoading) return <ActivityIndicator />;
|
||||||
if (error) return <Text>Failed to load comic: {error.toString()}</Text>;
|
if (error) return <Text>Failed to load comic: {error.toString()}</Text>;
|
||||||
if (!data) return <Text>Whoops! We couldn't find that comic :/</Text>;
|
if (!data) return <Text>Whoops! We couldn't find that comic :/</Text>;
|
||||||
|
@ -38,11 +67,32 @@ export default function LocalComicList() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.length === 0) {
|
||||||
|
return <View style={styles.center}>
|
||||||
|
<MaterialIcons name='sentiment-dissatisfied' size={32} color='#666' />
|
||||||
|
<Text style={styles.noComicsText}>You don't have any comics downloaded</Text>
|
||||||
|
</View>
|
||||||
|
}
|
||||||
|
|
||||||
return <FlatList data={data} renderItem={({ item }) => <Comic onClick={() => openComic(item.id)} {...item} />} keyExtractor={item => item.id} />
|
return <FlatList data={data} renderItem={({ item }) => <Comic onClick={() => openComic(item.id)} {...item} />} keyExtractor={item => item.id} />
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
center: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
noComicsText: {
|
||||||
|
color: '#666',
|
||||||
|
},
|
||||||
comic: {
|
comic: {
|
||||||
padding: 8,
|
padding: 8,
|
||||||
},
|
},
|
||||||
|
iconRow: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
},
|
||||||
|
padding: {
|
||||||
|
paddingEnd: 16,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -40,7 +40,7 @@ async function localJson<T>(comicId: string, path: string): Promise<T | null> {
|
||||||
if (parsed === null) return null;
|
if (parsed === null) return null;
|
||||||
const [providerKey, id] = parsed;
|
const [providerKey, id] = parsed;
|
||||||
const pth = dataPath(`comics/${providerKey}/${id}/${path}`);
|
const pth = dataPath(`comics/${providerKey}/${id}/${path}`);
|
||||||
if (!pathExists(pth)) return null;
|
if (!await pathExists(pth)) return null;
|
||||||
|
|
||||||
return JSON.parse(await FileSystem.readAsStringAsync(pth));
|
return JSON.parse(await FileSystem.readAsStringAsync(pth));
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ async function localJson<T>(comicId: string, path: string): Promise<T | null> {
|
||||||
const localProvider: LocalProvider = {
|
const localProvider: LocalProvider = {
|
||||||
async listComics() {
|
async listComics() {
|
||||||
const directory = dataPath('comics/');
|
const directory = dataPath('comics/');
|
||||||
if (!pathExists(directory)) return [];
|
if (!await pathExists(directory)) return [];
|
||||||
const providers = await FileSystem.readDirectoryAsync(directory) as NonLocalProviderKey[];
|
const providers = await FileSystem.readDirectoryAsync(directory) as NonLocalProviderKey[];
|
||||||
const comics: LocalComicMetadata[] = [];
|
const comics: LocalComicMetadata[] = [];
|
||||||
for (const provider of providers) {
|
for (const provider of providers) {
|
||||||
|
|
Loading…
Reference in a new issue