Skip to content

Commit 5b59db0

Browse files
committed
animations working on android and iOS. WT banner on iOS StartScreen fixed.
1 parent 51dbb88 commit 5b59db0

File tree

17 files changed

+154
-77
lines changed

17 files changed

+154
-77
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<activity
1616
android:name="com.willowtreeapps.namegame.MainActivity"
1717
android:label="@string/app_name"
18-
android:theme="@style/AppTheme.TransparentTheme">
18+
android:theme="@style/AppTheme">
1919
<intent-filter>
2020
<action android:name="android.intent.action.MAIN" />
2121

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

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package com.willowtreeapps.namegame.store
22

3-
import android.animation.Animator
4-
import android.animation.AnimatorListenerAdapter
53
import android.animation.AnimatorSet
64
import android.animation.ObjectAnimator
75
import android.graphics.Color
6+
import android.graphics.drawable.Drawable
87
import android.os.Bundle
98
import android.view.LayoutInflater
109
import android.view.View
@@ -22,6 +21,10 @@ import android.widget.Button
2221
import androidx.annotation.ColorRes
2322
import androidx.core.content.res.ResourcesCompat
2423
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
24+
import com.bumptech.glide.load.DataSource
25+
import com.bumptech.glide.load.engine.GlideException
26+
import com.bumptech.glide.request.RequestListener
27+
import com.bumptech.glide.request.target.Target
2528
import com.willowtreeapps.common.ui.QuestionPresenter
2629
import com.willowtreeapps.namegame.*
2730
import kotlinx.coroutines.*
@@ -36,7 +39,6 @@ class QuestionFragment : Fragment(), CoroutineScope, QuestionView, MainActivity.
3639

3740
private var restoreX: Float? = null
3841
private var restoreY: Float? = null
39-
@ColorRes
4042
var lastCorrectBtn: Button? = null
4143
private var lastSelectedBtn: Button? = null
4244

@@ -114,11 +116,7 @@ class QuestionFragment : Fragment(), CoroutineScope, QuestionView, MainActivity.
114116
upSet.playTogether(animScaleX, animScaleY)
115117
upSet.interpolator = BounceInterpolator()
116118
upSet.duration = 500
117-
upSet.addListener(object : AnimatorListenerAdapter() {
118-
override fun onAnimationEnd(animation: Animator?) {
119-
after()
120-
}
121-
})
119+
upSet.onComplete { after() }
122120
upSet.start()
123121
} else {
124122
after()
@@ -189,26 +187,31 @@ class QuestionFragment : Fragment(), CoroutineScope, QuestionView, MainActivity.
189187
}
190188

191189
private fun fadeNextButton(after: () -> Unit) {
192-
btn_next.animate().alpha(0f).setListener(object : AnimatorListenerAdapter() {
193-
override fun onAnimationEnd(animation: Animator?) {
194-
btn_next.visibility = View.GONE
195-
after()
196-
btn_next.animate().setListener(null)
197-
}
198-
})
190+
btn_next.animate().alpha(0f).withEndAction {
191+
btn_next.visibility = View.GONE
192+
after()
193+
}
199194
}
200195

201196
private fun setProfileAndFadeIn(viewState: QuestionViewState) {
202197
with(viewState) {
203198
txt_results.text = title
204199
GlideApp.with(this@QuestionFragment).load(profileImageUrl)
205200
.transition(DrawableTransitionOptions.withCrossFade())
201+
.listener(object : RequestListener<Drawable> {
202+
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
203+
return true
204+
}
205+
override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
206+
showButtons()
207+
return false
208+
}
209+
})
206210
.into(imageView)
207211
button1.text = button1Text
208212
button2.text = button2Text
209213
button3.text = button3Text
210214
button4.text = button4Text
211-
showButtons()
212215
}
213216
}
214217

