Skip to content

Commit d934494

Browse files
Adressed Comments
1 parent 2de00a4 commit d934494

5 files changed

Lines changed: 177 additions & 100 deletions

File tree

app/src/main/java/com/cornellappdev/uplift/data/repositories/LocationRepository.kt

Lines changed: 68 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,71 +4,99 @@ import android.Manifest
44
import android.content.Context
55
import android.content.pm.PackageManager
66
import android.location.Location
7-
import android.util.Log
7+
import android.os.Looper
88
import androidx.compose.runtime.MutableState
99
import androidx.compose.runtime.State
1010
import androidx.compose.runtime.mutableStateOf
1111
import androidx.core.app.ActivityCompat
1212
import com.google.android.gms.location.FusedLocationProviderClient
13+
import com.google.android.gms.location.LocationCallback
14+
import com.google.android.gms.location.LocationRequest
15+
import com.google.android.gms.location.LocationResult
1316
import com.google.android.gms.location.LocationServices
1417
import com.google.android.gms.location.Priority
15-
import kotlinx.coroutines.delay
16-
import kotlinx.coroutines.flow.Flow
17-
import kotlinx.coroutines.flow.flow
18-
import kotlinx.coroutines.tasks.await
18+
import kotlinx.coroutines.flow.MutableStateFlow
19+
import kotlinx.coroutines.flow.StateFlow
20+
1921

