Move sessions page functionality onto Plan page
The sessions page mostly copied the exact same features as Plans, which would confuse the user.
This commit is contained in:
parent
5481e8a20d
commit
e0b84af9e7
42
PlanItem.tsx
42
PlanItem.tsx
|
@ -1,10 +1,12 @@
|
||||||
import {NavigationProp, useNavigation} from '@react-navigation/native';
|
import {NavigationProp, useNavigation} from '@react-navigation/native';
|
||||||
import React, {useCallback, useState} from 'react';
|
import React, {useCallback, useMemo, useState} from 'react';
|
||||||
import {GestureResponderEvent} from 'react-native';
|
import {GestureResponderEvent, Text} from 'react-native';
|
||||||
import {List, Menu} from 'react-native-paper';
|
import {List, Menu} from 'react-native-paper';
|
||||||
|
import {getBestSet} from './best.service';
|
||||||
import {Plan} from './plan';
|
import {Plan} from './plan';
|
||||||
import {PlanPageParams} from './plan-page-params';
|
import {PlanPageParams} from './plan-page-params';
|
||||||
import {deletePlan} from './plan.service';
|
import {deletePlan} from './plan.service';
|
||||||
|
import {DAYS} from './time';
|
||||||
|
|
||||||
export default function PlanItem({
|
export default function PlanItem({
|
||||||
item,
|
item,
|
||||||
|
@ -15,7 +17,9 @@ export default function PlanItem({
|
||||||
}) {
|
}) {
|
||||||
const [show, setShow] = useState(false);
|
const [show, setShow] = useState(false);
|
||||||
const [anchor, setAnchor] = useState({x: 0, y: 0});
|
const [anchor, setAnchor] = useState({x: 0, y: 0});
|
||||||
|
const days = useMemo(() => item.days.split(','), [item.days]);
|
||||||
const navigation = useNavigation<NavigationProp<PlanPageParams>>();
|
const navigation = useNavigation<NavigationProp<PlanPageParams>>();
|
||||||
|
const today = useMemo(() => DAYS[new Date().getDay()], []);
|
||||||
|
|
||||||
const remove = useCallback(async () => {
|
const remove = useCallback(async () => {
|
||||||
if (typeof item.id === 'number') await deletePlan(item.id);
|
if (typeof item.id === 'number') await deletePlan(item.id);
|
||||||
|
@ -23,6 +27,14 @@ export default function PlanItem({
|
||||||
onRemove();
|
onRemove();
|
||||||
}, [setShow, item.id, onRemove]);
|
}, [setShow, item.id, onRemove]);
|
||||||
|
|
||||||
|
const start = useCallback(async () => {
|
||||||
|
const workouts = item.workouts.split(',');
|
||||||
|
const first = workouts[0];
|
||||||
|
const set = await getBestSet(first);
|
||||||
|
setShow(false);
|
||||||
|
navigation.navigate('StartPlan', {plan: item, set});
|
||||||
|
}, [item, navigation]);
|
||||||
|
|
||||||
const longPress = useCallback(
|
const longPress = useCallback(
|
||||||
(e: GestureResponderEvent) => {
|
(e: GestureResponderEvent) => {
|
||||||
setAnchor({x: e.nativeEvent.pageX, y: e.nativeEvent.pageY});
|
setAnchor({x: e.nativeEvent.pageX, y: e.nativeEvent.pageY});
|
||||||
|
@ -31,19 +43,33 @@ export default function PlanItem({
|
||||||
[setAnchor, setShow],
|
[setAnchor, setShow],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const edit = useCallback(() => {
|
||||||
|
setShow(false);
|
||||||
|
navigation.navigate('EditPlan', {plan: item});
|
||||||
|
}, [navigation, item]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<List.Item
|
<List.Item
|
||||||
onPress={() => navigation.navigate('EditPlan', {plan: item})}
|
onPress={start}
|
||||||
title={
|
title={days.map((day, index) => (
|
||||||
item.days
|
<Text key={day}>
|
||||||
? item.days.replace(/,/g, ', ')
|
{day === today ? (
|
||||||
: item.workouts.replace(/,/g, ', ')
|
<Text
|
||||||
}
|
style={{fontWeight: 'bold', textDecorationLine: 'underline'}}>
|
||||||
|
{day}
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
day
|
||||||
|
)}
|
||||||
|
{index === days.length - 1 ? '' : ', '}
|
||||||
|
</Text>
|
||||||
|
))}
|
||||||
description={item.days ? item.workouts.replace(/,/g, ', ') : null}
|
description={item.days ? item.workouts.replace(/,/g, ', ') : null}
|
||||||
onLongPress={longPress}
|
onLongPress={longPress}
|
||||||
right={() => (
|
right={() => (
|
||||||
<Menu anchor={anchor} visible={show} onDismiss={() => setShow(false)}>
|
<Menu anchor={anchor} visible={show} onDismiss={() => setShow(false)}>
|
||||||
|
<Menu.Item icon="edit" onPress={edit} title="Edit" />
|
||||||
<Menu.Item icon="delete" onPress={remove} title="Delete" />
|
<Menu.Item icon="delete" onPress={remove} title="Delete" />
|
||||||
</Menu>
|
</Menu>
|
||||||
)}
|
)}
|
||||||
|
|
15
PlanPage.tsx
15
PlanPage.tsx
|
@ -7,6 +7,7 @@ import {DrawerParamList} from './drawer-param-list';
|
||||||
import EditPlan from './EditPlan';
|
import EditPlan from './EditPlan';
|
||||||
import {PlanPageParams} from './plan-page-params';
|
import {PlanPageParams} from './plan-page-params';
|
||||||
import PlanList from './PlanList';
|
import PlanList from './PlanList';
|
||||||
|
import StartPlan from './StartPlan';
|
||||||
|
|
||||||
const Stack = createStackNavigator<PlanPageParams>();
|
const Stack = createStackNavigator<PlanPageParams>();
|
||||||
|
|
||||||
|
@ -31,6 +32,20 @@ export default function PlanPage() {
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="StartPlan"
|
||||||
|
component={StartPlan}
|
||||||
|
listeners={{
|
||||||
|
beforeRemove: () => {
|
||||||
|
navigation.setOptions({
|
||||||
|
headerLeft: () => (
|
||||||
|
<IconButton icon="menu" onPress={navigation.openDrawer} />
|
||||||
|
),
|
||||||
|
title: 'Plans',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import {DrawerParamList} from './drawer-param-list';
|
||||||
import HomePage from './HomePage';
|
import HomePage from './HomePage';
|
||||||
import PlanPage from './PlanPage';
|
import PlanPage from './PlanPage';
|
||||||
import Route from './route';
|
import Route from './route';
|
||||||
import SessionPage from './SessionPage';
|
|
||||||
import SettingsPage from './SettingsPage';
|
import SettingsPage from './SettingsPage';
|
||||||
import useDark from './use-dark';
|
import useDark from './use-dark';
|
||||||
import WorkoutsPage from './WorkoutsPage';
|
import WorkoutsPage from './WorkoutsPage';
|
||||||
|
@ -19,7 +18,6 @@ export default function Routes() {
|
||||||
const routes: Route[] = [
|
const routes: Route[] = [
|
||||||
{name: 'Home', component: HomePage, icon: 'home'},
|
{name: 'Home', component: HomePage, icon: 'home'},
|
||||||
{name: 'Plans', component: PlanPage, icon: 'event'},
|
{name: 'Plans', component: PlanPage, icon: 'event'},
|
||||||
{name: 'Session', component: SessionPage, icon: 'directions-run'},
|
|
||||||
{name: 'Best', component: BestPage, icon: 'insights'},
|
{name: 'Best', component: BestPage, icon: 'insights'},
|
||||||
{name: 'Workouts', component: WorkoutsPage, icon: 'fitness-center'},
|
{name: 'Workouts', component: WorkoutsPage, icon: 'fitness-center'},
|
||||||
{name: 'Settings', component: SettingsPage, icon: 'settings'},
|
{name: 'Settings', component: SettingsPage, icon: 'settings'},
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
import {
|
|
||||||
NavigationProp,
|
|
||||||
useFocusEffect,
|
|
||||||
useNavigation,
|
|
||||||
} from '@react-navigation/native';
|
|
||||||
import React, {useCallback, useEffect, useState} from 'react';
|
|
||||||
import {FlatList} from 'react-native';
|
|
||||||
import {List} from 'react-native-paper';
|
|
||||||
import {getBestSet} from './best.service';
|
|
||||||
import Page from './Page';
|
|
||||||
import {Plan} from './plan';
|
|
||||||
import {getPlans} from './plan.service';
|
|
||||||
import {SessionPageParams} from './session-page-params';
|
|
||||||
|
|
||||||
export default function SessionList() {
|
|
||||||
const [search, setSearch] = useState('');
|
|
||||||
const [plans, setPlans] = useState<Plan[]>([]);
|
|
||||||
const navigation = useNavigation<NavigationProp<SessionPageParams>>();
|
|
||||||
|
|
||||||
const refresh = useCallback(async () => {
|
|
||||||
getPlans(search).then(setPlans);
|
|
||||||
}, [search]);
|
|
||||||
|
|
||||||
useFocusEffect(
|
|
||||||
useCallback(() => {
|
|
||||||
refresh();
|
|
||||||
}, [refresh]),
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
refresh();
|
|
||||||
}, [search, refresh]);
|
|
||||||
|
|
||||||
const press = useCallback(
|
|
||||||
async (item: Plan) => {
|
|
||||||
const workouts = item.workouts.split(',');
|
|
||||||
const first = workouts[0];
|
|
||||||
const set = await getBestSet(first);
|
|
||||||
navigation.navigate('StartSession', {plan: item, set});
|
|
||||||
},
|
|
||||||
[navigation],
|
|
||||||
);
|
|
||||||
|
|
||||||
const renderItem = useCallback(
|
|
||||||
({item}: {item: Plan}) => (
|
|
||||||
<List.Item
|
|
||||||
title={item.days.replace(/,/g, ', ')}
|
|
||||||
description={item.workouts.replace(/,/g, ', ')}
|
|
||||||
onPress={() => press(item)}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
[press],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Page search={search} setSearch={setSearch}>
|
|
||||||
<FlatList
|
|
||||||
style={{height: '99%'}}
|
|
||||||
data={plans}
|
|
||||||
renderItem={renderItem}
|
|
||||||
keyExtractor={set => set.id?.toString() || ''}
|
|
||||||
ListEmptyComponent={
|
|
||||||
<List.Item
|
|
||||||
title="No plans yet"
|
|
||||||
description="After making a plan, you can use it here."
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Page>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
import {DrawerNavigationProp} from '@react-navigation/drawer';
|
|
||||||
import {useNavigation} from '@react-navigation/native';
|
|
||||||
import {createStackNavigator} from '@react-navigation/stack';
|
|
||||||
import React from 'react';
|
|
||||||
import {IconButton} from 'react-native-paper';
|
|
||||||
import {DrawerParamList} from './drawer-param-list';
|
|
||||||
import {SessionPageParams} from './session-page-params';
|
|
||||||
import SessionList from './SessionList';
|
|
||||||
import StartSession from './StartSession';
|
|
||||||
|
|
||||||
const Stack = createStackNavigator<SessionPageParams>();
|
|
||||||
|
|
||||||
export default function SessionPage() {
|
|
||||||
const navigation = useNavigation<DrawerNavigationProp<DrawerParamList>>();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Stack.Navigator
|
|
||||||
screenOptions={{headerShown: false, animationEnabled: false}}>
|
|
||||||
<Stack.Screen name="SessionList" component={SessionList} />
|
|
||||||
<Stack.Screen
|
|
||||||
name="StartSession"
|
|
||||||
component={StartSession}
|
|
||||||
listeners={{
|
|
||||||
beforeRemove: () => {
|
|
||||||
navigation.setOptions({
|
|
||||||
headerLeft: () => (
|
|
||||||
<IconButton icon="menu" onPress={navigation.openDrawer} />
|
|
||||||
),
|
|
||||||
title: 'Session',
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Stack.Navigator>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -12,13 +12,13 @@ import {MARGIN, PADDING} from './constants';
|
||||||
import CountMany from './count-many';
|
import CountMany from './count-many';
|
||||||
import MassiveInput from './MassiveInput';
|
import MassiveInput from './MassiveInput';
|
||||||
import {SnackbarContext} from './MassiveSnack';
|
import {SnackbarContext} from './MassiveSnack';
|
||||||
import {SessionPageParams} from './session-page-params';
|
import {PlanPageParams} from './plan-page-params';
|
||||||
import {addSet, countManyToday} from './set.service';
|
import {addSet, countManyToday} from './set.service';
|
||||||
import SetForm from './SetForm';
|
import SetForm from './SetForm';
|
||||||
import {useSettings} from './use-settings';
|
import {useSettings} from './use-settings';
|
||||||
|
|
||||||
export default function StartSession() {
|
export default function StartPlan() {
|
||||||
const {params} = useRoute<RouteProp<SessionPageParams, 'StartSession'>>();
|
const {params} = useRoute<RouteProp<PlanPageParams, 'StartPlan'>>();
|
||||||
const {set} = params;
|
const {set} = params;
|
||||||
const [name, setName] = useState(set.name);
|
const [name, setName] = useState(set.name);
|
||||||
const [reps, setReps] = useState(set.reps.toString());
|
const [reps, setReps] = useState(set.reps.toString());
|
||||||
|
@ -64,6 +64,7 @@ export default function StartSession() {
|
||||||
unit,
|
unit,
|
||||||
});
|
});
|
||||||
countManyToday().then(setCounts);
|
countManyToday().then(setCounts);
|
||||||
|
toast('Saved workout', 3000);
|
||||||
if (!settings.alarm) return;
|
if (!settings.alarm) return;
|
||||||
const milliseconds = Number(minutes) * 60 * 1000 + Number(seconds) * 1000;
|
const milliseconds = Number(minutes) * 60 * 1000 + Number(seconds) * 1000;
|
||||||
const args = [milliseconds, !!settings.vibrate, settings.sound];
|
const args = [milliseconds, !!settings.vibrate, settings.sound];
|
||||||
|
@ -81,11 +82,11 @@ export default function StartSession() {
|
||||||
|
|
||||||
const select = useCallback(
|
const select = useCallback(
|
||||||
async (index: number) => {
|
async (index: number) => {
|
||||||
console.log(`${StartSession.name}.next:`, {name, workouts});
|
console.log(`${StartPlan.name}.next:`, {name, workouts});
|
||||||
const workout = workouts[index];
|
const workout = workouts[index];
|
||||||
console.log(`${StartSession.name}.next:`, {workout});
|
console.log(`${StartPlan.name}.next:`, {workout});
|
||||||
const best = await getBestSet(workout);
|
const best = await getBestSet(workout);
|
||||||
console.log(`${StartSession.name}.next:`, {best});
|
console.log(`${StartPlan.name}.next:`, {best});
|
||||||
setMinutes(best.minutes);
|
setMinutes(best.minutes);
|
||||||
setSeconds(best.seconds);
|
setSeconds(best.seconds);
|
||||||
setName(best.name);
|
setName(best.name);
|
||||||
|
@ -97,7 +98,8 @@ export default function StartSession() {
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{padding: PADDING}}>
|
<View style={{padding: PADDING, flex: 1, flexDirection: 'column'}}>
|
||||||
|
<View style={{flex: 1}}>
|
||||||
<MassiveInput
|
<MassiveInput
|
||||||
label="Reps"
|
label="Reps"
|
||||||
keyboardType="numeric"
|
keyboardType="numeric"
|
||||||
|
@ -116,6 +118,7 @@ export default function StartSession() {
|
||||||
onChangeText={setWeight}
|
onChangeText={setWeight}
|
||||||
onSubmitEditing={handleSubmit}
|
onSubmitEditing={handleSubmit}
|
||||||
innerRef={weightRef}
|
innerRef={weightRef}
|
||||||
|
blurOnSubmit
|
||||||
/>
|
/>
|
||||||
{!!settings.showUnit && (
|
{!!settings.showUnit && (
|
||||||
<MassiveInput
|
<MassiveInput
|
||||||
|
@ -139,6 +142,7 @@ export default function StartSession() {
|
||||||
</Chip>
|
</Chip>
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
|
</View>
|
||||||
<Button mode="contained" icon="save" onPress={handleSubmit}>
|
<Button mode="contained" icon="save" onPress={handleSubmit}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
|
@ -83,6 +83,7 @@ class TimerService() : Service() {
|
||||||
.setProgress(0, 0, false)
|
.setProgress(0, 0, false)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
|
.setContentIntent(finishPending)
|
||||||
.setFullScreenIntent(finishPending, true)
|
.setFullScreenIntent(finishPending, true)
|
||||||
.setChannelId(CHANNEL_ID_DONE)
|
.setChannelId(CHANNEL_ID_DONE)
|
||||||
.setCategory(NotificationCompat.CATEGORY_ALARM)
|
.setCategory(NotificationCompat.CATEGORY_ALARM)
|
||||||
|
|
|
@ -4,5 +4,4 @@ export type DrawerParamList = {
|
||||||
Best: {};
|
Best: {};
|
||||||
Plans: {};
|
Plans: {};
|
||||||
Workouts: {};
|
Workouts: {};
|
||||||
Session: {};
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
import {Plan} from './plan';
|
import {Plan} from './plan';
|
||||||
|
import Set from './set';
|
||||||
|
|
||||||
export type PlanPageParams = {
|
export type PlanPageParams = {
|
||||||
PlanList: {};
|
PlanList: {};
|
||||||
EditPlan: {
|
EditPlan: {
|
||||||
plan: Plan;
|
plan: Plan;
|
||||||
};
|
};
|
||||||
|
StartPlan: {
|
||||||
|
plan: Plan;
|
||||||
|
set: Set;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
import {Plan} from './plan';
|
|
||||||
import Set from './set';
|
|
||||||
|
|
||||||
export type SessionPageParams = {
|
|
||||||
SessionList: {};
|
|
||||||
StartSession: {
|
|
||||||
plan: Plan;
|
|
||||||
set: Set;
|
|
||||||
};
|
|
||||||
};
|
|
Loading…
Reference in New Issue
Block a user