diff --git a/.gitignore b/.gitignore index cee9f91..213dfad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,43 @@ -*.iml -.gradle -/local.properties -/.idea/caches -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -/.idea/navEditor.xml -/.idea/assetWizardSettings.xml -.DS_Store -app/build -/build -/captures -.externalNativeBuild -.cxx +# built application files +*.apk +*.ap_ + +# files for the dex VM +*.dex + +# Java class files +*.class + +# generated files +bin/ +gen/ +out/ +build/ + +# Local configuration file (sdk path, etc) local.properties + +# Eclipse project files +.classpath +.project + +# Windows thumbnail db +.DS_Store + +# IDEA/Android Studio project files, because +# the project can be imported from settings.gradle.kts +*.iml +.idea/* +!.idea/copyright +# Keep the code styles. +!/.idea/codeStyles +/.idea/codeStyles/* +!/.idea/codeStyles/Project.xml +!/.idea/codeStyles/codeStyleConfig.xml + +# Gradle cache +.gradle + +# app signing +*.jks +/keystore.properties diff --git a/app/.gitignore b/app/.gitignore deleted file mode 100644 index 42afabf..0000000 --- a/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 88a3501..39af1db 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,76 +1,71 @@ +import java.io.FileInputStream +import java.util.Properties + plugins { - id("com.android.application") - id("org.jetbrains.kotlin.android") - id("org.jetbrains.kotlin.plugin.compose") - id("com.google.devtools.ksp") - id("com.google.dagger.hilt.android") + alias(libs.plugins.kotlin.serialization) + alias(libs.plugins.flights.android.application.compose) + alias(libs.plugins.flights.android.application.hilt) } android { - namespace = "com.ryanair.androidchallenge" - compileSdk = 35 + namespace = "dev.adriankuta.flights" defaultConfig { - applicationId = "com.ryanair.androidchallenge" - versionCode = 1 - versionName = "1.0" - multiDexEnabled = true - - minSdk = 28 - targetSdk = 35 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + applicationId = "dev.adriankuta.flights" + versionCode = 10 + versionName = "0.0.1-${versionCode}" + //signingConfig = signingConfigs.getByName("debug") } + /*val keystorePropertiesFile = rootProject.file("keystore.properties") + val keystoreProperties = Properties() + keystoreProperties.load(FileInputStream(keystorePropertiesFile)) + + signingConfigs { + create("release") { + keyAlias = keystoreProperties["keyAlias"] as String + keyPassword = keystoreProperties["keyPassword"] as String + storeFile = file(keystoreProperties["storeFile"] as String) + storePassword = keystoreProperties["storePassword"] as String + } + }*/ + buildTypes { - getByName("debug") { + debug { + signingConfig = signingConfigs.getByName("debug") + isDebuggable = true + } + release { + //signingConfig = signingConfigs.getByName("release") isDebuggable = true isMinifyEnabled = false isShrinkResources = false - } - getByName("release") { - isMinifyEnabled = true - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro", + ) } } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 - } - kotlinOptions { - jvmTarget = JavaVersion.VERSION_17.toString() - } - buildFeatures { - viewBinding = true - compose = true + + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } } } dependencies { - val composeBom = platform("androidx.compose:compose-bom:2025.04.01") - implementation(composeBom) - implementation("androidx.compose.material3:material3") - implementation("androidx.compose.material:material-icons-core") - implementation("androidx.compose.ui:ui-tooling-preview") + implementation(projects.model.repository) + implementation(projects.model.data.room) + implementation(projects.model.data.simple) - implementation("androidx.activity:activity-compose:1.10.1") - implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.9.0") + implementation(projects.ui.designsystem) + implementation(projects.ui.home) - implementation("androidx.core:core-ktx:1.16.0") - implementation("androidx.appcompat:appcompat:1.7.0") - implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.9.0") - - // Dependency Injection - implementation("com.google.dagger:hilt-android:2.56.2") - ksp("com.google.dagger:hilt-compiler:2.56.2") - - // Network - ksp("com.squareup.moshi:moshi-kotlin-codegen:1.15.2") - implementation("com.squareup.moshi:moshi:1.15.2") - implementation("com.squareup.retrofit2:retrofit:2.11.0") - implementation("com.squareup.retrofit2:converter-moshi:2.11.0") - implementation("com.squareup.okhttp3:logging-interceptor:4.12.0") - -} \ No newline at end of file + implementation(libs.androidx.activity.compose) + implementation(libs.androidx.core.splashscreen) + implementation(libs.androidx.hilt.navigation.compose) + implementation(libs.app.update.ktx) +} diff --git a/app/config/detekt/detekt.yml b/app/config/detekt/detekt.yml new file mode 100644 index 0000000..ab95a32 --- /dev/null +++ b/app/config/detekt/detekt.yml @@ -0,0 +1,33 @@ +# Exceptions for compose. See https://detekt.dev/docs/introduction/compose +naming: + FunctionNaming: + functionPattern: '[a-zA-Z][a-zA-Z0-9]*' + + TopLevelPropertyNaming: + constantPattern: '[A-Z][A-Za-z0-9]*' + +complexity: + LongParameterList: + ignoreAnnotated: [ 'Composable' ] + TooManyFunctions: + ignoreAnnotatedFunctions: [ 'Preview' ] + +style: + MagicNumber: + ignorePropertyDeclaration: true + ignoreCompanionObjectPropertyDeclaration: true + ignoreAnnotated: [ 'Composable' ] + + UnusedPrivateMember: + ignoreAnnotated: [ 'Composable' ] + +# Deviations from defaults +formatting: + TrailingCommaOnCallSite: + active: true + autoCorrect: true + useTrailingCommaOnCallSite: true + TrailingCommaOnDeclarationSite: + active: true + autoCorrect: true + useTrailingCommaOnDeclarationSite: true \ No newline at end of file diff --git a/app/lint-baseline.xml b/app/lint-baseline.xml new file mode 100644 index 0000000..3acbfa8 --- /dev/null +++ b/app/lint-baseline.xml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index ff59496..44a4007 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,6 +1,6 @@ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle.kts. +# proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html @@ -18,4 +18,7 @@ # If you keep the line number information, uncomment this to # hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file +#-renamesourcefileattribute SourceFile + +-keep class dev.adriankuta.flights.data.dto.* { *; } +-keep class dev.adriankuta.flights.data.model.* { *; } \ No newline at end of file diff --git a/app/src/debug/kotlin/dev/adriankuta/flights/MyApplication.kt b/app/src/debug/kotlin/dev/adriankuta/flights/MyApplication.kt new file mode 100644 index 0000000..1548e75 --- /dev/null +++ b/app/src/debug/kotlin/dev/adriankuta/flights/MyApplication.kt @@ -0,0 +1,15 @@ +package dev.adriankuta.flights + +import android.app.Application +import dagger.hilt.android.HiltAndroidApp +import timber.log.Timber +import timber.log.Timber.DebugTree + +@HiltAndroidApp +class MyApplication : Application() { + + override fun onCreate() { + super.onCreate() + Timber.plant(DebugTree()) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d7fc4a9..79a2989 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,21 +1,29 @@ + xmlns:tools="http://schemas.android.com/tools"> + android:theme="@style/Theme.Flights" + tools:targetApi="33"> + android:name=".MainActivity" + android:exported="true" + android:theme="@style/Theme.Flights"> + - \ No newline at end of file + + diff --git a/app/src/main/assets/famous-characters.txt b/app/src/main/assets/famous-characters.txt new file mode 100644 index 0000000..a84feff --- /dev/null +++ b/app/src/main/assets/famous-characters.txt @@ -0,0 +1,28 @@ +Adam Małysz +Kubuś Puchatek +Prosiaczek +Harry Potter +SpongeBob +Miś Uszatek +Patryk (SpongeBob) +Pan krab (SpongeBob) +Brzydkie kaczątko +Alvin i Wiewiórki +Szymon (Alvin i wiewiórki) +Papa Smerf +Smerfetka +Gargamel (smerfy) +Ważniak (smerfy) +Roszpunka +Myszka Miki +Król Lew +Stitch +Elsa (kraina lodu) +Anna (kraina lodu) +Olaf (kraina lodu) +Mała syrenka +Tygrys (Kubuś Puchatek) +Kłapouchy (Kubuś Puchatek) +Maleństwo (Kubuś Puchatek) +Królik (Kubuś Puchatek) +Krzyś (Kubuś Puchatek) \ No newline at end of file diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..b716707 Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/java/com/ryanair/androidchallenge/di/NetworkModule.kt b/app/src/main/java/com/ryanair/androidchallenge/di/NetworkModule.kt deleted file mode 100644 index 0e2fc4f..0000000 --- a/app/src/main/java/com/ryanair/androidchallenge/di/NetworkModule.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.ryanair.androidchallenge.di - -import com.ryanair.androidchallenge.repository.airports.api.AirportService -import com.ryanair.androidchallenge.repository.airports.api.RoutesService -import com.ryanair.androidchallenge.repository.flights.api.FlightService -import com.squareup.moshi.Moshi -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import okhttp3.OkHttpClient -import okhttp3.logging.HttpLoggingInterceptor -import retrofit2.Retrofit -import retrofit2.converter.moshi.MoshiConverterFactory -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -class NetworkModule { - - @Singleton - @Provides - fun provideMoshi() = Moshi.Builder().build() - - @Singleton - @Provides - fun provideHttpLoggingInterceptor() = HttpLoggingInterceptor().apply { - setLevel(HttpLoggingInterceptor.Level.BODY) - } - - @Singleton - @Provides - fun providesOkHttpClient(loggingInterceptor: HttpLoggingInterceptor) = - OkHttpClient.Builder().also { builder -> - builder.addInterceptor(loggingInterceptor) - }.build() - - @Singleton - @Provides - fun provideRetrofit(client: OkHttpClient, moshi: Moshi): Retrofit = Retrofit.Builder() - // TODO("add URL provided in the task instructions") - .addConverterFactory(MoshiConverterFactory.create(moshi)) - .client(client) - .build() - - @Singleton - @Provides - fun provideAirportService(retrofit: Retrofit): AirportService = retrofit.create(AirportService::class.java) - - @Singleton - @Provides - fun provideRoutesService(retrofit: Retrofit): RoutesService = retrofit.create(RoutesService::class.java) - - @Singleton - @Provides - fun provideFlightService(retrofit: Retrofit): FlightService = retrofit.create(FlightService::class.java) -} \ No newline at end of file diff --git a/app/src/main/java/com/ryanair/androidchallenge/repository/airports/api/AirportService.kt b/app/src/main/java/com/ryanair/androidchallenge/repository/airports/api/AirportService.kt deleted file mode 100644 index de28d6f..0000000 --- a/app/src/main/java/com/ryanair/androidchallenge/repository/airports/api/AirportService.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.ryanair.androidchallenge.repository.airports.api - -import com.ryanair.androidchallenge.repository.airports.model.AirportResponse -import retrofit2.http.GET -import retrofit2.http.Path - -interface AirportService { - - @GET("/views/locate/5/airports/{language}/active") - suspend fun getAirports(@Path("language") languageCode: String): List - -} \ No newline at end of file diff --git a/app/src/main/java/com/ryanair/androidchallenge/repository/airports/api/RoutesService.kt b/app/src/main/java/com/ryanair/androidchallenge/repository/airports/api/RoutesService.kt deleted file mode 100644 index c5c497a..0000000 --- a/app/src/main/java/com/ryanair/androidchallenge/repository/airports/api/RoutesService.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.ryanair.androidchallenge.repository.airports.api - -import com.ryanair.androidchallenge.repository.airports.model.RouteResponse -import retrofit2.http.GET -import retrofit2.http.Path - -interface RoutesService { - - @GET("/views/locate/5/routes/{language}") - suspend fun getAllRoutes( - @Path("language") languageCode: String, - ): List - - @GET("/views/locate/5/routes/{language}/airport/{departure}") - suspend fun getRoutes( - @Path("language") languageCode: String, - @Path("departure") departureAirportCode: String, - ): List -} \ No newline at end of file diff --git a/app/src/main/java/com/ryanair/androidchallenge/repository/airports/model/AirportResponse.kt b/app/src/main/java/com/ryanair/androidchallenge/repository/airports/model/AirportResponse.kt deleted file mode 100644 index 4c96339..0000000 --- a/app/src/main/java/com/ryanair/androidchallenge/repository/airports/model/AirportResponse.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.ryanair.androidchallenge.repository.airports.model - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -data class AirportResponse( - @Json(name = "code") val code: String?, - @Json(name = "name") val name: String?, - @Json(name = "seoName") val seoName: String?, - @Json(name = "base") val isBase: Boolean?, - @Json(name = "timeZone") val timeZone: String?, - @Json(name = "city") val city: City?, - @Json(name = "macCity") val macCity: MacCity?, - @Json(name = "region") val region: Region?, - @Json(name = "country") val country: Country?, - @Json(name = "coordinates") val coordinates: Coordinates? -) { - - @JsonClass(generateAdapter = true) - data class City( - @Json(name = "code") val code: String?, - @Json(name = "name") val name: String? - ) - - @JsonClass(generateAdapter = true) - data class MacCity( - @Json(name = "code") val code: String?, - @Json(name = "macCode") val macCode: String?, - @Json(name = "name") val name: String? - ) - - @JsonClass(generateAdapter = true) - data class Region( - @Json(name = "code") val code: String?, - @Json(name = "name") val name: String? - ) - - @JsonClass(generateAdapter = true) - data class Country( - @Json(name = "code") val code: String?, - @Json(name = "name") val name: String?, - @Json(name = "currency") val currencyCode: String? - ) - - @JsonClass(generateAdapter = true) - data class Coordinates( - @Json(name = "latitude") val latitude: Double?, - @Json(name = "longitude") val longitude: Double? - ) -} diff --git a/app/src/main/java/com/ryanair/androidchallenge/repository/airports/model/RouteResponse.kt b/app/src/main/java/com/ryanair/androidchallenge/repository/airports/model/RouteResponse.kt deleted file mode 100644 index 22c128f..0000000 --- a/app/src/main/java/com/ryanair/androidchallenge/repository/airports/model/RouteResponse.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.ryanair.androidchallenge.repository.airports.model - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -data class RouteResponse( - @Json(name = "departureAirport") val departureAirport: Airport.Departure?, - @Json(name = "arrivalAirport") val arrivalAirport: Airport.Arrival?, - @Json(name = "connectingAirport") val connectingAirport: Airport.Connecting? -) { - - sealed interface Airport { - - @Json(name = "code") - val code: String? - - @Json(name = "name") - val name: String? - - @Json(name = "macCity") - val macCity: MacCity? - - @JsonClass(generateAdapter = true) - data class Departure( - override val code: String?, - override val name: String?, - override val macCity: MacCity?, - ) : Airport - - @JsonClass(generateAdapter = true) - data class Arrival( - override val code: String?, - override val name: String?, - override val macCity: MacCity? - ) : Airport - - @JsonClass(generateAdapter = true) - data class Connecting( - override val code: String?, - override val name: String?, - override val macCity: MacCity? - ) : Airport - - @JsonClass(generateAdapter = true) - data class MacCity( - @Json(name = "macCode") val macCode: String? - ) - } -} diff --git a/app/src/main/java/com/ryanair/androidchallenge/repository/flights/api/FlightService.kt b/app/src/main/java/com/ryanair/androidchallenge/repository/flights/api/FlightService.kt deleted file mode 100644 index 5c08faa..0000000 --- a/app/src/main/java/com/ryanair/androidchallenge/repository/flights/api/FlightService.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.ryanair.androidchallenge.repository.flights.api - -import com.ryanair.androidchallenge.repository.flights.model.FlightResponse -import retrofit2.http.GET -import retrofit2.http.Headers -import retrofit2.http.Query - -interface FlightService { - - // example query: v4/en-gb/Availability?dateout=2025-09-17&origin=WRO&destination=DUB&adt=1&ToUs=AGREED - @Headers( - "client: android", - "client-version: 3.300.0" - ) - @GET("v4/en-gb/Availability") - suspend fun getFlights( - @Query("dateout") date: String, - @Query("origin") origin: String, - @Query("destination") destination: String, - @Query("adt") adult: Int, - @Query("teen") teen: Int, - @Query("chd") child: Int, - @Query("inf") inf: Int = 0, - @Query("ToUs") toUs: String = "AGREED" - ): FlightResponse -} \ No newline at end of file diff --git a/app/src/main/java/com/ryanair/androidchallenge/repository/flights/model/FlightResponse.kt b/app/src/main/java/com/ryanair/androidchallenge/repository/flights/model/FlightResponse.kt deleted file mode 100644 index 3dd4887..0000000 --- a/app/src/main/java/com/ryanair/androidchallenge/repository/flights/model/FlightResponse.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.ryanair.androidchallenge.repository.flights.model - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -data class FlightResponse( - @Json(name = "currency") val currency: String?, - @Json(name = "currPrecision") val currPrecision: Int?, - @Json(name = "trips") val trips: List? -) - -@JsonClass(generateAdapter = true) -data class Trip( - @Json(name = "dates") val dates: List?, - @Json(name = "origin") val origin: String?, - @Json(name = "destination") val destination: String? -) - -@JsonClass(generateAdapter = true) -data class TripDate( - @Json(name = "dateOut") val dateOut: String?, - @Json(name = "flights") val flights: List? -) - -@JsonClass(generateAdapter = true) -data class TripFlight( - @Json(name = "faresLeft") val faresLeft: Int?, - @Json(name = "regularFare") val regularFare: RegularFare?, - @Json(name = "flightNumber") val flightNumber: String?, - @Json(name = "time") val dateTimes: List?, - @Json(name = "duration") val duration: String?, - @Json(name = "segments") val segments: List?, - @Json(name = "operatedBy") val operatedBy: String?, -) - -@JsonClass(generateAdapter = true) -data class RegularFare( - @Json(name = "fares") val fares: List? -) - -@JsonClass(generateAdapter = true) -data class TripFare( - @Json(name = "type") val type: String?, - @Json(name = "amount") val amount: Double?, - @Json(name = "count") val count: Int? -) - -@JsonClass(generateAdapter = true) -data class Segment( - @Json(name = "origin") val origin: String?, - @Json(name = "destination") val destination: String?, - @Json(name = "flightNumber") val flightNumber: String?, - @Json(name = "time") val dateTimes: List?, - @Json(name = "duration") val duration: String? -) \ No newline at end of file diff --git a/app/src/main/java/com/ryanair/androidchallenge/ui/MainActivity.kt b/app/src/main/java/com/ryanair/androidchallenge/ui/MainActivity.kt deleted file mode 100644 index 476825c..0000000 --- a/app/src/main/java/com/ryanair/androidchallenge/ui/MainActivity.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.ryanair.androidchallenge.ui - -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import com.ryanair.androidchallenge.ui.search.SearchScreen -import com.ryanair.androidchallenge.ui.theme.AndroidChallengeTheme -import dagger.hilt.android.AndroidEntryPoint - -@AndroidEntryPoint -class MainActivity : ComponentActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContent { - AndroidChallengeTheme { - SearchScreen() - } - } - } -} diff --git a/app/src/main/java/com/ryanair/androidchallenge/ui/search/SearchScreen.kt b/app/src/main/java/com/ryanair/androidchallenge/ui/search/SearchScreen.kt deleted file mode 100644 index 3427947..0000000 --- a/app/src/main/java/com/ryanair/androidchallenge/ui/search/SearchScreen.kt +++ /dev/null @@ -1,118 +0,0 @@ -package com.ryanair.androidchallenge.ui.search - -import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Search -import androidx.compose.material3.Button -import androidx.compose.material3.Card -import androidx.compose.material3.CardDefaults -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import com.ryanair.androidchallenge.ui.theme.Theme - -@Composable -internal fun SearchScreen() { - Column( - modifier = Modifier - .padding(Theme.spacing.spacing16) - .fillMaxSize(), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.SpaceBetween - ) { - Column( - modifier = Modifier - .wrapContentHeight() - .fillMaxWidth() - ) { - Card( - modifier = Modifier - .fillMaxWidth() - .clickable { }, - border = BorderStroke(Theme.spacing.spacing1, Theme.colors.primary), - colors = CardDefaults.cardColors().copy(containerColor = Theme.colors.background) - ) { - Box(modifier = Modifier.padding(Theme.spacing.spacing8)) { - Column { - Text(text = "From") - - Text(text = "", maxLines = 3) - } - } - } - Spacer(modifier = Modifier.height(Theme.spacing.spacing16)) - Card( - modifier = Modifier - .fillMaxWidth() - .clickable { }, - border = BorderStroke(Theme.spacing.spacing1, Theme.colors.primary), - colors = CardDefaults.cardColors().copy(containerColor = Theme.colors.background) - ) { - Box(modifier = Modifier.padding(Theme.spacing.spacing8)) { - Column { - Text(text = "To") - - Text(text = "", maxLines = 3) - } - } - } - Spacer(modifier = Modifier.height(Theme.spacing.spacing16)) - Card( - modifier = Modifier - .fillMaxWidth() - .clickable { }, - border = BorderStroke(Theme.spacing.spacing1, Theme.colors.primary), - colors = CardDefaults.cardColors().copy(containerColor = Theme.colors.background) - ) { - Box(modifier = Modifier.padding(Theme.spacing.spacing8)) { - Column { - Text(text = "Departure date") - - Text(text = "", maxLines = 3) - } - } - } - Spacer(modifier = Modifier.height(Theme.spacing.spacing16)) - Card( - modifier = Modifier - .fillMaxWidth() - .clickable { }, - border = BorderStroke(Theme.spacing.spacing1, Theme.colors.primary), - colors = CardDefaults.cardColors().copy(containerColor = Theme.colors.background) - ) { - Box(modifier = Modifier.padding(Theme.spacing.spacing8)) { - Column { - Text(text = "Passengers") - - Text(text = "", maxLines = 3) - } - } - } - } - Button(modifier = Modifier - .fillMaxWidth(), - enabled = false, - onClick = { /*TODO*/ }) { - Row { - Icon( - imageVector = Icons.Rounded.Search, - contentDescription = "" - ) - Text(text = "Search") - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/ryanair/androidchallenge/ui/theme/Color.kt b/app/src/main/java/com/ryanair/androidchallenge/ui/theme/Color.kt deleted file mode 100644 index 5443dfb..0000000 --- a/app/src/main/java/com/ryanair/androidchallenge/ui/theme/Color.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.ryanair.androidchallenge.ui.theme - -import androidx.compose.runtime.Stable -import androidx.compose.runtime.staticCompositionLocalOf -import androidx.compose.ui.graphics.Color - -object Palette { - - val Purple80 = Color(0xFFD0BCFF) - val Purple40 = Color(0xFF6650a4) - val White = Color(0xFFFFFFFF) - -} - -@Stable -data class ColorScheme( - val primary: Color = Palette.Purple80, - val primaryAccent: Color = Palette.Purple40, - val background: Color = Palette.White, -) - - -val LocalColorScheme = staticCompositionLocalOf { ColorScheme() } \ No newline at end of file diff --git a/app/src/main/java/com/ryanair/androidchallenge/ui/theme/Spacing.kt b/app/src/main/java/com/ryanair/androidchallenge/ui/theme/Spacing.kt deleted file mode 100644 index cd9a8a3..0000000 --- a/app/src/main/java/com/ryanair/androidchallenge/ui/theme/Spacing.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.ryanair.androidchallenge.ui.theme - -import androidx.compose.runtime.Stable -import androidx.compose.runtime.staticCompositionLocalOf -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp - -@Stable -data class Spacing( - val spacing0: Dp = 0.dp, - val spacing1: Dp = 1.dp, - val spacing2: Dp = 2.dp, - val spacing4: Dp = 4.dp, - val spacing6: Dp = 6.dp, - val spacing8: Dp = 8.dp, - val spacing10: Dp = 10.dp, - val spacing12: Dp = 12.dp, - val spacing14: Dp = 14.dp, - val spacing16: Dp = 16.dp, - val spacing18: Dp = 18.dp, - val spacing20: Dp = 20.dp, - val spacing22: Dp = 22.dp, - val spacing24: Dp = 24.dp, - val spacing26: Dp = 26.dp, - val spacing28: Dp = 28.dp, - val spacing30: Dp = 30.dp, - val spacing32: Dp = 32.dp, - val spacing36: Dp = 36.dp, - val spacing38: Dp = 38.dp, - val spacing40: Dp = 40.dp, - val spacing42: Dp = 42.dp, - val spacing48: Dp = 48.dp, - val spacing56: Dp = 56.dp, - val spacing66: Dp = 66.dp, -) - -val LocalSpacing = staticCompositionLocalOf { Spacing() } diff --git a/app/src/main/java/com/ryanair/androidchallenge/ui/theme/Theme.kt b/app/src/main/java/com/ryanair/androidchallenge/ui/theme/Theme.kt deleted file mode 100644 index 5b3086c..0000000 --- a/app/src/main/java/com/ryanair/androidchallenge/ui/theme/Theme.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.ryanair.androidchallenge.ui.theme - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.ReadOnlyComposable - - -@Composable -fun AndroidChallengeTheme( - colorScheme: ColorScheme = Theme.colors, - typography: Typography = Theme.typography, - spacing: Spacing = Theme.spacing, - content: @Composable () -> Unit -) { - CompositionLocalProvider( - LocalColorScheme provides colorScheme, - LocalTypography provides typography, - LocalSpacing provides spacing - ) { - content() - } -} - -object Theme { - val colors: ColorScheme - @Composable - @ReadOnlyComposable - get() = LocalColorScheme.current - val typography: Typography - @Composable - @ReadOnlyComposable - get() = LocalTypography.current - - val spacing: Spacing - @Composable - @ReadOnlyComposable - get() = LocalSpacing.current -} diff --git a/app/src/main/java/com/ryanair/androidchallenge/ui/theme/Typography.kt b/app/src/main/java/com/ryanair/androidchallenge/ui/theme/Typography.kt deleted file mode 100644 index a5f009b..0000000 --- a/app/src/main/java/com/ryanair/androidchallenge/ui/theme/Typography.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.ryanair.androidchallenge.ui.theme - -import androidx.compose.runtime.Stable -import androidx.compose.runtime.staticCompositionLocalOf -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.sp - - -@Stable -data class Typography( - val titleSmall: TextStyle = TextStyle( - fontFamily = FontFamily.Default, - fontSize = 14.sp, - fontWeight = FontWeight.Bold, - lineHeight = 20.sp, - ), - val titleLarge: TextStyle = TextStyle( - fontFamily = FontFamily.Default, - fontSize = 18.sp, - fontWeight = FontWeight.Bold, - lineHeight = 20.sp, - ), - val subtitleSmall: TextStyle = TextStyle( - fontFamily = FontFamily.Default, - fontSize = 12.sp, - fontWeight = FontWeight.Bold, - lineHeight = 16.sp, - ), - val subtitleLarge: TextStyle = TextStyle( - fontFamily = FontFamily.Default, - fontSize = 16.sp, - fontWeight = FontWeight.Bold, - lineHeight = 20.sp, - ), - val bodySmall: TextStyle = TextStyle( - fontFamily = FontFamily.Default, - fontSize = 10.sp, - fontWeight = FontWeight.Normal, - lineHeight = 12.sp, - ), - val bodyLarge: TextStyle = TextStyle( - fontFamily = FontFamily.Default, - fontSize = 14.sp, - fontWeight = FontWeight.Normal, - lineHeight = 20.sp, - ) -) - -val LocalTypography = staticCompositionLocalOf { Typography() } \ No newline at end of file diff --git a/app/src/main/kotlin/dev/adriankuta/flights/FlightsNavGraph.kt b/app/src/main/kotlin/dev/adriankuta/flights/FlightsNavGraph.kt new file mode 100644 index 0000000..e6027eb --- /dev/null +++ b/app/src/main/kotlin/dev/adriankuta/flights/FlightsNavGraph.kt @@ -0,0 +1,23 @@ +package dev.adriankuta.flights + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.navigation.NavHostController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.rememberNavController +import dev.adriankuta.flights.ui.home.navigation.HomeRoute +import dev.adriankuta.flights.ui.home.navigation.homeScreen + +@Composable +fun FlightsNavGraph( + modifier: Modifier = Modifier, + navController: NavHostController = rememberNavController(), +) { + NavHost( + navController = navController, + startDestination = HomeRoute, + modifier = modifier, + ) { + homeScreen() + } +} diff --git a/app/src/main/kotlin/dev/adriankuta/flights/MainActivity.kt b/app/src/main/kotlin/dev/adriankuta/flights/MainActivity.kt new file mode 100644 index 0000000..46ec3a9 --- /dev/null +++ b/app/src/main/kotlin/dev/adriankuta/flights/MainActivity.kt @@ -0,0 +1,85 @@ +package dev.adriankuta.flights + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.SystemBarStyle +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen +import androidx.lifecycle.lifecycleScope +import dagger.hilt.android.AndroidEntryPoint +import dev.adriankuta.flights.ui.FlightsApp +import dev.adriankuta.flights.ui.designsystem.theme.FlightsTheme +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + +@AndroidEntryPoint +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + val splashScreen = installSplashScreen() + super.onCreate(savedInstanceState) + + var isLoading: Boolean by mutableStateOf(true) + + lifecycleScope.launch { + @Suppress("MagicNumber") + delay(500) + isLoading = false + } + + splashScreen.setKeepOnScreenCondition { + isLoading + } + + enableEdgeToEdge() + + setContent { + val darkTheme = shouldUseDarkTheme() + // Update the edge to edge configuration to match the theme + // This is the same parameters as the default enableEdgeToEdge call, but we manually + // resolve whether or not to show dark theme using uiState, since it can be different + // than the configuration's dark theme value based on the user preference. + DisposableEffect(darkTheme) { + enableEdgeToEdge( + statusBarStyle = SystemBarStyle.auto( + android.graphics.Color.TRANSPARENT, + android.graphics.Color.TRANSPARENT, + ) { darkTheme }, + navigationBarStyle = SystemBarStyle.auto( + lightScrim, + darkScrim, + ) { darkTheme }, + ) + onDispose {} + } + FlightsTheme { + FlightsApp() + } + } + } +} + +/** + * Returns `true` if dark theme should be used, as a function of the [uiState] and the + * current system context. + */ +@Composable +private fun shouldUseDarkTheme(): Boolean = isSystemInDarkTheme() + +/** + * The default light scrim, as defined by androidx and the platform: + * https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt;l=35-38;drc=27e7d52e8604a080133e8b842db10c89b4482598 + */ +private val lightScrim = android.graphics.Color.argb(0xe6, 0xFF, 0xFF, 0xFF) + +/** + * The default dark scrim, as defined by androidx and the platform: + * https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt;l=40-44;drc=27e7d52e8604a080133e8b842db10c89b4482598 + */ +private val darkScrim = android.graphics.Color.argb(0x80, 0x1b, 0x1b, 0x1b) diff --git a/app/src/main/kotlin/dev/adriankuta/flights/ui/FlightsApp.kt b/app/src/main/kotlin/dev/adriankuta/flights/ui/FlightsApp.kt new file mode 100644 index 0000000..da24fda --- /dev/null +++ b/app/src/main/kotlin/dev/adriankuta/flights/ui/FlightsApp.kt @@ -0,0 +1,25 @@ +package dev.adriankuta.flights.ui + +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import dev.adriankuta.flights.FlightsNavGraph +import dev.adriankuta.flights.ui.designsystem.theme.Elevation + +@Composable +fun FlightsApp( + modifier: Modifier = Modifier, +) { + Surface( + tonalElevation = Elevation.Surface, + modifier = modifier, + ) { + Scaffold( + snackbarHost = { InAppUpdates() }, + ) { paddingValues -> + FlightsNavGraph(Modifier.padding(paddingValues)) + } + } +} diff --git a/app/src/main/kotlin/dev/adriankuta/flights/ui/InAppUpdates.kt b/app/src/main/kotlin/dev/adriankuta/flights/ui/InAppUpdates.kt new file mode 100644 index 0000000..f9bb975 --- /dev/null +++ b/app/src/main/kotlin/dev/adriankuta/flights/ui/InAppUpdates.kt @@ -0,0 +1,93 @@ +package dev.adriankuta.flights.ui + +import androidx.activity.compose.LocalActivity +import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.SnackbarResult +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Modifier +import com.google.android.play.core.appupdate.AppUpdateInfo +import com.google.android.play.core.appupdate.AppUpdateManager +import com.google.android.play.core.appupdate.AppUpdateManagerFactory +import com.google.android.play.core.appupdate.AppUpdateOptions +import com.google.android.play.core.install.InstallException +import com.google.android.play.core.install.InstallStateUpdatedListener +import com.google.android.play.core.install.model.AppUpdateType +import com.google.android.play.core.install.model.InstallStatus +import com.google.android.play.core.install.model.UpdateAvailability +import kotlinx.coroutines.launch +import timber.log.Timber +import kotlin.coroutines.suspendCoroutine + +@Composable +fun InAppUpdates( + modifier: Modifier = Modifier, + @AppUpdateType updateType: Int = AppUpdateType.FLEXIBLE, +) { + val activity = LocalActivity.current ?: return + val scope = rememberCoroutineScope() + val snackbarHostState = remember { SnackbarHostState() } + val appUpdateManager = remember { AppUpdateManagerFactory.create(requireNotNull(activity)) } + val flexibleUpdateListener = remember { + InstallStateUpdatedListener { state -> + if (state.installStatus() == InstallStatus.DOWNLOADED) { + // After the update is downloaded, show a notification + // and request user confirmation to restart the app. + scope.launch { + val result = snackbarHostState.showSnackbar( + message = "An update has just been downloaded", + actionLabel = "Reload", + ) + when (result) { + SnackbarResult.Dismissed -> Unit + SnackbarResult.ActionPerformed -> { + appUpdateManager.completeUpdate() + } + } + } + } + } + } + + LaunchedEffect(Unit) { + try { + val appUpdateInfo = appUpdateManager.checkUpdateInfo() + if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && + appUpdateInfo.isUpdateTypeAllowed(updateType) + ) { + appUpdateManager.startUpdateFlow( + appUpdateInfo, + activity, + AppUpdateOptions.newBuilder(updateType).build(), + ) + } + } catch (e: InstallException) { + Timber.w(e) + } + } + + DisposableEffect(appUpdateManager) { + appUpdateManager.registerListener(flexibleUpdateListener) + onDispose { + appUpdateManager.unregisterListener(flexibleUpdateListener) + } + } + + SnackbarHost( + hostState = snackbarHostState, + modifier = modifier, + ) +} + +private suspend fun AppUpdateManager.checkUpdateInfo() = + suspendCoroutine { continuation -> + appUpdateInfo.addOnSuccessListener { + continuation.resumeWith(Result.success(it)) + }.addOnFailureListener { + continuation.resumeWith(Result.failure(it)) + } + } diff --git a/app/src/main/res/drawable/ic_baseline_flight_land.xml b/app/src/main/res/drawable/ic_baseline_flight_land.xml deleted file mode 100644 index a47afda..0000000 --- a/app/src/main/res/drawable/ic_baseline_flight_land.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_baseline_flight_takeoff.xml b/app/src/main/res/drawable/ic_baseline_flight_takeoff.xml deleted file mode 100644 index e74cffd..0000000 --- a/app/src/main/res/drawable/ic_baseline_flight_takeoff.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml index b03f0f5..ca3826a 100644 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -1,170 +1,74 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + xmlns:android="http://schemas.android.com/apk/res/android"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml similarity index 95% rename from app/src/main/res/drawable-v24/ic_launcher_foreground.xml rename to app/src/main/res/drawable/ic_launcher_foreground.xml index 41ea3f9..2b068d1 100644 --- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -25,6 +25,6 @@ android:fillColor="#FFFFFF" android:fillType="nonZero" android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" - android:strokeColor="#00000000" - android:strokeWidth="1" /> + android:strokeWidth="1" + android:strokeColor="#00000000" /> \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index eca70cf..c4a603d 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,5 @@ - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index eca70cf..c4a603d 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,5 @@ - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp index c209e78..9f092de 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.webp and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..9b3d81d Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp index b2dfe3d..80b31b2 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp index 4f0f1d6..4b95d06 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.webp and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..1d77e79 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp index 62b611d..1bf668c 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp index 948a307..5dd3b1e 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..8c3cffa Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp index 1b9a695..e384f1c 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp index 28d4b77..a0b0a03 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..d314663 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp index 9287f50..3332ef1 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp index aa7d642..bfb7b18 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..b4e7599 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp index 9126ae3..d6ab7c6 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml new file mode 100644 index 0000000..55344e5 --- /dev/null +++ b/app/src/main/res/values-pl/strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 3a02f80..f8c6127 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,12 +1,10 @@ - #1f60f5 - #0037c1 - #1A6F8DFF - @color/white - #f1c931 - #ba9900 - @color/black - #ff000000 - #ffffffff + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml deleted file mode 100644 index 4b0eea0..0000000 --- a/app/src/main/res/values/dimens.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - 0dp - 2dp - 4dp - 6dp - 8dp - 10dp - 12dp - 16dp - 18dp - 20dp - 26dp - 32dp - 36dp - 42dp - 64dp - \ No newline at end of file diff --git a/app/src/main/res/values/plurals.xml b/app/src/main/res/values/plurals.xml deleted file mode 100644 index 08f24d6..0000000 --- a/app/src/main/res/values/plurals.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - %d Adult - %d Adults - - - %d Teen - %d Teens - - - %d Child - %d Children - - - %d Stop - %d Stops - - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 355a891..f5810f2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,32 +1,3 @@ - AndroidChallenge - From - To - Departure date - Passengers - Search - You need to select departure airport first - Select departure date - Adult - Teen - Child - Cancel - Submit - Unable to connect to server - No internet connection - You need to fill all data first. - Unfortunately there is no flight on particular date.\nChoose different one. - Go back - Total price: - Adult: %d x %.2f %s - Teen: %d x %.2f %s - Child: %d x %.2f %s - Search airport - Find airport - Flights - Search origin airport - Search destination airport - Flight details - Price range: - There are no flights in selected price range + Flights \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..e577542 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + +