Skip to content

Commit

Permalink
Merge pull request #4 from VeceluXa/develop
Browse files Browse the repository at this point in the history
Release v1.0
  • Loading branch information
VeceluXa committed Aug 4, 2023
2 parents 9d51528 + 1fdbad6 commit 457c776
Show file tree
Hide file tree
Showing 168 changed files with 4,589 additions and 65 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
.externalNativeBuild
.cxx
local.properties
/app/google-services.json
17 changes: 17 additions & 0 deletions .idea/deploymentTargetDropDown.xml

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

4 changes: 4 additions & 0 deletions .idea/gradle.xml

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

6 changes: 6 additions & 0 deletions .idea/kotlinc.xml

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

1 change: 0 additions & 1 deletion .idea/misc.xml

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

41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Space Android App
## Mars Photos
App uses Nasa's API to display photos from Mars in a list. When clicking on a photo, details screen is opened. There user can zoom/move photo like in a gallery app. Also user can share photo with 3rd party apps.


## Map

User can view map of Earth in 3 different views (default, hybrid, satellite). When user clicks on a map the dialog opens up to type marker name. Upon saving marker it will be displayed in bottom sheet dialog that is visible to user but collapsed by default.

---
# Tech stack
- Android SDK
- Clean Architecture
- Moxy MVP
- Cicerone Navigation
- RxJava3
- Retrofit, OkHttp
- Hilt
- Splash Screen API
- Google Maps SDK
- Firebase Cloud Messaging
- Moshi