2022
/**
2123
* Collection of all location data for the user.
2224
*/
2325
object LocationRepository {
2426
private lateinit var fusedLocationClient: FusedLocationProviderClient
25-
private val _currentLocation: MutableState<Location?> = mutableStateOf(null)
27+
private var callback: LocationCallback? = null
2628

2729
/**
28-
* Either is the current user's location, or null if the location has not yet
29-
* been initialized.
30+
* Compose State for UI (home cards can read this .value and recompose on location updates).
31+
* Null if not yet initialized.
3032
* */
31-
var currentLocation = (_currentLocation as State<Location?>)
33+
private val _currentLocationState: MutableState<Location?> = mutableStateOf(null)
34+
val currentLocation: State<Location?> = _currentLocationState
3235

3336
/**
34-
* Starts updating [currentLocation] to the user's current location.
37+
* StateFLow for ViewModels to be able to collect and react to location updates. Null if not yet
38+
* initialized.
39+
*/
40+
private val _currentLocationFlow = MutableStateFlow<Location?>(null)
41+
val currentLocationFlow: StateFlow<Location?> = _currentLocationFlow
42+
43+
/**
44+
* Initializes the fused location client, if hasn't already been.
3545
*/
3646
fun instantiate(context: Context) {
37-
fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
47+
if (!::fusedLocationClient.isInitialized){
48+
fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
49+
}
3850
}
3951

40-
4152
/**
42-
* A [Flow] emitting the most recent [Location] every 30 seconds, or `null` if unavailable. ALso
43-
* updates [currentLocation] to the most recent [Location].
53+
* Updates [Location] every 30 seconds. Also updates [currentLocation] and [currentLocationFlow]
54+
* to the user's current [Location].
4455
*/
45-
fun locationFlow(context: Context): Flow<Location?> = flow {
46-
while (true) {
47-
if (ActivityCompat.checkSelfPermission(
48-
context,
49-
Manifest.permission.ACCESS_FINE_LOCATION
50-
) == PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(
51-
context,
52-
Manifest.permission.ACCESS_COARSE_LOCATION
53-
) == PackageManager.PERMISSION_GRANTED
54-
) {
55-
val location = try {
56-
fusedLocationClient.getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, null).await()
57-
} catch(e: Exception) {
58-
Log.e("LocationRepo", "Failed to get location", e)
59-
null
60-
}
61-
62-
if (location != null){
63-
_currentLocation.value = location
64-
emit(location)
65-
} else {
66-
Log.d("LocationRepo", "No location available right now")
67-
}
68-
} else {
69-
Log.d("LocationRepo", "Location permissions not granted")
56+
fun startLocationUpdates(context: Context) {
57+
if (ActivityCompat.checkSelfPermission(
58+
context,
59+
Manifest.permission.ACCESS_FINE_LOCATION
60+
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
61+
context,
62+
Manifest.permission.ACCESS_COARSE_LOCATION
63+
) != PackageManager.PERMISSION_GRANTED
64+
) return
65+
66+
if (callback != null) return
67+
68+
instantiate(context)
69+
70+
val request = LocationRequest.Builder(
71+
Priority.PRIORITY_HIGH_ACCURACY,
72+
30_000L
73+
).build()
74+
75+
val cb = object : LocationCallback() {
76+
override fun onLocationResult(locationResult: LocationResult) {
77+
super.onLocationResult(locationResult)
78+
_currentLocationState.value = locationResult.lastLocation
79+
_currentLocationFlow.value = locationResult.lastLocation
7080
}
71-
delay(30_000L)
7281
}
82+
83+
callback = cb
84+
85+
fusedLocationClient.requestLocationUpdates(
86+
request,
87+
cb,
88+
Looper.getMainLooper()
89+
)
7390
}
91+
92+
/**
93+
* Stops location updates.
94+
*/
95+
fun stopLocationUpdates() {
96+
val cb = callback ?: return
97+
fusedLocationClient.removeLocationUpdates(cb)
98+
callback = null
99+
}
100+
101+
74102
}

app/src/main/java/com/cornellappdev/uplift/ui/components/general/CheckInPopUp.kt

Lines changed: 17 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,13 @@ import androidx.compose.runtime.Composable
2626
import androidx.compose.ui.Alignment
2727
import androidx.compose.ui.Modifier
2828
import androidx.compose.ui.draw.shadow
29-
import androidx.compose.ui.graphics.Color
3029
import androidx.compose.ui.layout.ContentScale
3130
import androidx.compose.ui.res.painterResource
32-
import androidx.compose.ui.text.TextStyle
33-
import androidx.compose.ui.text.font.Font
34-
import androidx.compose.ui.text.font.FontFamily
35-
import androidx.compose.ui.text.font.FontWeight
3631
import androidx.compose.ui.tooling.preview.Preview
3732
import androidx.compose.ui.unit.dp
38-
import androidx.compose.ui.unit.sp
3933
import com.cornellappdev.uplift.R
34+
import com.cornellappdev.uplift.ui.theme.AppColors
35+
import com.cornellappdev.uplift.ui.theme.AppTextStyles
4036
import com.cornellappdev.uplift.ui.viewmodels.profile.CheckInMode
4137

4238

@@ -53,12 +49,12 @@ fun CheckInPopUp(
5349
modifier = Modifier
5450
.shadow(
5551
elevation = 40.dp,
56-
spotColor = Color(0xFFE5ECED),
57-
ambientColor = Color(0xFFE5ECED)
52+
spotColor = AppColors.Gray01,
53+
ambientColor = AppColors.Gray01
5854
)
5955
.fillMaxWidth()
6056
.height(62.dp)
61-
.background(color = Color(0xFFFFFFFF), shape = RoundedCornerShape(size = 12.dp))
57+
.background(color = AppColors.White, shape = RoundedCornerShape(size = 12.dp))
6258
.padding(12.dp),
6359
horizontalArrangement = Arrangement.SpaceBetween,
6460
verticalAlignment = Alignment.CenterVertically,
@@ -81,27 +77,14 @@ fun CheckInPopUp(
8177
) {
8278
Text(
8379
text = "We see you're near a gym...",
84-
style = TextStyle(
85-
fontSize = 14.sp,
86-
lineHeight = 16.sp,
87-
fontFamily = FontFamily(Font(R.font.montserrat_bold)),
88-
fontWeight = FontWeight(600),
89-
color = Color(0xFF222222),
90-
91-
)
80+
style = AppTextStyles.BodySemibold,
81+
color = AppColors.Black
9282
)
9383
Spacer(Modifier.height(4.dp))
9484
Text(
9585
text = "$gymName at $currentTimeText",
96-
style = TextStyle(
97-
fontSize = 12.sp,
98-
lineHeight = 16.sp,
99-
fontFamily = FontFamily(Font(R.font.montserrat_regular)),
100-
fontWeight = FontWeight(400),
101-
color = Color(0xFF707070),
102-
103-
)
104-
86+
style = AppTextStyles.LabelNormal,
87+
color = AppColors.Black
10588
)
10689
}
10790
Row(
@@ -116,21 +99,16 @@ fun CheckInPopUp(
11699
.height(34.dp),
117100
shape = RoundedCornerShape(size = 11.05263.dp),
118101
colors = ButtonDefaults.buttonColors(
119-
backgroundColor = Color(0xFFFCF5A4),
120-
contentColor = Color.Black
102+
backgroundColor = AppColors.LightYellow,
103+
contentColor = AppColors.Black
121104
),
122105
contentPadding = PaddingValues(horizontal = 12.dp, vertical = 10.dp),
123106
onClick = onCheckIn
124107
) {
125108
Text(
126109
text = "Check In?",
127-
style = TextStyle(
128-
fontSize = 14.sp,
129-
lineHeight = 16.sp,
130-
fontFamily = FontFamily(Font(R.font.montserrat_regular)),
131-
fontWeight = FontWeight(500),
132-
color = Color(0xFF000000),
133-
)
110+
style = AppTextStyles.LabelBig,
111+
color = AppColors.Black
134112
)
135113
}
136114

@@ -153,13 +131,8 @@ fun CheckInPopUp(
153131
) {
154132
Text(
155133
text = "You’re all set. Enjoy your workout!",
156-
style = TextStyle(
157-
fontSize = 14.sp,
158-
lineHeight = 16.sp,
159-
fontFamily = FontFamily(Font(R.font.montserrat_bold)),
160-
fontWeight = FontWeight(600),
161-
color = Color(0xFF222222),
162-
)
134+
style = AppTextStyles.BodySemibold,
135+
color = AppColors.Black
163136
)
164137
Image(
165138
painter = painterResource(id = R.drawable.ic_close),
@@ -175,8 +148,8 @@ fun CheckInPopUp(
175148

176149
@Preview
177150
@Composable
178-
fun CheckInPopUpPreview(
151+
private fun CheckInPopUpPreview(
179152
){
180153
CheckInPopUp("Helen Newman",
181-
"1:00 PM", {}, {}, {}, CheckInMode.Prompt)
154+
"1:00 PM", {}, {}, {}, CheckInMode.Complete)
182155
}

app/src/main/java/com/cornellappdev/uplift/ui/theme/Color.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,13 @@ import androidx.compose.ui.graphics.Color
55
val Purple200 = Color(0xFFBB86FC)
66
val Purple500 = Color(0xFF6200EE)
77
val Purple700 = Color(0xFF3700B3)
8-
val Teal200 = Color(0xFF03DAC5)
8+
val Teal200 = Color(0xFF03DAC5)
9+
10+
11+
object AppColors {
12+
val Black = Color(0xFF222222)
13+
val White = Color(0xFFFFFFFF)
14+
val LightYellow = Color(0xFFFCF5A4)
15+
val TextPrimary = Color(0xFF1B1F23)
16+
val Gray01 = Color(0xFFE5ECED)
17+
}

app/src/main/java/com/cornellappdev/uplift/ui/theme/Type.kt

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@ package com.cornellappdev.uplift.ui.theme
22

33
import androidx.compose.material.Typography
44
import androidx.compose.ui.text.TextStyle
5+
import androidx.compose.ui.text.font.Font
56
import androidx.compose.ui.text.font.FontFamily
67
import androidx.compose.ui.text.font.FontWeight
78
import androidx.compose.ui.unit.sp
9+
import com.cornellappdev.uplift.R
810

911
// Set of Material typography styles to start with
1012
val Typography = Typography(
1113
body1 = TextStyle(
1214
fontFamily = FontFamily.Default,
1315
fontWeight = FontWeight.Normal,
1416
fontSize = 16.sp
15-
)
17+
),
1618
/* Other default text styles to override
1719
button = TextStyle(
1820
fontFamily = FontFamily.Default,
@@ -25,4 +27,40 @@ val Typography = Typography(
2527
fontSize = 12.sp
2628
)
2729
*/
28-
)
30+
31+
)
32+
33+
val Montserrat = FontFamily(
34+
Font(R.font.montserrat_regular, FontWeight.Normal),
35+
Font(R.font.montserrat_bold, FontWeight.Bold),
36+
)
37+
38+
object AppTextStyles {
39+
val BodySemibold = TextStyle(
40+
fontFamily = Montserrat,
41+
fontSize = 14.sp,
42+
lineHeight = 16.sp,
43+
fontWeight = FontWeight.SemiBold
44+
)
45+
46+
val LabelNormal = TextStyle(
47+
fontFamily = Montserrat,
48+
fontSize = 12.sp,
49+
lineHeight = 16.sp,
50+
fontWeight = FontWeight.Normal
51+
)
52+
53+
val LabelMedium = TextStyle(
54+
fontFamily = Montserrat,
55+
fontSize = 12.sp,
56+
lineHeight = 16.sp,
57+
fontWeight = FontWeight.Medium
58+
)
59+
60+
val LabelBig= TextStyle(
61+
fontFamily = Montserrat,
62+
fontSize = 14.sp,
63+
lineHeight = 16.sp,
64+
fontWeight = FontWeight.Medium
65+
)
66+
}

0 commit comments

Comments
 (0)