From dda041a9aebc23f7a0576fc4030d06c71fa370d2 Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Sun, 12 May 2024 20:04:58 +0530 Subject: Add draggable favorite apps list --- src/components/Favorites.tsx | 65 ++++++++++++++++++++++++++++++++++++++++++++ src/hooks/useFavorites.ts | 52 +++++++++++++++++++++++++++++++++++ src/screens/Home.tsx | 12 ++++---- 3 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 src/components/Favorites.tsx create mode 100644 src/hooks/useFavorites.ts (limited to 'src') diff --git a/src/components/Favorites.tsx b/src/components/Favorites.tsx new file mode 100644 index 0000000..712a07f --- /dev/null +++ b/src/components/Favorites.tsx @@ -0,0 +1,65 @@ +import React, {useCallback, useMemo} from 'react'; +import {ScrollView, Text, TouchableOpacity, View} from 'react-native'; +import {AppDetail} from 'react-native-launcher-kit/typescript/Interfaces/InstalledApps'; +import {useFavorites} from '../hooks/useFavorites'; +import DraggableFlatList, { + OpacityDecorator, + ScaleDecorator, + ShadowDecorator, +} from 'react-native-draggable-flatlist'; +import Icon from 'react-native-vector-icons/MaterialIcons'; + +export const Favorites: React.FC<{apps: AppDetail[]}> = ({apps}) => { + const {favoriteAppNames, setFavorites} = useFavorites(); + + const appByName = useMemo( + () => Object.fromEntries(apps.map(app => [app.packageName, app])), + [apps], + ); + + const favoriteApps = useMemo( + () => favoriteAppNames.map(name => appByName[name]).filter(Boolean), + [appByName, favoriteAppNames], + ); + + const onDragEnd = useCallback( + ({data}: {data: AppDetail[]}) => { + setFavorites(data.map(app => app.packageName)); + }, + [setFavorites], + ); + + return ( + + item.packageName} + renderItem={({item: app, drag, isActive}) => ( + + + + + + + + + + + {app.label} + + + + + )} + renderPlaceholder={() => } + /> + + ); +}; diff --git a/src/hooks/useFavorites.ts b/src/hooks/useFavorites.ts new file mode 100644 index 0000000..54d77fd --- /dev/null +++ b/src/hooks/useFavorites.ts @@ -0,0 +1,52 @@ +import {useCallback, useEffect, useState} from 'react'; +import {useAsyncStorage} from '@react-native-async-storage/async-storage'; + +export const useFavorites = () => { + const favoritesStorage = useAsyncStorage('favorites'); + const [favoriteAppNames, setFavoriteAppNames] = useState([]); + + const getFavoriteAppNames = useCallback(async (): Promise => { + try { + const result = await favoritesStorage.getItem(); + const apps = result ? JSON.parse(result) : []; + if (!Array.isArray(apps)) return []; + return apps; + } catch (err) { + console.error(err); + return []; + } + }, [favoritesStorage]); + + const refreshFavorites = useCallback(async () => { + getFavoriteAppNames().then(setFavoriteAppNames); + }, [getFavoriteAppNames]); + + const setFavorites = useCallback( + async (names: string[]) => { + const newNames = [...new Set(names)]; + setFavoriteAppNames(newNames); + await favoritesStorage.setItem(JSON.stringify(newNames)); + }, + [favoritesStorage], + ); + + const addToFavorites = useCallback( + async (packageName: string) => { + const names = await getFavoriteAppNames(); + setFavorites([...names, packageName]); + }, + [getFavoriteAppNames, setFavorites], + ); + + useEffect(() => { + refreshFavorites(); + }, [refreshFavorites]); + + return { + favoriteAppNames, + getFavoriteAppNames, + addToFavorites, + refreshFavorites, + setFavorites, + }; +}; diff --git a/src/screens/Home.tsx b/src/screens/Home.tsx index da24e13..00a4b1f 100644 --- a/src/screens/Home.tsx +++ b/src/screens/Home.tsx @@ -1,14 +1,14 @@ -import React, {useMemo} from 'react'; -import {Text, View} from 'react-native'; +import React from 'react'; +import {View} from 'react-native'; import {Clock} from '../components/Clock'; +import {AppDetail} from 'react-native-launcher-kit/typescript/Interfaces/InstalledApps'; +import {Favorites} from '../components/Favorites'; -export const Home: React.FC = () => { +export const Home: React.FC<{apps: AppDetail[]}> = ({apps}) => { return ( - - Favorites list - + ); }; -- cgit v1.3.1