Skip to content
This repository has been archived by the owner on Mar 18, 2024. It is now read-only.

Commit

Permalink
Add rpe
Browse files Browse the repository at this point in the history
  • Loading branch information
AnkitSuda committed Nov 12, 2022
1 parent 7e7b6d9 commit 2b48121
Show file tree
Hide file tree
Showing 12 changed files with 538 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import com.ankitsuda.rebound.ui.measure.MeasureScreen
import com.ankitsuda.rebound.ui.exercise_details.ExerciseDetailScreen
import com.ankitsuda.rebound.ui.exercises.ExercisesScreen
import com.ankitsuda.rebound.ui.calendar.CalendarScreen
import com.ankitsuda.rebound.ui.components.workouteditor.rpeselector.RpeSelectorBottomSheet
import com.ankitsuda.rebound.ui.components.workouteditor.supersetselector.SupersetSelectorBottomSheet
import com.ankitsuda.rebound.ui.create_exercise.CreateExerciseScreen
import com.ankitsuda.rebound.ui.customizeplates.CustomizePlatesScreen
Expand Down Expand Up @@ -127,6 +128,7 @@ internal fun AppNavigation(
addExercisesBottomSheet(navController)
addRestTimer(navController)
addSupersetSelector(navController)
addRpeSelector(navController)
}
}

Expand Down Expand Up @@ -401,6 +403,12 @@ private fun NavGraphBuilder.addSupersetSelector(navController: NavController) {
}
}

private fun NavGraphBuilder.addRpeSelector(navController: NavController) {
bottomSheetScreen(LeafScreen.RpeSelector()) {
RpeSelectorBottomSheet(navController)
}
}


