Skip to content

Commit

Permalink
1.0.10
Browse files Browse the repository at this point in the history
+ Customize controls

Took 2 hours 35 minutes
  • Loading branch information
JulesPvx committed May 30, 2024
1 parent 9267465 commit e6ec107
Show file tree
Hide file tree
Showing 19 changed files with 1,340 additions and 812 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ android {
applicationId = "fr.angel.soundtap"
minSdk = 30
targetSdk = 34
versionCode = 29
versionName = "1.0.9"
versionCode = 32
versionName = "1.1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
33 changes: 20 additions & 13 deletions app/src/main/java/fr/angel/soundtap/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
/*
* Copyright 2024 Angel Studio
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* * Copyright (c) 2024 Angel Studio
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fr.angel.soundtap

Expand Down Expand Up @@ -108,6 +110,7 @@ class MainActivity : ComponentActivity() {
}

LaunchedEffect(key1 = Unit) {
mainViewModel.setDefaultNavController(navController)
mainViewModel.updatePermissionStates(this@MainActivity)
}

Expand Down Expand Up @@ -144,7 +147,9 @@ class MainActivity : ComponentActivity() {
enter = scaleIn(),
exit = scaleOut(),
) {
IconButton(onClick = { navController.popBackStack() }) {
IconButton(onClick = {
uiState.currentNavController.navigateUp()
}) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = "Back",
Expand Down Expand Up @@ -211,7 +216,9 @@ class MainActivity : ComponentActivity() {
)
}
Spacer(modifier = Modifier.height(24.dp))
sheetState.content(sheetState)
sheetState.content(sheetState) {
scope.launch { mainViewModel.hideBottomSheet() }
}
Spacer(modifier = Modifier.navigationBarsPadding())
}
}
Expand Down
77 changes: 66 additions & 11 deletions app/src/main/java/fr/angel/soundtap/MainViewModel.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
/*
* Copyright 2024 Angel Studio
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* * Copyright (c) 2024 Angel Studio
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fr.angel.soundtap

Expand All @@ -23,12 +25,14 @@ import androidx.compose.material3.SheetState
import androidx.datastore.core.DataStore
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.navigation.NavHostController
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import fr.angel.soundtap.data.enums.AutoPlayMode
import fr.angel.soundtap.data.enums.HapticFeedbackLevel
import fr.angel.soundtap.data.enums.WorkingMode
import fr.angel.soundtap.data.models.BottomSheetState
import fr.angel.soundtap.data.settings.customization.ControlMediaAction
import fr.angel.soundtap.data.settings.customization.CustomizationSettings
import fr.angel.soundtap.data.settings.settings.AppSettings
import fr.angel.soundtap.data.settings.stats.StatsSettings
Expand All @@ -52,7 +56,11 @@ data class MainUiState(
val customizationSettings: CustomizationSettings = CustomizationSettings(),
val appSettings: AppSettings = AppSettings(),
val statsSettings: StatsSettings = StatsSettings(),
val defaultNavController: NavHostController? = null,
val focusedNavController: NavHostController? = null,
) {
val currentNavController: NavHostController
get() = focusedNavController ?: defaultNavController!!
val defaultScreen: Screens
get() = if (appSettings.onboardingPageCompleted) Screens.App else Screens.Onboarding
}
Expand Down Expand Up @@ -208,4 +216,51 @@ class MainViewModel
fun setBottomSheetState(sheetState: SheetState) {
this.sheetState = sheetState
}

fun setDefaultNavController(navController: NavHostController) {
_uiState.value = _uiState.value.copy(defaultNavController = navController)
}

fun setFocusedNavController(navController: NavHostController) {
_uiState.value = _uiState.value.copy(focusedNavController = navController)
}

fun resetFocusedNavController() {
_uiState.value = _uiState.value.copy(focusedNavController = null)
}

fun toggleControlMediaAction(action: ControlMediaAction) {
viewModelScope.launch {
customizationSettingsDataStore.updateData { settings ->
val newAction = action.copy(enabled = !action.enabled)
when (action.id) {
0 -> settings.copy(longVolumeUpPressControlMediaAction = newAction)
1 -> settings.copy(longVolumeDownPressControlMediaAction = newAction)
2 -> settings.copy(doubleVolumeLongPressControlMediaAction = newAction)
else -> settings
}
}
}
}

fun changeControlMediaAction(controlMediaAction: ControlMediaAction) {
showBottomSheet(
BottomSheetState.EditControlMediaAction(
displayName = "Edit ${controlMediaAction.title} action",
onSetAction = { newAction ->
viewModelScope.launch {
customizationSettingsDataStore.updateData { settings ->
val newControlMediaAction = controlMediaAction.copy(action = newAction)
when (controlMediaAction.id) {
0 -> settings.copy(longVolumeUpPressControlMediaAction = newControlMediaAction)
1 -> settings.copy(longVolumeDownPressControlMediaAction = newControlMediaAction)
2 -> settings.copy(doubleVolumeLongPressControlMediaAction = newControlMediaAction)
else -> settings
}
}
}
},
),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,33 @@

package fr.angel.soundtap.data.models

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import fr.angel.soundtap.data.settings.customization.MediaAction

sealed class BottomSheetState(
open val displayName: String?,
open val onDismiss: (() -> Unit)? = null,
val content: @Composable (BottomSheetState) -> Unit,
val content: @Composable (BottomSheetState, () -> Unit) -> Unit,
) {
data object None : BottomSheetState(
displayName = "Oops, something went wrong",
content = { },
content = { _, _ ->
Text("An error occurred while trying to display the bottom sheet.")
},
)

data class SetTimer(
Expand All @@ -46,7 +53,7 @@ sealed class BottomSheetState(
val onTimerSet: (Long) -> Unit,
) : BottomSheetState(
displayName = displayName,
content = { state ->
content = { state, hide ->
val timerChoices: Map<String, Long> =
mapOf(
"5 minutes" to 5 * 60 * 1000,
Expand All @@ -58,7 +65,7 @@ sealed class BottomSheetState(
)

Column(
verticalArrangement = androidx.compose.foundation.layout.Arrangement.spacedBy(4.dp),
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
timerChoices.forEach { (label, duration) ->
Button(
Expand All @@ -71,17 +78,64 @@ sealed class BottomSheetState(
),
onClick = {
onTimerSet(duration)
hide()
state.onDismiss?.invoke()
},
) {
Text(
modifier =
Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
text = label,
textAlign = TextAlign.Start,
)
}
}
}
},
)

data class EditControlMediaAction(
override val displayName: String? = "Control Media Action",
override val onDismiss: (() -> Unit)? = null,
val onSetAction: (MediaAction) -> Unit,
) : BottomSheetState(
displayName = displayName,
content = { state, hide ->
val options = MediaAction.entries

Column(
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
options.forEach { action ->
Button(
modifier = Modifier.fillMaxWidth(),
shape = MaterialTheme.shapes.medium,
colors =
ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.surfaceContainerHigh,
contentColor = MaterialTheme.colorScheme.onSurface,
),
onClick = {
onSetAction(action)

hide()
// Dismiss the bottom sheet
state.onDismiss?.invoke()
},
) {
Icon(
imageVector = action.icon,
contentDescription = null,
)
Spacer(modifier = Modifier.width(8.dp))
Text(
modifier =
Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
text = label,
text = action.title,
textAlign = TextAlign.Start,
)
}
Expand Down
Loading

0 comments on commit e6ec107

Please sign in to comment.