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

💣 BIG BANG : Migrate Material 2 -> 3 + Design System + Data exclusion logic + Minor tweaks #77

Merged
merged 30 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6d26050
move excluded data to repository
odaridavid Mar 10, 2024
51bb6c2
add material 3 dependency
odaridavid Mar 11, 2024
130877e
add excluded data logic to data layer
odaridavid Mar 11, 2024
fe3a5fd
refactor and move tests
odaridavid Mar 11, 2024
f7ac5a2
add resources
odaridavid Mar 11, 2024
134e2e3
migrate to material3
odaridavid Mar 11, 2024
034b9a9
material3 migration cleanup
odaridavid Mar 11, 2024
ced162d
tweak material3 changes
odaridavid Mar 11, 2024
5e03b66
expand color range
odaridavid Mar 11, 2024
e345e17
fix icons for dark theme with qualifier
odaridavid Mar 11, 2024
edf5d44
String update
odaridavid Mar 11, 2024
3c5c069
cleanup design system implementation
odaridavid Mar 11, 2024
f84fe54
ktlint fixes
odaridavid Mar 11, 2024
069fd3a
ktlint fixes
odaridavid Mar 11, 2024
0037c54
replace components with new ones
odaridavid Mar 11, 2024
1a4ca33
adjust button shapes
odaridavid Mar 11, 2024
8774053
add small headline
odaridavid Mar 11, 2024
47f8274
update strings
odaridavid Mar 11, 2024
1bf6721
add excluded data bottom sheet UI
odaridavid Mar 11, 2024
d460a12
add empty section component for excluded data
odaridavid Mar 11, 2024
ca741ae
delete old screenshots
odaridavid Mar 11, 2024
5bd744c
fix error + success and empty state ui
odaridavid Mar 11, 2024
c65ff82
ktlint fix
odaridavid Mar 11, 2024
f8d29c6
update screenshots
odaridavid Mar 11, 2024
d04f433
fix one screenshot
odaridavid Mar 11, 2024
8283909
introduce empty data state incase user deselects all options
odaridavid Mar 11, 2024
3e69d14
fix existing tests
odaridavid Mar 11, 2024
c3744a6
ktlint fix
odaridavid Mar 11, 2024
05c7c41
exclude common android in test cov
odaridavid Mar 11, 2024
ab09419
add tests
odaridavid Mar 12, 2024
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
15 changes: 14 additions & 1 deletion .idea/deploymentTargetDropDown.xml

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

25 changes: 14 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,15 @@ Typography:
Define font styles, sizes, and weights for headers, paragraphs, and other text elements.

Color Palette:
Establish a color palette with primary, secondary, and accent colors. Specify their usage in
Establish a color palette with primary, secondary, and accent colors. Specify their usage in
different contexts.

Icons:
Design a set of basic icons that represent common actions or concepts. Ensure consistency in style
and sizing.

Buttons:
Create button styles with variations for primary, secondary, and tertiary actions. Include states
Create button styles with variations for primary, secondary, and tertiary actions. Include states
like hover and disabled.

Input Fields:
Expand All @@ -146,7 +146,8 @@ Form Elements:
Combine atoms to create complete form components. Ensure consistency in spacing and alignment.

Cards:
Combine text, images, and buttons to create card components. Define variations for different use cases.
Combine text, images, and buttons to create card components. Define variations for different use
cases.

Badges:
Assemble icons and text to create badge components for notifications or status indicators.
Expand All @@ -163,7 +164,7 @@ Headers and Footers:
Define headers and footers with appropriate spacing, logos, and navigation links.

Lists:
Assemble atoms and molecules to create list components, incorporating variations like simple lists,
Assemble atoms and molecules to create list components, incorporating variations like simple lists,
detailed lists, and nested lists.

Modals:
Expand Down Expand Up @@ -249,13 +250,15 @@ LeakCanary is also used to monitor for any memory leaks that might occur in debu

# Screenshots 📱

| Light Theme | Dark Theme |
|:-----------------------------------------------------:|:-----------------------------------------------------:|
| <img src="/docs/screenshots/white.png" width="300px"> | <img src="/docs/screenshots/black.png" width="300px"> |

