Added working exercise submission.

This commit is contained in:
Andrew Lalis 2023-01-25 12:42:33 +01:00
parent e612c084da
commit 124e833d28
3 changed files with 81 additions and 15 deletions

View File

@ -167,7 +167,7 @@ public class ExerciseSubmissionService {
Path dir = tempFilePath.getParent();
String tempFileName = tempFilePath.getFileName().toString();
String tempFileBaseName = tempFileName.substring(0, tempFileName.length() - ".tmp".length());
Path outFilePath = dir.resolve(tempFileBaseName + "-out.tmp");
Path outFilePath = dir.resolve(tempFileBaseName + "-out.mp4");
StoredFile file;
try {
processVideo(dir, tempFilePath, outFilePath);
@ -229,7 +229,6 @@ public class ExerciseSubmissionService {
.command(command)
.redirectOutput(tmpStdout.toFile())
.redirectError(tmpStderr.toFile())
.redirectInput(ProcessBuilder.Redirect.DISCARD)
.directory(dir.toFile())
.start();
int result = ffmpegProcess.waitFor();

View File

@ -6,6 +6,7 @@ export const BASE_URL = 'http://localhost:8080';
const api = axios.create({
baseURL: BASE_URL
});
api.defaults.headers.post['Content-Type'] = 'application/json';
export interface Exercise {
shortName: string,
@ -25,6 +26,17 @@ export interface ExerciseSubmissionPayload {
videoId: number
}
export interface ExerciseSubmission {
id: number,
createdAt: string,
gym: SimpleGym,
exercise: Exercise,
status: string,
submitterName: string,
weight: number,
reps: number
}
export interface Gym {
countryCode: string,
countryName: string,
@ -38,6 +50,13 @@ export interface Gym {
streetAddress: string
}
export interface SimpleGym {
countryCode: string,
cityShortName: string,
shortName: string,
displayName: string
}
/**
* Gets the URL for uploading a video file when creating an exercise submission
* for a gym.
@ -82,3 +101,11 @@ export async function getGym(
streetAddress: d.streetAddress,
};
}
export async function createSubmission(gym: Gym, payload: ExerciseSubmissionPayload): Promise<ExerciseSubmission> {
const response = await api.post(
`/gyms/${gym.countryCode}/${gym.cityShortName}/${gym.shortName}/submissions`,
payload
);
return response.data;
}

View File

@ -2,10 +2,19 @@
<q-page v-if="gym">
<q-form @submit="onSubmitted">
<SlimForm>
<div class="row">
<q-input
:label="$t('gymPage.submitPage.name')"
v-model="submissionModel.name"
class="col-12"
/>
</div>
<div class="row">
<q-select
:options="exercisesF"
v-model="submissionModel.exercise"
:options="exerciseOptions"
map-options
emit-value
v-model="submissionModel.exerciseShortName"
:label="$t('gymPage.submitPage.exercise')"
class="col-12"
/>
@ -27,7 +36,7 @@
<q-input
:label="$t('gymPage.submitPage.reps')"
type="number"
v-model="submissionModel.repCount"
v-model="submissionModel.reps"
class="col-12"
/>
</div>
@ -39,12 +48,22 @@
class="col-12"
/>
</div>
<div class="row">
<q-uploader
:url="getUploadUrl(gym)"
:label="$t('gymPage.submitPage.upload')"
field-name="file"
@uploaded="onFileUploaded"
max-file-size="1000000000"
class="col-12 q-mt-md"
/>
</div>
<div class="row">
<q-btn
:label="$t('gymPage.submitPage.submit')"
color="primary"
type="submit"
class="q-mt-sm"
class="q-mt-md col-12"
/>
</div>
</SlimForm>
@ -54,26 +73,35 @@
<script setup lang="ts">
import {onMounted, ref, Ref} from 'vue';
import {Exercise, getExercises, Gym} from 'src/api/gymboard-api';
import {
createSubmission,
Exercise,
ExerciseSubmissionPayload,
getExercises,
getUploadUrl,
Gym
} from 'src/api/gymboard-api';
import {getGymFromRoute} from 'src/router/gym-routing';
import SlimForm from 'components/SlimForm.vue';
// interface Props {
// gym: Gym
// }
// const props = defineProps<Props>();
interface Option {
value: string,
label: string
}
const gym: Ref<Gym | undefined> = ref<Gym>();
const exercises: Ref<Array<Exercise> | undefined> = ref<Array<Exercise>>();
const exerciseOptions: Ref<Array<Option>> = ref([]);
let submissionModel = ref({
exercise: null,
weight: null,
name: '',
exerciseShortName: '',
weight: 100,
weightUnit: 'Kg',
repCount: 1,
reps: 1,
videoId: -1,
date: new Date().toLocaleDateString('en-CA')
});
const weightUnits = ['Kg', 'Lbs'];
const exercisesF = ['Bench Press', 'Squat', 'Deadlift'];
// TODO: Make it possible to pass the gym to this via props instead.
onMounted(async () => {
@ -84,13 +112,25 @@ onMounted(async () => {
}
try {
exercises.value = await getExercises();
exerciseOptions.value = exercises.value.map(exercise => {
return {value: exercise.shortName, label: exercise.displayName}
});
} catch (error) {
console.error(error);
}
});
function onFileUploaded(info: {files: Array<never>, xhr: XMLHttpRequest}) {
const responseData = JSON.parse(info.xhr.responseText);
submissionModel.value.videoId = responseData.id;
}
function onSubmitted() {
console.log('submitted');
if (gym.value) {
const submission = createSubmission(gym.value, submissionModel.value);
console.log(submission);
}
}
</script>