Skip to content

Commit 795b9d6

Browse files
authored
Merge pull request #10 from mrtry/feature/login
Feature/login
2 parents 251580e + 0dac617 commit 795b9d6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+424
-284
lines changed

.github/workflows/deploy_to_deploy_gate.yml

+7
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ jobs:
1919
with:
2020
java-version: 1.8
2121

22+
# google-service.jsonをデコードする
23+
# see:https://qiita.com/sudo5in5k/items/5b6da5dbba3fc2514319
24+
- name: decode google-service
25+
env:
26+
GOOGLE_SERVICE: ${{ secrets.GOOGLE_SERVICE_JSON }}
27+
run: echo $GOOGLE_SERVICE | base64 --decode --ignore-garbage > ./app/google-services.json
28+
2229
- name: Run unit test
2330
run: ./gradlew testDebugUnitTest
2431

.github/workflows/run_test.yml

+5
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,10 @@ jobs:
1919
with:
2020
java-version: 1.8
2121

22+
- name: decode google-service
23+
env:
24+
GOOGLE_SERVICE: ${{ secrets.GOOGLE_SERVICE_JSON }}
25+
run: echo $GOOGLE_SERVICE | base64 --decode --ignore-garbage > ./app/google-services.json
26+
2227
- name: Run unit test
2328
run: ./gradlew testDebugUnitTest

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,6 @@ lint/tmp/
8686

8787
# Android Profiling
8888
*.hprof
89+
90+
app/google-services.json
91+
.DS_Store

.idea/codeStyles/Project.xml

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

+37-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
apply plugin: 'com.android.application'
22
apply plugin: 'kotlin-android'
33
apply plugin: 'kotlin-android-extensions'
4+
apply plugin: 'com.google.gms.google-services'
45
apply plugin: 'kotlin-kapt'
56
apply plugin: 'deploygate'
67

@@ -25,6 +26,14 @@ android {
2526
}
2627
}
2728

29+
buildFeatures {
30+
dataBinding true
31+
}
32+
33+
viewBinding {
34+
enabled = true
35+
}
36+
2837
packagingOptions {
2938
exclude 'META-INF/AL2.0'
3039
exclude 'META-INF/LGPL2.1'
@@ -35,6 +44,12 @@ android {
3544
option("-Xmaxerrs", 5000)
3645
}
3746
}
47+
48+
testOptions {
49+
unitTests {
50+
includeAndroidResources = true
51+
}
52+
}
3853
}
3954

4055
dependencies {
@@ -46,15 +61,36 @@ dependencies {
4661
testImplementation 'junit:junit:4.12'
4762
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
4863
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
64+
implementation 'com.google.android.material:material:1.2.1'
4965

66+
// dagger
5067
def dagger_version = "2.29.1"
5168
implementation "com.google.dagger:dagger:$dagger_version"
5269
kapt "com.google.dagger:dagger-compiler:$dagger_version"
5370

71+
// coroutine
5472
def coroutine_version = "1.3.9"
5573
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutine_version"
5674
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutine_version"
5775

5876
// deploy gate
5977
implementation 'com.deploygate:sdk:4.1.0'
60-
}
78+
79+
// Firebase
80+
implementation 'com.google.firebase:firebase-analytics:17.5.0'
81+
implementation 'com.google.firebase:firebase-auth:19.4.0'
82+
implementation 'com.firebaseui:firebase-ui-auth:6.2.0'
83+
84+
// test
85+
testImplementation 'junit:junit:4.12'
86+
testImplementation 'org.robolectric:robolectric:4.4'
87+
testImplementation 'androidx.test:core:1.3.0'
88+
testImplementation 'org.mockito:mockito-core:3.3.3'
89+
testImplementation 'org.mockito:mockito-android:3.3.3'
90+
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
91+
androidTestImplementation 'androidx.annotation:annotation:1.1.0'
92+
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
93+
94+
// other
95+
implementation 'com.jakewharton.timber:timber:4.7.1'
96+
}

app/src/main/AndroidManifest.xml

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77
android:allowBackup="true"
88
android:icon="@mipmap/ic_launcher"
99
android:label="@string/app_name"
10-
android:roundIcon="@mipmap/ic_launcher_round"
1110
android:supportsRtl="true"
1211
android:theme="@style/AppTheme">
13-
<activity android:name=".todo.ui.LoginActivity">
12+
<activity android:name="io.github.mrtry.todolist.app.splash.ui.SplashActivity">
1413
<intent-filter>
1514
<action android:name="android.intent.action.MAIN" />
1615