@@ -217,7 +220,7 @@ class QuestionFragment : Fragment(), CoroutineScope, QuestionView, MainActivity.
217220
txt_timer.scaleX = 0f
218221
txt_timer.scaleY = 0f
219222
txt_timer.alpha = 1f
220-
txt_timer.text = viewState.questionTime.toString()
223+
txt_timer.text = viewState.timerText.toString()
221224
txt_timer.animate()
222225
.scaleX(1f)
223226
.scaleY(1f)
@@ -238,7 +241,8 @@ class QuestionFragment : Fragment(), CoroutineScope, QuestionView, MainActivity.
238241
activity?.runOnUiThread {
239242
txt_timer.scaleX = 0f
240243
txt_timer.scaleY = 0f
241-
txt_timer.text = "TIMES UP!!"
244+
txt_timer.text = viewState.timerText
245+
val restoreColor = txt_timer.currentTextColor
242246
txt_timer.setTextColor(ResourcesCompat.getColor(context?.resources!!, R.color.red, null))
243247
txt_timer.animate()
244248
.scaleX(1f)
@@ -248,6 +252,7 @@ class QuestionFragment : Fragment(), CoroutineScope, QuestionView, MainActivity.
248252
.withEndAction {
249253
showWrongAnswer(viewState, isEndGame)
250254
txt_timer.animate().alpha(0f)
255+
.withEndAction { txt_timer.setTextColor(restoreColor) }
251256
}
252257

253258
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,10 @@ class StartFragment : Fragment(), CoroutineScope, StartView {
5353
loading_spinner.visibility = View.VISIBLE
5454
}
5555
}
56+
57+
override fun showError(msg: String) {
58+
activity?.runOnUiThread {
59+
txt_error.text = msg
60+
}
61+
}
5662
}

app/src/main/res/layout/fragment_start.xml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
app:srcCompat="@drawable/willowtree_banner" />
3535

3636
<TextView
37-
style="@style/Title"
3837
android:id="@+id/textView"
38+
style="@style/Title"
3939
android:layout_width="wrap_content"
4040
android:layout_height="wrap_content"
4141
android:layout_marginBottom="248dp"
@@ -58,6 +58,17 @@
5858
app:layout_constraintHorizontal_bias="0.5"
5959
app:layout_constraintStart_toStartOf="parent"
6060
app:layout_constraintTop_toTopOf="parent"
61-
app:layout_constraintVertical_bias="0.53" />
61+
app:layout_constraintVertical_bias="0.86" />
62+
63+
<TextView
64+
android:id="@+id/txt_error"
65+
android:layout_width="wrap_content"
66+
android:layout_height="wrap_content"
67+
android:layout_marginTop="24dp"
68+
android:text="TextView"
69+
app:layout_constraintEnd_toEndOf="parent"
70+
app:layout_constraintHorizontal_bias="0.5"
71+
app:layout_constraintStart_toStartOf="parent"
72+
app:layout_constraintTop_toBottomOf="@+id/btn_start" />
6273

6374
</androidx.constraintlayout.widget.ConstraintLayout>