| Error |
|:---------------------------------------------------:|
| <img src="/docs/screenshots/drk.png" width="300px"> |
| Light Theme | Dark Theme |
|:----------------------------------------------------------------------:|:---------------------------------------------------------------------:|
| <img src="/docs/screenshots/(Light)Main.png" width="250px"> | <img src="/docs/screenshots/(Dark)Main.png" width="250px"> |
| <img src="/docs/screenshots/(Light)Settings.png" width="250px"> | <img src="/docs/screenshots/(Dark)Settings.png" width="250px"> |
| <img src="/docs/screenshots/(Light)Settings-Option.png" width="250px"> | <img src="/docs/screenshots/(Dark)Settings-Option.png" width="250px"> |
| <img src="/docs/screenshots/(Light)About.png" width="250px"> | <img src="/docs/screenshots/(Dark)About.png" width="250px"> |
| <img src="/docs/screenshots/(Light)About.png" width="250px"> | <img src="/docs/screenshots/(Dark)About.png" width="250px"> |
| <img src="/docs/screenshots/(Light)Error.png" width="250px"> | <img src="/docs/screenshots/(Dark)Error.png" width="250px"> |
| <img src="/docs/screenshots/(Light)Excluded.png" width="250px"> | - |

![](https://media.giphy.com/media/hWvk9iUU4uBBeyBq0k/giphy.gif)

Expand Down
5 changes: 3 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ fun setupAndroidReporting() {
"**/*_MembersInjector.class",
"**/*_Factory*.*",
"**/*_Provide*Factory*.*",
"**/*Extensions*.*",
// sealed and data classes
"**/*\$Result.*",
"**/*\$Result$*.*",
Expand All @@ -83,7 +82,9 @@ fun setupAndroidReporting() {
"**/designsystem/**",
"**/*Screen*.*",
"**/*NavGraph*.*",
"**/*Destinations*.*"
"**/*Destinations*.*",
"**/common/**",
"**/*Extensions*.*",
)

val javaTree = fileTree("${project.buildDir}/intermediates/javac/$sourceName/classes") {
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<application
android:name=".WeatherApp"
Expand All @@ -19,7 +19,8 @@
<activity
android:name=".ui.MainActivity"
android:exported="true"
android:theme="@style/Theme.WeatherApp">
android:theme="@style/Theme.WeatherApp"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand All @@ -30,6 +31,7 @@
android:name="android.app.lib_name"
android:value="" />
</activity>
<!-- TODO Add new activity launcher with different icon for debug stuff-->
</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class WeatherApp : Application()
// TODO Add global error handling
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.odaridavid.weatherapp.core.api

import com.github.odaridavid.weatherapp.core.model.DefaultLocation
import com.github.odaridavid.weatherapp.core.model.TimeFormat
import com.github.odaridavid.weatherapp.core.model.ExcludedData
import kotlinx.coroutines.flow.Flow

interface SettingsRepository {
Expand All @@ -27,6 +27,9 @@ interface SettingsRepository {

suspend fun setFormat(format: String)

fun getFormats() : List<String>
fun getFormats(): List<String>

suspend fun getExcludedData(): Flow<String>

suspend fun setExcludedData(excludedData: List<ExcludedData>)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.github.odaridavid.weatherapp.core.model
enum class ExcludedData(val value:String){

enum class ExcludedData(val value: String) {
CURRENT("current"),
HOURLY("hourly"),
DAILY("daily"),
MINUTELY("minutely"),
ALERTS("alerts"),
NONE(""),
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.github.odaridavid.weatherapp.core.model

data class Weather(
val current: CurrentWeather,
val hourly: List<HourlyWeather>,
val daily: List<DailyWeather>
val current: CurrentWeather?,
val hourly: List<HourlyWeather>?,
val daily: List<DailyWeather>?
)

data class CurrentWeather(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.github.odaridavid.weatherapp.BuildConfig
import com.github.odaridavid.weatherapp.core.api.SettingsRepository
import com.github.odaridavid.weatherapp.core.model.DefaultLocation
import com.github.odaridavid.weatherapp.core.model.ExcludedData
import com.github.odaridavid.weatherapp.core.model.SupportedLanguage
import com.github.odaridavid.weatherapp.core.model.TimeFormat
import com.github.odaridavid.weatherapp.core.model.Units
Expand All @@ -24,6 +25,7 @@
private val PREF_UNITS by lazy { stringPreferencesKey(KEY_UNITS) }
private val TIME_FORMAT by lazy { stringPreferencesKey(KEY_TIME_FORMAT) }
private val PREF_LAT_LNG by lazy { stringPreferencesKey(KEY_LAT_LNG) }
private val PREF_EXCLUDED_DATA by lazy { stringPreferencesKey(KEY_EXCLUDED_DATA) }

Check warning on line 28 in app/src/main/java/com/github/odaridavid/weatherapp/data/settings/DefaultSettingsRepository.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/com/github/odaridavid/weatherapp/data/settings/DefaultSettingsRepository.kt#L28

Added line #L28 was not covered by tests

override suspend fun setLanguage(language: String) {
set(key = PREF_LANGUAGE, value = language)
Expand Down Expand Up @@ -64,13 +66,22 @@
override suspend fun getFormat(): Flow<String> =
get(key = TIME_FORMAT, default = TimeFormat.TWENTY_FOUR_HOUR.value)


override suspend fun setFormat(format: String) {
set(key = TIME_FORMAT, value = format)
}

override fun getFormats(): List<String> {
return TimeFormat.values().map { it.value }
return TimeFormat.entries.map { it.value }

Check warning on line 74 in app/src/main/java/com/github/odaridavid/weatherapp/data/settings/DefaultSettingsRepository.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/com/github/odaridavid/weatherapp/data/settings/DefaultSettingsRepository.kt#L74

Added line #L74 was not covered by tests
}

override suspend fun getExcludedData(): Flow<String> = get(
key = PREF_EXCLUDED_DATA,
default = "${ExcludedData.MINUTELY.value},${ExcludedData.ALERTS.value}"
)

Check warning on line 80 in app/src/main/java/com/github/odaridavid/weatherapp/data/settings/DefaultSettingsRepository.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/com/github/odaridavid/weatherapp/data/settings/DefaultSettingsRepository.kt#L77-L80

Added lines #L77 - L80 were not covered by tests

override suspend fun setExcludedData(excludedData: List<ExcludedData>) {
val formattedData = excludedData.joinToString(separator = ",") { it.value }
set(key = PREF_EXCLUDED_DATA, value = formattedData)

Check warning on line 84 in app/src/main/java/com/github/odaridavid/weatherapp/data/settings/DefaultSettingsRepository.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/com/github/odaridavid/weatherapp/data/settings/DefaultSettingsRepository.kt#L83-L84

Added lines #L83 - L84 were not covered by tests
}

private suspend fun <T> set(key: Preferences.Key<T>, value: T) {
Expand All @@ -86,13 +97,14 @@
}

companion object {
//Düsseldorf
// Düsseldorf
const val DEFAULT_LONGITUDE = 6.773456
const val DEFAULT_LATITUDE = 51.227741

const val KEY_LANGUAGE = "language"
const val KEY_UNITS = "units"
const val KEY_LAT_LNG = "lat_lng"
const val KEY_TIME_FORMAT = "time_formats"
const val KEY_EXCLUDED_DATA = "excluded_data"
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package com.github.odaridavid.weatherapp.data.weather

import com.github.odaridavid.weatherapp.core.Result
import com.github.odaridavid.weatherapp.core.Result.Success
import com.github.odaridavid.weatherapp.core.Result.Error
import com.github.odaridavid.weatherapp.core.api.Logger
import com.github.odaridavid.weatherapp.core.api.SettingsRepository
import com.github.odaridavid.weatherapp.core.api.WeatherRepository
import com.github.odaridavid.weatherapp.core.model.DefaultLocation
import com.github.odaridavid.weatherapp.core.model.TimeFormat
import com.github.odaridavid.weatherapp.core.model.Weather
import com.github.odaridavid.weatherapp.data.weather.remote.RemoteWeatherDataSource
import com.github.odaridavid.weatherapp.data.weather.remote.mapThrowableToErrorType
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.first
import javax.inject.Inject

class DefaultWeatherRepository @Inject constructor(
Expand All @@ -23,23 +21,23 @@ class DefaultWeatherRepository @Inject constructor(
override suspend fun fetchWeatherData(
defaultLocation: DefaultLocation,
language: String,
units: String
units: String,
): Result<Weather> =
try {
val format =
settingsRepository.getFormat().firstOrNull() ?: TimeFormat.TWENTY_FOUR_HOUR.value
val format = settingsRepository.getFormat().first()

val excludedData = settingsRepository.getExcludedData().first()

remoteWeatherDataSource.fetchWeatherData(
defaultLocation = defaultLocation,
units = units,
language = language,
format = format,
excludedData = excludedData
)
} catch (throwable: Throwable) {
val errorType = mapThrowableToErrorType(throwable)
logger.logException(throwable)
Error(errorType)
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.github.odaridavid.weatherapp.data.weather.remote
import com.github.odaridavid.weatherapp.BuildConfig
import com.github.odaridavid.weatherapp.core.Result
import com.github.odaridavid.weatherapp.core.model.DefaultLocation
import com.github.odaridavid.weatherapp.core.model.ExcludedData
import com.github.odaridavid.weatherapp.core.model.SupportedLanguage
import com.github.odaridavid.weatherapp.core.model.Weather
import javax.inject.Inject
Expand All @@ -17,18 +16,17 @@ class DefaultRemoteWeatherDataSource @Inject constructor(
language: String,
units: String,
format: String,
excludedData: String,
): Result<Weather> =
try {

val excludedData = "${ExcludedData.MINUTELY.value},${ExcludedData.ALERTS.value}"

val response = openWeatherService.getWeatherData(
longitude = defaultLocation.longitude,
latitude = defaultLocation.latitude,
excludedInfo = excludedData,
units = units,
language = getLanguageValue(language),
appid = BuildConfig.OPEN_WEATHER_API_KEY
appid = BuildConfig.OPEN_WEATHER_API_KEY,
)

if (response.isSuccessful && response.body() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ import java.util.Locale
import kotlin.math.roundToInt

fun WeatherResponse.toCoreModel(unit: String, format: String): Weather = Weather(
current = current.toCoreModel(unit = unit),
daily = daily.map { it.toCoreModel(unit = unit) },
hourly = hourly.map { it.toCoreModel(unit = unit, format = format) }
current = current?.toCoreModel(unit = unit),
daily = daily?.map { it.toCoreModel(unit = unit) },
hourly = hourly?.map { it.toCoreModel(unit = unit, format = format) }
)

fun CurrentWeatherResponse.toCoreModel(unit: String): CurrentWeather =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ interface RemoteWeatherDataSource {
language: String,
units: String,
format: String,
excludedData: String
): Result<Weather>
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import kotlinx.serialization.Serializable

@Serializable
data class WeatherResponse(
@SerialName("current") val current: CurrentWeatherResponse,
@SerialName("hourly") val hourly: List<HourlyWeatherResponse>,
@SerialName("daily") val daily: List<DailyWeatherResponse>
@SerialName("current") val current: CurrentWeatherResponse? = null,
@SerialName("hourly") val hourly: List<HourlyWeatherResponse>? = null,
@SerialName("daily") val daily: List<DailyWeatherResponse>? = null,
)

@Serializable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,18 @@
package com.github.odaridavid.weatherapp.designsystem

import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material.MaterialTheme
import androidx.compose.material.darkColors
import androidx.compose.material.lightColors
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import com.github.odaridavid.weatherapp.designsystem.atom.DarkColorPalette
import com.github.odaridavid.weatherapp.designsystem.atom.Dimensions
import com.github.odaridavid.weatherapp.designsystem.atom.LightColorPalette
import com.github.odaridavid.weatherapp.designsystem.atom.LocalDimens
import com.github.odaridavid.weatherapp.designsystem.atom.LocalWeight
import com.github.odaridavid.weatherapp.designsystem.atom.Weight
import com.github.odaridavid.weatherapp.designsystem.atom.pink200
import com.github.odaridavid.weatherapp.designsystem.atom.pink500
import com.github.odaridavid.weatherapp.designsystem.atom.pink600
import com.github.odaridavid.weatherapp.designsystem.atom.pinkDarkPrimary
import com.github.odaridavid.weatherapp.designsystem.atom.shapes
import com.github.odaridavid.weatherapp.designsystem.atom.typography

private val LightColorPalette = lightColors(
primary = pink500,
secondary = pink500,
primaryVariant = pink600,
onPrimary = Color.Black,
onSecondary = Color.Black
)

private val DarkColorPalette = darkColors(
primary = pink200,
secondary = pink200,
surface = pinkDarkPrimary
)

// TODO Debug menu or app to preview design system components
@Composable
fun WeatherAppTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
val colors = if (darkTheme) {
Expand All @@ -40,7 +22,7 @@ fun WeatherAppTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Compos
}

MaterialTheme(
colors = colors,
colorScheme = colors,
typography = typography,
shapes = shapes,
content = content
Expand Down
Loading
Loading