Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/home screen #63

Open
wants to merge 14 commits into
base: version/0.2.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.content.Context
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import org.koin.dsl.module

/**
Expand All @@ -16,6 +17,8 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

enableEdgeToEdge()

initKoin(
additionalModules = listOf(
module {
Expand Down
17 changes: 11 additions & 6 deletions composeApp/src/commonMain/composeResources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@
<!-- PlatformInfoScreen -->
<string name="platform_info_title">Platform information</string>


<!-- HomeScreen -->
<string name="menu_new_measurement">New measurement</string>
<string name="menu_history">Measurements history</string>
<string name="menu_feedback">Measurement feedback</string>
<string name="menu_statistics">Measurements statistics</string>
<string name="menu_map">Last measurement map</string>
<string name="menu_settings">Settings</string>
<string name="home_slm_hint">Visualise and measure the noise level around you as you navigate your surroundings!</string>
<string name="home_slm_button_title">Open sound level meter</string>


<!-- Sound level meter -->
<string name="sound_level_meter_current_dba">Current dB(A)</string>
<string name="sound_level_meter_min_dba">Min</string>
<string name="sound_level_meter_avg_dba">Avg</string>
<string name="sound_level_meter_max_dba">Max</string>


<!-- PermissionScreen -->
<string name="request_permission_title">Permissions</string>
Expand Down
8 changes: 6 additions & 2 deletions composeApp/src/commonMain/kotlin/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import org.jetbrains.compose.ui.tooling.preview.Preview
import org.koin.compose.KoinContext
import org.noiseplanet.noisecapture.NoiseCaptureApp
import org.koin.compose.koinInject
import org.noiseplanet.noisecapture.ui.navigation.RootCoordinator
import org.noiseplanet.noisecapture.ui.navigation.RootCoordinatorViewModel

/**
* Entry point of the Compose app.
Expand All @@ -12,7 +14,9 @@ import org.noiseplanet.noisecapture.NoiseCaptureApp
fun App() {
KoinContext {
MaterialTheme {
NoiseCaptureApp()
val coordinatorViewModel: RootCoordinatorViewModel = koinInject()

RootCoordinator(viewModel = coordinatorViewModel)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.noiseplanet.noisecapture.ui.features.home.homeModule
import org.noiseplanet.noisecapture.ui.features.measurement.measurementModule
import org.noiseplanet.noisecapture.ui.features.permission.requestPermissionModule
import org.noiseplanet.noisecapture.ui.features.settings.settingsModule
import org.noiseplanet.noisecapture.ui.navigation.coordinatorModule

/**
* Create root Koin application and register modules shared between platforms
Expand All @@ -25,6 +26,7 @@ fun initKoin(
return startKoin {
modules(
servicesModule,
coordinatorModule,

defaultPermissionModule,
platformPermissionModule(),
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ class DefaultLiveAudioService(
override val isRunning: Boolean
get() = _isRunningFlow.value

override val audioSourceStateFlow: Flow<AudioSourceState> = audioSource.stateFlow
override val audioSourceState: AudioSourceState
get() = audioSource.state
override val audioSourceStateFlow: Flow<AudioSourceState>
get() = audioSource.stateFlow

override fun setupAudioSource() {
// Create a job that will process incoming audio samples in a background thread
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ interface LiveAudioService {
* State of the underlying audio source.
* Can be used to reflect system interruptions or resumes to user interface
*/
val audioSourceState: AudioSourceState

/**
* A flow of [audioSourceState] values.
*/
val audioSourceStateFlow: Flow<AudioSourceState>

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.noiseplanet.noisecapture.ui.components

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.animateOffsetAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
Expand All @@ -17,17 +15,12 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import org.noiseplanet.noisecapture.util.shadow.dropShadow


private const val CORNER_RADIUS: Float = 10f
private const val SHADOW_OFFSET_X: Float = 0f
private const val SHADOW_OFFSET_Y: Float = 4f
private const val SHADOW_BLUR_RADIUS: Float = 12f


