diff --git a/android/DartsScorecard/app/build.gradle b/android/DartsScorecard/app/build.gradle index 591dcb24..901cdeac 100644 --- a/android/DartsScorecard/app/build.gradle +++ b/android/DartsScorecard/app/build.gradle @@ -42,7 +42,6 @@ dependencies { implementation "com.android.support:appcompat-v7:$support" implementation "com.android.support:design:$support" implementation "com.android.support.constraint:constraint-layout:$constraint" - implementation "com.google.firebase:firebase-core:$firebase" implementation "com.google.android.gms:play-services-ads:$firebase" implementation "android.arch.lifecycle:extensions:$architectureComponents" implementation "android.arch.persistence.room:runtime:$architectureComponents" diff --git a/android/DartsScorecard/app/src/main/AndroidManifest.xml b/android/DartsScorecard/app/src/main/AndroidManifest.xml index 86f68e47..83829d19 100644 --- a/android/DartsScorecard/app/src/main/AndroidManifest.xml +++ b/android/DartsScorecard/app/src/main/AndroidManifest.xml @@ -25,8 +25,7 @@ android:parentActivityName=".launch.LaunchActivity" /> + android:windowSoftInputMode="adjustResize" /> diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/base/widget/MaxHeightRecyclerView.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/base/widget/MaxHeightRecyclerView.kt new file mode 100644 index 00000000..f6d2371d --- /dev/null +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/base/widget/MaxHeightRecyclerView.kt @@ -0,0 +1,20 @@ +package nl.entreco.dartsscorecard.base.widget + +import android.content.Context +import android.support.v7.widget.RecyclerView +import android.util.AttributeSet + +/** + * Created by entreco on 14/01/2018. + */ +class MaxHeightRecyclerView @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 +) : RecyclerView(context, attrs, defStyleAttr) { + + var maxHeight: Int = 400 + + override fun onMeasure(widthSpec: Int, heightSpec: Int) { + val height = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST) + super.onMeasure(widthSpec, height) + } +} \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/application/AppModule.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/application/AppModule.kt index 82ec16dc..34977075 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/application/AppModule.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/application/AppModule.kt @@ -5,8 +5,8 @@ import dagger.Module import dagger.Provides import nl.entreco.dartsscorecard.App import nl.entreco.dartsscorecard.DscLogger -import nl.entreco.dartsscorecard.analytics.FirebaseAnalytics -import nl.entreco.data.DscDatabase +import nl.entreco.data.analytics.FirebaseAnalytics +import nl.entreco.data.db.DscDatabase import nl.entreco.domain.Analytics import nl.entreco.domain.Logger diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/play/Play01Component.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/play/Play01Component.kt index 92f671b1..a1b655f3 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/play/Play01Component.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/play/Play01Component.kt @@ -4,7 +4,8 @@ import dagger.Subcomponent import nl.entreco.dartsscorecard.play.Play01ViewModel import nl.entreco.dartsscorecard.play.input.InputViewModel import nl.entreco.dartsscorecard.play.score.ScoreViewModel -import nl.entreco.domain.play.usecase.GetFinishUsecase +import nl.entreco.dartsscorecard.play.stats.MatchStatViewModel +import nl.entreco.domain.play.finish.GetFinishUsecase /** * Created by Entreco on 14/11/2017. @@ -15,5 +16,6 @@ interface Play01Component { fun viewModel(): Play01ViewModel fun scoreViewModel(): ScoreViewModel fun inputViewModel(): InputViewModel + fun statViewModel(): MatchStatViewModel fun finishUsecase(): GetFinishUsecase } \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/setup/Setup01Module.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/setup/Setup01Module.kt index 45ac58a5..6bad789c 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/setup/Setup01Module.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/setup/Setup01Module.kt @@ -6,7 +6,7 @@ import dagger.Provides import nl.entreco.dartsscorecard.setup.Setup01Activity import nl.entreco.dartsscorecard.setup.Setup01Navigator import nl.entreco.dartsscorecard.setup.players.PlayerEditor -import nl.entreco.data.setup.repository.SharedPreferenceRepo +import nl.entreco.data.prefs.SharedPreferenceRepo import nl.entreco.domain.repository.PreferenceRepository /** diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/ViewModelComponent.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/ViewModelComponent.kt index 622cbdc1..0d4326bf 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/ViewModelComponent.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/ViewModelComponent.kt @@ -10,16 +10,16 @@ import nl.entreco.dartsscorecard.di.setup.EditPlayerComponent import nl.entreco.dartsscorecard.di.setup.EditPlayerModule import nl.entreco.dartsscorecard.di.setup.Setup01Component import nl.entreco.dartsscorecard.di.setup.Setup01Module -import nl.entreco.dartsscorecard.di.viewmodel.db.GameDbModule -import nl.entreco.dartsscorecard.di.viewmodel.db.PlayerDbModule -import nl.entreco.dartsscorecard.di.viewmodel.db.TurnDbModule +import nl.entreco.dartsscorecard.di.viewmodel.db.* import nl.entreco.dartsscorecard.di.viewmodel.threading.ThreadingModule /** * Created by Entreco on 14/11/2017. */ @ActivityScope -@Subcomponent(modules = [(ViewModelModule::class), (ThreadingModule::class), (GameDbModule::class), (PlayerDbModule::class), (TurnDbModule::class)]) +@Subcomponent(modules = [(ViewModelModule::class), (ThreadingModule::class), + (GameDbModule::class), (PlayerDbModule::class), (TurnDbModule::class), + (MetaDbModule::class), (StatDbModule::class)]) interface ViewModelComponent { fun inject(activity: Activity) diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/GameDbModule.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/GameDbModule.kt index 33b38853..ca8e4bf6 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/GameDbModule.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/GameDbModule.kt @@ -3,9 +3,9 @@ package nl.entreco.dartsscorecard.di.viewmodel.db import dagger.Module import dagger.Provides import nl.entreco.dartsscorecard.di.viewmodel.ActivityScope -import nl.entreco.data.DscDatabase +import nl.entreco.data.db.DscDatabase import nl.entreco.data.db.game.GameMapper -import nl.entreco.data.play.repository.LocalGameRepository +import nl.entreco.data.db.game.LocalGameRepository import nl.entreco.domain.repository.GameRepository /** diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/MetaDbModule.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/MetaDbModule.kt new file mode 100644 index 00000000..814f4ede --- /dev/null +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/MetaDbModule.kt @@ -0,0 +1,28 @@ +package nl.entreco.dartsscorecard.di.viewmodel.db + +import dagger.Module +import dagger.Provides +import nl.entreco.dartsscorecard.di.viewmodel.ActivityScope +import nl.entreco.data.db.DscDatabase +import nl.entreco.data.db.meta.LocalMetaRepository +import nl.entreco.data.db.meta.MetaMapper +import nl.entreco.domain.repository.MetaRepository + +/** + * Created by entreco on 16/01/2018. + */ +@Module +class MetaDbModule { + + @Provides + @ActivityScope + fun provideMetaMapper(): MetaMapper { + return MetaMapper() + } + + @Provides + @ActivityScope + fun provideMetaRepository(db: DscDatabase, mapper: MetaMapper): MetaRepository { + return LocalMetaRepository(db, mapper) + } +} \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/PlayerDbModule.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/PlayerDbModule.kt index 6596a443..ce7d8ed2 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/PlayerDbModule.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/PlayerDbModule.kt @@ -3,9 +3,9 @@ package nl.entreco.dartsscorecard.di.viewmodel.db import dagger.Module import dagger.Provides import nl.entreco.dartsscorecard.di.viewmodel.ActivityScope -import nl.entreco.data.DscDatabase +import nl.entreco.data.db.DscDatabase +import nl.entreco.data.db.player.LocalPlayerRepository import nl.entreco.data.db.player.PlayerMapper -import nl.entreco.data.play.repository.LocalPlayerRepository import nl.entreco.domain.repository.PlayerRepository /** diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/StatDbModule.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/StatDbModule.kt new file mode 100644 index 00000000..ca9d32e7 --- /dev/null +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/StatDbModule.kt @@ -0,0 +1,28 @@ +package nl.entreco.dartsscorecard.di.viewmodel.db + +import dagger.Module +import dagger.Provides +import nl.entreco.dartsscorecard.di.viewmodel.ActivityScope +import nl.entreco.data.db.DscDatabase +import nl.entreco.data.db.stats.LocalStatRepository +import nl.entreco.data.db.stats.StatMapper +import nl.entreco.domain.repository.StatRepository + +/** + * Created by entreco on 16/01/2018. + */ +@Module +class StatDbModule { + + @Provides + @ActivityScope + fun provideStatMapper(): StatMapper { + return StatMapper() + } + + @Provides + @ActivityScope + fun provideStatRepository(db: DscDatabase, mapper: StatMapper): StatRepository { + return LocalStatRepository(db, mapper) + } +} \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/TurnDbModule.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/TurnDbModule.kt index 2e20267a..e99d5515 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/TurnDbModule.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/TurnDbModule.kt @@ -3,9 +3,9 @@ package nl.entreco.dartsscorecard.di.viewmodel.db import dagger.Module import dagger.Provides import nl.entreco.dartsscorecard.di.viewmodel.ActivityScope -import nl.entreco.data.DscDatabase +import nl.entreco.data.db.DscDatabase +import nl.entreco.data.db.turn.LocalTurnRepository import nl.entreco.data.db.turn.TurnMapper -import nl.entreco.data.play.repository.LocalTurnRepository import nl.entreco.domain.repository.TurnRepository /** diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/threading/ThreadingModule.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/threading/ThreadingModule.kt index 14f7eb77..f933107b 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/threading/ThreadingModule.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/threading/ThreadingModule.kt @@ -4,10 +4,10 @@ import android.os.Handler import dagger.Module import dagger.Provides import nl.entreco.dartsscorecard.di.viewmodel.ActivityScope -import nl.entreco.domain.executors.Background -import nl.entreco.domain.executors.BgExecutor -import nl.entreco.domain.executors.FgExecutor -import nl.entreco.domain.executors.Foreground +import nl.entreco.domain.common.executors.Background +import nl.entreco.domain.common.executors.BgExecutor +import nl.entreco.domain.common.executors.FgExecutor +import nl.entreco.domain.common.executors.Foreground /** * Created by Entreco on 17/12/2017. diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchBindings.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchBindings.kt index 6e30910e..4bc52dad 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchBindings.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchBindings.kt @@ -2,7 +2,7 @@ package nl.entreco.dartsscorecard.launch import android.databinding.BindingAdapter import android.view.View -import nl.entreco.domain.repository.RetrieveGameRequest +import nl.entreco.domain.setup.game.CreateGameResponse /** * Created by Entreco on 19/12/2017. @@ -12,8 +12,8 @@ abstract class LaunchBindings { companion object { @JvmStatic @BindingAdapter("resumeGame") - fun resumeGame(view: View, request: RetrieveGameRequest?) { - view.animate().alpha(if (request == null) 0.5F else 1.0F).start() + fun resumeGame(view: View, response: CreateGameResponse?) { + view.animate().alpha(if (response == null) 0.5F else 1.0F).start() } } } \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchViewModel.kt index 99202f6a..f4005c30 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchViewModel.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchViewModel.kt @@ -6,8 +6,8 @@ import nl.entreco.dartsscorecard.base.BaseViewModel import nl.entreco.dartsscorecard.play.Play01Activity import nl.entreco.dartsscorecard.setup.Setup01Activity import nl.entreco.domain.launch.FetchLatestGameResponse -import nl.entreco.domain.launch.usecase.RetrieveLatestGameUsecase -import nl.entreco.domain.repository.RetrieveGameRequest +import nl.entreco.domain.launch.RetrieveLatestGameUsecase +import nl.entreco.domain.setup.game.CreateGameResponse import javax.inject.Inject /** @@ -15,7 +15,7 @@ import javax.inject.Inject */ class LaunchViewModel @Inject constructor(private val retrieveGameUsecase: RetrieveLatestGameUsecase) : BaseViewModel() { - val resumedGame = ObservableField(null) + val resumedGame = ObservableField(null) fun onNewGamePressed(context: Context) { Setup01Activity.launch(context) @@ -35,8 +35,8 @@ class LaunchViewModel @Inject constructor(private val retrieveGameUsecase: Retri private fun removeGameToResume(): (Throwable) -> Unit = { resumedGame.set(null) } private fun setGameToResume(): (FetchLatestGameResponse) -> Unit { - return { (gameId, teamIds, gameRequest) -> - resumedGame.set(RetrieveGameRequest(gameId, teamIds, gameRequest)) + return { (gameId, teamIds, startScore, startIndex, numLegs, numSets) -> + resumedGame.set(CreateGameResponse(gameId, teamIds, startScore, startIndex, numLegs, numSets)) } } } \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Activity.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Activity.kt index 57104c5e..7cf508ef 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Activity.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Activity.kt @@ -14,9 +14,10 @@ import nl.entreco.dartsscorecard.di.play.Play01Component import nl.entreco.dartsscorecard.di.play.Play01Module import nl.entreco.dartsscorecard.play.input.InputViewModel import nl.entreco.dartsscorecard.play.score.ScoreViewModel -import nl.entreco.domain.play.usecase.GetFinishUsecase -import nl.entreco.domain.repository.RetrieveGameRequest -import nl.entreco.domain.repository.TeamIdsString +import nl.entreco.dartsscorecard.play.stats.MatchStatViewModel +import nl.entreco.domain.play.finish.GetFinishUsecase +import nl.entreco.domain.play.start.Play01Request +import nl.entreco.domain.setup.game.CreateGameResponse class Play01Activity : ViewModelActivity() { @@ -24,6 +25,7 @@ class Play01Activity : ViewModelActivity() { private val viewModel: Play01ViewModel by viewModelProvider { component.viewModel() } private val scoreViewModel: ScoreViewModel by viewModelProvider { component.scoreViewModel() } private val inputViewModel: InputViewModel by viewModelProvider { component.inputViewModel() } + private val statViewModel: MatchStatViewModel by viewModelProvider { component.statViewModel() } private val finishUsecase: GetFinishUsecase by componentProvider { component.finishUsecase() } override fun onCreate(savedInstanceState: Bundle?) { @@ -32,6 +34,7 @@ class Play01Activity : ViewModelActivity() { val binding = DataBindingUtil.setContentView(this, R.layout.activity_play_01) binding.viewModel = viewModel binding.inputViewModel = inputViewModel + binding.statViewModel = statViewModel binding.scoreViewModel = scoreViewModel binding.finishUsecase = finishUsecase binding.animator = Play01Animator(binding) @@ -45,7 +48,7 @@ class Play01Activity : ViewModelActivity() { } private fun initGame() { - viewModel.load(retrieveSetup(intent), scoreViewModel) + viewModel.load(retrieveSetup(intent), scoreViewModel, statViewModel) } private fun toolbar(binding: ActivityPlay01Binding): Toolbar { @@ -53,10 +56,7 @@ class Play01Activity : ViewModelActivity() { } private fun resumeGame() { - viewModel.addScoreListener(scoreViewModel) - viewModel.addPlayerListener(scoreViewModel) - viewModel.addPlayerListener(inputViewModel) - viewModel.addSpecialEventListener(inputViewModel) + viewModel.registerListeners(scoreViewModel, statViewModel, inputViewModel, scoreViewModel, inputViewModel) } override fun onCreateOptionsMenu(menu: Menu?): Boolean { @@ -73,18 +73,24 @@ class Play01Activity : ViewModelActivity() { companion object { @JvmStatic - fun retrieveSetup(intent: Intent): RetrieveGameRequest { - return RetrieveGameRequest(intent.getLongExtra("gameId", -1), - TeamIdsString(intent.getStringExtra("teamIds")), - intent.getParcelableExtra("exec")) + fun retrieveSetup(intent: Intent): Play01Request { + return Play01Request(intent.getLongExtra("gameId", -1), + intent.getStringExtra("teamIds"), + intent.getIntExtra("startScore", -1), + intent.getIntExtra("startIndex", -1), + intent.getIntExtra("legs", -1), + intent.getIntExtra("sets", -1)) } @JvmStatic - fun startGame(context: Context, retrieve: RetrieveGameRequest) { + fun startGame(context: Context, create: CreateGameResponse) { val intent = Intent(context, Play01Activity::class.java) - intent.putExtra("gameId", retrieve.gameId) - intent.putExtra("teamIds", retrieve.teamIds.toString()) - intent.putExtra("exec", retrieve.create) + intent.putExtra("gameId", create.gameId) + intent.putExtra("teamIds", create.teamIds) + intent.putExtra("startScore", create.startScore) + intent.putExtra("startIndex", create.startIndex) + intent.putExtra("legs", create.numLegs) + intent.putExtra("sets", create.numSets) context.startActivity(intent) } } diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Animator.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Animator.kt index d7f4b996..0fbdc7f7 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Animator.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Animator.kt @@ -1,8 +1,15 @@ package nl.entreco.dartsscorecard.play +import android.databinding.BindingAdapter import android.support.design.widget.BottomSheetBehavior +import android.support.design.widget.CoordinatorLayout +import android.view.LayoutInflater import android.view.View import android.view.ViewPropertyAnimator +import android.view.ViewTreeObserver +import kotlinx.android.synthetic.main.activity_play_01.view.* +import kotlinx.android.synthetic.main.play_01_score.view.* +import nl.entreco.dartsscorecard.R import nl.entreco.dartsscorecard.databinding.ActivityPlay01Binding import kotlin.math.max import kotlin.math.sqrt @@ -13,6 +20,8 @@ import kotlin.math.sqrt class Play01Animator(binding: ActivityPlay01Binding) { private val fab = binding.includeInput?.fab!! + private val scoreSheet = binding.includeScore?.scoreSheet!! + private val teamSheet = binding.includeScore?.teamContainer!! private val inputSheet = binding.includeInput?.inputSheet!! private val inputResume = binding.includeInput?.inputResume!! private val mainSheet = binding.includeMain?.mainSheet!! @@ -24,14 +33,23 @@ class Play01Animator(binding: ActivityPlay01Binding) { private val stat5 = binding.includeMain?.stat5!! private val stat6 = binding.includeMain?.stat6!! private val stat7 = binding.includeMain?.stat7!! + private val name1 = binding.includeMain?.name1!! + private val name2 = binding.includeMain?.name2!! + private val score = binding.includeMain?.score!! private val player1 = binding.includeMain?.player1!! private val player2 = binding.includeMain?.player2!! private val version = binding.includeMain?.version!! init { + + calculateHeightForScoreView(binding) + behaviour.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { override fun onSlide(bottomSheet: View, slideOffset: Float) { + // Slide Out ScoreViewModel + scoreSheet.animate().alpha(slideOffset).translationY(-scoreSheet.height * (1 - slideOffset)).setDuration(0).start() + // Scale Fab Out Bottom/Top fab.animate().scaleY(slideOffset).scaleX(slideOffset).setDuration(0).start() @@ -42,6 +60,9 @@ class Play01Animator(binding: ActivityPlay01Binding) { // Fly In Players player1.animate().translationX(slideOffset * -player1.width / 3).setDuration(0).start() player2.animate().translationX(slideOffset * player2.width / 3).setDuration(0).start() + name1.animate().translationX(slideOffset * -name1.width).setDuration(0).start() + name2.animate().translationX(slideOffset * name2.width).setDuration(0).start() + score.animate().alpha(1 - slideOffset).scaleX(1 - slideOffset).scaleY(1 - slideOffset).setDuration(0).start() // Fly In stats animateState(stat1.animate(), 1, slideOffset) @@ -79,4 +100,38 @@ class Play01Animator(binding: ActivityPlay01Binding) { private fun animateState(anim: ViewPropertyAnimator, index: Int, slideOffset: Float) { anim.translationY(-index * 50 * slideOffset * index).scaleX(max(0f, (1 - slideOffset * index))).alpha(1 - slideOffset).setDuration(0).start() } + + private fun calculateHeightForScoreView(binding: ActivityPlay01Binding) { + binding.root.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener { + override fun onPreDraw(): Boolean { + binding.root.viewTreeObserver.removeOnPreDrawListener(this) + + val input = inputSheet.height + val header = binding.root.includeScore.header.height + val footer = binding.root.includeScore.footer.height + val toolbar = binding.root.includeToolbar.height + teamSheet.maxHeight = binding.root.height - toolbar - header - footer - input - 100 + teamSheet.requestLayout() + return true + } + }) + } + + companion object { + @JvmStatic + @BindingAdapter("loading") + fun showLoading(view: CoordinatorLayout, loading: Boolean) { + if(loading) { + val loadingView = LayoutInflater.from(view.context).inflate(R.layout.play_01_loading, view, false) + view.addView(loadingView) + loadingView.animate().alpha(1F).start() + } else { + val count = view.childCount - 1 + val loadingView = view.getChildAt(count) + loadingView.animate().alpha(0F) + .withEndAction { view.removeView(loadingView) } + .start() + } + } + } } \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Listeners.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Listeners.kt new file mode 100644 index 00000000..b0baf1fd --- /dev/null +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Listeners.kt @@ -0,0 +1,106 @@ +package nl.entreco.dartsscorecard.play + +import nl.entreco.dartsscorecard.play.score.TeamScoreListener +import nl.entreco.domain.model.Game +import nl.entreco.domain.model.Next +import nl.entreco.domain.model.Score +import nl.entreco.domain.model.Turn +import nl.entreco.domain.model.players.Player +import nl.entreco.domain.play.listeners.PlayerListener +import nl.entreco.domain.play.listeners.ScoreListener +import nl.entreco.domain.play.listeners.SpecialEventListener +import nl.entreco.domain.play.listeners.StatListener +import javax.inject.Inject + +/** + * Created by entreco on 12/01/2018. + */ +class Play01Listeners @Inject constructor() { + internal val scoreListeners = mutableListOf() + internal val statListeners = mutableListOf() + internal val playerListeners = mutableListOf() + internal val specialEventListeners = mutableListOf>() + + fun registerListeners(scoreListener: ScoreListener, statListener: StatListener, specialEventListener: SpecialEventListener<*>, vararg playerListeners: PlayerListener) { + addScoreListener(scoreListener) + addStatListener(statListener) + addSpecialEventListener(specialEventListener) + playerListeners.forEach { + addPlayerListener(it) + } + } + + fun onLetsPlayDarts(game: Game, listeners: List) { + listeners.forEach { addSpecialEventListener(it) } + notifyNextPlayer(game.next) + notifyScoreChanged(game.scores, game.next.player) + } + + fun onDartThrown(turn: Turn, by: Player) { + synchronized(scoreListeners) { + scoreListeners.forEach { it.onDartThrown(turn, by) } + } + } + + fun onStatsUpdated(turnId: Long, metaId: Long) { + synchronized(statListeners) { + statListeners.forEach { it.onStatsChange(turnId, metaId) } + } + } + + fun onTurnSubmitted(next: Next, turn: Turn, by: Player, scores: Array) { + notifyAboutSpecialEvents(next, turn, by, scores) + notifyScoreChanged(scores, by) + notifyNextPlayer(next) + } + + private fun addScoreListener(scoreListener: ScoreListener) { + synchronized(scoreListeners) { + if (!scoreListeners.contains(scoreListener)) { + scoreListeners.add(scoreListener) + } + } + } + + private fun addStatListener(statListener: StatListener) { + synchronized(statListeners) { + if (!statListeners.contains(statListener)) { + statListeners.add(statListener) + } + } + } + + private fun addPlayerListener(playerListener: PlayerListener) { + synchronized(playerListeners) { + if (!playerListeners.contains(playerListener)) { + playerListeners.add(playerListener) + } + } + } + + private fun addSpecialEventListener(specialEventListener: SpecialEventListener<*>) { + synchronized(specialEventListener) { + if (!specialEventListeners.contains(specialEventListener)) { + specialEventListeners.add(specialEventListener) + } + } + } + + private fun notifyScoreChanged(scores: Array, by: Player) { + synchronized(scoreListeners) { + scoreListeners.forEach { it.onScoreChange(scores, by) } + } + } + + private fun notifyAboutSpecialEvents(next: Next, turn: Turn, by: Player, scores: Array) { + synchronized(specialEventListeners) { + specialEventListeners.forEach { it.onSpecialEvent(next, turn, by, scores) } + } + } + + private fun notifyNextPlayer(next: Next) { + synchronized(playerListeners) { + playerListeners.forEach { it.onNext(next) } + } + } +} \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01ViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01ViewModel.kt index cf240283..61fe4ac8 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01ViewModel.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01ViewModel.kt @@ -1,117 +1,115 @@ package nl.entreco.dartsscorecard.play +import android.databinding.ObservableBoolean import nl.entreco.dartsscorecard.base.BaseViewModel -import nl.entreco.dartsscorecard.play.score.GameLoadable +import nl.entreco.dartsscorecard.play.score.GameLoadedNotifier +import nl.entreco.dartsscorecard.play.score.TeamScoreListener import nl.entreco.dartsscorecard.play.score.UiCallback import nl.entreco.domain.Logger -import nl.entreco.domain.model.Game -import nl.entreco.domain.model.Next -import nl.entreco.domain.model.Score -import nl.entreco.domain.model.Turn +import nl.entreco.domain.model.* import nl.entreco.domain.model.players.Player -import nl.entreco.domain.play.listeners.InputListener -import nl.entreco.domain.play.listeners.PlayerListener -import nl.entreco.domain.play.listeners.ScoreListener -import nl.entreco.domain.play.listeners.SpecialEventListener -import nl.entreco.domain.play.usecase.Play01Usecase -import nl.entreco.domain.repository.RetrieveGameRequest -import nl.entreco.domain.repository.StoreTurnRequest +import nl.entreco.domain.play.listeners.* +import nl.entreco.domain.play.start.MarkGameAsFinishedRequest +import nl.entreco.domain.play.start.Play01Request +import nl.entreco.domain.play.start.Play01Response +import nl.entreco.domain.play.start.Play01Usecase +import nl.entreco.domain.play.stats.StoreTurnRequest +import nl.entreco.domain.play.stats.UndoTurnRequest +import nl.entreco.domain.play.stats.UndoTurnResponse +import nl.entreco.domain.settings.ScoreSettings import javax.inject.Inject /** * Created by Entreco on 11/11/2017. */ -class Play01ViewModel @Inject constructor(private val playGameUsecase: Play01Usecase, private val logger: Logger) : BaseViewModel(), UiCallback, InputListener { +class Play01ViewModel @Inject constructor(private val playGameUsecase: Play01Usecase, private val gameListeners: Play01Listeners, private val logger: Logger) : BaseViewModel(), UiCallback, InputListener { - // Lazy to keep state + val loading = ObservableBoolean(true) private lateinit var game: Game - private val playerListeners = mutableListOf() - private val scoreListeners = mutableListOf() - private val specialEventListeners = mutableListOf>() - - fun load(request: RetrieveGameRequest, load: GameLoadable) { - playGameUsecase.loadGameAndStart(request, - { game, teams -> - this.game = game - load.startWith(teams, game.scores, request.create, this) + private lateinit var request: Play01Request + private lateinit var load: GameLoadedNotifier + private lateinit var loaders: Array> + + fun load(request: Play01Request, load: GameLoadedNotifier, vararg loaders: GameLoadedNotifier) { + this.request = request + this.load = load + this.loaders = arrayOf(*loaders) + this.playGameUsecase.loadGameAndStart(request, + { response -> + this.game = response.game + load.onLoaded(response.teams, game.scores, response.settings, this) + loaders.forEach { + it.onLoaded(response.teams, game.scores, response, null) + } }, { err -> logger.e("err: $err") }) } - override fun onLetsPlayDarts() { - notifyNextPlayer(game.next) - notifyScoreChanged(game.scores, game.next.player) + fun registerListeners(scoreListener: ScoreListener, statListener: StatListener, specialEventListener: SpecialEventListener<*>, vararg playerListeners: PlayerListener) { + gameListeners.registerListeners(scoreListener, statListener, specialEventListener, *playerListeners) } - override fun onDartThrown(turn: Turn, by: Player) { - notifyDartThrown(turn, by) + override fun onLetsPlayDarts(listeners: List) { + this.gameListeners.onLetsPlayDarts(game, listeners) + this.loading.set(false) } - override fun onTurnSubmitted(turn: Turn, by: Player) { - handleTurn(turn, by) - storeTurn(turn) + override fun onUndo() { + loading.set(true) + playGameUsecase.undoLastTurn(UndoTurnRequest(game.id), undoSuccess(), undoFailed()) } - private fun storeTurn(turn: Turn) { - playGameUsecase.storeTurn(StoreTurnRequest(game.id, turn)) - } - - private fun handleTurn(turn: Turn, by: Player) { - game.handle(turn) - - val next = game.next - val scores = game.scores - - notifyAboutSpecialEvents(next, turn, by, scores) - notifyScoreChanged(scores, by) - notifyNextPlayer(next) + private fun undoFailed(): (Throwable) -> Unit { + return { err -> + logger.w("Undo failed! -> $err") + } } - fun addScoreListener(scoreListener: ScoreListener) { - synchronized(scoreListeners) { - if (!scoreListeners.contains(scoreListener)) { - scoreListeners.add(scoreListener) - } + private fun undoSuccess(): (UndoTurnResponse) -> Unit { + return { + logger.i("Undo done! -> go to Let's Play Darts Function") + load(request, load, *loaders) } } - fun addPlayerListener(playerListener: PlayerListener) { - synchronized(playerListeners) { - if (!playerListeners.contains(playerListener)) { - playerListeners.add(playerListener) - } - } + override fun onDartThrown(turn: Turn, by: Player) { + this.gameListeners.onDartThrown(turn, by) } - fun addSpecialEventListener(specialEventListener: SpecialEventListener<*>) { - synchronized(specialEventListener) { - if (!specialEventListeners.contains(specialEventListener)) { - specialEventListeners.add(specialEventListener) - } - } + override fun onTurnSubmitted(turn: Turn, by: Player) { + handleTurn(turn, by) + storeTurn(turn, by) } - private fun notifyScoreChanged(scores: Array, by: Player) { - synchronized(scoreListeners) { - scoreListeners.forEach { it.onScoreChange(scores, by) } - } + private fun handleTurn(turn: Turn, by: Player) { + game.handle(turn) + + val next = game.next + val scores = game.scores + + handleGameFinished(next, game.id) + notifyListeners(next, turn, by, scores) } - private fun notifyDartThrown(turn: Turn, by: Player) { - synchronized(scoreListeners) { - scoreListeners.forEach { it.onDartThrown(turn, by) } - } + private fun storeTurn(turn: Turn, by: Player) { + val turnRequest = StoreTurnRequest(by.id, game.id, turn) + val score = game.previousScore() + val started = game.isNewMatchLegOrSet() + val turnCounter = game.getTurnCount() + val breakMade = game.wasBreakMade(by) + val turnMeta = TurnMeta(by.id, turnCounter, score, started, breakMade) + playGameUsecase.storeTurnAndMeta(turnRequest, turnMeta, { turnId, metaId -> + gameListeners.onStatsUpdated(turnId, metaId) + }) } - private fun notifyAboutSpecialEvents(next: Next, turn: Turn, by: Player, scores: Array) { - synchronized(specialEventListeners) { - specialEventListeners.forEach { it.onSpecialEvent(next, turn, by, scores) } + private fun handleGameFinished(next: Next, gameId: Long) { + if (next.state == State.MATCH) { + playGameUsecase.markGameAsFinished(MarkGameAsFinishedRequest(gameId)) } } - private fun notifyNextPlayer(next: Next) { - synchronized(playerListeners) { - playerListeners.forEach { it.onNext(next) } - } + private fun notifyListeners(next: Next, turn: Turn, by: Player, scores: Array) { + gameListeners.onTurnSubmitted(next, turn, by, scores) } } \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/input/InputViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/input/InputViewModel.kt index bdc94c1a..cd9fbfca 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/input/InputViewModel.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/input/InputViewModel.kt @@ -33,6 +33,7 @@ class InputViewModel @Inject constructor(private val analytics: Analytics, priva val special = ObservableField() val required = ObservableField() val dartsLeft = ObservableInt() + val resumeDescription = ObservableInt(R.string.game_on) private val estimator = ScoreEstimator() private var turn = Turn() @@ -90,6 +91,11 @@ class InputViewModel @Inject constructor(private val analytics: Analytics, priva submit(scored, listener) } + fun onUndoPressed(listener: InputListener){ + listener.onUndo() + clearScoreInput() + } + private fun submit(scored: Int, listener: InputListener, singles: Boolean = toggle.get()) { if (gameIsFinished()) return @@ -148,6 +154,7 @@ class InputViewModel @Inject constructor(private val analytics: Analytics, priva toggle.set(false) required.set(next.requiredScore) nextDescription.set(descriptionFromNext(next)) + resumeDescription.set(resumeDescriptionFromNext(next)) current.set(next.player) turn = Turn() dartsLeft.set(turn.dartsLeft()) @@ -163,6 +170,16 @@ class InputViewModel @Inject constructor(private val analytics: Analytics, priva } } + private fun resumeDescriptionFromNext(next: Next): Int { + return when (next.state) { + State.START -> R.string.game_on + State.LEG -> R.string.tap_to_resume + State.SET -> R.string.tap_to_resume + State.MATCH -> R.string.game_shot_and_match + else -> R.string.tap_to_resume + } + } + private fun didFinishLeg(): Boolean { return required.get().score == turn.total() } diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/GameLoadable.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/GameLoadable.kt deleted file mode 100644 index 77a52224..00000000 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/GameLoadable.kt +++ /dev/null @@ -1,12 +0,0 @@ -package nl.entreco.dartsscorecard.play.score - -import nl.entreco.domain.model.Score -import nl.entreco.domain.model.players.Team -import nl.entreco.domain.repository.CreateGameRequest - -/** - * Created by Entreco on 12/12/2017. - */ -interface GameLoadable { - fun startWith(teams: Array, scores: Array, create: CreateGameRequest, uiCallback: UiCallback) -} \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/GameLoadedNotifier.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/GameLoadedNotifier.kt new file mode 100644 index 00000000..9e6931c3 --- /dev/null +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/GameLoadedNotifier.kt @@ -0,0 +1,11 @@ +package nl.entreco.dartsscorecard.play.score + +import nl.entreco.domain.model.Score +import nl.entreco.domain.model.players.Team + +/** + * Created by Entreco on 12/12/2017. + */ +interface GameLoadedNotifier { + fun onLoaded(teams: Array, scores: Array, info: T, uiCallback: UiCallback?) +} \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreBindings.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreBindings.kt index 4769f164..8b6b8cab 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreBindings.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreBindings.kt @@ -5,7 +5,7 @@ import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import nl.entreco.domain.model.Score import nl.entreco.domain.model.players.Team -import nl.entreco.domain.play.usecase.GetFinishUsecase +import nl.entreco.domain.play.finish.GetFinishUsecase import nl.entreco.domain.settings.ScoreSettings @@ -23,12 +23,14 @@ abstract class ScoreBindings { recyclerView.adapter = adapter adapter.clear() + val listeners = mutableListOf() teams.forEachIndexed { index, team -> val vm = TeamScoreViewModel(team, scores[index], finishUsecase, starter = scoreSettings.teamStartIndex == index) adapter.addItem(vm) + listeners.add(vm) } - uiCallback?.onLetsPlayDarts() + uiCallback?.onLetsPlayDarts(listeners) } @JvmStatic diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreViewModel.kt index 1b9c971c..af2f73c6 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreViewModel.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreViewModel.kt @@ -12,14 +12,13 @@ import nl.entreco.domain.model.players.Player import nl.entreco.domain.model.players.Team import nl.entreco.domain.play.listeners.PlayerListener import nl.entreco.domain.play.listeners.ScoreListener -import nl.entreco.domain.repository.CreateGameRequest import nl.entreco.domain.settings.ScoreSettings import javax.inject.Inject /** * Created by Entreco on 18/11/2017. */ -class ScoreViewModel @Inject constructor(val adapter: ScoreAdapter, private val logger: Logger) : BaseViewModel(), GameLoadable, ScoreListener, PlayerListener { +class ScoreViewModel @Inject constructor(val adapter: ScoreAdapter, private val logger: Logger) : BaseViewModel(), GameLoadedNotifier, ScoreListener, PlayerListener { val numSets = ObservableInt(0) val teams = ObservableArrayList() @@ -28,17 +27,19 @@ class ScoreViewModel @Inject constructor(val adapter: ScoreAdapter, private val val scoreSettings = ObservableField(ScoreSettings()) val uiCallback = ObservableField() - override fun startWith(teams: Array, scores: Array, create: CreateGameRequest, uiCallback: UiCallback) { + override fun onLoaded(teams: Array, scores: Array, info: ScoreSettings, uiCallback: UiCallback?) { this.uiCallback.set(uiCallback) - this.scoreSettings.set(ScoreSettings(create.startScore, create.numLegs, create.numSets, create.startIndex)) + this.scoreSettings.set(info) + this.scores.clear() this.scores.addAll(scores) + this.teams.clear() this.teams.addAll(teams) - this.numSets.set(create.numSets) + this.numSets.set(info.numSets) } override fun onScoreChange(scores: Array, by: Player) { logger.d("NoNICE", "1:$scores by:$by") - scores.forEachIndexed { index, score -> adapter.teamAtIndexScored(index, score, by); } + scores.forEachIndexed { index, score -> adapter.teamAtIndexScored(index, score, by) } } override fun onDartThrown(turn: Turn, by: Player) { diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreBindings.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreBindings.kt index 03543060..38ffb8bd 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreBindings.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreBindings.kt @@ -6,7 +6,6 @@ import android.databinding.BindingAdapter import android.graphics.Color import android.support.annotation.ColorInt import android.support.v4.graphics.ColorUtils -import android.util.Log import android.util.TypedValue import android.view.animation.AccelerateDecelerateInterpolator import android.view.animation.AccelerateInterpolator @@ -16,6 +15,7 @@ import android.widget.TextView import nl.entreco.dartsscorecard.R import nl.entreco.dartsscorecard.base.widget.CounterTextView + /** * Created by Entreco on 25/11/2017. */ @@ -30,13 +30,29 @@ abstract class TeamScoreBindings { view.setTarget(score.toLong()) } + @JvmStatic + @BindingAdapter("nine") + fun showNineDarter(view: TextView, possibleNineDart: Boolean) { + if (possibleNineDart) handleNine(view) + else clearNine(view) + } + + private fun handleNine(view: TextView) { + show(view) + } + + private fun clearNine(view: TextView) { + hide(view) + } + @JvmStatic @BindingAdapter("special") fun showSpecials(view: TextView, oldScore: Int, score: Int) { val diff = oldScore - score when (diff) { 180 -> handle180(view) - 0 -> { } + 0 -> { + } else -> { clear(view) } @@ -83,8 +99,9 @@ abstract class TeamScoreBindings { @BindingAdapter("currentScore") fun showCurrentScore(view: CounterTextView, score: Int) { view.setTarget(score.toLong()) + view.measure(0, 0) if (score <= 0) { - view.animate().translationX(200F).setInterpolator(AccelerateDecelerateInterpolator()).setDuration(DEFAULT_ANIMATION_TIME).start() + view.animate().translationX(view.measuredWidth.toFloat() * 3).setInterpolator(AccelerateDecelerateInterpolator()).setDuration(DEFAULT_ANIMATION_TIME).start() } else { view.animate().translationX(0f).setInterpolator(AccelerateDecelerateInterpolator()).setDuration(DEFAULT_ANIMATION_TIME).start() view.setTextColor(fromAttr(view.context, R.attr.scoreText)) @@ -94,8 +111,14 @@ abstract class TeamScoreBindings { @JvmStatic @BindingAdapter("currentTeam") fun showCurrentTeam(view: ImageView, isCurrentTeam: Boolean) { - val w = if (view.width.toFloat() <= 0.0f) 200f else view.width.toFloat() - view.animate().translationX(if (isCurrentTeam) 0f else w).setInterpolator(AccelerateDecelerateInterpolator()).setDuration(DEFAULT_ANIMATION_TIME).start() + var target = 0F + if (!isCurrentTeam) { + view.measure(0, 0) + val w = view.width.toFloat() * 3 + target = if (w == 0F) 50F else w + } + + view.animate().translationX(target).setInterpolator(AccelerateDecelerateInterpolator()).setDuration(DEFAULT_ANIMATION_TIME).start() } @ColorInt @@ -111,19 +134,13 @@ abstract class TeamScoreBindings { @BindingAdapter("finish", "finishAlpha", requireAll = false) fun showFinishWithAlpha(view: TextView, finish: String, isCurrentTeam: Boolean) { view.text = finish + view.measure(0, 0) if (finish.isEmpty()) { - view.animate() - .translationX(-200F) - .setInterpolator(AccelerateDecelerateInterpolator()) - .setDuration(DEFAULT_ANIMATION_TIME).start() + hide(view) } else { - view.animate() - .translationX(0f) - .setInterpolator(AccelerateDecelerateInterpolator()) - .setDuration(DEFAULT_ANIMATION_TIME).start() + show(view) val startColor = colorToHex(view.currentTextColor) - Log.e("REMCO", "COLORINT:${view.currentTextColor}") val endColor = if (isCurrentTeam) "#FFFFFFFF" else "#aaFFFFFF" if (startColor != endColor) { val valueAnimator = ValueAnimator.ofFloat(0.0f, 1.0f).setDuration(DEFAULT_ANIMATION_TIME) @@ -136,6 +153,30 @@ abstract class TeamScoreBindings { } } + private fun hide(view: TextView) { + view.measure(0, 0) + val animator = ValueAnimator.ofInt(view.width, 0).setDuration(DEFAULT_ANIMATION_TIME) + animator.addUpdateListener { + val lp = view.layoutParams + lp.width = it.animatedValue as Int + view.layoutParams = lp + view.parent.requestLayout() + } + animator.start() + } + + private fun show(view: TextView) { + view.measure(0, 0) + val animator = ValueAnimator.ofInt(view.width, view.measuredWidth).setDuration(DEFAULT_ANIMATION_TIME) + animator.addUpdateListener { + val lp = view.layoutParams + lp.width = it.animatedValue as Int + view.layoutParams = lp + view.parent.requestLayout() + } + animator.start() + } + private fun colorToHex(color: Int): String { val alpha = Color.alpha(color) val blue = Color.blue(color) diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreListener.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreListener.kt new file mode 100644 index 00000000..4076163b --- /dev/null +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreListener.kt @@ -0,0 +1,16 @@ +package nl.entreco.dartsscorecard.play.score + +import nl.entreco.domain.play.listeners.SpecialEventListener +import nl.entreco.domain.play.listeners.events.NineDartEvent +import nl.entreco.domain.play.listeners.events.SpecialEvent + + +interface TeamScoreListener : SpecialEventListener { + override fun handle(event: SpecialEvent) { + when (event) { + is NineDartEvent -> onNineDartEvent(event) + } + } + + fun onNineDartEvent(event: NineDartEvent) +} \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreViewModel.kt index 9a328475..bcae0ed3 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreViewModel.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreViewModel.kt @@ -7,33 +7,41 @@ import android.os.Handler import nl.entreco.dartsscorecard.base.BaseViewModel import nl.entreco.domain.model.Next import nl.entreco.domain.model.Score +import nl.entreco.domain.model.State import nl.entreco.domain.model.Turn import nl.entreco.domain.model.players.Player -import nl.entreco.domain.model.State import nl.entreco.domain.model.players.Team -import nl.entreco.domain.play.usecase.GetFinishUsecase +import nl.entreco.domain.play.finish.GetFinishRequest +import nl.entreco.domain.play.finish.GetFinishUsecase +import nl.entreco.domain.play.listeners.events.NineDartEvent import java.util.concurrent.Future /** * Created by Entreco on 22/11/2017. */ -class TeamScoreViewModel(val team: Team, startScore: Score, private val getFinishUsecase: GetFinishUsecase, private val handler: Handler = Handler(), starter: Boolean) : BaseViewModel() { +class TeamScoreViewModel(val team: Team, startScore: Score, + private val getFinishUsecase: GetFinishUsecase, + private val handler: Handler = Handler(), + starter: Boolean) : BaseViewModel(), TeamScoreListener { val finish = ObservableField("") + val nineDarter = ObservableBoolean(false) val started = ObservableBoolean(starter) val scored = ObservableInt(0) val score = ObservableField(startScore) val currentTeam = ObservableBoolean() + private var isNineDarterStillPossible = true private var finishFuture: Future<*>? = null fun turnUpdate(next: Next) { + updateNineDarter(next) updateLegStarter(next) updateCurrentTeam(next) } fun scored(input: Score, by: Player) { - this.score.set(input.copy()) + score.set(input.copy()) removeScoredBadgeAfter(100) calculateFinish(input, by) } @@ -57,9 +65,23 @@ class TeamScoreViewModel(val team: Team, startScore: Score, private val getFinis } } + private fun updateNineDarter(next: Next) { + if (next.state == State.LEG || next.state == State.SET || next.state == State.START) { + isNineDarterStillPossible = true + nineDarter.set(false) + } + } + + override fun onNineDartEvent(event: NineDartEvent) { + if (team.contains(event.by())) { + nineDarter.set(event.isPossible() && isNineDarterStillPossible) + isNineDarterStillPossible = event.isPossible() + } + } + private fun calculateFinish(input: Score, player: Player, turn: Turn = Turn()) { finishFuture?.cancel(true) - finishFuture = getFinishUsecase.calculate(input, turn, player.prefs.favoriteDouble, { finish.set(it) }) + finishFuture = getFinishUsecase.calculate(GetFinishRequest(input, turn, player.prefs.favoriteDouble), { finish.set(it.finish) }) } private fun removeScoredBadgeAfter(duration: Long) { diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/UiCallback.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/UiCallback.kt index 1344faf0..a6e75207 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/UiCallback.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/UiCallback.kt @@ -4,5 +4,5 @@ package nl.entreco.dartsscorecard.play.score * Created by Entreco on 12/12/2017. */ interface UiCallback { - fun onLetsPlayDarts() + fun onLetsPlayDarts(listeners: List) } \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/stats/MatchStatViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/stats/MatchStatViewModel.kt new file mode 100644 index 00000000..fbf50b0c --- /dev/null +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/stats/MatchStatViewModel.kt @@ -0,0 +1,67 @@ +package nl.entreco.dartsscorecard.play.stats + +import android.databinding.ObservableArrayMap +import nl.entreco.dartsscorecard.base.BaseViewModel +import nl.entreco.dartsscorecard.play.score.GameLoadedNotifier +import nl.entreco.dartsscorecard.play.score.UiCallback +import nl.entreco.domain.Logger +import nl.entreco.domain.model.Score +import nl.entreco.domain.model.players.Team +import nl.entreco.domain.play.listeners.StatListener +import nl.entreco.domain.play.start.Play01Response +import nl.entreco.domain.play.stats.* +import javax.inject.Inject + +/** + * Created by entreco on 11/01/2018. + */ +class MatchStatViewModel @Inject constructor( + private val fetchGameStatsUsecase: FetchGameStatsUsecase, + private val fetchGameStatUsecase: FetchGameStatUsecase, + private val logger: Logger +) : BaseViewModel(), GameLoadedNotifier, StatListener { + + val teamStats = ObservableArrayMap() + private lateinit var teams: Array + + override fun onLoaded(teams: Array, scores: Array, info: Play01Response, uiCallback: UiCallback?) { + initializeStats(teams) + fetchGameStatsUsecase.exec(FetchGameStatsRequest(info.game.id, info.teamIds), + onStatsFetched(teams), + onStatsFailed()) + } + + private fun initializeStats(teams: Array) { + this.teamStats.clear() + this.teams = teams + teams.forEachIndexed { index, team -> + teamStats[index] = TeamStatModel(team) + } + } + + private fun onStatsFetched(teams: Array): (FetchGameStatsResponse) -> Unit { + return { response -> + teams.forEachIndexed { index, team -> + val stats = team.players.mapNotNull { + response.stats[it.id] + } + teamStats[index]?.append(stats) + } + } + } + + private fun onStatsFailed(): (Throwable) -> Unit = { err -> logger.e(err.localizedMessage) } + + override fun onStatsChange(turnId: Long, metaId: Long) { + fetchGameStatUsecase.exec(FetchGameStatRequest(turnId, metaId), onStatUpdated(), onStatsFailed()) + } + + private fun onStatUpdated(): (FetchGameStatResponse) -> Unit { + return { response -> + val teamIndex = teams.indexOfFirst { it.contains(response.stat.playerId) } + if (teamIndex >= 0) { + teamStats[teamIndex]?.append(listOf(response.stat)) + } + } + } +} \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/stats/TeamStatModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/stats/TeamStatModel.kt new file mode 100644 index 00000000..63d5cf64 --- /dev/null +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/stats/TeamStatModel.kt @@ -0,0 +1,98 @@ +package nl.entreco.dartsscorecard.play.stats + +import android.databinding.ObservableField +import nl.entreco.domain.model.Stat +import nl.entreco.domain.model.players.Team + +/** + * Created by entreco on 11/01/2018. + */ +class TeamStatModel(team: Team, private val stats: MutableList = mutableListOf()) { + + companion object { + const val empty = "--" + } + + val name = ObservableField(team.toString()) + val avg = ObservableField(empty) + val n180 = ObservableField(empty) + val n140 = ObservableField(empty) + val n100 = ObservableField(empty) + val hCo = ObservableField(empty) + val co = ObservableField(empty) + val breaks = ObservableField(empty) + + init { + if (stats.isNotEmpty()) { + update() + } + } + + fun append(updates: List) { + updates.forEach { stats.add(it) } + if (stats.isNotEmpty()) { + update() + } + } + + private fun update() { + updateAverage() + update180s() + update140s() + update100s() + updateHighestCheckout() + updateDoublePercentage() + updateBreaksMade() + } + + private fun updateBreaksMade() { + val value = stats.sumBy { it.nBreaks } + breaks.set("$value") + } + + private fun updateDoublePercentage() { + val aggregator = stats.sumBy { it.nCheckouts } + val denominator = stats.sumBy { it.nAtCheckout } + + when (denominator) { + 0 -> co.set(empty) + else -> co.set("%.2f".format(aggregator / denominator.toDouble() * 100) + "%") + } + } + + private fun updateHighestCheckout() { + val value = stats + .filter { it.highestCo.isNotEmpty() } + .maxBy { it.highestCo[0] } + ?.highestCo?.firstOrNull() + when (value) { + null -> hCo.set(empty) + else -> hCo.set("$value") + } + } + + private fun update100s() { + val value = stats.sumBy { it.n100 } + n100.set("$value") + } + + private fun update140s() { + val value = stats.sumBy { it.n140 } + n140.set("$value") + } + + private fun update180s() { + val value = stats.sumBy { it.n180 } + n180.set("$value") + } + + private fun updateAverage() { + val aggregator = stats.sumBy { it.totalScore } + val denominator = stats.sumBy { it.nDarts } + + when (denominator) { + 0 -> avg.set(empty) + else -> avg.set("%.2f".format(aggregator / denominator.toDouble() * 3)) + } + } +} \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Activity.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Activity.kt index eaa8b059..e84f9d10 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Activity.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Activity.kt @@ -35,8 +35,11 @@ class Setup01Activity : ViewModelActivity() { binding.settingsViewModel = settingsViewModel binding.navigator = navigator - navigator.onAddNewPlayer(0) initToolbar(toolbar(binding), R.string.title_setup) + + if (savedInstanceState == null) { + navigator.onAddNewPlayer(0) + } } private fun toolbar(binding: ActivitySetup01Binding): Toolbar { diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Navigator.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Navigator.kt index 48bb7dbc..586e7f5d 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Navigator.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Navigator.kt @@ -9,14 +9,14 @@ import nl.entreco.dartsscorecard.setup.edit.EditPlayerActivity import nl.entreco.dartsscorecard.setup.players.PlayerEditor import nl.entreco.dartsscorecard.setup.players.PlayerViewModel import nl.entreco.domain.model.players.Player -import nl.entreco.domain.repository.RetrieveGameRequest +import nl.entreco.domain.setup.game.CreateGameResponse /** * Created by Entreco on 02/01/2018. */ class Setup01Navigator(private val activity: Setup01Activity) : PlayerEditor { - fun launch(req: RetrieveGameRequest) { + fun launch(req: CreateGameResponse) { Play01Activity.startGame(activity, req) activity.finish() } @@ -47,9 +47,9 @@ class Setup01Navigator(private val activity: Setup01Activity) : PlayerEditor { if (isNewPlayer(index)) { - if(suggestion.isEmpty()){ + if (suggestion.isEmpty()) { callback.onPlayerAdded(playerName) - } else if(suggestion == "Player 1"){ + } else if (suggestion == "Player 1") { callback.onPlayerAdded(suggestion) } @@ -83,7 +83,7 @@ class Setup01Navigator(private val activity: Setup01Activity) : PlayerEditor { fun cancelPlayerResponse(request: Intent): Intent { val response = Intent() response.putExtra(EXTRA_SUGGESTION, request.getStringExtra(EXTRA_SUGGESTION)) - response.putExtra(EXTRA_PLAYER_NAME, "") + response.putExtra(EXTRA_PLAYER_NAME, request.getStringExtra(EXTRA_SUGGESTION)) response.putExtra(EXTRA_TEAM_INDEX, request.getIntExtra(EXTRA_TEAM_INDEX, POSITION_NONE)) response.putExtra(EXTRA_POSITION_IN_LIST, request.getIntExtra(EXTRA_POSITION_IN_LIST, POSITION_NONE)) return response diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01ViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01ViewModel.kt index 0cdb246b..852c3d77 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01ViewModel.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01ViewModel.kt @@ -2,12 +2,12 @@ package nl.entreco.dartsscorecard.setup import nl.entreco.dartsscorecard.base.BaseViewModel import nl.entreco.domain.Logger -import nl.entreco.domain.launch.TeamNamesString -import nl.entreco.domain.launch.usecase.CreateGameUsecase -import nl.entreco.domain.launch.usecase.ExtractTeamsUsecase -import nl.entreco.domain.repository.CreateGameRequest -import nl.entreco.domain.repository.RetrieveGameRequest -import nl.entreco.domain.repository.TeamIdsString +import nl.entreco.domain.launch.ExtractTeamsRequest +import nl.entreco.domain.launch.ExtractTeamsResponse +import nl.entreco.domain.launch.ExtractTeamsUsecase +import nl.entreco.domain.setup.game.CreateGameRequest +import nl.entreco.domain.setup.game.CreateGameResponse +import nl.entreco.domain.setup.game.CreateGameUsecase import javax.inject.Inject /** @@ -15,24 +15,24 @@ import javax.inject.Inject */ class Setup01ViewModel @Inject constructor(private val createGameUsecase: CreateGameUsecase, private val extractTeamsUsecase: ExtractTeamsUsecase, private val logger: Logger) : BaseViewModel() { - fun onStartPressed(navigator: Setup01Navigator, setup: CreateGameRequest, teams: TeamNamesString) { - ensureTeamPlayersExist(teams, { - createNewGame(setup, it, onGameCreated(navigator), onGameCreatedFailed()) + fun onStartPressed(navigator: Setup01Navigator, setup: CreateGameRequest, request: ExtractTeamsRequest) { + ensureTeamPlayersExist(request, { + createNewGame(setup, it.teamNames, onGameCreated(navigator), onGameCreatedFailed()) }, onGameCreatedFailed()) } - private fun onGameCreated(navigator: Setup01Navigator): (RetrieveGameRequest) -> Unit = + private fun onGameCreated(navigator: Setup01Navigator): (CreateGameResponse) -> Unit = { req -> navigator.launch(req) } private fun onGameCreatedFailed(): (Throwable) -> Unit = { err -> logger.w("Unable to create game $err") } - private fun ensureTeamPlayersExist(teamNamesInput: TeamNamesString, done: (TeamIdsString) -> Unit, fail: (Throwable) -> Unit) { + private fun ensureTeamPlayersExist(teamNamesInput: ExtractTeamsRequest, done: (ExtractTeamsResponse) -> Unit, fail: (Throwable) -> Unit) { extractTeamsUsecase.exec(teamNamesInput, done, fail) } - private fun createNewGame(createGameRequest: CreateGameRequest, teamNames: TeamIdsString, done: (RetrieveGameRequest) -> Unit, fail: (Throwable) -> Unit) { + private fun createNewGame(createGameRequest: CreateGameRequest, teamNames: String, done: (CreateGameResponse) -> Unit, fail: (Throwable) -> Unit) { createGameUsecase.exec(createGameRequest, teamNames, done, fail) } } \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/ad/AdViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/ad/AdViewModel.kt index 70c8c1ed..a1986fcb 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/ad/AdViewModel.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/ad/AdViewModel.kt @@ -10,9 +10,9 @@ import javax.inject.Inject */ class AdViewModel @Inject constructor(private val analytics: Analytics) : BaseViewModel(), AdLoader.Listener { - val loadAd = ObservableBoolean(true) - val showAd = ObservableBoolean(false) - val adLoader = AdLoader(this) + val loadAd by lazy { ObservableBoolean(true) } + val showAd by lazy { ObservableBoolean(false) } + val adLoader by lazy { AdLoader(this) } override fun onAdClicked() { analytics.trackAchievement("onAdClicked") diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerActivity.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerActivity.kt index ea5f75c3..4a280984 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerActivity.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerActivity.kt @@ -3,6 +3,7 @@ package nl.entreco.dartsscorecard.setup.edit import android.databinding.DataBindingUtil import android.os.Bundle import android.support.v7.widget.Toolbar +import android.view.MenuItem import nl.entreco.dartsscorecard.R import nl.entreco.dartsscorecard.base.ViewModelActivity import nl.entreco.dartsscorecard.databinding.ActivityEditPlayerBinding @@ -34,6 +35,16 @@ class EditPlayerActivity : ViewModelActivity() { return binding.includeToolbar?.toolbar!! } + override fun onOptionsItemSelected(item: MenuItem?): Boolean { + return when (item?.itemId) { + android.R.id.home -> { + onBackPressed() + true + } + else -> super.onOptionsItemSelected(item) + } + } + override fun onBackPressed() { navigator.onBackPressed() } diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerViewModel.kt index 1ad3b6c3..4d2852e5 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerViewModel.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerViewModel.kt @@ -2,16 +2,17 @@ package nl.entreco.dartsscorecard.setup.edit import android.databinding.ObservableArrayList import android.databinding.ObservableField -import android.support.design.widget.Snackbar import android.view.View import android.view.inputmethod.EditorInfo import android.widget.TextView +import android.widget.Toast import nl.entreco.dartsscorecard.R import nl.entreco.dartsscorecard.base.BaseViewModel import nl.entreco.domain.model.players.Player -import nl.entreco.domain.setup.usecase.CreatePlayerRequest -import nl.entreco.domain.setup.usecase.CreatePlayerUsecase -import nl.entreco.domain.setup.usecase.FetchExistingPlayersUsecase +import nl.entreco.domain.setup.players.CreatePlayerRequest +import nl.entreco.domain.setup.players.CreatePlayerResponse +import nl.entreco.domain.setup.players.CreatePlayerUsecase +import nl.entreco.domain.setup.players.FetchExistingPlayersUsecase import javax.inject.Inject import javax.inject.Named @@ -29,7 +30,7 @@ class EditPlayerViewModel @Inject constructor(private val createPlayerUsecase: C init { fetchExistingPlayersUsecase.exec( - { players -> onPlayersRetrieved(players) }, + { response -> onPlayersRetrieved(response.players) }, { onPlayersFailed() } ) } @@ -102,10 +103,11 @@ class EditPlayerViewModel @Inject constructor(private val createPlayerUsecase: C private fun donePressed(action: Int) = action == EditorInfo.IME_ACTION_DONE - private fun onCreateSuccess(navigator: EditPlayerNavigator): (Player) -> Unit = - { player -> navigator.onSelected(player) } + private fun onCreateSuccess(navigator: EditPlayerNavigator): (CreatePlayerResponse) -> Unit = { response -> + navigator.onSelected(response.player) + } - private fun onCreateFailed(view : View): (Throwable) -> Unit = { - Snackbar.make(view, R.string.err_unable_to_create_player, Snackbar.LENGTH_SHORT).show() + private fun onCreateFailed(view: View): (Throwable) -> Unit = { + Toast.makeText(view.context, R.string.err_unable_to_create_player, Toast.LENGTH_SHORT).show() } } \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/players/PlayersViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/players/PlayersViewModel.kt index 6f71ae0a..5e25adaa 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/players/PlayersViewModel.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/players/PlayersViewModel.kt @@ -1,7 +1,7 @@ package nl.entreco.dartsscorecard.setup.players import nl.entreco.dartsscorecard.base.BaseViewModel -import nl.entreco.domain.launch.TeamNamesString +import nl.entreco.domain.launch.ExtractTeamsRequest import nl.entreco.domain.model.players.PlayerSeperator import nl.entreco.domain.model.players.TeamSeperator import javax.inject.Inject @@ -11,11 +11,11 @@ import javax.inject.Inject */ class PlayersViewModel @Inject constructor(val adapter: PlayerAdapter) : BaseViewModel() { - fun setupTeams(): TeamNamesString { + fun setupTeams(): ExtractTeamsRequest { val teamString = StringBuilder() val players = adapter.playersMap().groupBy { it.teamIndex.get() }.toSortedMap() appendTeams(players, teamString) - return TeamNamesString(teamString.toString()) + return ExtractTeamsRequest(teamString.toString()) } private fun appendTeams(players: Map>, teamString: StringBuilder) { diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/settings/SettingsViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/settings/SettingsViewModel.kt index d10a090e..d7a19713 100644 --- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/settings/SettingsViewModel.kt +++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/settings/SettingsViewModel.kt @@ -5,11 +5,11 @@ import android.databinding.ObservableInt import android.widget.AdapterView import android.widget.SeekBar import nl.entreco.dartsscorecard.base.BaseViewModel -import nl.entreco.domain.repository.CreateGameRequest -import nl.entreco.domain.setup.usecase.FetchPreferredSettingsUsecase -import nl.entreco.domain.setup.usecase.FetchSettingsResponse -import nl.entreco.domain.setup.usecase.StorePreferredSettingsUsecase -import nl.entreco.domain.setup.usecase.StoreSettingsRequest +import nl.entreco.domain.setup.game.CreateGameRequest +import nl.entreco.domain.setup.settings.FetchPreferredSettingsUsecase +import nl.entreco.domain.setup.settings.FetchSettingsResponse +import nl.entreco.domain.setup.settings.StorePreferredSettingsUsecase +import nl.entreco.domain.setup.settings.StoreSettingsRequest import javax.inject.Inject /** diff --git a/android/DartsScorecard/app/src/main/res/drawable-nodpi/crowd.jpg b/android/DartsScorecard/app/src/main/res/drawable-nodpi/crowd.jpg new file mode 100644 index 00000000..3a7b2a52 Binary files /dev/null and b/android/DartsScorecard/app/src/main/res/drawable-nodpi/crowd.jpg differ diff --git a/android/DartsScorecard/app/src/main/res/drawable/ic_player1.xml b/android/DartsScorecard/app/src/main/res/drawable/ic_player1.xml index a80a26a5..18e72a0a 100644 --- a/android/DartsScorecard/app/src/main/res/drawable/ic_player1.xml +++ b/android/DartsScorecard/app/src/main/res/drawable/ic_player1.xml @@ -1,75 +1,175 @@ + android:width="100dp" + android:height="100dp" + android:viewportHeight="240.0" + android:viewportWidth="240.0"> + + + + + + + + + + + + - - - - - - - - - - - - - + android:fillColor="#FFFFFF" + android:fillType="nonZero" + android:pathData="M130.47,197.53h12.35v5.93h-12.35z" + android:strokeColor="#00000000" + android:strokeWidth="1" /> + + + + + android:fillType="nonZero" + android:pathData="M100.84,114.31C100.1,114.31 99.38,114.01 98.87,113.5C98.35,112.98 98.05,112.27 98.05,111.54C98.05,110.81 98.35,110.1 98.87,109.59C99.51,108.95 100.47,108.65 101.38,108.83C101.56,108.87 101.73,108.92 101.91,108.99C102.07,109.06 102.24,109.14 102.38,109.24C102.54,109.34 102.68,109.46 102.81,109.59C102.94,109.72 103.05,109.85 103.16,110.01C103.26,110.16 103.34,110.32 103.41,110.49C103.48,110.65 103.54,110.83 103.57,111C103.61,111.18 103.62,111.36 103.62,111.54C103.62,111.72 103.61,111.91 103.57,112.08C103.54,112.26 103.48,112.44 103.41,112.6C103.34,112.77 103.26,112.93 103.16,113.08C103.05,113.23 102.94,113.37 102.81,113.5C102.29,114.01 101.57,114.31 100.84,114.31Z" + android:strokeColor="#00000000" + android:strokeWidth="1" /> + android:fillType="nonZero" + android:pathData="M132.44,114.31C132.26,114.31 132.07,114.29 131.9,114.26C131.72,114.22 131.54,114.16 131.38,114.09C131.2,114.03 131.05,113.94 130.89,113.84C130.74,113.74 130.6,113.62 130.47,113.5C130.34,113.37 130.22,113.23 130.12,113.08C130.02,112.93 129.94,112.77 129.87,112.6C129.8,112.44 129.74,112.26 129.71,112.08C129.67,111.91 129.65,111.72 129.65,111.54C129.65,111.36 129.67,111.18 129.71,111C129.74,110.83 129.8,110.65 129.87,110.49C129.94,110.32 130.02,110.16 130.12,110.01C130.22,109.85 130.34,109.72 130.47,109.59C130.6,109.46 130.74,109.34 130.89,109.24C131.05,109.14 131.2,109.06 131.38,108.99C131.54,108.92 131.72,108.87 131.9,108.83C132.8,108.65 133.77,108.95 134.41,109.59C134.54,109.72 134.66,109.85 134.76,110.01C134.86,110.16 134.95,110.32 135.02,110.49C135.09,110.65 135.14,110.83 135.17,111C135.21,111.18 135.23,111.36 135.23,111.54C135.23,111.72 135.21,111.91 135.17,112.08C135.14,112.26 135.09,112.44 135.02,112.6C134.95,112.77 134.86,112.93 134.76,113.08C134.66,113.23 134.54,113.37 134.41,113.5C133.9,114.01 133.18,114.31 132.44,114.31Z" + android:strokeColor="#00000000" + android:strokeWidth="1" /> + android:fillType="nonZero" + android:pathData="M105.92,105.96L95.75,105.96C94.32,105.96 93.15,104.81 93.15,103.39L93.15,103.39C93.15,101.96 94.32,100.81 95.75,100.81L105.92,100.81C107.35,100.81 108.52,101.96 108.52,103.39L108.52,103.39C108.52,104.81 107.35,105.96 105.92,105.96Z" + android:strokeColor="#00000000" + android:strokeWidth="1" /> + android:fillType="nonZero" + android:pathData="M137.52,105.96L127.36,105.96C125.92,105.96 124.76,104.81 124.76,103.39L124.76,103.39C124.76,101.96 125.92,100.81 127.36,100.81L137.52,100.81C138.96,100.81 140.12,101.96 140.12,103.39L140.12,103.39C140.12,104.81 138.96,105.96 137.52,105.96Z" + android:strokeColor="#00000000" + android:strokeWidth="1" /> + android:fillType="nonZero" + android:pathData="M128,129.88C128,131.28 127.76,132.62 127.32,133.87C127.11,134.47 126.85,135.05 126.56,135.6C124.58,139.25 120.78,141.73 116.4,141.73C112.01,141.73 108.21,139.25 106.23,135.6C105.93,135.05 105.67,134.47 105.47,133.87C105.02,132.62 104.79,131.28 104.79,129.88L128,129.88Z" + android:strokeColor="#00000000" + android:strokeWidth="1" /> - - - + android:fillType="nonZero" + android:pathData="M127.51,133.33C127.3,133.94 127.03,134.52 126.73,135.07C124.72,138.75 120.85,141.23 116.4,141.23C111.94,141.23 108.07,138.75 106.06,135.07C105.76,134.52 105.49,133.94 105.28,133.33L127.51,133.33Z" + android:strokeColor="#00000000" + android:strokeWidth="1" /> + + + + + + diff --git a/android/DartsScorecard/app/src/main/res/drawable/ic_player2.xml b/android/DartsScorecard/app/src/main/res/drawable/ic_player2.xml index d5fc6065..f010a222 100644 --- a/android/DartsScorecard/app/src/main/res/drawable/ic_player2.xml +++ b/android/DartsScorecard/app/src/main/res/drawable/ic_player2.xml @@ -1,126 +1,163 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:width="100dp" + android:height="100dp" + android:viewportHeight="240.0" + android:viewportWidth="240.0"> + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/DartsScorecard/app/src/main/res/drawable/score_nine.xml b/android/DartsScorecard/app/src/main/res/drawable/score_nine.xml new file mode 100644 index 00000000..84b849b5 --- /dev/null +++ b/android/DartsScorecard/app/src/main/res/drawable/score_nine.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/DartsScorecard/app/src/main/res/layout/activity_edit_player.xml b/android/DartsScorecard/app/src/main/res/layout/activity_edit_player.xml index 4a52ce5b..ed36460f 100644 --- a/android/DartsScorecard/app/src/main/res/layout/activity_edit_player.xml +++ b/android/DartsScorecard/app/src/main/res/layout/activity_edit_player.xml @@ -57,7 +57,8 @@ + android:layout_height="wrap_content" + android:fillViewport="true"> @@ -36,9 +35,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:drawableEnd="@drawable/ic_dart" - app:resumeGame="@{viewModel.resumedGame}" android:onClick="@{() -> viewModel.onResumePressed(context)}" - android:text="@string/resume" /> + android:text="@string/resume" + app:resumeGame="@{viewModel.resumedGame}" />