/**
* Adds an [NavController.OnDestinationChangedListener] to this [NavController] and updates the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ import com.ankitsuda.rebound.domain.entities.ExerciseSetGroupNote
import com.ankitsuda.rebound.domain.entities.ExerciseWorkoutJunction
import com.ankitsuda.rebound.domain.entities.LogEntriesWithExerciseJunction
import com.ankitsuda.rebound.ui.components.AppTextField
import com.ankitsuda.rebound.ui.components.workouteditor.rpeselector.models.RpeSelectorResult
import com.ankitsuda.rebound.ui.components.workouteditor.supersetselector.models.SupersetSelectorResult
import com.ankitsuda.rebound.ui.components.workouteditor.warmupcalculator.toExerciseLogEntries
import com.ankitsuda.rebound.ui.keyboard.LocalReboundSetKeyboard
import com.ankitsuda.rebound.ui.theme.ReboundTheme
import com.google.accompanist.insets.LocalWindowInsets
import timber.log.Timber
import kotlin.math.log

@OptIn(ExperimentalComposeUiApi::class, ExperimentalFoundationApi::class)
Expand Down Expand Up @@ -87,6 +89,12 @@ fun WorkoutEditorComponent(
?.getStateFlow<SupersetSelectorResult?>(RESULT_SUPERSET_SELECTOR_SUPERSET_ID_KEY, null)
?.collectAsState()

// Observes results when RPE Selector changes value of arg
val rpeSelectorResult = navController.currentBackStackEntry
?.savedStateHandle
?.getStateFlow<RpeSelectorResult?>(RESULT_RPE_SELECTOR_KEY, null)
?.collectAsState()

val navigationBarHeight =
with(LocalDensity.current) { if (addNavigationBarPadding) LocalWindowInsets.current.navigationBars.bottom.toDp() else 0.dp }

Expand Down Expand Up @@ -117,6 +125,26 @@ fun WorkoutEditorComponent(
}
}

LaunchedEffect(key1 = rpeSelectorResult?.value) {
rpeSelectorResult?.value?.let { result ->

logEntriesWithJunction.flatMap { it.logEntries }.find {
it.entryId == result.entryId
}?.let {
onUpdateLogEntry(
it.copy(
rpe = result.rpe
)
)
}

navController.currentBackStackEntry?.savedStateHandle?.set(
RESULT_RPE_SELECTOR_KEY,
null
)
}
}

val keyboardController = LocalSoftwareKeyboardController.current
val reboundKeyboard = LocalReboundSetKeyboard.current
fun hideKeyboard() {
Expand Down Expand Up @@ -221,6 +249,15 @@ fun WorkoutEditorComponent(
junctionId = logEntriesWithJunctionItem.junction.id,
)
)
},
onRequestRpeSelector = {
hideKeyboard()
navigator.navigate(
LeafScreen.RpeSelector.createRoute(
it.entryId,
it.rpe
)
)
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
Expand Down Expand Up @@ -70,6 +72,7 @@ fun LazyListScope.workoutExerciseItemAlt(
onChangeNote: (ExerciseSetGroupNote) -> Unit,
onAddToSuperset: () -> Unit,
onRemoveFromSuperset: () -> Unit,
onRequestRpeSelector: (ExerciseLogEntry) -> Unit,
) {

val supersetId = logEntriesWithJunction.junction.supersetId
Expand Down Expand Up @@ -238,6 +241,19 @@ fun LazyListScope.workoutExerciseItemAlt(
textAlign = TextAlign.Center,
modifier = Modifier.weight(1.25f)
)

if (exercise.category == ExerciseCategory.WEIGHTS_AND_REPS
|| exercise.category == ExerciseCategory.REPS
) {
Text(
text = stringResource(id = R.string.rpe),
style = ReboundTheme.typography.caption,
color = ReboundTheme.colors.onBackground.copy(alpha = 0.5f),
textAlign = TextAlign.Center,
modifier = Modifier.weight(.75f)
)
}

Box(
modifier = Modifier.weight(0.5f),
contentAlignment = Alignment.Center,
Expand Down Expand Up @@ -278,8 +294,9 @@ fun LazyListScope.workoutExerciseItemAlt(
val revisedSetsTexts = getRevisedSetNumbers()

items(items = sortedEntries, key = {
"${it.entryId}_${it.rpe}"
// "${it.entryId}_${it.setNumber}"
it.entryId
// it.entryId
}) { entry ->
SetItem(
useReboundKeyboard = useReboundKeyboard,
Expand All @@ -291,7 +308,8 @@ fun LazyListScope.workoutExerciseItemAlt(
},
onSwipeDelete = {
onSwipeDelete(it)
}
},
onRequestRpeSelector = onRequestRpeSelector
)
}

Expand Down Expand Up @@ -330,6 +348,7 @@ private fun LazyItemScope.SetItem(
exerciseLogEntry: ExerciseLogEntry,
onChange: (ExerciseLogEntry) -> Unit,
onSwipeDelete: (ExerciseLogEntry) -> Unit,
onRequestRpeSelector: (ExerciseLogEntry) -> Unit,
) {
var mLogEntry by rememberSaveable {
mutableStateOf(exerciseLogEntry)
Expand Down Expand Up @@ -448,6 +467,7 @@ private fun LazyItemScope.SetItem(
onSetTypeChange = { _, value ->
handleOnChange(mLogEntry.copy(setType = value))
},
onRequestRpeSelector = onRequestRpeSelector
)
}
}
Expand All @@ -466,6 +486,7 @@ private fun SetItemLayout(
onTimeChange: (ExerciseLogEntry, Long?) -> Unit,
onCompleteChange: (ExerciseLogEntry, Boolean) -> Unit,
onSetTypeChange: (ExerciseLogEntry, LogSetType) -> Unit,
onRequestRpeSelector: (ExerciseLogEntry) -> Unit,
) {
val typeOfSet = exerciseLogEntry.setType ?: LogSetType.NORMAL
var isSetTypeChangerExpanded by rememberSaveable {
Expand Down Expand Up @@ -596,6 +617,32 @@ private fun SetItemLayout(
)
}

if (exercise.category == ExerciseCategory.WEIGHTS_AND_REPS
|| exercise.category == ExerciseCategory.REPS
) {
Box(
modifier = Modifier
.defaultMinSize(minHeight = 32.dp)
.padding(start = 8.dp, end = 8.dp)
.weight(0.75f)
.clip(RoundedCornerShape(12.dp))
.background(bgColor.lighterOrDarkerColor(0.10f))
.clickable {
onRequestRpeSelector(exerciseLogEntry)
},
contentAlignment = Alignment.Center
) {
Text(
exerciseLogEntry.rpe?.toReadableString() ?: "",
style = LocalTextStyle.current.copy(
textAlign = TextAlign.Center,
fontSize = 14.sp,
color = contentColor
)
)
}
}

IconButton(
onClick = {
onCompleteChange(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright (c) 2022 Ankit Suda.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/

package com.ankitsuda.rebound.ui.components.workouteditor.rpeselector

import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.ankitsuda.navigation.ENTRY_ID_KEY
import com.ankitsuda.navigation.RESULT_RPE_SELECTOR_KEY
import com.ankitsuda.navigation.RPE_KEY
import com.ankitsuda.rebound.ui.components.BottomSheetRButton
import com.ankitsuda.rebound.ui.components.BottomSheetSecondaryRButton
import com.ankitsuda.rebound.ui.components.BottomSheetSurface
import com.ankitsuda.rebound.ui.components.TopBar
import com.ankitsuda.rebound.ui.components.workouteditor.R
import com.ankitsuda.rebound.ui.components.workouteditor.rpeselector.components.RpeSlider
import com.ankitsuda.rebound.ui.components.workouteditor.rpeselector.components.SelectedRpeOverview
import com.ankitsuda.rebound.ui.components.workouteditor.rpeselector.models.RpeSelectorResult

@Composable
fun RpeSelectorBottomSheet(
navController: NavController
) {
val initialRpe: Float? = with(
navController.currentBackStackEntry?.arguments
?.getFloat(RPE_KEY)
) {
if (this == -1f) null else this
}

var rpe: Float? by rememberSaveable {
mutableStateOf(initialRpe)
}

fun handleSelectClick() {

navController.currentBackStackEntry?.arguments?.getString(ENTRY_ID_KEY)?.let {
navController.previousBackStackEntry?.savedStateHandle?.set(
RESULT_RPE_SELECTOR_KEY,
RpeSelectorResult(
entryId = it,
rpe = rpe,
)
)
}

navController.popBackStack()

}

BottomSheetSurface {
Column(
modifier = Modifier
.fillMaxWidth()
.navigationBarsPadding(),
) {
TopBar(
title = stringResource(id = R.string.rpe),
statusBarEnabled = false,
elevationEnabled = false
)
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
SelectedRpeOverview(
modifier = Modifier.fillMaxWidth(),
rpe = rpe,
)
RpeSlider(
modifier = Modifier.fillMaxWidth(),
value = rpe,
onValueChange = {
rpe = it
}
)
}
Row(
Modifier
.padding(end = 16.dp, start = 16.dp, bottom = 16.dp, top = 16.dp)
.align(Alignment.End)
) {
BottomSheetSecondaryRButton(
modifier = Modifier.padding(end = 16.dp),
onClick = {
navController.popBackStack()
}) {
Text(stringResource(id = R.string.cancel))
}

BottomSheetRButton(
onClick = ::handleSelectClick,
modifier = Modifier.width(88.dp)
) {
Text(stringResource(id = R.string.select))
}
}
}
}
}
Loading

0 comments on commit 2b48121

Please sign in to comment.