Skip to content

Commit 664d7b3

Browse files
author
Patrick Jackson
committed
before gateway refactor
1 parent 812c4f0 commit 664d7b3

Some content is hidden

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

43 files changed

+1049
-651
lines changed

android/build.gradle

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,13 @@ android {
5050
dependencies {
5151
implementation fileTree(dir: 'libs', include: ['*.jar'])
5252
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
53-
implementation 'androidx.appcompat:appcompat:1.0.2'
54-
implementation 'com.google.android.material:material:1.1.0-alpha08'
53+
implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
54+
implementation 'com.google.android.material:material:1.1.0-alpha09'
5555
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
5656
implementation "android.arch.navigation:navigation-fragment-ktx:$ktxVersion"
5757
implementation "android.arch.navigation:navigation-ui-ktx:$ktxVersion"
58+
implementation "org.reduxkotlin:redux-kotlin:$reduxVersion"
59+
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
5860

5961
implementation "com.facebook.stetho:stetho:$stethoVersion"
6062
implementation "com.facebook.stetho:stetho-okhttp3:$stethoVersion"

android/src/main/java/com/willowtreeapps/namegame/NameGameApp.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import com.google.firebase.FirebaseApp
77
import com.willowtreeapps.common.GameEngine
88
import com.willowtreeapps.common.Logger
99
import kotlinx.coroutines.Dispatchers
10+
import org.reduxkotlin.Dispatcher
11+
12+
lateinit var dispatch: Dispatcher
1013

1114
class NameGameApp : Application() {
1215

@@ -18,6 +21,7 @@ class NameGameApp : Application() {
1821
instance = this
1922
val navigator = AndroidNavigator()
2023
gameEngine = GameEngine(navigator, this, Dispatchers.IO, Dispatchers.Main)
24+
dispatch = gameEngine.appStore.dispatch
2125

2226
registerActivityLifecycleCallbacks(navigator)
2327
registerActivityLifecycleCallbacks(LifeCycleLogger)

android/src/main/java/com/willowtreeapps/namegame/store/BaseNameGameViewFragment.kt

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,16 @@ package com.willowtreeapps.namegame.store
22

33
import android.os.Bundle
44
import androidx.fragment.app.Fragment
5-
import com.willowtreeapps.common.Logger
6-
import com.willowtreeapps.common.ui.Presenter
7-
import com.willowtreeapps.common.ui.View
8-
import com.willowtreeapps.namegame.NameGameApp
9-
import kotlinx.coroutines.CoroutineScope
10-
import kotlinx.coroutines.Dispatchers
11-
import kotlin.coroutines.CoroutineContext
5+
import com.willowtreeapps.common.PresenterLifecycleObserver
6+
import com.willowtreeapps.common.ui.GameBaseView
127

13-
open class BaseNameGameViewFragment<TPresenter: Presenter<*>>: Fragment(), CoroutineScope, View<TPresenter> {
14-
override val coroutineContext: CoroutineContext
15-
get() = Dispatchers.Main
16-
17-
override lateinit var presenter: TPresenter
8+
open class BaseNameGameViewFragment<V: GameBaseView>: Fragment(), GameBaseView {
9+
private val presenterObserver = PresenterLifecycleObserver(this)
1810
private var viewRecreated: Boolean = false
1911

20-
override fun onViewCreated(view: android.view.View, savedInstanceState: Bundle?) {
21-
super.onViewCreated(view, savedInstanceState)
22-
if (savedInstanceState == null)
23-
Logger.d("savedInstanceState == null")
24-
else {
25-
Logger.d("savedInstanceState != null")
26-
viewRecreated = true
27-
}
28-
}
29-
30-
override fun onResume() {
31-
super.onResume()
32-
NameGameApp.gameEngine().attachView(this)
33-
if (viewRecreated) {
34-
presenter.recreateView()
35-
}
36-
}
37-
38-
override fun onPause() {
39-
super.onPause()
40-
NameGameApp.gameEngine().detachView(this)
12+
override fun onCreate(savedInstanceState: Bundle?) {
13+
retainInstance = true
14+
lifecycle.addObserver(presenterObserver)
15+
super.onCreate(savedInstanceState)
4116
}
4217
}

android/src/main/java/com/willowtreeapps/namegame/store/GameResultsFragment.kt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ import android.os.Bundle
44
import android.view.LayoutInflater
55
import android.view.View
66
import android.view.ViewGroup
7-
import com.willowtreeapps.common.GameResultsViewState
8-
import com.willowtreeapps.common.ui.GameResultsPresenter
7+
import com.willowtreeapps.common.middleware.UiActions
8+
import com.willowtreeapps.common.ui.GameResultsViewState
99
import com.willowtreeapps.common.ui.GameResultsView
1010
import com.willowtreeapps.namegame.MainActivity
1111
import com.willowtreeapps.namegame.NameGameApp
1212
import com.willowtreeapps.namegame.R
13+
import com.willowtreeapps.namegame.dispatch
1314
import kotlinx.android.synthetic.main.fragment_game_results.*
1415

15-
class GameResultsFragment : BaseNameGameViewFragment<GameResultsPresenter>(), GameResultsView, MainActivity.IOnBackPressed {
16+
class GameResultsFragment : BaseNameGameViewFragment<GameResultsView>(), GameResultsView, MainActivity.IOnBackPressed {
1617

1718
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
1819
return inflater.inflate(R.layout.fragment_game_results, container, false)
@@ -24,8 +25,9 @@ class GameResultsFragment : BaseNameGameViewFragment<GameResultsPresenter>(), Ga
2425

2526
private fun initViews() {
2627
btn_start_over.setOnClickListener {
27-
NameGameApp.gameEngine().detachView(this)
28-
presenter.startOverTapped()
28+
//TODO is this needed?
29+
// NameGameApp.gameEngine().detachView(this)
30+
dispatch(UiActions.StartOverTapped())
2931
}
3032
}
3133

@@ -35,7 +37,7 @@ class GameResultsFragment : BaseNameGameViewFragment<GameResultsPresenter>(), Ga
3537
}
3638

3739
override fun onBackPressed(): Boolean {
38-
presenter.onBackPressed()
40+
// presenter.onBackPressed()
3941
return false
4042
}
4143

android/src/main/java/com/willowtreeapps/namegame/store/QuestionFragment.kt

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import android.speech.SpeechRecognizer
1111
import android.view.*
1212
import android.view.animation.BounceInterpolator
1313
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
14-
import com.willowtreeapps.common.QuestionViewState
14+
import com.willowtreeapps.common.ui.QuestionViewState
1515
import com.willowtreeapps.common.ui.QuestionView
1616
import kotlinx.android.synthetic.main.fragment_question.*
1717
import nl.dionsegijn.konfetti.models.Shape
@@ -20,12 +20,12 @@ import android.widget.Button
2020
import androidx.core.content.res.ResourcesCompat
2121
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
2222
import com.willowtreeapps.common.Logger
23-
import com.willowtreeapps.common.ui.QuestionPresenter
23+
import com.willowtreeapps.common.middleware.UiActions
2424
import com.willowtreeapps.namegame.*
2525
import java.util.*
2626

2727

28-
class QuestionFragment : BaseNameGameViewFragment<QuestionPresenter>(), QuestionView, MainActivity.IOnBackPressed {
28+
class QuestionFragment : BaseNameGameViewFragment<QuestionView>(), QuestionView, MainActivity.IOnBackPressed {
2929
private lateinit var speechRecognizer: SpeechRecognizer
3030
private val speechRecognizerIntent by lazy {
3131
val speechRecIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
@@ -53,7 +53,7 @@ class QuestionFragment : BaseNameGameViewFragment<QuestionPresenter>(), Question
5353

5454
//displaying the first match
5555
if (matches != null)
56-
presenter.namePicked(matches[0])
56+
dispatch(UiActions.NamePicked(matches[0]))
5757
}
5858

5959
override fun onEvent(eventType: Int, params: Bundle?) {
@@ -75,7 +75,7 @@ class QuestionFragment : BaseNameGameViewFragment<QuestionPresenter>(), Question
7575

7676
//displaying the first match
7777
if (matches != null)
78-
presenter.namePicked(matches[0])
78+
dispatch(UiActions.NamePicked(matches[0]))
7979
}
8080

8181
})
@@ -103,18 +103,19 @@ class QuestionFragment : BaseNameGameViewFragment<QuestionPresenter>(), Question
103103
}
104104

105105
private fun initViews() {
106-
button1.setOnClickListener { presenter.namePicked(button1.text.toString()) }
107-
button2.setOnClickListener { presenter.namePicked(button2.text.toString()) }
108-
button3.setOnClickListener { presenter.namePicked(button3.text.toString()) }
109-
button4.setOnClickListener { presenter.namePicked(button4.text.toString()) }
110-
btn_next.setOnClickListener { presenter.nextTapped() }
111-
btn_end_game.setOnClickListener { presenter.endGameTapped() }
106+
button1.setOnClickListener { dispatch(UiActions.NamePicked(button1.text.toString())) }
107+
button2.setOnClickListener { dispatch(UiActions.NamePicked(button2.text.toString())) }
108+
button3.setOnClickListener { dispatch(UiActions.NamePicked(button3.text.toString())) }
109+
button4.setOnClickListener { dispatch(UiActions.NamePicked(button4.text.toString())) }
110+
btn_next.setOnClickListener { dispatch(UiActions.NextTapped()) }
111+
btn_end_game.setOnClickListener { dispatch(UiActions.EndGameTapped()) }
112112
}
113113

114114

115115
override fun onBackPressed(): Boolean {
116-
NameGameApp.gameEngine().detachView(this)
117-
presenter.onBackPressed()
116+
//TODO revisit this - is needed with presenter middleware
117+
// NameGameApp.gameEngine().detachView(this)
118+
// presenter.onBackPressed()
118119
return false
119120
}
120121

@@ -153,7 +154,7 @@ class QuestionFragment : BaseNameGameViewFragment<QuestionPresenter>(), Question
153154
btn_end_game.visibility = View.GONE
154155
btn_end_game.alpha = 1f
155156
//start timer again
156-
presenter.profileImageIsVisible()
157+
dispatch(UiActions.ProfileImageDidShow())
157158
}
158159

159160
}
@@ -309,7 +310,7 @@ class QuestionFragment : BaseNameGameViewFragment<QuestionPresenter>(), Question
309310
.onComplete {
310311
showButtons()
311312
txt_timer.visibility = View.VISIBLE
312-
presenter.profileImageIsVisible()
313+
dispatch(UiActions.ProfileImageDidShow())
313314
}
314315
.into(imageView)
315316
setButtonText(viewState)

android/src/main/java/com/willowtreeapps/namegame/store/SettingsDialogFragment.kt

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,24 @@ import androidx.core.content.ContextCompat
1111
import androidx.fragment.app.DialogFragment
1212
import com.firebase.ui.auth.AuthUI
1313
import com.google.firebase.auth.FirebaseAuth
14+
import com.willowtreeapps.common.*
15+
import com.willowtreeapps.common.middleware.UiActions
1416
//import com.google.firebase.auth.FirebaseAuth
15-
import com.willowtreeapps.common.Logger
16-
import com.willowtreeapps.common.QuestionCategoryId
17-
import com.willowtreeapps.common.SettingsViewState
18-
import com.willowtreeapps.common.ui.SettingsPresenter
1917
import com.willowtreeapps.common.ui.SettingsView
18+
import com.willowtreeapps.common.ui.SettingsViewState
2019
import com.willowtreeapps.namegame.MainActivity
21-
import com.willowtreeapps.namegame.NameGameApp
2220
import com.willowtreeapps.namegame.R
21+
import com.willowtreeapps.namegame.dispatch
2322
import kotlinx.android.synthetic.main.fragment_settings.*
2423

2524
class SettingsDialogFragment : DialogFragment(), SettingsView {
2625

27-
override lateinit var presenter: SettingsPresenter
26+
private val presenterObserver = PresenterLifecycleObserver(this)
27+
28+
override fun onCreate(savedInstanceState: Bundle?) {
29+
super.onCreate(savedInstanceState)
30+
lifecycle.addObserver(presenterObserver)
31+
}
2832

2933
companion object {
3034
fun newInstance(): SettingsDialogFragment {
@@ -41,29 +45,25 @@ class SettingsDialogFragment : DialogFragment(), SettingsView {
4145
numberPicker.minValue = 1
4246
numberPicker.maxValue = 20
4347
numberPicker.setOnValueChangedListener { _, _, newVal ->
44-
presenter.numQuestionsChanged(newVal)
48+
dispatch(UiActions.NumQuestionsPicked(newVal))
4549
}
4650

4751
categoryPicker.setOnValueChangedListener { _, _, newVal ->
48-
presenter.categoryChanged(QuestionCategoryId.fromDisplayName(categoryPicker.displayedValues[categoryPicker.value])!!)
52+
val newCategory = QuestionCategoryId.fromDisplayName(categoryPicker.displayedValues[categoryPicker.value])!!
53+
dispatch(UiActions.CategoryPicked(newCategory))
4954
}
5055
btn_ok.setOnClickListener { dismiss() }
5156
btn_sign_in.setOnClickListener { launchSignIn() }
5257
switch_mic.setOnCheckedChangeListener { buttonView, isChecked ->
53-
presenter.microphoneModeChanged(isChecked)
58+
//TODO consider moving this logic somewhere else
59+
if (isChecked) {
60+
askForMicPermissions()
61+
} else {
62+
dispatch(UiActions.MicrophoneModeToggled(false))
63+
}
5464
}
5565
}
5666

57-
override fun onResume() {
58-
super.onResume()
59-
NameGameApp.gameEngine().attachView(this)
60-
}
61-
62-
override fun onPause() {
63-
super.onPause()
64-
NameGameApp.gameEngine().detachView(this)
65-
}
66-
6767
override fun showSettings(viewState: SettingsViewState) {
6868
categoryPicker.displayedValues = viewState.categoryDisplayValues.toTypedArray()
6969
categoryPicker.maxValue = 0
@@ -97,7 +97,7 @@ class SettingsDialogFragment : DialogFragment(), SettingsView {
9797
arrayOf(Manifest.permission.RECORD_AUDIO),
9898
MainActivity.RECORD_REQUEST_CODE)
9999
} else {
100-
presenter.microphonePermissionGranted()
100+
dispatch(UiActions.MicrophoneModeToggled(true))
101101
}
102102
}
103103

@@ -106,9 +106,9 @@ class SettingsDialogFragment : DialogFragment(), SettingsView {
106106
when (requestCode) {
107107
MainActivity.RECORD_REQUEST_CODE -> {
108108
if (grantResults.isEmpty() || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
109-
presenter.microphonePermissionDenied()
109+
dispatch(UiActions.MicrophoneModeToggled(false))
110110
} else {
111-
presenter.microphonePermissionGranted()
111+
dispatch(UiActions.MicrophoneModeToggled(true))
112112
}
113113
}
114114
}
@@ -126,7 +126,7 @@ class SettingsDialogFragment : DialogFragment(), SettingsView {
126126
AuthUI.getInstance()
127127
.signOut(activity?.applicationContext!!)
128128
.addOnCompleteListener {
129-
presenter.signOutSuccess()
129+
dispatch(Actions.WillowTreeSignInSuccessAction())
130130
}
131131
}
132132

@@ -135,7 +135,7 @@ class SettingsDialogFragment : DialogFragment(), SettingsView {
135135
if (requestCode == 0) {
136136
val auth = FirebaseAuth.getInstance()
137137
val email = auth.currentUser?.email!!
138-
presenter.signInSuccess()
138+
dispatch(Actions.WillowTreeSignOutSuccessAction())
139139
}
140140

141141
}

android/src/main/java/com/willowtreeapps/namegame/store/StartFragment.kt

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,20 @@ import android.view.LayoutInflater
55
import android.view.View
66
import android.view.ViewGroup
77
import androidx.fragment.app.Fragment
8-
import com.willowtreeapps.common.ui.StartPresenter
8+
import com.willowtreeapps.common.middleware.UiActions
99
import com.willowtreeapps.common.ui.StartView
1010
import com.willowtreeapps.namegame.*
1111
import kotlinx.android.synthetic.main.fragment_start.*
12-
import kotlinx.coroutines.CoroutineScope
13-
import kotlinx.coroutines.Dispatchers
14-
import kotlin.coroutines.CoroutineContext
1512

16-
class StartFragment : Fragment(), CoroutineScope, StartView {
17-
18-
override val coroutineContext: CoroutineContext
19-
get() = Dispatchers.Main
20-
21-
override lateinit var presenter: StartPresenter
13+
class StartFragment : Fragment(), StartView {
2214

2315
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
2416
return inflater.inflate(R.layout.fragment_start, container, false)
2517
}
2618

2719
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
28-
btn_start.setOnClickListener {
29-
presenter?.startGame()
30-
}
31-
btn_settings.setOnClickListener {
32-
presenter?.settingsTapped()
33-
}
34-
}
35-
36-
override fun onResume() {
37-
super.onResume()
38-
NameGameApp.gameEngine().attachView(this)
39-
}
40-
41-
override fun onPause() {
42-
super.onPause()
43-
NameGameApp.gameEngine().detachView(this)
20+
btn_start.setOnClickListener { dispatch(UiActions.StartGameTapped()) }
21+
btn_settings.setOnClickListener { dispatch(UiActions.SettingsTapped()) }
4422
}
4523

4624
override fun hideLoading() {

build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,8 @@ ext {
4545
ktorVersion = '1.2.2'
4646
serializationVersion = '0.11.1'
4747
multiplatformSettingsVersion = '0.3.2'
48+
reduxVersion = '0.2.6'
49+
reduxThunkVersion = '0.2.8'
50+
reduxPresenterMiddlewareVersion = '0.2.7'
51+
reduxReselectVersion = '0.2.7'
4852
}

0 commit comments

Comments
 (0)