parent
f6a75d89cd
commit
608bb3e97a
|
@ -8,7 +8,7 @@ import {
|
||||||
import { useCallback, useRef, useState } from "react";
|
import { useCallback, useRef, useState } from "react";
|
||||||
import { ScrollView, TextInput, View } from "react-native";
|
import { ScrollView, TextInput, View } from "react-native";
|
||||||
import DocumentPicker from "react-native-document-picker";
|
import DocumentPicker from "react-native-document-picker";
|
||||||
import { Button, Card, TouchableRipple } from "react-native-paper";
|
import { Button, Card, IconButton, TouchableRipple } from "react-native-paper";
|
||||||
import AppInput from "./AppInput";
|
import AppInput from "./AppInput";
|
||||||
import { StackParams } from "./AppStack";
|
import { StackParams } from "./AppStack";
|
||||||
import ConfirmDialog from "./ConfirmDialog";
|
import ConfirmDialog from "./ConfirmDialog";
|
||||||
|
@ -25,7 +25,8 @@ import { toast } from "./toast";
|
||||||
export default function EditExercise() {
|
export default function EditExercise() {
|
||||||
const { params } = useRoute<RouteProp<StackParams, "EditExercise">>();
|
const { params } = useRoute<RouteProp<StackParams, "EditExercise">>();
|
||||||
const [removeImage, setRemoveImage] = useState(false);
|
const [removeImage, setRemoveImage] = useState(false);
|
||||||
const [showRemove, setShowRemove] = useState(false);
|
const [showRemoveImage, setShowRemoveImage] = useState(false);
|
||||||
|
const [showDelete, setShowDelete] = useState(false);
|
||||||
const [name, setName] = useState(params.gymSet.name);
|
const [name, setName] = useState(params.gymSet.name);
|
||||||
const [steps, setSteps] = useState(params.gymSet.steps);
|
const [steps, setSteps] = useState(params.gymSet.steps);
|
||||||
const [uri, setUri] = useState(params.gymSet.image);
|
const [uri, setUri] = useState(params.gymSet.image);
|
||||||
|
@ -45,16 +46,22 @@ export default function EditExercise() {
|
||||||
|
|
||||||
useFocusEffect(
|
useFocusEffect(
|
||||||
useCallback(() => {
|
useCallback(() => {
|
||||||
settingsRepo.findOne({ where: {} }).then(setSettings);
|
settingsRepo.findOne({ where: {} }).then((gotSettings) => {
|
||||||
}, [])
|
setSettings(gotSettings);
|
||||||
|
if (params.gymSet.id) return;
|
||||||
|
setSets(gotSettings.defaultSets?.toString() ?? "3");
|
||||||
|
setMinutes(gotSettings.defaultMinutes?.toString() ?? "3");
|
||||||
|
setSeconds(gotSettings.defaultSeconds?.toString() ?? "30");
|
||||||
|
});
|
||||||
|
}, [params.gymSet.id])
|
||||||
);
|
);
|
||||||
|
|
||||||
const update = async () => {
|
const update = async () => {
|
||||||
const newExercise = {
|
const newExercise = {
|
||||||
name: name || params.gymSet.name,
|
name: name || params.gymSet.name,
|
||||||
sets: Number(sets),
|
sets: Number(sets),
|
||||||
minutes: +minutes,
|
minutes: Number(minutes),
|
||||||
seconds: +seconds,
|
seconds: Number(seconds),
|
||||||
steps,
|
steps,
|
||||||
image: removeImage ? "" : uri,
|
image: removeImage ? "" : uri,
|
||||||
} as GymSet;
|
} as GymSet;
|
||||||
|
@ -75,15 +82,20 @@ export default function EditExercise() {
|
||||||
name,
|
name,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
image: uri,
|
image: uri,
|
||||||
minutes: minutes ? +minutes : 3,
|
minutes: minutes ? Number(minutes) : 3,
|
||||||
seconds: seconds ? +seconds : 30,
|
seconds: seconds ? Number(seconds) : 30,
|
||||||
sets: sets ? +sets : 3,
|
sets: sets ? Number(sets) : 3,
|
||||||
steps,
|
steps,
|
||||||
created: now,
|
created: now,
|
||||||
});
|
});
|
||||||
navigate("Exercises");
|
navigate("Exercises");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const remove = async () => {
|
||||||
|
await setRepo.delete({ name: params.gymSet.name });
|
||||||
|
navigate("Exercises");
|
||||||
|
};
|
||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
if (params.gymSet.name) return update();
|
if (params.gymSet.name) return update();
|
||||||
return add();
|
return add();
|
||||||
|
@ -100,7 +112,7 @@ export default function EditExercise() {
|
||||||
const handleRemove = useCallback(async () => {
|
const handleRemove = useCallback(async () => {
|
||||||
setUri("");
|
setUri("");
|
||||||
setRemoveImage(true);
|
setRemoveImage(true);
|
||||||
setShowRemove(false);
|
setShowRemoveImage(false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const submitName = () => {
|
const submitName = () => {
|
||||||
|
@ -112,7 +124,11 @@ export default function EditExercise() {
|
||||||
<>
|
<>
|
||||||
<StackHeader
|
<StackHeader
|
||||||
title={params.gymSet.name ? "Edit exercise" : "Add exercise"}
|
title={params.gymSet.name ? "Edit exercise" : "Add exercise"}
|
||||||
/>
|
>
|
||||||
|
{typeof params.gymSet.id === "number" ? (
|
||||||
|
<IconButton onPress={() => setShowDelete(true)} icon="delete" />
|
||||||
|
) : null}
|
||||||
|
</StackHeader>
|
||||||
<View style={{ padding: PADDING, flex: 1 }}>
|
<View style={{ padding: PADDING, flex: 1 }}>
|
||||||
<ScrollView style={{ flex: 1 }}>
|
<ScrollView style={{ flex: 1 }}>
|
||||||
<AppInput
|
<AppInput
|
||||||
|
@ -175,7 +191,7 @@ export default function EditExercise() {
|
||||||
<TouchableRipple
|
<TouchableRipple
|
||||||
style={{ marginBottom: MARGIN }}
|
style={{ marginBottom: MARGIN }}
|
||||||
onPress={changeImage}
|
onPress={changeImage}
|
||||||
onLongPress={() => setShowRemove(true)}
|
onLongPress={() => setShowRemoveImage(true)}
|
||||||
>
|
>
|
||||||
<Card.Cover source={{ uri }} />
|
<Card.Cover source={{ uri }} />
|
||||||
</TouchableRipple>
|
</TouchableRipple>
|
||||||
|
@ -193,14 +209,24 @@ export default function EditExercise() {
|
||||||
<PrimaryButton disabled={!name} icon="content-save" onPress={save}>
|
<PrimaryButton disabled={!name} icon="content-save" onPress={save}>
|
||||||
Save
|
Save
|
||||||
</PrimaryButton>
|
</PrimaryButton>
|
||||||
|
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
title="Remove image"
|
title="Remove image"
|
||||||
onOk={handleRemove}
|
onOk={handleRemove}
|
||||||
show={showRemove}
|
show={showRemoveImage}
|
||||||
setShow={setShowRemove}
|
setShow={setShowRemoveImage}
|
||||||
>
|
>
|
||||||
Are you sure you want to remove the image?
|
Are you sure you want to remove the image?
|
||||||
</ConfirmDialog>
|
</ConfirmDialog>
|
||||||
|
|
||||||
|
<ConfirmDialog
|
||||||
|
title="Delete set"
|
||||||
|
show={showDelete}
|
||||||
|
onOk={remove}
|
||||||
|
setShow={setShowDelete}
|
||||||
|
>
|
||||||
|
<>Are you sure you want to delete {name}</>
|
||||||
|
</ConfirmDialog>
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
27
EditSet.tsx
27
EditSet.tsx
|
@ -49,7 +49,7 @@ export default function EditSet() {
|
||||||
set.created ? new Date(set.created) : new Date()
|
set.created ? new Date(set.created) : new Date()
|
||||||
);
|
);
|
||||||
const [createdDirty, setCreatedDirty] = useState(false);
|
const [createdDirty, setCreatedDirty] = useState(false);
|
||||||
const [showRemove, setShowRemove] = useState(false);
|
const [showRemoveImage, setShowRemoveImage] = useState(false);
|
||||||
const [removeImage, setRemoveImage] = useState(false);
|
const [removeImage, setRemoveImage] = useState(false);
|
||||||
const [setOptions, setSets] = useState<GymSet[]>([]);
|
const [setOptions, setSets] = useState<GymSet[]>([]);
|
||||||
const weightRef = useRef<TextInput>(null);
|
const weightRef = useRef<TextInput>(null);
|
||||||
|
@ -145,7 +145,7 @@ export default function EditSet() {
|
||||||
const handleRemove = useCallback(async () => {
|
const handleRemove = useCallback(async () => {
|
||||||
setNewImage("");
|
setNewImage("");
|
||||||
setRemoveImage(true);
|
setRemoveImage(true);
|
||||||
setShowRemove(false);
|
setShowRemoveImage(false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const pickDate = useCallback(() => {
|
const pickDate = useCallback(() => {
|
||||||
|
@ -202,14 +202,6 @@ export default function EditSet() {
|
||||||
<IconButton onPress={() => setShowDelete(true)} icon="delete" />
|
<IconButton onPress={() => setShowDelete(true)} icon="delete" />
|
||||||
) : null}
|
) : null}
|
||||||
</StackHeader>
|
</StackHeader>
|
||||||
<ConfirmDialog
|
|
||||||
title="Delete set"
|
|
||||||
show={showDelete}
|
|
||||||
onOk={remove}
|
|
||||||
setShow={setShowDelete}
|
|
||||||
>
|
|
||||||
<>Are you sure you want to delete {name}</>
|
|
||||||
</ConfirmDialog>
|
|
||||||
|
|
||||||
<View style={{ padding: PADDING, flex: 1 }}>
|
<View style={{ padding: PADDING, flex: 1 }}>
|
||||||
<View>
|
<View>
|
||||||
|
@ -324,7 +316,7 @@ export default function EditSet() {
|
||||||
<TouchableRipple
|
<TouchableRipple
|
||||||
style={{ marginBottom: MARGIN }}
|
style={{ marginBottom: MARGIN }}
|
||||||
onPress={changeImage}
|
onPress={changeImage}
|
||||||
onLongPress={() => setShowRemove(true)}
|
onLongPress={() => setShowRemoveImage(true)}
|
||||||
>
|
>
|
||||||
<Card.Cover source={{ uri: newImage }} />
|
<Card.Cover source={{ uri: newImage }} />
|
||||||
</TouchableRipple>
|
</TouchableRipple>
|
||||||
|
@ -353,11 +345,20 @@ export default function EditSet() {
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
title="Remove image"
|
title="Remove image"
|
||||||
onOk={handleRemove}
|
onOk={handleRemove}
|
||||||
show={showRemove}
|
show={showRemoveImage}
|
||||||
setShow={setShowRemove}
|
setShow={setShowRemoveImage}
|
||||||
>
|
>
|
||||||
Are you sure you want to remove the image?
|
Are you sure you want to remove the image?
|
||||||
</ConfirmDialog>
|
</ConfirmDialog>
|
||||||
|
|
||||||
|
<ConfirmDialog
|
||||||
|
title="Delete set"
|
||||||
|
show={showDelete}
|
||||||
|
onOk={remove}
|
||||||
|
setShow={setShowDelete}
|
||||||
|
>
|
||||||
|
<>Are you sure you want to delete {name}</>
|
||||||
|
</ConfirmDialog>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,6 +269,60 @@ export default function SettingsPage() {
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Default sets",
|
||||||
|
renderItem: (name: string) => (
|
||||||
|
<AppInput
|
||||||
|
value={settings.defaultSets?.toString() ?? "3"}
|
||||||
|
label={name}
|
||||||
|
onChangeText={(value) => setValue("defaultSets", Number(value))}
|
||||||
|
onSubmitEditing={async (e) => {
|
||||||
|
const value = e.nativeEvent.text;
|
||||||
|
setValue("defaultSets", Number(value));
|
||||||
|
await update("defaultSets", value);
|
||||||
|
toast(`New exercises now have ${value} sets by default.`);
|
||||||
|
}}
|
||||||
|
keyboardType="numeric"
|
||||||
|
blurOnSubmit
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Default minutes",
|
||||||
|
renderItem: (name: string) => (
|
||||||
|
<AppInput
|
||||||
|
value={settings.defaultMinutes?.toString() ?? "3"}
|
||||||
|
label={name}
|
||||||
|
onChangeText={(value) => setValue("defaultMinutes", Number(value))}
|
||||||
|
onSubmitEditing={async (e) => {
|
||||||
|
const value = e.nativeEvent.text;
|
||||||
|
setValue("defaultMinutes", Number(value));
|
||||||
|
await update("defaultMinutes", value);
|
||||||
|
toast(`New exercises now wait ${value} minutes by default.`);
|
||||||
|
}}
|
||||||
|
keyboardType="numeric"
|
||||||
|
blurOnSubmit
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Default seconds",
|
||||||
|
renderItem: (name: string) => (
|
||||||
|
<AppInput
|
||||||
|
value={settings.defaultSeconds?.toString() ?? "30"}
|
||||||
|
label={name}
|
||||||
|
onChangeText={(value) => setValue("defaultSeconds", Number(value))}
|
||||||
|
onSubmitEditing={async (e) => {
|
||||||
|
const value = e.nativeEvent.text;
|
||||||
|
setValue("defaultSeconds", Number(value));
|
||||||
|
await update("defaultSeconds", value);
|
||||||
|
toast(`New exercises now wait ${value} seconds by default.`);
|
||||||
|
}}
|
||||||
|
keyboardType="numeric"
|
||||||
|
blurOnSubmit
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Rest timers",
|
name: "Rest timers",
|
||||||
renderItem: (name: string) => (
|
renderItem: (name: string) => (
|
||||||
|
|
|
@ -125,8 +125,8 @@ export default function StartPlan() {
|
||||||
await refresh();
|
await refresh();
|
||||||
if (
|
if (
|
||||||
settings.notify &&
|
settings.notify &&
|
||||||
(+weight > best.weight ||
|
(Number(weight) > best.weight ||
|
||||||
(Number(reps) > best.reps && +weight === best.weight))
|
(Number(reps) > best.reps && Number(weight) === best.weight))
|
||||||
) {
|
) {
|
||||||
toast("Great work King! That's a new record.");
|
toast("Great work King! That's a new record.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,8 +85,8 @@ android {
|
||||||
applicationId "com.massive"
|
applicationId "com.massive"
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 36214
|
versionCode 36216
|
||||||
versionName "1.188"
|
versionName "2.1"
|
||||||
}
|
}
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
release {
|
release {
|
||||||
|
|
|
@ -37,6 +37,8 @@ import { autoConvert1699948105001 } from "./migrations/1699948105001-auto-conver
|
||||||
import { Plan } from "./plan";
|
import { Plan } from "./plan";
|
||||||
import Settings from "./settings";
|
import Settings from "./settings";
|
||||||
import Weight from "./weight";
|
import Weight from "./weight";
|
||||||
|
import { settingsDefaultSets1700009253976 } from "./migrations/1700009253976-settings-default-sets";
|
||||||
|
import { settingsDefaults1700009729468 } from "./migrations/1700009729468-settings-defaults";
|
||||||
|
|
||||||
export const AppDataSource = new DataSource({
|
export const AppDataSource = new DataSource({
|
||||||
type: "react-native",
|
type: "react-native",
|
||||||
|
@ -80,5 +82,7 @@ export const AppDataSource = new DataSource({
|
||||||
settingsBackupDir1699839054226,
|
settingsBackupDir1699839054226,
|
||||||
homeHistoryStartup1699853245534,
|
homeHistoryStartup1699853245534,
|
||||||
autoConvert1699948105001,
|
autoConvert1699948105001,
|
||||||
|
settingsDefaultSets1700009253976,
|
||||||
|
settingsDefaults1700009729468,
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class settingsDefaultSets1700009253976 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE settings ADD COLUMN defaultSets INTEGER"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class settingsDefaults1700009729468 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE settings ADD COLUMN defaultMinutes INTEGER"
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE settings ADD COLUMN defaultSeconds INTEGER"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "massive",
|
"name": "massive",
|
||||||
"version": "1.188",
|
"version": "2.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "GPL-3.0-only",
|
"license": "GPL-3.0-only",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -55,4 +55,13 @@ export default class Settings {
|
||||||
|
|
||||||
@Column("text")
|
@Column("text")
|
||||||
autoConvert: string | null;
|
autoConvert: string | null;
|
||||||
|
|
||||||
|
@Column("int")
|
||||||
|
defaultSets: number | null;
|
||||||
|
|
||||||
|
@Column("int")
|
||||||
|
defaultMinutes: number | null;
|
||||||
|
|
||||||
|
@Column("int")
|
||||||
|
defaultSeconds: number | null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue