Skip to content

Commit

Permalink
Merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
yzueger committed May 19, 2024
2 parents 2ba020e + e95a829 commit 1df9b2a
Show file tree
Hide file tree
Showing 40 changed files with 238 additions and 94 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/CI.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,4 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: instrumentation-test-logs
path: instrumentation_test_log.txt
path: instrumentation_test_log.txt
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,11 @@ class BeaconScreenViewModelTest {
assertFalse(uiStateError.isLoading)
assertEquals("Test Exception", uiStateError.error)
}

@Test
fun emptyChildrenList_clearsChildrenPlaylistTrackList() = runBlockingTest {

// Act
viewModel.emptyChildrenList()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,11 @@ class TrackListViewModelTest {
assertEquals(emptyList<Track>(), viewModel.uiState.value.tracks)
assertEquals(false, viewModel.uiState.value.loading)
}

@Test
fun emptyChildrenList_clearsChildrenPlaylistTrackList() = runBlockingTest {

// Act
viewModel.emptyChildrenList()
}
}
Binary file added app/src/main/ic_launcher-playstore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package ch.epfl.cs311.wanderwave.ui.components

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.List
import androidx.compose.material.icons.filled.LocationOn
Expand All @@ -11,11 +15,16 @@ import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import ch.epfl.cs311.wanderwave.R
import ch.epfl.cs311.wanderwave.navigation.NavigationActions
import ch.epfl.cs311.wanderwave.navigation.Route
import ch.epfl.cs311.wanderwave.navigation.TOP_LEVEL_DESTINATIONS
Expand Down Expand Up @@ -45,34 +54,53 @@ fun AppBottomBar(navActions: NavigationActions) {
Modifier.fillMaxWidth()
.background(MaterialTheme.colorScheme.surface)
.testTag("appBottomBar"),
) {
// Assumes TOP_LEVEL_DESTINATIONS are in the order of Track List, Main, and Map for indexing
IconButton(
onClick = { navActions.navigateToTopLevel(TOP_LEVEL_DESTINATIONS[0].route) },
modifier =
Modifier.weight(1f) // Spread the icons evenly across the BottomAppBar
.testTag("bottomAppBarButton" + Route.TRACK_LIST.routeString)) {
Icon(
trackListIcon,
contentDescription = stringResource(id = TOP_LEVEL_DESTINATIONS[0].textId))
}
containerColor = MaterialTheme.colorScheme.scrim) {
// Assumes TOP_LEVEL_DESTINATIONS are in the order of Track List, Main, and Map for indexing
IconButton(
onClick = { navActions.navigateToTopLevel(TOP_LEVEL_DESTINATIONS[0].route) },
modifier =
Modifier.weight(1f) // Spread the icons evenly across the BottomAppBar
.testTag("bottomAppBarButton" + Route.TRACK_LIST.routeString)) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxHeight()) {
Icon(
trackListIcon,
contentDescription = stringResource(id = TOP_LEVEL_DESTINATIONS[0].textId),
)
Text(
text = stringResource(id = R.string.trackList),
style = MaterialTheme.typography.bodySmall)
}
}

Spacer(Modifier.weight(1f)) // Spacer for centering the middle icon
IconButton(
onClick = { navActions.navigateToTopLevel(TOP_LEVEL_DESTINATIONS[1].route) },
modifier = Modifier.weight(1f).testTag("bottomAppBarButton" + Route.MAP.routeString)) {
Image(
modifier = Modifier.padding(top = 5.dp, bottom = 5.dp),
painter = painterResource(id = R.drawable.beaconlogo),
contentDescription = "Beacon icon",
)
}

IconButton(
onClick = { navActions.navigateToTopLevel(TOP_LEVEL_DESTINATIONS[1].route) },
modifier = Modifier.weight(1f).testTag("bottomAppBarButton" + Route.MAP.routeString)) {
Icon(mapIcon, contentDescription = stringResource(id = TOP_LEVEL_DESTINATIONS[1].textId))
}

Spacer(Modifier.weight(1f)) // Spacer for centering the middle icon

IconButton(
onClick = { navActions.navigateToTopLevel(TOP_LEVEL_DESTINATIONS[2].route) },
modifier = Modifier.weight(1f).testTag("bottomAppBarButton" + Route.PROFILE.routeString)) {
Icon(
profileIcon,
contentDescription = stringResource(id = TOP_LEVEL_DESTINATIONS[2].textId))
}
}
IconButton(
onClick = { navActions.navigateToTopLevel(TOP_LEVEL_DESTINATIONS[2].route) },
modifier =
Modifier.weight(1f).testTag("bottomAppBarButton" + Route.PROFILE.routeString)) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxHeight()) {
Icon(
profileIcon,
contentDescription = stringResource(id = TOP_LEVEL_DESTINATIONS[2].textId),
)
Text(
text = stringResource(id = R.string.profile),
style = MaterialTheme.typography.bodySmall)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
Expand Down Expand Up @@ -49,13 +51,15 @@ fun ExclusivePlayer(
Column(verticalArrangement = Arrangement.Top) {
PlayerDragHandleComponent(checked)
Box(
contentAlignment = Alignment.TopStart,
modifier = Modifier.padding(start = 5.dp, top = 5.dp)) {
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxWidth().padding(top = 10.dp)) {
SwitchComponent(checked)
}
Spacer(modifier = Modifier.height(10.dp))
PlayerIconButtonRowComponent()
Spacer(modifier = Modifier.height(15.dp))
VotingButtonsComponent(selectedVote)
}
PlayerIconButtonRowComponent()
VotingButtonsComponent(selectedVote)
TrackInfoComponent(uiState)
SliderComponent(progress)
PlayerControlRowComponent(viewModel, uiState)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ fun TrackList(
}
}
}

var selectedTrack by remember { mutableStateOf<Track?>(null) }
LazyColumn {
LazyColumn(Modifier.padding(bottom = 63.dp)) {
items(tracks) { track ->
TrackListItem(
track,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.OutlinedTextField
Expand All @@ -25,11 +27,13 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import ch.epfl.cs311.wanderwave.R
import ch.epfl.cs311.wanderwave.navigation.NavigationActions
import ch.epfl.cs311.wanderwave.navigation.Route
import ch.epfl.cs311.wanderwave.ui.components.profile.ImageSelection
import ch.epfl.cs311.wanderwave.ui.theme.md_theme_light_error
import ch.epfl.cs311.wanderwave.ui.theme.md_theme_dark_error
import ch.epfl.cs311.wanderwave.ui.theme.md_theme_light_primary
import ch.epfl.cs311.wanderwave.viewmodel.ProfileViewModel

Expand All @@ -55,7 +59,7 @@ fun EditProfileScreen(navActions: NavigationActions, viewModel: ProfileViewModel

Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.testTag("editProfileScreen")) {
modifier = Modifier.testTag("editProfileScreen").fillMaxHeight()) {
ImageSelection(
profile = profile2, onImageChange = { uri -> profile2.profilePictureUri = uri })
EditableTextFields(
Expand Down Expand Up @@ -168,24 +172,27 @@ fun ActionButtons(onSave: () -> Unit, onCancel: () -> Unit, onDelete: () -> Unit
Button(
onClick = onSave,
colors = ButtonDefaults.buttonColors(containerColor = md_theme_light_primary),
modifier = Modifier.width(100.dp).testTag("saveButton")) {
Text("Save")
modifier = Modifier.width(100.dp).testTag("saveButton"),
shape = RoundedCornerShape(size = 10.dp)) {
Text(stringResource(id = R.string.save))
}
Spacer(modifier = Modifier.width(8.dp))
Button(
onClick = onCancel,
colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent),
border = BorderStroke(1.dp, md_theme_light_error),
border = BorderStroke(1.dp, md_theme_dark_error),
shape = RoundedCornerShape(size = 10.dp),
modifier = Modifier.width(100.dp).testTag("cancelButton")) {
Text(text = "Cancel", color = md_theme_light_error)
Text(text = stringResource(id = R.string.cancel), color = md_theme_dark_error)
}
Spacer(Modifier.padding(8.dp))
Button(
onClick = onDelete,
colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent),
border = BorderStroke(1.dp, md_theme_light_error),
border = BorderStroke(1.dp, md_theme_dark_error),
shape = RoundedCornerShape(size = 10.dp),
modifier = Modifier.width(200.dp).testTag("deleteButton")) {
Text(text = "Delete profile", color = md_theme_light_error)
Text(text = stringResource(id = R.string.deleteProfile), color = md_theme_dark_error)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ch.epfl.cs311.wanderwave.ui.screens

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand All @@ -12,9 +13,12 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Create
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Switch
import androidx.compose.material3.SwitchDefaults
Expand All @@ -32,8 +36,11 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import ch.epfl.cs311.wanderwave.R
import ch.epfl.cs311.wanderwave.model.data.ListType
import ch.epfl.cs311.wanderwave.model.data.Profile
import ch.epfl.cs311.wanderwave.model.data.viewModelType
Expand All @@ -43,6 +50,7 @@ import ch.epfl.cs311.wanderwave.ui.components.profile.ClickableIcon
import ch.epfl.cs311.wanderwave.ui.components.profile.SelectImage
import ch.epfl.cs311.wanderwave.ui.components.profile.SongsListDisplay
import ch.epfl.cs311.wanderwave.ui.components.profile.VisitCard
import ch.epfl.cs311.wanderwave.ui.theme.spotify_green
import ch.epfl.cs311.wanderwave.viewmodel.ProfileViewModel

const val SCALE_X = 0.5f
Expand Down Expand Up @@ -78,6 +86,10 @@ fun ProfileScreen(navActions: NavigationActions, viewModel: ProfileViewModel) {
Column(
modifier = Modifier.fillMaxSize().padding(16.dp).testTag("profileScreen"),
horizontalAlignment = Alignment.CenterHorizontally) {
Row(horizontalArrangement = Arrangement.SpaceAround, modifier = Modifier.fillMaxWidth()) {
SignOutButton(modifier = Modifier, navActions = navActions)
AboutButton(modifier = Modifier, navActions = navActions)
}
Box(modifier = Modifier.fillMaxWidth()) {
VisitCard(Modifier, currentProfile)
ProfileSwitch(Modifier.align(Alignment.TopEnd), viewModel)
Expand All @@ -89,8 +101,19 @@ fun ProfileScreen(navActions: NavigationActions, viewModel: ProfileViewModel) {
// Toggle Button to switch between TOP SONGS and CHOSEN SONGS
Button(
onClick = { viewModel.changeChosenSongs() },
modifier = Modifier.testTag("toggleSongList")) {
Text(if (isTopSongsListVisible) "Show CHOSEN TOPS" else "Show LIKED SONGS")
modifier = Modifier.testTag("toggleSongList"),
colors =
ButtonColors(
contentColor = Color.Black,
containerColor =
if (isTopSongsListVisible) MaterialTheme.colorScheme.primary
else spotify_green,
disabledContentColor = Color.Gray,
disabledContainerColor = Color.Black),
shape = RoundedCornerShape(size = 10.dp)) {
Text(
if (isTopSongsListVisible) stringResource(id = R.string.showChosenSongs)
else stringResource(id = R.string.showLikedSongs))
}
SongsListDisplay(
navigationActions = navActions,
Expand All @@ -104,12 +127,6 @@ fun ProfileScreen(navActions: NavigationActions, viewModel: ProfileViewModel) {
viewModelName = viewModelType.PROFILE,
)
}

Row {
SignOutButton(modifier = Modifier, navActions = navActions)
Spacer(modifier = Modifier.width(5.dp))
AboutButton(modifier = Modifier, navActions = navActions)
}
}
/**
* This handle the logic behind the switch that can permit the user to switch to the anonymous mode
Expand Down Expand Up @@ -191,16 +208,45 @@ fun SignOutButton(modifier: Modifier, navActions: NavigationActions) {
// TODO: Implement actual user sign out
Button(
onClick = { navActions.navigateToTopLevel(Route.LOGIN) },
modifier = modifier.testTag("signOutButton")) {
Text(text = "Sign Out")
modifier = modifier.testTag("signOutButton"),
colors =
ButtonColors(
containerColor = MaterialTheme.colorScheme.surfaceContainerHigh,
contentColor = MaterialTheme.colorScheme.onSurface,
disabledContainerColor = Color.Gray,
disabledContentColor = MaterialTheme.colorScheme.primary),
shape = RoundedCornerShape(size = 10.dp)) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween) {
Icon(
painter = painterResource(id = R.drawable.logout_icon),
contentDescription = "logout")
Spacer(modifier = Modifier.width(5.dp))
Text(text = stringResource(id = R.string.signOut))
}
}
}

@Composable
fun AboutButton(modifier: Modifier, navActions: NavigationActions) {
Button(
onClick = { navActions.navigateTo(Route.ABOUT) },
modifier = modifier.testTag("aboutButton")) {
Text(text = "About")
modifier = modifier.testTag("aboutButton"),
colors =
ButtonColors(
containerColor = MaterialTheme.colorScheme.surfaceContainerHigh,
contentColor = MaterialTheme.colorScheme.onSurface,
disabledContainerColor = Color.Gray,
disabledContentColor = MaterialTheme.colorScheme.primary),
shape = RoundedCornerShape(size = 10.dp)) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween) {
Icon(
painter = painterResource(id = R.drawable.info_icon), contentDescription = "info")
Spacer(modifier = Modifier.width(5.dp))
Text(text = stringResource(id = R.string.about))
}
}
}
Loading

0 comments on commit 1df9b2a

Please sign in to comment.