Merge pull request #111 from lucasnlm/new-beta-release

Fix bug
This commit is contained in:
Lucas Nunes 2020-06-30 12:02:36 -03:00 committed by GitHub
commit 4c583f6a22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 162 additions and 32 deletions

View file

@ -9,8 +9,8 @@ android {
defaultConfig {
// versionCode and versionName must be hardcoded to support F-droid
versionCode 702001
versionName '7.2.0'
versionCode 702011
versionName '7.2.1'
minSdkVersion 16
targetSdkVersion 29
multiDexEnabled true

View file

@ -15,4 +15,6 @@ class FixedDimensionRepository : IDimensionRepository {
override fun displaySize(): Size = Size(50 * 15, 50 * 30)
override fun actionBarSize(): Int = 50
override fun navigationBarHeight(): Int = 0
}

View file

@ -9,8 +9,8 @@ android {
defaultConfig {
// versionCode and versionName must be hardcoded to support F-droid
versionCode 702001
versionName '7.2.0'
versionCode 702011
versionName '7.2.1'
minSdkVersion 16
targetSdkVersion 29
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'

View file

@ -12,6 +12,7 @@ interface IDimensionRepository {
fun areaSeparator(): Float
fun displaySize(): Size
fun actionBarSize(): Int
fun navigationBarHeight(): Int
}
data class Size(
@ -51,4 +52,17 @@ class DimensionRepository(
styledAttributes.recycle()
return actionBarSize
}
override fun navigationBarHeight(): Int {
// TODO use official mode if available
val resources = context.resources
val resourceId: Int = resources.getIdentifier(NAVIGATION_BAR_HEIGHT, DEF_TYPE_DIMEN, DEF_PACKAGE)
return if (resourceId > 0) { resources.getDimensionPixelSize(resourceId) } else 0
}
companion object {
private const val NAVIGATION_BAR_HEIGHT = "navigation_bar_height"
private const val DEF_TYPE_DIMEN = "dimen"
private const val DEF_PACKAGE = "android"
}
}

View file

@ -35,10 +35,12 @@ class MinefieldRepository : IMinefieldRepository {
dimensionRepository: IDimensionRepository
): Minefield {
val fieldSize = dimensionRepository.areaSize()
val verticalGap = if (dimensionRepository.navigationBarHeight() > 0)
VERTICAL_STANDARD_GAP else VERTICAL_STANDARD_GAP_WITHOUT_BOTTOM
val display = dimensionRepository.displaySize()
val calculatedWidth = ((display.width / fieldSize).toInt() - HORIZONTAL_STANDARD_GAP)
val calculatedHeight = ((display.height / fieldSize).toInt() - VERTICAL_STANDARD_GAP)
val calculatedHeight = ((display.height / fieldSize).toInt() - verticalGap)
val finalWidth = calculatedWidth.coerceAtLeast(MIN_STANDARD_WIDTH)
val finalHeight = calculatedHeight.coerceAtLeast(MIN_STANDARD_HEIGHT)
val finalMines = (finalWidth * finalHeight * CUSTOM_LEVEL_RATIO).toInt()
@ -55,6 +57,7 @@ class MinefieldRepository : IMinefieldRepository {
private const val CUSTOM_LEVEL_RATIO = 0.2
private const val HORIZONTAL_STANDARD_GAP = 1
private const val VERTICAL_STANDARD_GAP_WITHOUT_BOTTOM = 4
private const val VERTICAL_STANDARD_GAP = 3
private const val MIN_STANDARD_WIDTH = 6
private const val MIN_STANDARD_HEIGHT = 9

View file

@ -14,10 +14,13 @@ import dev.lucasnlm.antimine.common.R
import dev.lucasnlm.antimine.common.level.models.Area
import dev.lucasnlm.antimine.common.level.models.AreaPaintSettings
import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel
import dev.lucasnlm.antimine.core.control.ControlStyle
import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository
class AreaAdapter(
context: Context,
private val viewModel: GameViewModel
private val viewModel: GameViewModel,
private val preferencesRepository: IPreferencesRepository
) : RecyclerView.Adapter<AreaViewHolder>() {
private var field = listOf<Area>()
@ -74,7 +77,18 @@ class AreaAdapter(
}
}
override fun onSingleTapConfirmed(e: MotionEvent?): Boolean = false
override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
if (preferencesRepository.controlStyle() == ControlStyle.DoubleClick) {
val position = adapterPosition
if (position == RecyclerView.NO_POSITION) {
Log.d(TAG, "Item no longer exists.")
} else if (clickEnabled) {
viewModel.onSingleClick(position)
return true
}
}
return false
}
})
itemView.setOnLongClickListener { target ->
@ -91,11 +105,13 @@ class AreaAdapter(
}
itemView.setOnClickListener {
val position = adapterPosition
if (position == RecyclerView.NO_POSITION) {
Log.d(TAG, "Item no longer exists.")
} else if (clickEnabled) {
viewModel.onSingleClick(position)
if (preferencesRepository.controlStyle() != ControlStyle.DoubleClick) {
val position = adapterPosition
if (position == RecyclerView.NO_POSITION) {
Log.d(TAG, "Item no longer exists.")
} else if (clickEnabled) {
viewModel.onSingleClick(position)
}
}
}

View file

@ -3,7 +3,6 @@ package dev.lucasnlm.antimine.common.level.view
import android.content.Context
import android.os.Bundle
import android.util.DisplayMetrics
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -14,14 +13,17 @@ import androidx.recyclerview.widget.RecyclerView
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository
import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel
import dev.lucasnlm.antimine.common.level.widget.FixedGridLayoutManager
import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository
import javax.inject.Inject
abstract class CommonLevelFragment : Fragment() {
@Inject
lateinit var dimensionRepository: IDimensionRepository
@Inject
lateinit var preferencesRepository: IPreferencesRepository
protected val viewModel: GameViewModel by activityViewModels()
protected val areaAdapter by lazy { AreaAdapter(requireContext(), viewModel) }
protected val areaAdapter by lazy { AreaAdapter(requireContext(), viewModel, preferencesRepository) }
protected lateinit var recyclerGrid: RecyclerView
abstract val levelFragmentResId: Int
@ -54,19 +56,9 @@ abstract class CommonLevelFragment : Fragment() {
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
val typedValue = TypedValue()
val actionBarHeight = if (context.theme.resolveAttribute(android.R.attr.actionBarSize, typedValue, true)) {
TypedValue.complexToDimensionPixelSize(typedValue.data, resources.displayMetrics)
} else {
0
}
val resourceId: Int = resources.getIdentifier("navigation_bar_height", "dimen", "android")
val bottom = if (resourceId > 0) { resources.getDimensionPixelSize(resourceId) } else 0
val height = displayMetrics.heightPixels - actionBarHeight - bottom
val height = recyclerGrid.measuredHeight
val recyclerViewHeight = (dimensionRepository.areaSize() * boardHeight)
val separatorsHeight = (dimensionRepository.areaSeparator() * (boardHeight - 1))
val separatorsHeight = (2 * dimensionRepository.areaSeparator() * (boardHeight - 1))
return ((height - recyclerViewHeight - separatorsHeight) / 2).coerceAtLeast(0.0f).toInt()
}

View file

@ -4,6 +4,7 @@
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primary_dark</item>
<item name="colorAccent">@color/accent</item>
<item name="android:background">@color/primary</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>

View file

@ -4,6 +4,7 @@
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primary_dark</item>
<item name="colorAccent">@color/accent</item>
<item name="android:background">@color/primary</item>
</style>
<style name="Theme.Splash" parent="Theme.AppCompat.NoActionBar">

View file

@ -15,4 +15,6 @@ class FixedDimensionRepository : IDimensionRepository {
override fun displaySize(): Size = Size(50 * 15, 50 * 30)
override fun actionBarSize(): Int = 50
override fun navigationBarHeight(): Int = 0
}

View file

@ -0,0 +1,99 @@
package dev.lucasnlm.antimine.common.level.repository
import dev.lucasnlm.antimine.common.level.models.Difficulty
import dev.lucasnlm.antimine.common.level.models.Minefield
import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository
import io.mockk.every
import io.mockk.mockk
import org.junit.Assert.assertEquals
import org.junit.Test
class MinefieldRepositoryTest {
private val beginnerMinefield = Minefield(9, 9, 10)
private val intermediateMinefield = Minefield(16, 16, 40)
private val expertMinefield = Minefield(24, 24, 99)
@Test
fun testStandardSizeCalcWithoutNavigationBar() {
val minefieldRepository = MinefieldRepository()
val preferencesRepository = mockk<IPreferencesRepository>(relaxed = true)
val dimensionRepository = mockk<IDimensionRepository>(relaxed = true) {
every { areaSize() } returns 10.0f
every { navigationBarHeight() } returns 0
every { displaySize() } returns Size(1000, 1000)
}
val minefield = minefieldRepository.fromDifficulty(
Difficulty.Standard, dimensionRepository, preferencesRepository
)
assertEquals(Minefield(99, 96, 1900), minefield)
}
@Test
fun testStandardSizeCalcWithNavigationBar() {
val minefieldRepository = MinefieldRepository()
val preferencesRepository = mockk<IPreferencesRepository>(relaxed = true)
val dimensionRepository = mockk<IDimensionRepository>(relaxed = true) {
every { areaSize() } returns 10.0f
every { navigationBarHeight() } returns 100
every { displaySize() } returns Size(1000, 1000)
}
val minefield = minefieldRepository.fromDifficulty(
Difficulty.Standard, dimensionRepository, preferencesRepository
)
assertEquals(Minefield(99, 97, 1920), minefield)
}
@Test
fun testBeginnerMinefield() {
val minefieldRepository = MinefieldRepository()
val preferencesRepository = mockk<IPreferencesRepository>(relaxed = true)
val dimensionRepository = mockk<IDimensionRepository>(relaxed = true)
val minefield = minefieldRepository.fromDifficulty(
Difficulty.Beginner, dimensionRepository, preferencesRepository
)
assertEquals(beginnerMinefield, minefield)
}
@Test
fun testIntermediateMinefield() {
val minefieldRepository = MinefieldRepository()
val preferencesRepository = mockk<IPreferencesRepository>(relaxed = true)
val dimensionRepository = mockk<IDimensionRepository>(relaxed = true)
val minefield = minefieldRepository.fromDifficulty(
Difficulty.Intermediate, dimensionRepository, preferencesRepository
)
assertEquals(intermediateMinefield, minefield)
}
@Test
fun testExpertMinefieldMinefield() {
val minefieldRepository = MinefieldRepository()
val preferencesRepository = mockk<IPreferencesRepository>(relaxed = true)
val dimensionRepository = mockk<IDimensionRepository>(relaxed = true)
val minefield = minefieldRepository.fromDifficulty(
Difficulty.Expert, dimensionRepository, preferencesRepository
)
assertEquals(expertMinefield, minefield)
}
@Test
fun testCustomMinefieldMinefield() {
val minefieldRepository = MinefieldRepository()
val preferencesRepository = mockk<IPreferencesRepository>(relaxed = true) {
every { customGameMode() } returns Minefield(25, 20, 12)
}
val dimensionRepository = mockk<IDimensionRepository>(relaxed = true)
val minefield = minefieldRepository.fromDifficulty(
Difficulty.Custom, dimensionRepository, preferencesRepository
)
assertEquals(Minefield(25, 20, 12), minefield)
}
}

View file

@ -6,8 +6,8 @@ android {
compileSdkVersion 29
defaultConfig {
versionCode 702001 // MMmmPPv
versionName '7.2.0'
versionCode 702011 // MMmmPPv
versionName '7.2.1'
minSdkVersion 16
targetSdkVersion 29
resConfigs 'ar', 'en', 'cs', 'de', 'el', 'es', 'fr', 'ja', 'pt', 'ru', 'tr', 'uk', 'vi', 'zh'

View file

@ -6,8 +6,8 @@ android {
compileSdkVersion 29
defaultConfig {
versionCode 702001 // MMmmPPv
versionName '7.2.0'
versionCode 702011 // MMmmPPv
versionName '7.2.1'
minSdkVersion 16
targetSdkVersion 29
resConfigs 'ar', 'en', 'cs', 'de', 'el', 'es', 'fr', 'ja', 'pt', 'ru', 'tr', 'uk', 'vi', 'zh'

View file

@ -9,8 +9,8 @@ android {
defaultConfig {
// versionCode and versionName must be hardcoded to support F-droid
versionCode 702001
versionName '7.2.0'
versionCode 702011
versionName '7.2.1'
applicationId 'dev.lucasnlm.antimine'
minSdkVersion 23
targetSdkVersion 29