# Setup
- Add Firebase's google-services.json to the root directory of app module to be able to send notification from Firebase Console
- Add [NASA_API_KEY](https://api.nasa.gov/) to local.properties
- Add [MAPS_API_KEY](https://developers.google.com/maps) to local.properties

# Screenshots
## Main Screen
![](./assets/screen_home.jpg)

## Details Screen
![](./assets/screen_details_tutorial.jpg)
![](./assets/screen_details.jpg)

## Map Screen
![](./assets/screen_map.jpg)
![](./assets/screen_map_marker_dialog.jpg)
![](./assets/screen_map_bottom_sheet_dialog.jpg)
58 changes: 54 additions & 4 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("kotlin-kapt")
id("com.google.dagger.hilt.android")
id("com.google.gms.google-services")
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
}

android {
Expand All @@ -27,21 +31,67 @@ android {
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "1.8"
jvmTarget = "17"
}
buildFeatures {
viewBinding = true
}
}

dependencies {

implementation("androidx.core:core-ktx:1.9.0")
implementation(project(":data"))
implementation(project(":common"))

implementation("androidx.core:core-ktx:1.10.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.9.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")

// Hilt
implementation(libs.hilt.android)

// Google Maps
implementation("com.google.android.gms:play-services-maps:18.1.0")
implementation("androidx.work:work-runtime-ktx:2.8.1")

kapt(libs.hilt.compiler)
implementation("androidx.hilt:hilt-navigation-fragment:1.0.0")

// Firebase
implementation(platform("com.google.firebase:firebase-bom:32.2.0"))
implementation("com.google.firebase:firebase-messaging-ktx:23.2.0")

// RxJava
implementation(libs.bundles.rxjava)

// Moxy
val moxyVersion = "2.2.2"
kapt("com.github.moxy-community:moxy-compiler:$moxyVersion")
implementation("com.github.moxy-community:moxy:$moxyVersion")
implementation("com.github.moxy-community:moxy-androidx:$moxyVersion") // AppCompat
implementation("com.github.moxy-community:moxy-material:$moxyVersion") // Bottom Sheet
implementation("com.github.moxy-community:moxy-ktx:$moxyVersion") // Kotlin Delegate


// Cicerone navigation
implementation("com.github.terrakok:cicerone:7.1")

implementation("androidx.core:core-splashscreen:1.0.1")
implementation("androidx.window:window:1.1.0")
implementation("com.github.bumptech.glide:glide:4.15.1")
implementation("com.github.MikeOrtiz:TouchImageView:3.4")

testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}

// Allow references to generated code
kapt {
correctErrorTypes = true
}
45 changes: 43 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />

<application
android:name=".presentation.App"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
Expand All @@ -11,16 +17,51 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Space"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
android:name=".presentation.ui.MainActivity"
android:exported="true"
android:theme="@style/Theme.Space.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".presentation.notifications.FirebaseNotificationService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<receiver
android:name=".presentation.notifications.DeviceBootBroadcastReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.danilovfa.space.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>

<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_launcher_foreground" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@android:color/black" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />
</application>

</manifest>
Binary file added app/src/main/ic_launcher-playstore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 0 additions & 11 deletions app/src/main/java/com/danilovfa/space/MainActivity.kt

This file was deleted.

7 changes: 7 additions & 0 deletions app/src/main/java/com/danilovfa/space/presentation/App.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.danilovfa.space.presentation

import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class App : Application()
54 changes: 54 additions & 0 deletions app/src/main/java/com/danilovfa/space/presentation/di/AppModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.danilovfa.space.presentation.di

import com.danilovfa.common.domain.usecase.GetRoverPhotosUseCase
import com.danilovfa.common.domain.usecase.HasTutorialBeenShownUseCase
import com.danilovfa.space.presentation.navigation.LocalNavigatorHolder
import com.danilovfa.space.presentation.mvp.home.HomePresenter
import com.danilovfa.space.presentation.mvp.main.MainPresenter
import com.danilovfa.space.presentation.mvp.map.MapPresenter
import com.danilovfa.space.presentation.mvp.photo.PhotoPresenter
import com.danilovfa.space.utils.Constants.Companion.HOME_TAB_ID
import com.danilovfa.space.utils.Constants.Companion.MAP_TAB_ID
import com.github.terrakok.cicerone.Router
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent

@Module
@InstallIn(ActivityComponent::class)
class AppModule {
@Provides
fun provideMainPresenter(router: Router): MainPresenter {
return MainPresenter(router)
}

@Provides
fun provideHomePresenter(
localNavigatorHolder: LocalNavigatorHolder,
getRoverPhotosUseCase: GetRoverPhotosUseCase,
): HomePresenter {
val router = localNavigatorHolder.getCicerone(HOME_TAB_ID).router
return HomePresenter(
getRoverPhotosUseCase = getRoverPhotosUseCase,
router = router
)
}

@Provides
fun providePhotoPresenter(
localNavigatorHolder: LocalNavigatorHolder,
hasTutorialBeenShownUseCase: HasTutorialBeenShownUseCase
): PhotoPresenter {
val router = localNavigatorHolder.getCicerone(HOME_TAB_ID).router
return PhotoPresenter(router, hasTutorialBeenShownUseCase)
}

@Provides
fun provideMapPresenter(localNavigatorHolder: LocalNavigatorHolder): MapPresenter {
val router = localNavigatorHolder.getCicerone(MAP_TAB_ID).router
return MapPresenter(router)
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.danilovfa.space.presentation.di

import com.danilovfa.space.presentation.navigation.LocalNavigatorHolder
import com.github.terrakok.cicerone.Cicerone
import com.github.terrakok.cicerone.NavigatorHolder
import com.github.terrakok.cicerone.Router
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
class NavigationModule {
@Provides
@Singleton
fun provideCicerone(): Cicerone<Router> = Cicerone.create()

@Provides
@Singleton
fun provideRouter(cicerone: Cicerone<Router>): Router = cicerone.router

@Provides
@Singleton
fun provideNavigatorHolder(cicerone: Cicerone<Router>): NavigatorHolder =
cicerone.getNavigatorHolder()

@Provides
@Singleton
fun provideLocalNavigatorHolder(): LocalNavigatorHolder = LocalNavigatorHolder()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.danilovfa.space.presentation.model

import com.google.android.gms.maps.model.Marker

data class MapMarker(
val label: String,
val marker: Marker
)
Loading

0 comments on commit 457c776

Please sign in to comment.