Skip to content

Commit 41f8b53

Browse files
authored
Merge pull request #5 from isoguzay/task/refactor-dimens-string-usage
task/refactor-dimens-string-usage
2 parents 7e3c259 + 23bbd87 commit 41f8b53

File tree

16 files changed

+212
-123
lines changed

16 files changed

+212
-123
lines changed

app/src/main/java/com/adyen/android/assignment/AdyenApplication.kt

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,4 @@ import android.app.Application
44
import dagger.hilt.android.HiltAndroidApp
55

66
@HiltAndroidApp
7-
class AdyenApplication : Application() {
8-
9-
override fun onCreate() {
10-
super.onCreate()
11-
}
12-
13-
}
7+
class AdyenApplication : Application()

app/src/main/java/com/adyen/android/assignment/datasource/remote/PlacesRemoteData.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import javax.inject.Inject
99

1010
class PlacesRemoteData @Inject constructor(private val remoteService: PlacesService) {
1111

12+
/**
13+
* Get places from service
14+
* @param requestModel
15+
*/
1216
suspend fun getPlaces(requestModel: LocationRequestModel): NetworkResult<PlacesResponse> {
1317
return remoteService.getVenueRecommendationPlaces(
1418
VenueRecommendationsQueryBuilder()

app/src/main/java/com/adyen/android/assignment/di/RemoteModule.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import android.content.Context
44
import com.adyen.android.assignment.BuildConfig
55
import com.adyen.android.assignment.network.service.PlacesService
66
import com.adyen.android.assignment.network.util.AppCallAdapterFactory
7+
import com.adyen.android.assignment.utils.Constant.NETWORK_REQUEST_TIME_OUT
78
import com.google.gson.Gson
89
import com.google.gson.GsonBuilder
910
import dagger.Module
@@ -39,8 +40,8 @@ object RemoteModule {
3940
interceptorDebug.level = HttpLoggingInterceptor.Level.BODY
4041

4142
val client = OkHttpClient.Builder()
42-
.connectTimeout(20, TimeUnit.SECONDS)
43-
.readTimeout(20, TimeUnit.SECONDS)
43+
.connectTimeout(NETWORK_REQUEST_TIME_OUT, TimeUnit.SECONDS)
44+
.readTimeout(NETWORK_REQUEST_TIME_OUT, TimeUnit.SECONDS)
4445
.addInterceptor { chain ->
4546
val request = chain.request()
4647
.newBuilder()

app/src/main/java/com/adyen/android/assignment/repository/remote/PlacesRepository.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import javax.inject.Inject
88

99
class PlacesRepository @Inject constructor(private val remote: PlacesRemoteData) {
1010

11+
/**
12+
* Get places from service
13+
* @param requestModel
14+
*/
1115
suspend fun getPlaces(requestModel: LocationRequestModel): NetworkResult<PlacesResponse> {
1216
return remote.getPlaces(requestModel)
1317
}

app/src/main/java/com/adyen/android/assignment/screens/MainActivity.kt

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,21 @@ import android.content.pm.PackageManager
66
import android.location.Location
77
import android.os.Build
88
import android.os.Bundle
9-
import android.util.Log
109
import androidx.activity.ComponentActivity
1110
import androidx.activity.compose.setContent
1211
import androidx.activity.viewModels
1312
import androidx.annotation.RequiresApi
1413
import androidx.compose.foundation.layout.fillMaxSize
1514
import androidx.compose.material.MaterialTheme
1615
import androidx.compose.material.Surface
16+
import androidx.compose.runtime.livedata.observeAsState
1717
import androidx.compose.ui.Modifier
1818
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
1919
import androidx.lifecycle.lifecycleScope
2020
import com.adyen.android.assignment.model.request.LocationRequestModel
2121
import com.adyen.android.assignment.screens.home.view.HomeScreen
2222
import com.adyen.android.assignment.screens.home.viewmodel.HomeViewModel
23+
import com.adyen.android.assignment.screens.permission.screen.LocationPermissionScreen
2324
import com.adyen.android.assignment.screens.permission.types.LocationPermissionTypes
2425
import com.adyen.android.assignment.screens.permission.viewmodel.PermissionViewModel
2526
import com.adyen.android.assignment.ui.theme.AdyenApplicationTheme
@@ -62,30 +63,46 @@ class MainActivity : ComponentActivity() {
6263
lifecycleScope.launchWhenCreated {
6364
delay(2000)
6465
keepSplashScreen = false
66+
6567
setContent {
68+
val permissionsState = permissionViewModel.locationPermission.observeAsState()
69+
6670
AdyenApplicationTheme {
6771
Surface(
6872
modifier = Modifier.fillMaxSize(),
6973
color = MaterialTheme.colors.background
7074
) {
71-
HomeScreen({ locationRequestOnClick() })
75+
if (permissionsState.value == true) {
76+
HomeScreen({ locationRequestOnClick() })
77+
} else {
78+
LocationPermissionScreen()
79+
}
7280
}
7381
}
7482
}
7583
}
7684
}
7785

86+
/**
87+
* cancel the cancellationTokenSource onDestroy
88+
*/
7889
override fun onDestroy() {
7990
super.onDestroy()
8091
cancellationTokenSource.cancel()
8192
}
8293

94+
/**
95+
* check location permissions granted onStart
96+
*/
8397
@RequiresApi(Build.VERSION_CODES.M)
8498
override fun onStart() {
8599
super.onStart()
86100
getPermission()
87101
}
88102

103+
/**
104+
* request permission result
105+
*/
89106
@SuppressLint("MissingSuperCall")
90107
override fun onRequestPermissionsResult(
91108
requestCode: Int,
@@ -107,6 +124,9 @@ class MainActivity : ComponentActivity() {
107124
}
108125
}
109126

127+
/**
128+
* get location permission, if permissionState true request it again
129+
*/
110130
@RequiresApi(Build.VERSION_CODES.M)
111131
fun getPermission() {
112132
val permissionState = requestPermissionWithRationale(
@@ -118,6 +138,9 @@ class MainActivity : ComponentActivity() {
118138
LocationPermissionTypes.REQUEST_AGAIN
119139
}
120140

141+
/**
142+
* request current location, check the location permissions approved state
143+
*/
121144
@RequiresApi(Build.VERSION_CODES.M)
122145
fun locationRequestOnClick() {
123146
Timber.d("locationRequestOnClick()")
@@ -131,6 +154,9 @@ class MainActivity : ComponentActivity() {
131154
}
132155
}
133156

157+
/**
158+
* request current location from location api
159+
*/
134160
@SuppressLint("MissingPermission")
135161
private fun requestCurrentLocation() {
136162
if (applicationContext.hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
@@ -141,10 +167,7 @@ class MainActivity : ComponentActivity() {
141167
currentLocationTask.addOnCompleteListener { task: Task<Location> ->
142168
if (task.isSuccessful && task.result != null) {
143169
val result: Location = task.result
144-
Log.d(
145-
TAG,
146-
"getCurrentLocation() (success): ${result.latitude}, ${result.longitude}"
147-
)
170+
Timber.d("getCurrentLocation() (success): ${result.latitude} ${result.longitude}")
148171
homeViewModel.setCurrentLocation(
149172
LocationRequestModel(
150173
latitude = task.result.latitude,
@@ -153,16 +176,12 @@ class MainActivity : ComponentActivity() {
153176
)
154177
} else {
155178
val exception = task.exception
156-
Log.d(TAG, "getCurrentLocation() (failure): $exception\"")
179+
Timber.d("getCurrentLocation() (failure): $exception")
157180

158181
}
159-
Log.d(TAG, "getCurrentLocation() result: ${task.result.longitude}")
160-
182+
Timber.d("getCurrentLocation() result: " + task.result.longitude)
161183
}
162184
}
163185
}
164-
165-
companion object {
166-
private const val TAG = "MainActivity"
167-
}
186+
168187
}

app/src/main/java/com/adyen/android/assignment/screens/home/view/HomeScreen.kt

Lines changed: 22 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,24 @@ import androidx.annotation.RequiresApi
55
import androidx.compose.animation.animateContentSize
66
import androidx.compose.animation.core.Spring
77
import androidx.compose.animation.core.spring
8-
import androidx.compose.foundation.background
9-
import androidx.compose.foundation.border
108
import androidx.compose.foundation.layout.*
119
import androidx.compose.foundation.lazy.LazyRow
12-
import androidx.compose.foundation.shape.RoundedCornerShape
1310
import androidx.compose.material.*
1411
import androidx.compose.material.icons.Icons
1512
import androidx.compose.material.icons.filled.*
1613
import androidx.compose.runtime.*
1714
import androidx.compose.runtime.livedata.observeAsState
1815
import androidx.compose.ui.Alignment
1916
import androidx.compose.ui.Modifier
20-
import androidx.compose.ui.graphics.Color
2117
import androidx.compose.ui.res.dimensionResource
22-
import androidx.compose.ui.text.font.FontWeight
23-
import androidx.compose.ui.unit.dp
18+
import androidx.compose.ui.res.stringResource
2419
import androidx.compose.ui.unit.sp
2520
import androidx.hilt.navigation.compose.hiltViewModel
2621
import com.adyen.android.assignment.R
2722
import com.adyen.android.assignment.model.response.Category
2823
import com.adyen.android.assignment.model.response.Result
2924
import com.adyen.android.assignment.screens.home.viewmodel.HomeViewModel
30-
import com.adyen.android.assignment.screens.permission.screen.LocationPermissionScreen
31-
import com.adyen.android.assignment.screens.permission.viewmodel.PermissionViewModel
25+
import com.adyen.android.assignment.ui.components.CategoryChip
3226
import com.adyen.android.assignment.utils.Constant.GOOGLE_MAPS_CAMERA_ZOOM
3327
import com.google.android.gms.maps.model.CameraPosition
3428
import com.google.android.gms.maps.model.LatLng
@@ -41,27 +35,20 @@ import com.google.maps.android.compose.rememberCameraPositionState
4135
fun HomeScreen(
4236
locationRequestOnClick: () -> Unit,
4337
homeViewModel: HomeViewModel = hiltViewModel(),
44-
permissionViewModel: PermissionViewModel = hiltViewModel()
4538
) {
46-
val venuesListState = homeViewModel.venuesListState
47-
4839
val showProgress = remember { mutableStateOf(false) }
4940
val showInfo = remember { mutableStateOf(false) }
41+
val cameraPositionState = rememberCameraPositionState {}
42+
val venuesListState = homeViewModel.venuesListState
5043
val selectedPlaceState = homeViewModel.selectedPlace.observeAsState()
51-
val permissionsState = permissionViewModel.locationPermission.observeAsState()
5244
val currentLocation = homeViewModel.currentLocation.observeAsState()
53-
val cameraPositionState = rememberCameraPositionState {}
5445

55-
if (permissionsState.value == true) {
56-
LaunchedEffect(Unit) {
57-
homeViewModel.getPlaces(homeViewModel.getDummyLocationRequest())
58-
cameraPositionState.position = CameraPosition.fromLatLngZoom(
59-
homeViewModel.getDummyAmsterdamLocation(),
60-
GOOGLE_MAPS_CAMERA_ZOOM
61-
)
62-
}
63-
} else {
64-
LocationPermissionScreen()
46+
LaunchedEffect(Unit) {
47+
homeViewModel.getPlaces(homeViewModel.getDummyLocationRequest())
48+
cameraPositionState.position = CameraPosition.fromLatLngZoom(
49+
homeViewModel.getDummyAmsterdamLocation(),
50+
GOOGLE_MAPS_CAMERA_ZOOM
51+
)
6552
}
6653

6754
if (venuesListState.venueList?.isNotEmpty() == true) {
@@ -89,7 +76,7 @@ fun HomeScreen(
8976
Box(
9077
modifier = Modifier
9178
.fillMaxWidth()
92-
.padding(all = 16.dp),
79+
.padding(all = dimensionResource(id = R.dimen.home_screen_show_my_current_location_box_padding)),
9380
contentAlignment = Alignment.BottomStart
9481
) {
9582
Button(modifier = Modifier
@@ -100,9 +87,9 @@ fun HomeScreen(
10087
}) {
10188
Icon(
10289
Icons.Default.Place,
103-
contentDescription = "Show My Location"
90+
contentDescription = stringResource(id = R.string.home_screen_show_my_current_location_button_content_description)
10491
)
105-
Text(text = "My Location")
92+
Text(text = stringResource(id = R.string.home_screen_show_my_current_location_button_text))
10693
}
10794
}
10895
}
@@ -146,7 +133,6 @@ fun HomeScreen(
146133
SelectedPlaceInfo(showInfo, place)
147134
}
148135
}
149-
150136
}
151137

152138
@Composable
@@ -191,13 +177,13 @@ fun SelectedPlaceInfo(showInfo: MutableState<Boolean>, place: Result) {
191177
IconButton(onClick = { expanded = !expanded }) {
192178
Icon(
193179
imageVector = if (expanded) Icons.Filled.ExpandLess else Icons.Filled.ExpandMore,
194-
contentDescription = ""
180+
contentDescription = stringResource(id = R.string.home_screen_place_detail_expand_content_description)
195181
)
196182
}
197183
IconButton(onClick = { showInfo.value = false }) {
198184
Icon(
199185
imageVector = Icons.Filled.Close,
200-
contentDescription = ""
186+
contentDescription = stringResource(id = R.string.home_screen_place_detail_close_content_description)
201187
)
202188
}
203189
}
@@ -218,10 +204,10 @@ fun SelectedPlaceNameField(name: String?) {
218204
Spacer(modifier = Modifier.height(dimensionResource(id = R.dimen.place_info_spacer)))
219205
Icon(
220206
Icons.Default.Business,
221-
contentDescription = ""
207+
contentDescription = stringResource(id = R.string.home_screen_place_detail_name_content_description)
222208
)
223209
Spacer(modifier = Modifier.width(dimensionResource(id = R.dimen.place_info_spacer)))
224-
Text(text = "Name : $name")
210+
Text(text = stringResource(id = R.string.home_screen_place_detail_name) + " $name")
225211
}
226212

227213
@Composable
@@ -230,10 +216,10 @@ fun SelectedPlaceAddressField(formatted_address: String?) {
230216
Row(modifier = Modifier.fillMaxWidth()) {
231217
Icon(
232218
Icons.Default.Place,
233-
contentDescription = ""
219+
contentDescription = stringResource(id = R.string.home_screen_place_detail_address_content_description)
234220
)
235221
Spacer(modifier = Modifier.width(dimensionResource(id = R.dimen.place_info_spacer)))
236-
Text(text = "Address : $formatted_address")
222+
Text(text = stringResource(id = R.string.home_screen_place_detail_address) + " $formatted_address")
237223
}
238224
}
239225
}
@@ -245,12 +231,12 @@ fun SelectedPlaceCategoriesField(categoryList: List<Category>?) {
245231
Row(modifier = Modifier.fillMaxWidth()) {
246232
Icon(
247233
Icons.Filled.Storefront,
248-
contentDescription = ""
234+
contentDescription = stringResource(id = R.string.home_screen_place_detail_categories_content_description)
249235
)
250236
Spacer(modifier = Modifier.width(dimensionResource(id = R.dimen.place_info_spacer)))
251237
Text(
252-
text = "Categories",
253-
fontSize = 16.sp
238+
text = stringResource(id = R.string.home_screen_place_detail_categories),
239+
fontSize = dimensionResource(id = R.dimen.place_info_categories_text_size).value.sp
254240
)
255241
}
256242
Spacer(modifier = Modifier.height(dimensionResource(id = R.dimen.place_info_spacer)))
@@ -266,36 +252,6 @@ fun SelectedPlaceCategoriesField(categoryList: List<Category>?) {
266252
}
267253
}
268254

269-
@Composable
270-
fun CategoryChip(
271-
categoryName: String
272-
) {
273-
Row(
274-
horizontalArrangement = Arrangement.Center,
275-
verticalAlignment = Alignment.CenterVertically,
276-
modifier = Modifier
277-
.padding(
278-
vertical = 2.dp,
279-
horizontal = 4.dp
280-
)
281-
.border(
282-
width = 1.dp,
283-
color = Color.White,
284-
shape = RoundedCornerShape(16.dp)
285-
)
286-
.background(
287-
color = Color.Transparent,
288-
)
289-
.padding(4.dp)
290-
) {
291-
Text(
292-
text = categoryName,
293-
fontWeight = FontWeight.Bold,
294-
fontSize = 14.sp,
295-
modifier = Modifier.padding(4.dp)
296-
)
297-
}
298-
}
299255

300256

301257

0 commit comments

Comments
 (0)