Skip to content

Commit

Permalink
[v1.0.2] Upgrade version to 1.0.2(#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
hide-your-code committed Jul 11, 2022
1 parent 73864f1 commit ee802f6
Show file tree
Hide file tree
Showing 33 changed files with 600 additions and 197 deletions.
19 changes: 19 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
## ✏️ TODO
*(List your doing in your pull request here)*

- Feature one.
- Feature two.

## 📘 Libraries
*(List your libraries that you add or modifier in your pull request)*

- Jetpack Compose.
- Jetpack DataStore.

## 🔔 Notes
*(You must provides some information such as how to testing your pull request because this is important for your reviewer to check your pull request)*

- Delete the project because it's suck. :smile:

## 📷 Screenshots
*(Add some screenshots in here)*
2 changes: 1 addition & 1 deletion .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ I want to say thanks for those people to help me to make this app.

## :hammer: How to build app

- Using android 13 and above to build app.
- Using the newest version of Android Studio Canary.
- You must add `BASE_URL`, `API_KEY` and `MAPS_API_KEY` inside `local.properties` to build and run Weapose app, like the code below:

Expand Down Expand Up @@ -51,6 +50,12 @@ Weapose is built according to the Clean Architecture model combined with the MVV
- Guild to app architecture by Google Android.
- Clean architectur by Uncle Bob.

## :mag_right: Unit test

- Using [MockK](https://mockk.io/) to write unit test.
- Using [Kotlin Reflection](https://kotlinlang.org/docs/reflection.html) to access the private method, private property, etc.
- Using [Kotlin Kover](https://github.com/Kotlin/kotlinx-kover) to generate the test coverage. To generate, you just run command ` ./gradlew koverHtmlReport`.

## :tram: Data flow

Weapose is supported by `Flow` and `suspend` for data stream flow in app.
Expand Down
74 changes: 58 additions & 16 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,48 @@ plugins {
kotlin("kapt")
id("dagger.hilt.android.plugin")
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
id("org.jetbrains.kotlinx.kover") version "0.5.0"
}

val properties = Properties().apply {
load(project.rootProject.file("local.properties").inputStream())
}

project.afterEvaluate {
tasks.koverHtmlReport {
group = "kover"
description = ""
dependsOn("testDebugUnitTest")

isEnabled = true
htmlReportDir.set(layout.buildDirectory.dir("kover_report/html_result"))
includes = listOf("com.minhdtm.example.weapose.*")
excludes = listOf(
"*Screen*",
"*_Factory*",
"*_HiltModules*",
"*di*",
"*_Impl*",
"*BuildConfig*",
"*Activity*",
"*App*",
"*Drawer*",
"*Graph*",
"*.theme*",
)
}
}

android {
namespace = "com.minhdtm.example.weapose"
compileSdkPreview = "Tiramisu"
compileSdk = 33

defaultConfig {
applicationId = "com.minhdtm.example.weapose"
minSdk = 21
targetSdkPreview = "Tiramisu"
targetSdk = 33
versionCode = 1
versionName = "1.0.1"
versionName = "1.0.2"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand All @@ -39,6 +65,12 @@ android {
}
}

testOptions {
unitTests {
isIncludeAndroidResources = true
}
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
Expand All @@ -48,6 +80,7 @@ android {
jvmTarget = "11"
freeCompilerArgs = freeCompilerArgs.toMutableList().apply {
add("-opt-in=kotlin.RequiresOptIn")
add("-Xuse-experimental=androidx.compose.ui.text.ExperimentalTextApi")
}
}

Expand All @@ -67,13 +100,13 @@ android {
}

dependencies {
implementation("androidx.core:core-ktx:1.7.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.4.1")
implementation("androidx.activity:activity-compose:1.4.0")
implementation("androidx.compose.ui:ui:1.1.1")
implementation("androidx.compose.ui:ui-tooling-preview:1.1.1")
implementation("androidx.compose.material3:material3:1.0.0-alpha12")
implementation("androidx.compose.material:material:1.2.0-beta03")
implementation("androidx.core:core-ktx:1.8.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.5.0")
implementation("androidx.activity:activity-compose:1.5.0")
implementation("androidx.compose.ui:ui:1.3.0-alpha01")
implementation("androidx.compose.ui:ui-tooling-preview:1.3.0-alpha01")
implementation("androidx.compose.material3:material3:1.0.0-alpha14")
implementation("androidx.compose.material:material:1.3.0-alpha01")

// Google accompanist
implementation("com.google.accompanist:accompanist-navigation-animation:0.24.9-beta")
Expand All @@ -83,7 +116,7 @@ dependencies {
implementation("com.google.accompanist:accompanist-flowlayout:0.24.9-beta")

// Google play services
implementation("com.google.android.gms:play-services-location:19.0.1")
implementation("com.google.android.gms:play-services-location:20.0.0")
implementation("com.google.android.gms:play-services-maps:18.0.2")
implementation("com.google.android.libraries.places:places:2.6.0")
implementation("com.google.maps.android:maps-compose:2.1.1")
Expand Down Expand Up @@ -112,12 +145,14 @@ dependencies {
kapt("com.google.dagger:hilt-android-compiler:2.40")

// Navigation
implementation("androidx.navigation:navigation-compose:2.4.2")
implementation("androidx.navigation:navigation-compose:2.5.0")

// ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0-rc01")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.5.0-rc01")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.0-alpha01")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.0-alpha01")

// LiveData
implementation("androidx.compose.runtime:runtime-livedata:1.3.0-alpha01")
// Gson
implementation("com.google.code.gson:gson:2.9.0")

Expand All @@ -127,13 +162,20 @@ dependencies {
// DataStore
implementation("androidx.datastore:datastore-preferences:1.0.0")

// Kotlin reflect
implementation("org.jetbrains.kotlin:kotlin-reflect:1.7.0")

testImplementation("junit:junit:4.13.2")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.1")

// MockK
testImplementation("io.mockk:mockk:1.12.4")
testImplementation("io.mockk:mockk-agent-jvm:1.12.4")

androidTestImplementation("androidx.test.ext:junit:1.1.3")
androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
androidTestImplementation("androidx.compose.ui:ui-test-junit4:1.1.1")

debugImplementation("androidx.compose.ui:ui-tooling:1.1.1")
debugImplementation("androidx.compose.ui:ui-test-manifest:1.1.1")
debugImplementation("androidx.compose.ui:ui-tooling:1.3.0-alpha01")
debugImplementation("androidx.compose.ui:ui-test-manifest:1.3.0-alpha01")
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import com.google.gson.annotations.SerializedName
data class CurrentWeather(
@SerializedName("id") val id: Int? = 0,
@SerializedName("name") val name: String? = "",
@SerializedName("cod") val cod: Int,
@SerializedName("coord") val coord: Coord,
@SerializedName("weather") val weatherItems: List<Weather>,
@SerializedName("cod") val cod: Int? = 0,
@SerializedName("coord") val coord: Coord? = null,
@SerializedName("weather") val weatherItems: List<Weather>? = emptyList(),
@SerializedName("base") val base: String? = "",
@SerializedName("main") val main: Main,
@SerializedName("visibility") val visibility: Int,
@SerializedName("wind") val wind: Wind,
@SerializedName("clouds") val clouds: Cloud,
@SerializedName("dt") val dt: Long,
@SerializedName("sys") val sys: Sys,
@SerializedName("timezone") val timezone: Int
@SerializedName("main") val main: Main? = null,
@SerializedName("visibility") val visibility: Int? = 0,
@SerializedName("wind") val wind: Wind? = null,
@SerializedName("clouds") val clouds: Cloud? = null,
@SerializedName("dt") val dt: Long? = 0L,
@SerializedName("sys") val sys: Sys? = null,
@SerializedName("timezone") val timezone: Int? = null
) : Model()
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import android.content.Context
import android.location.Address
import android.location.Geocoder
import android.os.Build
import androidx.compose.ui.text.intl.Locale
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.tasks.CancellationTokenSource
import com.google.android.libraries.places.api.model.AutocompletePrediction
Expand All @@ -25,7 +24,6 @@ import kotlinx.coroutines.flow.flatMapConcat
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.suspendCancellableCoroutine
import timber.log.Timber
import java.util.*
import javax.inject.Inject
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
Expand All @@ -45,7 +43,7 @@ class LocationRepositoryImpl @Inject constructor(
val cancellationTokenSource = CancellationTokenSource()

fusedLocationProviderClient.getCurrentLocation(
LocationRequest.PRIORITY_HIGH_ACCURACY,
Priority.PRIORITY_HIGH_ACCURACY,
cancellationTokenSource.token,
).addOnSuccessListener { location ->
if (location != null) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.minhdtm.example.weapose.presentation.model

import androidx.compose.ui.text.capitalize
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.toUpperCase
import com.minhdtm.example.weapose.data.model.CurrentWeather
import com.minhdtm.example.weapose.presentation.utils.Constants
import com.minhdtm.example.weapose.presentation.utils.toBackground
Expand All @@ -28,14 +27,14 @@ class CurrentWeatherMapper @Inject constructor() : DataModelMapper<CurrentWeathe

override fun mapToViewData(model: CurrentWeather): CurrentWeatherViewData {
val city = model.name?.uppercase() ?: ""
val maxTemp = model.main.tempMax?.toString() ?: ""
val minTemp = model.main.tempMin?.toString() ?: ""
val temp = model.main.temp?.toString() ?: ""
val weather = model.weatherItems.firstOrNull()?.description?.capitalize(Locale.current) ?: ""
val sunRise = model.sys.sunrise?.toDateTime(Constants.DateFormat.HH_mm, model.timezone) ?: ""
val wind = model.wind.speed?.toString() ?: ""
val humidity = model.main.humidity?.toString() ?: ""
val background = (model.weatherItems.firstOrNull()?.icon ?: "").toBackground()
val maxTemp = model.main?.tempMax?.toString() ?: ""
val minTemp = model.main?.tempMin?.toString() ?: ""
val temp = model.main?.temp?.toString() ?: ""
val weather = model.weatherItems?.firstOrNull()?.description?.capitalize(Locale.current) ?: ""
val sunRise = model.sys?.sunrise?.toDateTime(Constants.DateFormat.HH_mm, model.timezone) ?: ""
val wind = model.wind?.speed?.toString() ?: ""
val humidity = model.main?.humidity?.toString() ?: ""
val background = (model.weatherItems?.firstOrNull()?.icon ?: "").toBackground()

return CurrentWeatherViewData(
city = city,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.minhdtm.example.weapose.presentation.model.factory

import com.minhdtm.example.weapose.R
import com.minhdtm.example.weapose.presentation.model.DayWeatherViewData

fun previewDayWeatherViewData() = DayWeatherViewData(
dateTime = "Saturday, Jan 1",
weatherDetail = "Rain",
icon = R.drawable.ic_rain,
maxTemp = 40.0,
minTemp = 30.0,
humidity = 80,
sunset = "06:00",
sunrise = "17:00",
uvIndex = 8.0,
windSpeed = "10",
)
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ import com.minhdtm.example.weapose.presentation.ui.WeatherAppState
import com.minhdtm.example.weapose.presentation.utils.Constants
import kotlinx.coroutines.flow.collectLatest


@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun CurrentWeather(
Expand Down Expand Up @@ -101,27 +100,30 @@ fun CurrentWeather(
}

// Get event
LaunchedEffect(true) {
viewModel.event.collectLatest { event ->
when (event) {
is CurrentWeatherEvent.CheckPermission -> {
when {
locationPermissionState.allPermissionsGranted -> {
viewModel.getCurrentLocation()
}
locationPermissionState.shouldShowRationale -> {
viewModel.permissionIsNotGranted()
}
else -> {
locationPermissionState.launchMultiplePermissionRequest()
}
LaunchedEffect(state) {
val navigateToSearch = state.navigateSearch
val requestPermission = state.isRequestPermission

when {
requestPermission -> {
when {
locationPermissionState.allPermissionsGranted -> {
viewModel.getCurrentLocation()
}
locationPermissionState.shouldShowRationale -> {
viewModel.permissionIsNotGranted()
}
else -> {
locationPermissionState.launchMultiplePermissionRequest()
}
}
is CurrentWeatherEvent.NavigateToSearchByMap -> {
appState.navigateToSearchByText(Screen.CurrentWeather, event.latLng)
}
}
navigateToSearch != null -> {
appState.navigateToSearchByText(Screen.CurrentWeather, navigateToSearch)
}
else -> return@LaunchedEffect
}
viewModel.cleanEvent()
}

CurrentWeatherScreen(
Expand Down
Loading

0 comments on commit ee802f6

Please sign in to comment.