From 7928cab4c178121c2f2880d181d73997ffc83d4d Mon Sep 17 00:00:00 2001 From: Brandon Presley Date: Thu, 19 Oct 2023 18:28:56 +1300 Subject: [PATCH] Swap to using MaterialCommunityIcons --- App.tsx | 2 +- AppFab.tsx | 2 +- EditPlan.tsx | 4 +- EditSet.tsx | 12 +- EditSets.tsx | 12 +- EditWeight.tsx | 303 +++++++++++++++++++++++++++++++++++++++ ListMenu.tsx | 10 +- Page.tsx | 4 +- Routes.tsx | 16 ++- StackHeader.tsx | 2 +- StartPlan.tsx | 14 +- StartPlanItem.tsx | 4 +- WeightList.tsx | 213 +++++++++++++++++++++++++++ WeightPage.tsx | 23 +++ android/app/build.gradle | 2 +- drawer-param-list.ts | 1 + 16 files changed, 586 insertions(+), 38 deletions(-) create mode 100644 EditWeight.tsx create mode 100644 WeightList.tsx create mode 100644 WeightPage.tsx diff --git a/App.tsx b/App.tsx index 4a3b019..9471f21 100644 --- a/App.tsx +++ b/App.tsx @@ -11,7 +11,7 @@ import { Provider as PaperProvider, Snackbar, } from "react-native-paper"; -import MaterialIcon from "react-native-vector-icons/MaterialIcons"; +import MaterialIcon from "react-native-vector-icons/MaterialCommunityIcons"; import { AppDataSource } from "./data-source"; import { settingsRepo } from "./db"; import { emitter } from "./emitter"; diff --git a/AppFab.tsx b/AppFab.tsx index ef6d565..840e294 100644 --- a/AppFab.tsx +++ b/AppFab.tsx @@ -16,7 +16,7 @@ export default function AppFab(props: Partial>) { return ( )} @@ -138,7 +138,7 @@ export default function EditPlan() { disabled={workouts.length === 0 && days.length === 0} style={styles.button} mode="outlined" - icon="save" + icon="content-save" onPress={async () => { await save(); navigation.navigate("PlanList"); diff --git a/EditSet.tsx b/EditSet.tsx index a2c4520..e45018f 100644 --- a/EditSet.tsx +++ b/EditSet.tsx @@ -202,11 +202,11 @@ export default function EditSet() { innerRef={repsRef} /> setReps((Number(reps) + 1).toString())} /> setReps((Number(reps) - 1).toString())} /> @@ -232,11 +232,11 @@ export default function EditSet() { innerRef={weightRef} /> setWeight((Number(weight) + 2.5).toString())} /> setWeight((Number(weight) - 2.5).toString())} /> @@ -273,7 +273,7 @@ export default function EditSet() { @@ -283,7 +283,7 @@ export default function EditSet() { @@ -184,7 +184,7 @@ export default function EditSets() { + )} + + + + + + Are you sure you want to remove the image? + + + ); +} diff --git a/ListMenu.tsx b/ListMenu.tsx index 76b21f7..c97104f 100644 --- a/ListMenu.tsx +++ b/ListMenu.tsx @@ -49,17 +49,19 @@ export default function ListMenu({ setShowMenu(false)} - anchor={ setShowMenu(true)} icon="more-vert" />} + anchor={ + setShowMenu(true)} icon="dots-vertical" /> + } > - + {children} {onAdd && } diff --git a/Routes.tsx b/Routes.tsx index e51b5c6..7379c91 100644 --- a/Routes.tsx +++ b/Routes.tsx @@ -8,6 +8,7 @@ import SettingsPage from "./SettingsPage"; import TimerPage from "./TimerPage"; import useDark from "./use-dark"; import WorkoutsPage from "./WorkoutsPage"; +import WeightPage from "./WeightPage"; const Drawer = createDrawerNavigator(); @@ -30,27 +31,32 @@ export default function Routes() { }} + options={{ drawerIcon: () => }} /> }} + options={{ drawerIcon: () => }} /> }} + options={{ drawerIcon: () => }} /> }} + options={{ drawerIcon: () => }} + /> + }} /> }} + options={{ drawerIcon: () => }} /> ); diff --git a/StackHeader.tsx b/StackHeader.tsx index fe05776..cb4bfed 100644 --- a/StackHeader.tsx +++ b/StackHeader.tsx @@ -12,7 +12,7 @@ export default function StackHeader({ return ( - + {children} diff --git a/StartPlan.tsx b/StartPlan.tsx index c1fd3f9..60e8df1 100644 --- a/StartPlan.tsx +++ b/StartPlan.tsx @@ -16,7 +16,7 @@ import { AppDataSource } from "./data-source"; import { getNow, setRepo, settingsRepo } from "./db"; import { emitter } from "./emitter"; import { fixNumeric } from "./fix-numeric"; -import GymSet, { GYM_SET_CREATED, GYM_SET_UPDATED } from "./gym-set"; +import GymSet, { GYM_SET_CREATED } from "./gym-set"; import { PlanPageParams } from "./plan-page-params"; import Settings from "./settings"; import StackHeader from "./StackHeader"; @@ -125,7 +125,7 @@ export default function StartPlan() { > navigation.navigate("EditPlan", { plan: params.plan })} - icon="edit" + icon="pencil" /> @@ -153,11 +153,11 @@ export default function StartPlan() { innerRef={repsRef} /> setReps((Number(reps) + 1).toString())} /> setReps((Number(reps) - 1).toString())} /> @@ -184,11 +184,11 @@ export default function StartPlan() { blurOnSubmit /> setWeight((Number(weight) + 2.5).toString())} /> setWeight((Number(weight) - 2.5).toString())} /> @@ -222,7 +222,7 @@ export default function StartPlan() { /> )} - diff --git a/StartPlanItem.tsx b/StartPlanItem.tsx index d229f50..8df5d3a 100644 --- a/StartPlanItem.tsx +++ b/StartPlanItem.tsx @@ -100,8 +100,8 @@ export default function StartPlanItem(props: Props) { visible={showMenu} onDismiss={() => setShowMenu(false)} > - - + + diff --git a/WeightList.tsx b/WeightList.tsx new file mode 100644 index 0000000..cc2e5b8 --- /dev/null +++ b/WeightList.tsx @@ -0,0 +1,213 @@ +import { + NavigationProp, + RouteProp, + useNavigation, + useRoute, +} from "@react-navigation/native"; +import { useCallback, useEffect, useState } from "react"; +import { FlatList } from "react-native"; +import { List } from "react-native-paper"; +import { Like } from "typeorm"; +import { LIMIT } from "./constants"; +import { getNow, setRepo, settingsRepo } from "./db"; +import DrawerHeader from "./DrawerHeader"; +import { emitter } from "./emitter"; +import GymSet, { + defaultSet, + GYM_SET_CREATED, + GYM_SET_DELETED, + GYM_SET_UPDATED, +} from "./gym-set"; +import { HomePageParams } from "./home-page-params"; +import ListMenu from "./ListMenu"; +import Page from "./Page"; +import SetItem from "./SetItem"; +import Settings, { SETTINGS } from "./settings"; + +export default function WeightList() { + const [refreshing, setRefreshing] = useState(false); + const [sets, setSets] = useState(); + const [offset, setOffset] = useState(0); + const [end, setEnd] = useState(false); + const [settings, setSettings] = useState(); + const [ids, setIds] = useState([]); + const navigation = useNavigation>(); + const { params } = useRoute>(); + const [term, setTerm] = useState(params?.search || ""); + + const reset = useCallback( + async (value: string) => { + const newSets = await setRepo.find({ + where: { name: Like(`%${value.trim()}%`), hidden: 0 as any }, + take: LIMIT, + skip: 0, + order: { created: "DESC" }, + }); + console.log(`${SetList.name}.reset:`, { value, offset }); + setSets(newSets); + setEnd(false); + }, + [offset] + ); + + useEffect(() => { + settingsRepo.findOne({ where: {} }).then(setSettings); + reset(""); + /* eslint-disable react-hooks/exhaustive-deps */ + }, []); + + useEffect(() => { + const updated = (gymSet: GymSet) => { + if (!sets) console.log({ sets }); + console.log(`${SetList.name}.updated:`, { gymSet, length: sets.length }); + const newSets = sets.map((set) => { + if (set.id !== gymSet.id) return set; + if (gymSet.created === undefined) gymSet.created = set.created; + return gymSet; + }); + setSets(newSets); + }; + + const descriptions = [ + emitter.addListener(SETTINGS, () => { + settingsRepo.findOne({ where: {} }).then(setSettings); + }), + emitter.addListener(GYM_SET_UPDATED, updated), + emitter.addListener(GYM_SET_CREATED, () => reset("")), + emitter.addListener(GYM_SET_DELETED, () => reset("")), + ]; + return () => descriptions.forEach((description) => description.remove()); + }, [sets]); + + const search = (value: string) => { + console.log(`${SetList.name}.search:`, value); + setTerm(value); + setOffset(0); + reset(value); + }; + + useEffect(() => { + console.log(`${SetList.name}.useEffect:`, params); + if (params?.search) search(params.search); + }, [params]); + + const renderItem = useCallback( + ({ item }: { item: GymSet }) => ( + + ), + [settings, ids] + ); + + const next = async () => { + console.log({ end, refreshing }); + if (end || refreshing) return; + const newOffset = offset + LIMIT; + console.log(`${SetList.name}.next:`, { offset, newOffset, term }); + const newSets = await setRepo.find({ + where: { name: Like(`%${term}%`), hidden: 0 as any }, + take: LIMIT, + skip: newOffset, + order: { created: "DESC" }, + }); + if (newSets.length === 0) return setEnd(true); + if (!sets) return; + const map = new Map(); + for (const set of sets) map.set(set.id, set); + for (const set of newSets) map.set(set.id, set); + const unique = Array.from(map.values()); + setSets(unique); + if (newSets.length < LIMIT) return setEnd(true); + setOffset(newOffset); + }; + + const onAdd = useCallback(async () => { + const now = await getNow(); + let set = sets?.[0]; + if (!set) set = { ...defaultSet }; + set.created = now; + delete set.id; + navigation.navigate("EditSet", { set }); + }, [navigation, sets]); + + const edit = useCallback(() => { + navigation.navigate("EditSets", { ids }); + setIds([]); + }, [ids, navigation]); + + const copy = useCallback(async () => { + const set = await setRepo.findOne({ + where: { id: ids.pop() }, + }); + delete set.id; + delete set.created; + navigation.navigate("EditSet", { set }); + setIds([]); + }, [ids, navigation]); + + const clear = useCallback(() => { + setIds([]); + }, []); + + const remove = async () => { + setIds([]); + await setRepo.delete(ids.length > 0 ? ids : {}); + return reset(term); + }; + + const select = useCallback(() => { + if (!sets) return; + if (ids.length === sets.length) return setIds([]); + setIds(sets.map((set) => set.id)); + }, [sets, ids]); + + const getContent = () => { + if (!settings) return null; + if (sets?.length === 0) + return ( + + ); + return ( + set.id?.toString()} + onRefresh={() => { + setOffset(0); + setRefreshing(true); + reset(term).finally(() => setRefreshing(false)); + }} + /> + ); + }; + + return ( + <> + 0 ? `${ids.length} selected` : "Home"}> + + + + + {getContent()} + + + ); +} diff --git a/WeightPage.tsx b/WeightPage.tsx new file mode 100644 index 0000000..c612924 --- /dev/null +++ b/WeightPage.tsx @@ -0,0 +1,23 @@ +import { createStackNavigator } from "@react-navigation/stack"; +import EditSet from "./EditSet"; +import SetList from "./SetList"; + +export type WeightPageParams = { + Weights: {}; + EditWeight: { + weight: any; + }; +}; + +const Stack = createStackNavigator(); + +export default function WeightPage() { + return ( + + + + + ); +} diff --git a/android/app/build.gradle b/android/app/build.gradle index 72e4448..e01bf13 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -143,6 +143,6 @@ dependencies { apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) project.ext.vectoricons = [ - iconFontNames: ['MaterialIcons.ttf'] + iconFontNames: ['MaterialCommunityIcons.ttf'] ] apply from: "../../node_modules/react-native-vector-icons/fonts.gradle" diff --git a/drawer-param-list.ts b/drawer-param-list.ts index 9b1b3d0..576d3f8 100644 --- a/drawer-param-list.ts +++ b/drawer-param-list.ts @@ -5,4 +5,5 @@ export type DrawerParamList = { Plans: {}; Workouts: {}; Timer: {}; + Weight: {}; };