app/src/main/java/io/github/mrtry/todolist/MainApplication.kt

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import android.app.Application
44
import android.content.Context
55
import io.github.mrtry.todolist.di.component.AppComponent
66
import io.github.mrtry.todolist.di.component.DaggerAppComponent
7+
import timber.log.Timber
78

89

910
class MainApplication : Application() {
@@ -21,5 +22,6 @@ class MainApplication : Application() {
2122

2223
override fun onCreate() {
2324
super.onCreate()
25+
Timber.plant(Timber.DebugTree())
2426
}
2527
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package io.github.mrtry.todolist.app.splash.ui
2+
3+
import android.content.Intent
4+
import android.os.Bundle
5+
import androidx.appcompat.app.AppCompatActivity
6+
import androidx.databinding.DataBindingUtil
7+
import io.github.mrtry.todolist.MainApplication
8+
import io.github.mrtry.todolist.R
9+
import io.github.mrtry.todolist.app.splash.ui.navigator.SplashNavigator
10+
import io.github.mrtry.todolist.app.splash.ui.result.SplashActivityResult
11+
import io.github.mrtry.todolist.app.splash.viewmodel.SplashViewModel
12+
import io.github.mrtry.todolist.databinding.ActivitySplashBinding
13+
import io.github.mrtry.todolist.di.Injectable
14+
import io.github.mrtry.todolist.di.component.LoginComponent
15+
import io.github.mrtry.todolist.di.module.ActivityModule
16+
import io.github.mrtry.todolist.misc.ui.binding.Bindable
17+
import kotlinx.coroutines.CoroutineScope
18+
import javax.inject.Inject
19+
20+
class SplashActivity : AppCompatActivity(), Injectable<LoginComponent>, Bindable<ActivitySplashBinding> {
21+
22+
@Inject
23+
internal lateinit var viewModel: SplashViewModel
24+
25+
@Inject
26+
internal lateinit var navigator: SplashNavigator
27+
28+
@Inject
29+
internal lateinit var coroutineScope: CoroutineScope
30+
31+
override val viewBinding: ActivitySplashBinding by lazy {
32+
DataBindingUtil.setContentView<ActivitySplashBinding>(this, R.layout.activity_splash)
33+
}
34+
35+
override val component: LoginComponent by lazy {
36+
MainApplication.getComponent(this)
37+
.plusLoginComponent(ActivityModule(this))
38+
}
39+
40+
override fun onCreate(savedInstanceState: Bundle?) {
41+
super.onCreate(savedInstanceState)
42+
component.inject(this)
43+
viewBinding
44+
}
45+
46+
override fun onResume() {
47+
super.onResume()
48+
viewModel.ensuredLoggedIn()
49+
}
50+
51+
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
52+
super.onActivityResult(requestCode, resultCode, data)
53+
SplashActivityResult
54+
.valueOf(requestCode)
55+
.getResultHandler(component)
56+
.handleResult(resultCode, data)
57+
}
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package io.github.mrtry.todolist.app.splash.ui.navigator
2+
3+
import android.app.Activity
4+
import com.firebase.ui.auth.AuthUI
5+
import io.github.mrtry.todolist.app.splash.ui.result.SplashActivityResult
6+
import io.github.mrtry.todolist.di.scope.ActivityScope
7+
import io.github.mrtry.todolist.misc.ui.navigator.AbsNavigator
8+
import timber.log.Timber
9+
import javax.inject.Inject
10+
11+
@ActivityScope
12+
class SplashNavigator
13+
@Inject constructor(
14+
private val activity: Activity
15+
) : AbsNavigator(activity) {
16+
fun navigateToToDo() {
17+
// TODO
18+
Timber.d("navigateToToDo() called")
19+
}
20+
21+
fun navigateToAuthentication() {
22+
val providers = arrayListOf(
23+
AuthUI.IdpConfig.EmailBuilder().build()
24+
)
25+
26+
val intent = AuthUI.getInstance()
27+
.createSignInIntentBuilder()
28+
.setAvailableProviders(providers)
29+
.build()
30+
31+
activity.startActivityForResult(intent, SplashActivityResult.AUTH.requestCode)
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.github.mrtry.todolist.app.splash.ui.result
2+
3+
import android.app.Activity
4+
import android.content.Intent
5+
import io.github.mrtry.todolist.app.splash.ui.navigator.SplashNavigator
6+
import io.github.mrtry.todolist.di.scope.ActivityScope
7+
import javax.inject.Inject
8+
9+
@ActivityScope
10+
class AuthResultHandler
11+
@Inject constructor(
12+
private val navigator: SplashNavigator
13+
) : SplashResultHandler {
14+
override fun handleResult(resultCode: Int, data: Intent?) {
15+
// Firebase-UIの戻り値
16+
// see: https://github.com/firebase/FirebaseUI-Android/blob/master/auth/README.md#response-codes
17+
when (resultCode == Activity.RESULT_OK) {
18+
true -> navigator.navigateToToDo()
19+
false -> navigator.finishApplication()
20+
}
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.github.mrtry.todolist.app.splash.ui.result
2+
3+
import io.github.mrtry.todolist.di.component.LoginComponent
4+
import io.github.mrtry.todolist.misc.ui.result.ActivityResult
5+
6+
enum class SplashActivityResult(
7+
override val requestCode: Int
8+
) : ActivityResult<SplashResultHandler, LoginComponent> {
9+
AUTH(0) {
10+
override fun getResultHandler(component: LoginComponent): SplashResultHandler =
11+
component.authResultHandler
12+
};
13+
14+
companion object {
15+
fun valueOf(requestCode: Int): SplashActivityResult =
16+
values().first { it.requestCode == requestCode }
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package io.github.mrtry.todolist.app.splash.ui.result
2+
3+
import io.github.mrtry.todolist.misc.ui.result.ResultHandler
4+
5+
interface SplashResultHandler : ResultHandler
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.github.mrtry.todolist.app.splash.viewmodel
2+
3+
import io.github.mrtry.todolist.app.splash.ui.navigator.SplashNavigator
4+
import io.github.mrtry.todolist.auth.AuthenticationClient
5+
import io.github.mrtry.todolist.di.scope.ActivityScope
6+
import javax.inject.Inject
7+
8+
@ActivityScope
9+
class SplashViewModel
10+
@Inject constructor(
11+
private val authenticationClient: AuthenticationClient,
12+
private val navigator: SplashNavigator
13+
) {
14+
fun ensuredLoggedIn() {
15+
when (authenticationClient.isLoggedIn()) {
16+
true -> navigator.navigateToToDo()
17+
false -> navigator.navigateToAuthentication()
18+
}
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.github.mrtry.todolist.auth
2+
3+
import com.google.firebase.auth.FirebaseAuth
4+
import javax.inject.Inject
5+
import javax.inject.Singleton
6+
7+
@Singleton
8+
class AuthenticationClient
9+
@Inject constructor() {
10+
private val firebaseAuth = FirebaseAuth.getInstance()
11+
12+
fun isLoggedIn() = firebaseAuth.currentUser != null
13+
}

app/src/main/java/io/github/mrtry/todolist/di/component/AppComponent.kt

+2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import dagger.Component
44
import io.github.mrtry.todolist.MainApplication
55
import io.github.mrtry.todolist.di.module.ActivityModule
66
import io.github.mrtry.todolist.di.module.AppModule
7+
import javax.inject.Singleton
78

9+
@Singleton
810
@Component(modules = [AppModule::class])
911
interface AppComponent {
1012
fun inject(application: MainApplication)
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package io.github.mrtry.todolist.di.component
22

33
import dagger.Subcomponent
4+
import io.github.mrtry.todolist.app.splash.ui.SplashActivity
5+
import io.github.mrtry.todolist.app.splash.ui.result.AuthResultHandler
46
import io.github.mrtry.todolist.di.module.ActivityModule
57
import io.github.mrtry.todolist.di.scope.ActivityScope
6-
import io.github.mrtry.todolist.todo.ui.LoginActivity
78

89
@ActivityScope
910
@Subcomponent(modules = [ActivityModule::class])
1011
interface LoginComponent : Component {
1112

12-
/* activity */
13-
fun inject(activity: LoginActivity)
13+
fun inject(activity: SplashActivity)
14+
15+
val authResultHandler: AuthResultHandler
1416
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package io.github.mrtry.todolist.misc.ui.binding
2+
3+
import androidx.databinding.ViewDataBinding
4+
5+
interface Bindable<out T : ViewDataBinding> {
6+
7+
val viewBinding: T
8+
}

0 commit comments

Comments
 (0)