Skip to content

Commit

Permalink
feat: module updater
Browse files Browse the repository at this point in the history
  • Loading branch information
hoangvu12 committed Sep 7, 2024
1 parent 292d95b commit a53e433
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/navigation/root-navigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { AnimeDetailsScreen } from '@/screens/anime/details/screen';
import RecentlyWatchedScreen from '@/screens/anime/recently-watched/screen';
import { AnimeWatchScreen } from '@/screens/anime/watch/screen';
import CharacterDetailsScreen from '@/screens/character-details/screen';
import ModuleUpdater from '@/ui/module-updater';
import Updater from '@/ui/updater';

import { NavigationContainer } from './navigation-container';
Expand Down Expand Up @@ -93,6 +94,7 @@ export const RootNavigator = () => {
<NavigationContainer>
<Root />
<Updater />
<ModuleUpdater />
</NavigationContainer>
</BottomSheetModalProvider>
</WebViewProvider>
Expand Down
116 changes: 116 additions & 0 deletions src/ui/module-updater.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import type { BottomSheetModal } from '@gorhom/bottom-sheet';
import axios from 'axios';
import { useAtomValue } from 'jotai/react';
import React, { useCallback, useEffect, useRef } from 'react';
import { ToastAndroid } from 'react-native';
import { FlatList } from 'react-native-gesture-handler';

import IndexSchema from '@/core/remote-index';
import useModules from '@/hooks/use-modules';
import RemoteModuleItem from '@/screens/module/screens/remote/components/remote-module-item';
import type { IndexWithUrl } from '@/screens/module/screens/remote/store';
import { indexListAtom } from '@/screens/module/screens/remote/store';
import type { Module } from '@/types';

import { Text, View } from './core';
import BottomSheet from './core/bottom-sheet';

interface ModuleWithUrl extends Module {
url: string;
}

const ModuleUpdater = () => {
const indexList = useAtomValue(indexListAtom);
const { data: modules, isLoading } = useModules({ variables: null });
const [updatedModules, setUpdatedModules] = React.useState<ModuleWithUrl[]>(
[]
);

const bottomSheetRef = useRef<BottomSheetModal | null>(null);

const refreshIndex = useCallback(async (index: IndexWithUrl) => {
try {
const { data } = await axios.get(index.url);

const validation = IndexSchema.safeParse(data);

if (!validation.success) {
return;
}

return validation.data;
} catch (error) {
if (error instanceof Error) {
ToastAndroid.show(
`Something went wrong when updating the index (${error.message})`,
ToastAndroid.SHORT
);
}
}
}, []);

const checkIndex = useCallback(
async (modules: Module[]) => {
if (!modules?.length) return;

const updatedModules: ModuleWithUrl[] = [];

for (const index of indexList) {
const validationData = await refreshIndex(index);

if (!validationData?.modules?.length) continue;

for (const module of modules) {
const indexModule = validationData.modules.find(
(m) =>
m.name === module.name &&
m.info.author === module.info.author &&
m.version !== module.version
);

if (!indexModule) continue;

updatedModules.push(indexModule);
}
}

if (!updatedModules.length) return;

setUpdatedModules(updatedModules);

bottomSheetRef.current?.present();
},
[indexList, refreshIndex]
);

useEffect(() => {
if (isLoading) return;

if (!modules?.length) return;

checkIndex(modules);
}, [checkIndex, isLoading, modules]);

return (
<BottomSheet ref={bottomSheetRef} snapPoints={['80%']}>
<View className="pb-12">
<Text className="mb-4 text-xl" weight="bold">
New module update available
</Text>

<FlatList
data={updatedModules}
keyExtractor={(item) => item.id}
renderItem={({ item }) => {
return (
<RemoteModuleItem hasNewVersion hasInstalled module={item} />
);
}}
ItemSeparatorComponent={() => <View className="h-2" />}
/>
</View>
</BottomSheet>
);
};

export default ModuleUpdater;

0 comments on commit a53e433

Please sign in to comment.