Prevent double searching everywhere

Also change variable names. Search should represent the
act of searching, rather than the value being typed by the user.
This commit is contained in:
Brandon Presley 2022-10-28 18:59:54 +13:00
parent 3d591f4618
commit 463852e6a6
8 changed files with 88 additions and 75 deletions

View File

@ -3,7 +3,7 @@ import {
useFocusEffect,
useNavigation,
} from '@react-navigation/native';
import {useCallback, useEffect, useState} from 'react';
import {useCallback, useState} from 'react';
import {FlatList, Image} from 'react-native';
import {List} from 'react-native-paper';
import {getBestReps, getBestWeights} from './best.service';
@ -15,12 +15,12 @@ import {useSettings} from './use-settings';
export default function BestList() {
const [bests, setBests] = useState<Set[]>();
const [search, setSearch] = useState('');
const [term, setTerm] = useState('');
const navigation = useNavigation<NavigationProp<BestPageParams>>();
const {settings} = useSettings();
const refresh = useCallback(async () => {
const weights = await getBestWeights(search);
const refresh = useCallback(async (value: string) => {
const weights = await getBestWeights(value);
console.log(`${BestList.name}.refresh:`, {length: weights.length});
let newBest: Set[] = [];
for (const set of weights) {
@ -28,17 +28,21 @@ export default function BestList() {
newBest.push(...reps);
}
setBests(newBest);
}, [search]);
}, []);
useFocusEffect(
useCallback(() => {
refresh();
}, [refresh]),
refresh(term);
}, [refresh, term]),
);
useEffect(() => {
refresh();
}, [search, refresh]);
const search = useCallback(
(value: string) => {
setTerm(value);
refresh(value);
},
[refresh],
);
const renderItem = ({item}: {item: Set}) => (
<List.Item
@ -58,7 +62,7 @@ export default function BestList() {
return (
<>
<DrawerHeader name="Best" />
<Page search={search} setSearch={setSearch}>
<Page term={term} search={search}>
{bests?.length === 0 ? (
<List.Item
title="No exercises yet"

View File

@ -6,20 +6,20 @@ import MassiveFab from './MassiveFab';
export default function Page({
onAdd,
children,
term,
search,
setSearch,
}: {
children: JSX.Element | JSX.Element[];
onAdd?: () => void;
search: string;
setSearch: (value: string) => void;
term: string;
search: (value: string) => void;
}) {
return (
<View style={styles.container}>
<Searchbar
placeholder="Search"
value={search}
onChangeText={setSearch}
value={term}
onChangeText={search}
icon="search"
clearIcon="clear"
/>

View File

@ -3,7 +3,7 @@ import {
useFocusEffect,
useNavigation,
} from '@react-navigation/native';
import {useCallback, useEffect, useState} from 'react';
import {useCallback, useState} from 'react';
import {FlatList} from 'react-native';
import {List} from 'react-native-paper';
import DrawerHeader from './DrawerHeader';
@ -14,29 +14,33 @@ import {getPlans} from './plan.service';
import PlanItem from './PlanItem';
export default function PlanList() {
const [search, setSearch] = useState('');
const [term, setTerm] = useState('');
const [plans, setPlans] = useState<Plan[]>();
const navigation = useNavigation<NavigationProp<PlanPageParams>>();
const refresh = useCallback(async () => {
getPlans(search).then(setPlans);
}, [search]);
const refresh = useCallback(async (value: string) => {
getPlans(value).then(setPlans);
}, []);
useFocusEffect(
useCallback(() => {
refresh();
}, [refresh]),
refresh(term);
}, [refresh, term]),
);
useEffect(() => {
refresh();
}, [search, refresh]);
const search = useCallback(
(value: string) => {
setTerm(value);
refresh(value);
},
[refresh],
);
const renderItem = useCallback(
({item}: {item: Plan}) => (
<PlanItem item={item} key={item.id} onRemove={refresh} />
<PlanItem item={item} key={item.id} onRemove={() => refresh(term)} />
),
[refresh],
[refresh, term],
);
const onAdd = () =>
@ -45,7 +49,7 @@ export default function PlanList() {
return (
<>
<DrawerHeader name="Plans" />
<Page onAdd={onAdd} search={search} setSearch={setSearch}>
<Page onAdd={onAdd} term={term} search={search}>
{plans?.length === 0 ? (
<List.Item
title="No plans yet"

View File

@ -39,7 +39,7 @@ export default function SetForm({
if (!name) return;
let image = newImage;
if (!newImage && !removeImage)
image = await getSets({search: name, limit: 1, offset: 0}).then(
image = await getSets({term: name, limit: 1, offset: 0}).then(
([gotSet]) => gotSet?.image,
);
console.log(`${SetForm.name}.handleSubmit:`, {image});

View File

@ -20,17 +20,17 @@ export default function SetList() {
const [sets, setSets] = useState<Set[]>();
const [set, setSet] = useState<Set>();
const [offset, setOffset] = useState(0);
const [search, setSearch] = useState('');
const [term, setTerm] = useState('');
const [end, setEnd] = useState(false);
const {settings} = useSettings();
const navigation = useNavigation<NavigationProp<HomePageParams>>();
const refresh = useCallback(
async (term: string) => {
async (value: string) => {
const todaysSet = await getToday();
if (todaysSet) setSet({...todaysSet});
const newSets = await getSets({
search: `%${term}%`,
term: `%${value}%`,
limit,
offset: 0,
format: settings.date || '%Y-%m-%d %H:%M',
@ -46,33 +46,32 @@ export default function SetList() {
useFocusEffect(
useCallback(() => {
refresh(search);
}, [refresh, search]),
refresh(term);
}, [refresh, term]),
);
const renderItem = useCallback(
({item}: {item: Set}) => (
<SetItem item={item} key={item.id} onRemove={() => refresh(search)} />
<SetItem item={item} key={item.id} onRemove={() => refresh(term)} />
),
[refresh, search],
[refresh, term],
);
const next = useCallback(async () => {
if (end) return;
const newOffset = offset + limit;
console.log(`${SetList.name}.next:`, {offset, newOffset, search});
console.log(`${SetList.name}.next:`, {offset, newOffset, term});
const newSets = await getSets({
search: `%${search}%`,
term: `%${term}%`,
limit,
offset: newOffset,
format: settings.date || '%Y-%m-%d %H:%M',
});
if (newSets.length === 0) return setEnd(true);
if (!sets) return;
setSets([...sets, ...newSets]);
if (newSets.length < limit) return setEnd(true);
setOffset(newOffset);
}, [search, end, offset, sets, settings.date]);
}, [term, end, offset, sets]);
const onAdd = useCallback(async () => {
console.log(`${SetList.name}.onAdd`, {set});
@ -81,9 +80,9 @@ export default function SetList() {
});
}, [navigation, set]);
const handleSearch = useCallback(
const search = useCallback(
(value: string) => {
setSearch(value);
setTerm(value);
refresh(value);
},
[refresh],
@ -92,7 +91,7 @@ export default function SetList() {
return (
<>
<DrawerHeader name="Home" />
<Page onAdd={onAdd} search={search} setSearch={handleSearch}>
<Page onAdd={onAdd} term={term} search={search}>
{sets?.length === 0 ? (
<List.Item
title="No sets yet"

View File

@ -20,7 +20,7 @@ import {useSettings} from './use-settings';
export default function SettingsPage() {
const [battery, setBattery] = useState(false);
const [ignoring, setIgnoring] = useState(false);
const [search, setSearch] = useState('');
const [term, setTerm] = useState('');
const {settings, setSettings} = useSettings();
const {
vibrate,
@ -180,11 +180,11 @@ export default function SettingsPage() {
return (
<>
<DrawerHeader name="Settings" />
<Page search={search} setSearch={setSearch}>
<Page term={term} search={setTerm}>
<ScrollView style={{marginTop: MARGIN}}>
{switches
.filter(input =>
input.name.toLowerCase().includes(search.toLowerCase()),
input.name.toLowerCase().includes(term.toLowerCase()),
)
.map(input => (
<Switch
@ -195,7 +195,7 @@ export default function SettingsPage() {
{input.name}
</Switch>
))}
{'theme'.includes(search.toLowerCase()) && (
{'theme'.includes(term.toLowerCase()) && (
<Picker
style={{color}}
dropdownIconColor={color}
@ -206,7 +206,7 @@ export default function SettingsPage() {
<Picker.Item value="light" label="Light theme" />
</Picker>
)}
{'color'.includes(search.toLowerCase()) && (
{'color'.includes(term.toLowerCase()) && (
<Picker
style={{color, marginTop: -10}}
dropdownIconColor={color}
@ -222,7 +222,7 @@ export default function SettingsPage() {
))}
</Picker>
)}
{'date format'.includes(search.toLowerCase()) && (
{'date format'.includes(term.toLowerCase()) && (
<Picker
style={{color, marginTop: -10}}
dropdownIconColor={color}
@ -242,7 +242,7 @@ export default function SettingsPage() {
<Picker.Item value="%d/%m %h:%M %p" label="24/12 3:05 PM" />
</Picker>
)}
{'alarm sound'.includes(search.toLowerCase()) && (
{'alarm sound'.includes(term.toLowerCase()) && (
<Button style={{alignSelf: 'flex-start'}} onPress={changeSound}>
Alarm sound
{sound

View File

@ -3,7 +3,7 @@ import {
useFocusEffect,
useNavigation,
} from '@react-navigation/native';
import {useCallback, useEffect, useState} from 'react';
import {useCallback, useState} from 'react';
import {FlatList} from 'react-native';
import {List} from 'react-native-paper';
import DrawerHeader from './DrawerHeader';
@ -19,13 +19,13 @@ const limit = 15;
export default function WorkoutList() {
const [workouts, setWorkouts] = useState<Set[]>();
const [offset, setOffset] = useState(0);
const [search, setSearch] = useState('');
const [term, setTerm] = useState('');
const [end, setEnd] = useState(false);
const navigation = useNavigation<NavigationProp<WorkoutsPageParams>>();
const refresh = useCallback(async () => {
const refresh = useCallback(async (value: string) => {
const newWorkouts = await getDistinctSets({
search: `%${search}%`,
term: `%${value}%`,
limit,
offset: 0,
});
@ -33,23 +33,23 @@ export default function WorkoutList() {
setWorkouts(newWorkouts);
setOffset(0);
setEnd(false);
}, [search]);
useEffect(() => {
refresh();
}, [search, refresh]);
}, []);
useFocusEffect(
useCallback(() => {
refresh();
}, [refresh]),
refresh(term);
}, [refresh, term]),
);
const renderItem = useCallback(
({item}: {item: Set}) => (
<WorkoutItem item={item} key={item.name} onRemoved={refresh} />
<WorkoutItem
item={item}
key={item.name}
onRemoved={() => refresh(term)}
/>
),
[refresh],
[refresh, term],
);
const next = useCallback(async () => {
@ -59,10 +59,10 @@ export default function WorkoutList() {
offset,
limit,
newOffset,
search,
term,
});
const newWorkouts = await getDistinctSets({
search: `%${search}%`,
term: `%${term}%`,
limit,
offset: newOffset,
});
@ -71,7 +71,7 @@ export default function WorkoutList() {
setWorkouts([...workouts, ...newWorkouts]);
if (newWorkouts.length < limit) return setEnd(true);
setOffset(newOffset);
}, [search, end, offset, workouts]);
}, [term, end, offset, workouts]);
const onAdd = useCallback(async () => {
navigation.navigate('EditWorkout', {
@ -79,10 +79,18 @@ export default function WorkoutList() {
});
}, [navigation]);
const search = useCallback(
(value: string) => {
setTerm(value);
refresh(value);
},
[refresh],
);
return (
<>
<DrawerHeader name="Workouts" />
<Page onAdd={onAdd} search={search} setSearch={setSearch}>
<Page onAdd={onAdd} term={term} search={search}>
{workouts?.length === 0 ? (
<List.Item
title="No workouts yet."

View File

@ -57,10 +57,9 @@ export const getAllSets = async (): Promise<Set[]> => {
};
interface PageParams {
search: string;
term: string;
limit: number;
offset: number;
format?: string;
}
export const getSet = async (name: string): Promise<Set> => {
@ -75,10 +74,9 @@ export const getSet = async (name: string): Promise<Set> => {
};
export const getSets = async ({
search,
term,
limit,
offset,
format,
}: PageParams): Promise<Set[]> => {
const select = `
SELECT id, name, reps, weight, sets, minutes, seconds,
@ -88,7 +86,7 @@ export const getSets = async ({
ORDER BY STRFTIME('%Y-%m-%d %H:%M', created) DESC
LIMIT ? OFFSET ?
`;
const [result] = await db.executeSql(select, [`%${search}%`, limit, offset]);
const [result] = await db.executeSql(select, [`%${term}%`, limit, offset]);
return result.rows.raw();
};
@ -180,7 +178,7 @@ export const countMany = async (names: string[]): Promise<CountMany[]> => {
};
export const getDistinctSets = async ({
search,
term,
limit,
offset,
}: PageParams): Promise<Set[]> => {
@ -192,6 +190,6 @@ export const getDistinctSets = async ({
ORDER BY sets.name
LIMIT ? OFFSET ?
`;
const [result] = await db.executeSql(select, [search, limit, offset]);
const [result] = await db.executeSql(select, [term, limit, offset]);
return result.rows.raw();
};