/**
* Wraps the given content into a rounded cornered card.
Expand Down Expand Up @@ -55,17 +48,6 @@ fun CardView(
mutableStateOf(true)
}

val shadowOffset by animateOffsetAsState(
targetValue = if (isPressed) {
Offset.Zero
} else {
Offset(SHADOW_OFFSET_X, SHADOW_OFFSET_Y)
}
)
val shadowBlur by animateFloatAsState(
targetValue = if (isPressed) 0f else SHADOW_BLUR_RADIUS
)

var cardModifier = modifier
onClick?.let {
cardModifier = modifier.clickable(
Expand All @@ -77,7 +59,7 @@ fun CardView(

Box(
modifier = cardModifier
.dropShadow(shape, offset = shadowOffset, blur = shadowBlur)
.dropShadow(shape = shape, isPressed = isPressed)
.background(backgroundColor, shape)
.clip(shape)
.padding(16.dp),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.noiseplanet.noisecapture.ui.features.settings
package org.noiseplanet.noisecapture.ui.components

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
Expand All @@ -11,13 +11,15 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
import org.noiseplanet.noisecapture.ui.theme.listBackground

@Composable
fun SettingsSectionHeader(
fun ListSectionHeader(
title: StringResource,
) {
Box(modifier = Modifier.fillMaxWidth().background(listBackground)) {
Box(
modifier = Modifier.fillMaxWidth()
.background(MaterialTheme.colorScheme.background)
) {
Text(
text = stringResource(title).uppercase(),
style = MaterialTheme.typography.titleMedium,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
Expand All @@ -28,22 +28,30 @@ fun AppBar(
appBarState: AppBarState,
modifier: Modifier = Modifier,
) {
// - Properties

val currentBackStackEntry by appBarState.navController.currentBackStackEntryAsState()
val previousBackStackEntry = appBarState.navController.previousBackStackEntry
val currentRoute = currentBackStackEntry?.destination?.route
val canNavigateUp = currentRoute != null && previousBackStackEntry != null

val actions by appBarState.actions.collectAsState(emptyList())

TopAppBar(

// - Layout

CenterAlignedTopAppBar(
title = {
if (currentRoute != null) {
val title = Route.valueOf(currentRoute).title
Text(stringResource(title))
}
},
colors = TopAppBarDefaults.mediumTopAppBarColors(
containerColor = MaterialTheme.colorScheme.primaryContainer
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
titleContentColor = MaterialTheme.colorScheme.onSecondary,
containerColor = MaterialTheme.colorScheme.secondary,
navigationIconContentColor = MaterialTheme.colorScheme.onSecondary,
actionIconContentColor = MaterialTheme.colorScheme.onSecondary
),
navigationIcon = {
if (canNavigateUp) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.noiseplanet.noisecapture.ui.components.button

/**
* Different possible button styles
*/
enum class ButtonStyle {

PRIMARY,
SECONDARY,
OUTLINED,
TEXT,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.noiseplanet.noisecapture.ui.components.button

import androidx.compose.ui.graphics.vector.ImageVector
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import org.jetbrains.compose.resources.StringResource


/**
* Styling and contents of a button
*/
data class ButtonViewModel(
val title: Flow<StringResource?> = flow { emit(null) },
val icon: Flow<ImageVector?> = flow { emit(null) },
val style: ButtonStyle = ButtonStyle.PRIMARY,
val hasDropShadow: Boolean = false,
) {

/**
* Convenience initializer for buttons where title and icons are not state dependant.
*/
constructor(
title: StringResource? = null,
icon: ImageVector? = null,
style: ButtonStyle = ButtonStyle.PRIMARY,
hasDropShadow: Boolean = false,
) : this(
flow { emit(title) },
flow { emit(icon) },
style,
hasDropShadow
)
}
Loading
Loading