Skip to content

Commit

Permalink
Merge pull request #116 from HLCaptain/115-use-new-compose-previews
Browse files Browse the repository at this point in the history
Compose Preview Fix, Enhanced Theming, Data Access Fix
  • Loading branch information
HLCaptain authored Aug 13, 2023
2 parents c38984c + ed2ddb4 commit 00a3597
Show file tree
Hide file tree
Showing 33 changed files with 327 additions and 182 deletions.
7 changes: 7 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ dependencies {
implementation(libs.androidx.compose.material.icons.core)
implementation(libs.androidx.compose.material.icons.extended)

// Day-Night Cycle in Theming
implementation(libs.solarized)

// Item Swipe
implementation(libs.saket.swipe)

Expand Down Expand Up @@ -216,6 +219,10 @@ dependencies {
implementation(libs.firebase.firestore.ktx)
implementation(libs.firebase.perf.ktx)

// Firebase ML
implementation(libs.firebase.ml.modeldownloader)
implementation(libs.tensorflow.lite)

// JUnit5 testing tools
// (Required) Writing and executing Unit Tests on the JUnit Platform
testImplementation(libs.junit.jupiter.api)
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>

<uses-sdk tools:overrideLibrary="dev.zotov.phototime.solarized" />

<application
android:name=".MainApplication"
android:allowBackup="false"
Expand Down
8 changes: 4 additions & 4 deletions app/src/main/java/illyan/jay/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import com.ramcosta.composedestinations.DestinationsNavHost
import dagger.hilt.android.AndroidEntryPoint
import illyan.jay.domain.interactor.AuthInteractor
import illyan.jay.ui.NavGraphs
import illyan.jay.ui.components.PreviewThemesScreensFonts
import illyan.jay.ui.theme.JayTheme
import illyan.jay.ui.components.PreviewAccessibility
import illyan.jay.ui.theme.JayThemeWithViewModel
import javax.inject.Inject

@AndroidEntryPoint
Expand All @@ -56,7 +56,7 @@ class MainActivity : AppCompatActivity() {
}

setContent {
JayTheme {
JayThemeWithViewModel {
MainScreen(
modifier = Modifier.fillMaxSize()
)
Expand All @@ -65,7 +65,7 @@ class MainActivity : AppCompatActivity() {
}
}

@PreviewThemesScreensFonts
@PreviewAccessibility
@Composable
fun MainScreen(
modifier: Modifier = Modifier
Expand Down
8 changes: 5 additions & 3 deletions app/src/main/java/illyan/jay/data/resolver/DataResolver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package illyan.jay.data.resolver

import illyan.jay.data.DataStatus
import illyan.jay.di.CoroutineScopeIO
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
Expand All @@ -29,7 +30,7 @@ import kotlinx.coroutines.flow.stateIn
import timber.log.Timber

abstract class DataResolver<DataType>(
private val coroutineScopeIO: CoroutineScope
@CoroutineScopeIO private val coroutineScopeIO: CoroutineScope,
) {
abstract fun uploadDataToCloud(data: DataType)
abstract fun upsertDataToLocal(data: DataType)
Expand Down Expand Up @@ -120,8 +121,9 @@ abstract class DataResolver<DataType>(
}

val shouldSyncData by lazy {
localData.map { shouldSyncData(it) }
.stateIn(coroutineScopeIO, SharingStarted.Eagerly, shouldSyncData(null))
combine(canSyncData, localData) { canSyncData, localData ->
canSyncData && shouldSyncData(localData)
}.stateIn(coroutineScopeIO, SharingStarted.Eagerly, canSyncData.value && shouldSyncData(null))
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@

package illyan.jay.data.resolver

import android.net.ConnectivityManager
import android.net.ConnectivityManager.NetworkCallback
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import illyan.jay.data.DataStatus
import illyan.jay.data.datastore.datasource.AppSettingsDataSource
import illyan.jay.data.firestore.datasource.PreferencesFirestoreDataSource
Expand All @@ -31,6 +36,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
Expand All @@ -44,10 +50,29 @@ class PreferencesResolver @Inject constructor(
private val preferencesFirestoreDataSource: PreferencesFirestoreDataSource,
private val preferencesRoomDataSource: PreferencesRoomDataSource,
@CoroutineScopeIO private val coroutineScopeIO: CoroutineScope,
connectivityManager: ConnectivityManager,
) : DataResolver<DomainPreferences>(
coroutineScopeIO = coroutineScopeIO
) {
override val enableSyncedData = authInteractor.isUserSignedInStateFlow
val isConnectedToInternet = MutableStateFlow(false)
private val networkRequest: NetworkRequest = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build()
private val networkCallback = object : NetworkCallback() {
override fun onAvailable(network: Network) { isConnectedToInternet.update { true } }
override fun onLost(network: Network) { isConnectedToInternet.update { false } }
}
init {
connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
}

override val enableSyncedData = combine(
authInteractor.isUserSignedInStateFlow,
isConnectedToInternet,
) { isUserSignedIn, isConnectedToInternet ->
isUserSignedIn && isConnectedToInternet
}

override val cloudDataStatus = preferencesFirestoreDataSource.cloudPreferencesStatus

override val localDataStatus: StateFlow<DataStatus<DomainPreferences>> by lazy {
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/java/illyan/jay/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ package illyan.jay.di

import android.content.Context
import android.hardware.SensorManager
import android.net.ConnectivityManager
import androidx.core.content.getSystemService
import androidx.core.graphics.drawable.IconCompat
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.localbroadcastmanager.content.LocalBroadcastManager
Expand Down Expand Up @@ -102,4 +104,10 @@ object AppModule {
@Provides
@Singleton
fun providePerformance() = Firebase.performance

@Provides
@Singleton
fun provideConnectivityManager(@ApplicationContext context: Context): ConnectivityManager {
return context.getSystemService<ConnectivityManager>()!!
}
}
21 changes: 20 additions & 1 deletion app/src/main/java/illyan/jay/di/FirebaseModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

package illyan.jay.di

import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import com.google.firebase.auth.ktx.auth
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.FirebaseFirestoreSettings
Expand All @@ -42,14 +45,30 @@ object FirebaseModule {

@Singleton
@Provides
fun provideFirestore(): FirebaseFirestore {
fun provideFirestore(connectivityManager: ConnectivityManager): FirebaseFirestore {
Firebase.firestore.firestoreSettings = FirebaseFirestoreSettings.Builder()
.setLocalCacheSettings(
PersistentCacheSettings.newBuilder()
.setSizeBytes(FirebaseFirestoreSettings.CACHE_SIZE_UNLIMITED)
.build()
)
.build()
connectivityManager.registerNetworkCallback(
NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(),
object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: android.net.Network) {
Firebase.firestore.enableNetwork()
Timber.d("Network available!")
}

override fun onLost(network: android.net.Network) {
Firebase.firestore.disableNetwork()
Timber.d("Network lost!")
}
}
)
return Firebase.firestore
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package illyan.jay.domain.interactor
import android.hardware.SensorEventListener
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.Priority
import illyan.jay.data.sensor.SensorDataSource
import javax.inject.Inject
import javax.inject.Singleton
Expand Down Expand Up @@ -68,8 +69,13 @@ class SensorInteractor @Inject constructor(
* @param callback method to call when there is a new location update.
*/
fun requestLocationUpdates(
request: LocationRequest,
callback: LocationCallback
callback: LocationCallback,
request: LocationRequest = LocationRequest.Builder(
Priority.PRIORITY_BALANCED_POWER_ACCURACY,
LocationInteractor.LOCATION_REQUEST_INTERVAL_DEFAULT
)
.setMinUpdateDistanceMeters(LocationInteractor.LOCATION_REQUEST_DISPLACEMENT_DEFAULT)
.build()
) = sensorDataSource.requestLocationUpdates(request, callback)

/**
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/illyan/jay/domain/model/Theme.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@
package illyan.jay.domain.model

enum class Theme {
Light, Dark, System
Light, Dark, System, DayNightCycle
}
4 changes: 2 additions & 2 deletions app/src/main/java/illyan/jay/service/JayService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ class JayService @Inject constructor() : BaseService() {

// Start location requests
sensorInteractor.requestLocationUpdates(
locationEventListener.locationRequest,
locationEventListener.locationCallback
locationEventListener.locationCallback,
locationEventListener.locationRequest
)
}

Expand Down
6 changes: 3 additions & 3 deletions app/src/main/java/illyan/jay/ui/about/About.kt
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ import illyan.jay.R
import illyan.jay.domain.model.libraries.Library
import illyan.jay.ui.components.JayDialogContent
import illyan.jay.ui.components.JayDialogContentPadding
import illyan.jay.ui.components.PreviewThemesScreensFonts
import illyan.jay.ui.components.MenuButton
import illyan.jay.ui.components.PreviewAccessibility
import illyan.jay.ui.destinations.LibrariesDialogScreenDestination
import illyan.jay.ui.profile.MenuButton
import illyan.jay.ui.profile.ProfileNavGraph
import illyan.jay.ui.settings.user.BooleanSetting
import illyan.jay.ui.theme.JayTheme
Expand Down Expand Up @@ -334,7 +334,7 @@ fun AboutAdScreen(
}
}

@PreviewThemesScreensFonts
@PreviewAccessibility
@Composable
private fun AboutDialogScreenPreview() {
JayTheme {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ fun DefaultAvatar(
}
}

@PreviewThemesScreensFonts
@PreviewAccessibility
@Composable
private fun DefaultAvatarPreview() {
JayTheme {
Expand All @@ -109,7 +109,7 @@ fun BrokenAvatar(
)
}

@PreviewThemesScreensFonts
@PreviewAccessibility
@Composable
private fun BrokenAvatarPreview() {
JayTheme {
Expand All @@ -130,7 +130,7 @@ fun PlaceholderAvatar(
)
}

@PreviewThemesScreensFonts
@PreviewAccessibility
@Composable
private fun PlaceholderAvatarPreview() {
JayTheme {
Expand Down
19 changes: 16 additions & 3 deletions app/src/main/java/illyan/jay/ui/components/JayDialogContent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.widthIn
import androidx.compose.material3.AlertDialogDefaults
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ProvideTextStyle
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
Expand Down Expand Up @@ -163,8 +167,11 @@ fun JayDialogSurface(
tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
content: @Composable () -> Unit
) {
val configuration = LocalConfiguration.current
val screenWidthDp by remember { derivedStateOf { configuration.screenWidthDp.dp } }
// Increase width to edge of the screen until reaching DialogMaxWidth
Surface(
modifier = modifier,
modifier = modifier.dialogWidth(screenWidthDp),
shape = shape,
color = color,
tonalElevation = tonalElevation,
Expand All @@ -184,8 +191,14 @@ fun JayDialogContent(
content: @Composable () -> Unit = {},
) = surface(content)

internal val DialogMinWidth = 280.dp
internal val DialogMaxWidth = 560.dp
val DialogMinWidth = 280.dp
val DialogMaxWidth = 420.dp
val DialogMargin = 64.dp

fun Modifier.dialogWidth(screenWidthDp: Dp = 400.dp) = widthIn(
min = DialogMinWidth,
max = minOf(maxOf(DialogMinWidth, screenWidthDp - DialogMargin), DialogMaxWidth),
)

// Paddings for each of the dialog's parts.
val JayDialogContentPadding = PaddingValues(all = 24.dp)
Expand Down
44 changes: 44 additions & 0 deletions app/src/main/java/illyan/jay/ui/components/MenuButton.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2023 Balázs Püspök-Kiss (Illyan)
*
* Jay is a driver behaviour analytics app.
*
* This file is part of Jay.
*
* Jay 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.
* Jay 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.
*
* You should have received a copy of the GNU General Public License along with Jay.
* If not, see <https://www.gnu.org/licenses/>.
*/

package illyan.jay.ui.components

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ChevronRight
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

@Composable
fun MenuButton(
modifier: Modifier = Modifier,
onClick: () -> Unit = {},
text: String,
) {
TextButton(
modifier = modifier,
onClick = onClick,
) {
Text(text = text)
Icon(
imageVector = Icons.Rounded.ChevronRight, contentDescription = "",
)
}
}
Loading

0 comments on commit 00a3597

Please sign in to comment.