app/src/test/java/com/willowtreeapps/namegame/ReducersTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class ReducersTest {
1313
@Test
1414
fun `take random N items`() {
1515
val list = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
16-
val randomList = list.takeRandomDistint(10)
16+
val randomList = list.takeRandomDistinct(10)
1717
assert(randomList.size == 10)
1818
assert(randomList.distinctBy { it }.size == 10)
1919
}
@@ -22,7 +22,7 @@ class ReducersTest {
2222
fun `throw exception on N greater than size`() {
2323
val list = listOf(1, 2)
2424
val value = try {
25-
list.takeRandomDistint(3)
25+
list.takeRandomDistinct(3)
2626
} catch (e: Exception) {
2727
e
2828
}

build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ buildscript {
55
repositories {
66
google()
77
jcenter()
8+
maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
89
maven { url "https://kotlin.bintray.com/kotlinx" }
910
maven { url 'https://dl.bintray.com/jetbrains/kotlin-native-dependencies' }
1011
}
1112
dependencies {
12-
classpath 'com.android.tools.build:gradle:3.5.0-alpha09'
13+
classpath 'com.android.tools.build:gradle:3.5.0-alpha10'
1314
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
1415
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion"
1516
// NOTE: Do not place your application dependencies here; they belong
@@ -23,6 +24,7 @@ allprojects {
2324
jcenter()
2425
mavenCentral()
2526
maven { url "https://jitpack.io" }
27+
maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
2628
maven { url "https://kotlin.bintray.com/kotlinx" }
2729
maven { url "https://dl.bintray.com/kotlin/ktor" }
2830
maven { url "https://dl.bintray.com/soywiz/soywiz" }

common/build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
//plugins {
2+
// id("org.jetbrains.kotlin.native.cocoapods")
3+
//}
14
repositories {
25
maven { url "https://dl.bintray.com/soywiz/soywiz" }
36
}
@@ -8,7 +11,10 @@ apply plugin: 'kotlinx-serialization'
811

912

1013

14+
15+
1116
kotlin {
17+
1218
android {
1319
compilations.all {
1420
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) { task ->

common/src/commonMain/kotlin/com/beyondeye/reduks/builders.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,16 @@ class SelectorSubscriberBuilder<S : Any>(val store: Store<S>) {
6161
}
6262

6363
/**
64-
* Helper function that creates a DSL for subscribing to changes in specific state fields and actions to take
64+
* Helper function that creates a DSL for subscribing to changes in specific state fields and actions to take.
65+
* Inside the lambda there is access to the current state through the var `state`
66+
*
6567
* ex:
6668
* SelectorSubscriberFn {
6769
* withSingleField({it.foo}, { actionWhenFooChanges() }
6870
*
6971
* withAnyChange {
7072
* //called whenever any change happens to state
73+
* view.setMessage(state.barMsg) //state is current state
7174
* }
7275
* }
7376
*/

common/src/commonMain/kotlin/com/willowtreeapps/common/AppState.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ data class AppState(val isLoadingProfiles: Boolean = false,
1818

1919
fun Question.profile(): Profile = profiles.find { ProfileId(it.id) == this.profileId }!!
2020

21+
val timerText: String
22+
get() = if (questionClock >= 0) questionClock.toString() else "TIME'S UP!!"
23+
2124
val currentQuestion: Question?
2225
get() = if (questions.size > currentQuestionIndex)
2326
questions[currentQuestionIndex]

common/src/commonMain/kotlin/com/willowtreeapps/common/Reducers.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ val reducer = ReducerFn<AppState> { state, action ->
2121
}
2222
is FetchingProfilesFailedAction -> state.copy(isLoadingProfiles = false, errorLoadingProfiles = true, errorMsg = action.message)
2323
is NamePickedAction -> {
24-
val status = if (state.currentQuestionProfile()?.matches(action.name) == true) {
24+
val status = if (state.currentQuestionProfile().matches(action.name)) {
2525
Question.Status.CORRECT
2626
} else {
2727
Question.Status.INCORRECT
@@ -40,17 +40,17 @@ val reducer = ReducerFn<AppState> { state, action ->
4040
val status = Question.Status.TIMES_UP
4141
val newQuestions = state.questions.toMutableList()
4242
newQuestions[state.currentQuestionIndex] = newQuestions[state.currentQuestionIndex].copy(answerName = "", status = status)
43-
state.copy(questions = newQuestions, waitingForNextQuestion = true)
43+
state.copy(questions = newQuestions, waitingForNextQuestion = true, questionClock = -1)
4444
}
4545

4646
else -> throw AssertionError("Action ${action::class.simpleName} not handled")
4747
}
4848
}
4949

5050
fun generateRounds(profiles: List<Profile>, n: Int): List<Question> =
51-
profiles.takeRandomDistint(n)
51+
profiles.takeRandomDistinct(n)
5252
.map {
53-
val choiceList = profiles.takeRandomDistint(3).toMutableList()
53+
val choiceList = profiles.takeRandomDistinct(3).toMutableList()
5454
choiceList.add(abs(random.nextInt() % 4), it)
5555

5656
Question(profileId = ProfileId(it.id), choices = choiceList
@@ -61,12 +61,12 @@ fun generateRounds(profiles: List<Profile>, n: Int): List<Question> =
6161
private val random = Random(TimeUtil.systemTimeMs())
6262

6363
/**
64-
* Take N distict elements from the list. Distict is determined by a comparasion of objects in the
64+
* Take N distict elements from the list. Distinct is determined by a comparision of objects in the
6565
* list.
6666
* @throws IllegalStateException when n > number of distict elements.
6767
* @return New immutable list containing N random elements from the given List.
6868
*/
69-
fun <T> List<T>.takeRandomDistint(n: Int): List<T> {
69+
fun <T> List<T>.takeRandomDistinct(n: Int): List<T> {
7070
val newList = mutableListOf<T>()
7171
val uniqueItems = this.distinctBy { it }
7272
if (uniqueItems.size < n) {
@@ -87,3 +87,4 @@ fun <T> List<T>.takeRandomDistint(n: Int): List<T> {
8787

8888
fun <T> List<T>.takeRandom(): T =
8989
this[random.nextInt(this.size - 1)]
90+

0 commit comments

Comments
 (0)