Merge branch 'add-support-screen' of github.com:lucasnlm/antimine-android into add-support-screen

This commit is contained in:
Lucas Lima 2020-08-19 17:35:18 -03:00
commit d4d7d09110
96 changed files with 636 additions and 322 deletions

View file

@ -10,7 +10,7 @@ android {
// versionCode and versionName must be hardcoded to support F-droid
versionCode 800051
versionName '8.0.5'
minSdkVersion 16
minSdkVersion 21
targetSdkVersion 30
multiDexEnabled true
vectorDrawables.useSupportLibrary true

View file

@ -106,7 +106,6 @@ class GameFlowTests {
.perform(NavigationViewActions.navigateTo(R.id.control))
onView(withText(R.string.standard)).perform(click())
onView(withText(R.string.flag_first)).perform(click())
onView(withText(R.string.ok)).perform(click())
}

View file

@ -45,10 +45,11 @@ class AboutViewModel(
private fun getLicensesList() = mapOf(
"Android SDK License" to R.raw.android_sdk,
"Material Design Icons" to R.raw.apache2,
"Material Design" to R.raw.apache2,
"Dagger Hilt" to R.raw.apache2,
"Moshi" to R.raw.apache2,
"Mockito" to R.raw.mockito,
"Noto Emoji" to R.raw.apache2,
"Sounds" to R.raw.sounds
).map {
License(it.key, it.value)

View file

@ -29,7 +29,7 @@ class HistoryViewModel(
}
}
override suspend fun mapEventToState(event: HistoryEvent) = flow<HistoryState> {
override suspend fun mapEventToState(event: HistoryEvent) = flow {
when (event) {
is HistoryEvent.LoadAllSaves -> {
val newSaveList = savesRepository.getAllSaves().sortedByDescending { it.uid }

View file

@ -66,13 +66,6 @@ open class LevelFragment : CommonLevelFragment(R.layout.fragment_level) {
}
)
fieldRefresh.observe(
viewLifecycleOwner,
Observer {
areaAdapter.notifyItemChanged(it)
}
)
eventObserver.observe(
viewLifecycleOwner,
Observer {

View file

@ -73,7 +73,7 @@ class EndGameDialogViewModel(
false
)
override suspend fun mapEventToState(event: EndGameDialogEvent) = flow<EndGameDialogState> {
override suspend fun mapEventToState(event: EndGameDialogEvent) = flow {
if (event is EndGameDialogEvent.BuildCustomEndGame) {
val state = when (event.isVictory) {
true -> {

View file

@ -39,8 +39,6 @@ class ThemeActivity : ThematicActivity(R.layout.activity_theme) {
}
}
}
showUnlockDialog()
}
private fun showUnlockDialog() {

View file

@ -58,14 +58,27 @@ class ThemeAdapter(
val theme = themes[position]
val paintSettings = createAreaPaintSettings(holder.itemView.context, areaSize)
holder.itemView.run {
val selected = (theme.id == themeViewModel.singleState().current.id)
val areas = listOf(area0, area1, area2, area3, area4, area5, area6, area7, area8)
if (selected) {
areas.forEach { it.alpha = 0.25f }
} else {
areas.forEach { it.alpha = 1.0f }
}
areas.forEachIndexed { index, areaView -> areaView.bindTheme(minefield[index], theme, paintSettings) }
if (position == 0) {
if (position < 2 && !selected) {
areas.forEach { it.alpha = 0.35f }
label.apply {
text = if (position == 0) {
label.context.getString(R.string.system)
} else {
label.context.getString(R.string.amoled)
}
setTextColor(
with(theme.palette.background) {
Color.rgb(255 - Color.red(this), 255 - Color.green(this), 255 - Color.blue(this))

View file

@ -12,7 +12,7 @@ class ThemeViewModel(
themeRepository.setTheme(theme)
}
override suspend fun mapEventToState(event: ThemeEvent) = flow<ThemeState> {
override suspend fun mapEventToState(event: ThemeEvent) = flow {
if (event is ThemeEvent.ChangeTheme) {
setTheme(event.newTheme)
emit(state.copy(current = event.newTheme))

View file

@ -31,7 +31,6 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:includeFontPadding="false"

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -10,7 +11,7 @@
android:layout_height="wrap_content"
android:elevation="0dp"
android:minHeight="30dp"
android:theme="@style/AppTheme.AppBarOverlay"
android:theme="@style/AppTheme"
tools:targetApi="lollipop" />
<LinearLayout
@ -29,9 +30,6 @@
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:drawableStart="@drawable/timer"
android:drawableLeft="@drawable/timer"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:includeFontPadding="false"
@ -41,6 +39,8 @@
android:textSize="@dimen/text_size"
android:textStyle="bold"
android:visibility="gone"
app:drawableLeftCompat="@drawable/timer"
app:drawableStartCompat="@drawable/timer"
tools:text="10:00"
tools:visibility="visible" />
@ -49,8 +49,6 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:drawableStart="@drawable/mine"
android:drawableLeft="@drawable/mine"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:includeFontPadding="false"
@ -59,6 +57,7 @@
android:textSize="@dimen/text_size"
android:textStyle="bold"
android:visibility="gone"
app:drawableStartCompat="@drawable/mine"
tools:text="99"
tools:visibility="visible" />

View file

@ -13,13 +13,14 @@
android:layout_height="64dp"
android:background="?selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:focusable="false"
android:importantForAccessibility="no"
android:layout_marginTop="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/emoji_smiling_face_with_sunglasses" />
tools:src="@drawable/emoji_smiling_face_with_sunglasses"
tools:ignore="KeyboardInaccessibleWidget" />
<TextView
android:id="@+id/title"

View file

@ -9,8 +9,6 @@
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:paddingLeft="32dp"
android:paddingRight="48dp"
android:paddingStart="32dp"
android:paddingEnd="48dp"
android:paddingVertical="12dp">

View file

@ -24,7 +24,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
app:layout_constraintStart_toEndOf="@id/badge"
app:layout_constraintTop_toTopOf="parent"
@ -35,7 +34,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
app:layout_constraintStart_toEndOf="@id/badge"
app:layout_constraintTop_toBottomOf="@id/difficulty"
@ -46,7 +44,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="4dp"
android:text="-"
app:layout_constraintStart_toEndOf="@id/minefieldSize"
@ -58,7 +55,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="4dp"
app:layout_constraintStart_toEndOf="@id/dash"
app:layout_constraintTop_toBottomOf="@id/difficulty"

View file

@ -27,7 +27,6 @@
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:textStyle="bold"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
tools:text="Text" />

View file

@ -11,7 +11,6 @@
android:layout_height="match_parent"
android:layout_gravity="center"
android:columnCount="3"
android:background="#FFFF0000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"

View file

@ -10,7 +10,7 @@ android {
// versionCode and versionName must be hardcoded to support F-droid
versionCode 800051
versionName '8.0.5'
minSdkVersion 16
minSdkVersion 21
targetSdkVersion 30
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 664 B

After

Width:  |  Height:  |  Size: 695 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 799 B

After

Width:  |  Height:  |  Size: 807 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 864 B

After

Width:  |  Height:  |  Size: 925 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 969 B

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 647 B

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 799 B

After

Width:  |  Height:  |  Size: 807 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 664 B

After

Width:  |  Height:  |  Size: 695 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 799 B

After

Width:  |  Height:  |  Size: 807 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 865 B

After

Width:  |  Height:  |  Size: 936 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,001 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 925 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 635 B

After

Width:  |  Height:  |  Size: 654 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 726 B

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 925 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -10,13 +10,11 @@ import dev.lucasnlm.antimine.common.level.logic.MinefieldHandler
import dev.lucasnlm.antimine.common.level.logic.filterNeighborsOf
import dev.lucasnlm.antimine.common.level.models.Area
import dev.lucasnlm.antimine.common.level.models.Difficulty
import dev.lucasnlm.antimine.common.level.models.Mark
import dev.lucasnlm.antimine.common.level.models.Minefield
import dev.lucasnlm.antimine.common.level.models.Score
import dev.lucasnlm.antimine.common.level.solver.LimitedBruteForceSolver
import dev.lucasnlm.antimine.core.control.ActionResponse
import dev.lucasnlm.antimine.core.control.GameControl
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlin.random.Random
@ -53,6 +51,8 @@ class GameController {
fun field() = field
fun field(predicate: (Area) -> Boolean) = field.filter(predicate)
fun mines() = field.filter { it.hasMine }
fun hasMines() = field.firstOrNull { it.hasMine } != null
@ -167,7 +167,7 @@ class GameController {
}
}
fun findExplodedMine() = mines().filter { it.mistake }.firstOrNull()
fun findExplodedMine() = mines().firstOrNull { it.mistake }
fun takeExplosionRadius(target: Area): List<Area> =
mines().filter { it.isCovered && it.mark.isNone() }.sortedBy {
@ -192,7 +192,7 @@ class GameController {
fun showWrongFlags() {
field = field.map {
if (it.mark.isNotNone() && !it.hasMine) {
if (!it.hasMine && it.mark.isFlag()) {
it.copy(mistake = true)
} else {
it

View file

@ -8,14 +8,13 @@ class MinefieldHandler(
private val useQuestionMark: Boolean
) {
fun showAllMines() {
field.filter { it.hasMine && it.mark != Mark.Flag}
field.filter { it.hasMine && it.mark != Mark.Flag }
.forEach { field[it.id] = it.copy(isCovered = false) }
}
fun flagAllMines() {
field.filter { it.hasMine }
.forEach { field[it.id] = it.copy(mark = Mark.Flag) }
}
fun revealAllEmptyAreas() {
@ -86,16 +85,15 @@ class MinefieldHandler(
if (flaggedCount >= minesAround) {
neighbors
.filter { it.isCovered && it.mark.isNone() }
.onEach { openAt(it.id, passive = false, openNeighbors = true) }
.count()
.forEach { openAt(it.id, passive = false, openNeighbors = true) }
} else {
val coveredNeighbors = neighbors.filter { it.isCovered }
if (coveredNeighbors.count() == minesAround) {
coveredNeighbors.filter {
it.mark.isNone()
}.onEach {
}.forEach {
switchMarkAt(it.id)
}.count()
}
}
}
}

View file

@ -61,7 +61,6 @@ class DimensionRepository(
}
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

View file

@ -9,9 +9,7 @@ open class BruteForceSolver : GameSolver() {
do {
val initialMap = minefield.filter { !it.isCovered && it.minesAround != 0 }
initialMap.forEach {
minefieldHandler.openOrFlagNeighborsOf(it.id)
}
initialMap.forEach { minefieldHandler.openOrFlagNeighborsOf(it.id) }
} while (initialMap != minefield.filter { !it.isCovered && it.minesAround != 0 })
return minefield.count { it.hasMine && !it.mark.isFlag() } == 0

View file

@ -57,17 +57,19 @@ class AreaAdapter(
override fun getItemCount(): Int = field.size
private fun AreaView.onClickablePosition(position: Int, action: suspend (Int) -> Unit): Boolean {
return if (position == RecyclerView.NO_POSITION) {
Log.d(TAG, "Item no longer exists.")
false
} else if (clickEnabled) {
requestFocus()
GlobalScope.launch {
action(position)
return when {
position == RecyclerView.NO_POSITION -> {
Log.d(TAG, "Item no longer exists.")
false
}
true
} else {
false
clickEnabled -> {
requestFocus()
GlobalScope.launch {
action(position)
}
true
}
else -> false
}
}

View file

@ -106,12 +106,7 @@ class AreaView : View {
area.hasMine -> IMPORTANT_FOR_ACCESSIBILITY_YES
area.mistake -> IMPORTANT_FOR_ACCESSIBILITY_YES
area.mark.isNotNone() -> IMPORTANT_FOR_ACCESSIBILITY_YES
!area.isCovered ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
} else {
IMPORTANT_FOR_ACCESSIBILITY_NO
}
!area.isCovered -> IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
else -> IMPORTANT_FOR_ACCESSIBILITY_YES
}
)

View file

@ -53,7 +53,6 @@ class GameViewModel(
private var currentDifficulty: Difficulty = Difficulty.Standard
val field = MutableLiveData<List<Area>>()
val fieldRefresh = MutableLiveData<Int>()
val elapsedTimeSeconds = MutableLiveData<Long>()
val mineCount = MutableLiveData<Int>()
val difficulty = MutableLiveData<Difficulty>()

View file

@ -1,5 +1,6 @@
package dev.lucasnlm.antimine.core.di
import android.view.ViewConfiguration
import dev.lucasnlm.antimine.common.level.repository.DimensionRepository
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository
import dev.lucasnlm.antimine.core.preferences.IPreferencesManager
@ -18,7 +19,7 @@ val CommonModule = module {
single { DimensionRepository(get(), get()) } bind IDimensionRepository::class
single { PreferencesRepository(get()) } bind IPreferencesRepository::class
single { PreferencesRepository(get(), ViewConfiguration.getLongPressTimeout()) } bind IPreferencesRepository::class
single { SoundManager(get()) } bind ISoundManager::class

View file

@ -37,7 +37,8 @@ interface IPreferencesRepository {
}
class PreferencesRepository(
private val preferencesManager: IPreferencesManager
private val preferencesManager: IPreferencesManager,
private val defaultLongPressTimeout: Int
) : IPreferencesRepository {
init {
migrateOldPreferences()
@ -151,7 +152,7 @@ class PreferencesRepository(
}
if (!preferencesManager.contains(PREFERENCE_LONG_PRESS_TIMEOUT)) {
preferencesManager.putInt(PREFERENCE_LONG_PRESS_TIMEOUT, ViewConfiguration.getLongPressTimeout())
preferencesManager.putInt(PREFERENCE_LONG_PRESS_TIMEOUT, defaultLongPressTimeout)
}
}

View file

@ -7,11 +7,17 @@ import dev.lucasnlm.antimine.core.themes.model.AreaPalette
import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.core.themes.model.AppTheme
import dev.lucasnlm.antimine.core.themes.model.Assets
import dev.lucasnlm.antimine.core.themes.repository.Themes.AmoledTheme
import dev.lucasnlm.antimine.core.themes.repository.Themes.BlueGreyTheme
import dev.lucasnlm.antimine.core.themes.repository.Themes.BrownTheme
import dev.lucasnlm.antimine.core.themes.repository.Themes.ChessTheme
import dev.lucasnlm.antimine.core.themes.repository.Themes.DarkTheme
import dev.lucasnlm.antimine.core.themes.repository.Themes.GardenTheme
import dev.lucasnlm.antimine.core.themes.repository.Themes.LightTheme
import dev.lucasnlm.antimine.core.themes.repository.Themes.MarineTheme
import dev.lucasnlm.antimine.core.themes.repository.Themes.OrangeTheme
import dev.lucasnlm.antimine.core.themes.repository.Themes.PinkTheme
import dev.lucasnlm.antimine.core.themes.repository.Themes.PurpleTheme
interface IThemeRepository {
fun getCustomTheme(): AppTheme?
@ -33,7 +39,10 @@ class ThemeRepository(
}
override fun getAllThemes(): List<AppTheme> = listOf(
buildSystemTheme(), LightTheme, DarkTheme, GardenTheme, MarineTheme, ChessTheme
buildSystemTheme(), AmoledTheme, LightTheme,
DarkTheme, GardenTheme, MarineTheme,
ChessTheme, BlueGreyTheme, OrangeTheme,
PinkTheme, PurpleTheme, BrownTheme
)
override fun setTheme(theme: AppTheme) {

View file

@ -39,8 +39,41 @@ object Themes {
)
)
val DarkTheme = AppTheme(
val AmoledTheme = AppTheme(
id = 2L,
theme = R.style.CustomAmoledTheme,
themeNoActionBar = R.style.CustomAmoledTheme_NoActionBar,
palette = AreaPalette(
border = 0xFFFFFF,
background = 0x000000,
covered = 0x212121,
coveredOdd = 0x212121,
uncovered = 0x000000,
uncoveredOdd = 0x050505,
minesAround1 = 0xCCCCCC,
minesAround2 = 0xFFFFFF,
minesAround3 = 0xDDDDDD,
minesAround4 = 0xCCCCCC,
minesAround5 = 0xDDDDDD,
minesAround6 = 0xFFFFFF,
minesAround7 = 0xCCCCCC,
minesAround8 = 0xCCCCCC,
highlight = 0x212121,
focus = 0xD32F2F
),
assets = Assets(
wrongFlag = R.drawable.flag,
flag = R.drawable.flag,
questionMark = R.drawable.question,
toolbarMine = R.drawable.mine_low,
mine = R.drawable.mine_low,
mineExploded = R.drawable.mine_low,
mineLow = R.drawable.mine_low
)
)
val DarkTheme = AppTheme(
id = 3L,
theme = R.style.CustomDarkTheme,
themeNoActionBar = R.style.CustomDarkTheme_NoActionBar,
palette = AreaPalette(
@ -73,7 +106,7 @@ object Themes {
)
val GardenTheme = AppTheme(
id = 3L,
id = 4L,
theme = R.style.CustomGardenTheme,
themeNoActionBar = R.style.CustomGardenTheme_NoActionBar,
palette = AreaPalette(
@ -106,7 +139,7 @@ object Themes {
)
val ChessTheme = AppTheme(
id = 4L,
id = 5L,
theme = R.style.CustomLightTheme,
themeNoActionBar = R.style.CustomLightTheme_NoActionBar,
palette = AreaPalette(
@ -139,7 +172,7 @@ object Themes {
)
val MarineTheme = AppTheme(
id = 5L,
id = 6L,
theme = R.style.CustomMarineTheme,
themeNoActionBar = R.style.CustomMarineTheme_NoActionBar,
palette = AreaPalette(
@ -170,4 +203,169 @@ object Themes {
mineLow = R.drawable.mine_low
)
)
val BlueGreyTheme = AppTheme(
id = 7L,
theme = R.style.CustomBlueGreyTheme,
themeNoActionBar = R.style.CustomBlueGreyTheme_NoActionBar,
palette = AreaPalette(
border = 0x424242,
background = 0xFFFFFF,
covered = 0x37474f,
coveredOdd = 0x37474f,
uncovered = 0xcfd8dc,
uncoveredOdd = 0xcfd8dc,
minesAround1 = 0x527F8D,
minesAround2 = 0x2B8D43,
minesAround3 = 0x546e7a,
minesAround4 = 0x20A5f7,
minesAround5 = 0xED1C24,
minesAround6 = 0xFFC107,
minesAround7 = 0x66126B,
minesAround8 = 0x000000,
highlight = 0x212121,
focus = 0xD32F2F
),
assets = Assets(
wrongFlag = R.drawable.red_flag,
flag = R.drawable.flag,
questionMark = R.drawable.question,
toolbarMine = R.drawable.mine,
mine = R.drawable.mine,
mineExploded = R.drawable.mine_exploded_red,
mineLow = R.drawable.mine_low
)
)
val OrangeTheme = AppTheme(
id = 8L,
theme = R.style.CustomOrangeTheme,
themeNoActionBar = R.style.CustomOrangeTheme_NoActionBar,
palette = AreaPalette(
border = 0x000000,
background = 0x212121,
covered = 0xfb8c00,
coveredOdd = 0xfb8c00,
uncovered = 0x303030,
uncoveredOdd = 0x252525,
minesAround1 = 0xDDDDDD,
minesAround2 = 0xEEEEEE,
minesAround3 = 0xCCCCCC,
minesAround4 = 0xBBBBBB,
minesAround5 = 0xAAAAAA,
minesAround6 = 0xFFFFFF,
minesAround7 = 0xBBBBBB,
minesAround8 = 0xEEEEEE,
highlight = 0x212121,
focus = 0xD32F2F
),
assets = Assets(
wrongFlag = R.drawable.flag_black,
flag = R.drawable.flag_black,
questionMark = R.drawable.question_black,
toolbarMine = R.drawable.mine_low,
mine = R.drawable.mine_white,
mineExploded = R.drawable.mine_white,
mineLow = R.drawable.mine_low
)
)
val PinkTheme = AppTheme(
id = 9L,
theme = R.style.CustomPinkTheme,
themeNoActionBar = R.style.CustomPinkTheme_NoActionBar,
palette = AreaPalette(
border = 0x000000,
background = 0xFFFFFF,
covered = 0xf48fb1,
coveredOdd = 0xf48fb1,
uncovered = 0xfce4ec,
uncoveredOdd = 0xfce4ec,
minesAround1 = 0x616161,
minesAround2 = 0xe64a19,
minesAround3 = 0x8e24aa,
minesAround4 = 0x000000,
minesAround5 = 0x1e88e5,
minesAround6 = 0x424242,
minesAround7 = 0x616161,
minesAround8 = 0x000000,
highlight = 0x212121,
focus = 0xD32F2F
),
assets = Assets(
wrongFlag = R.drawable.flag,
flag = R.drawable.flag,
questionMark = R.drawable.question,
toolbarMine = R.drawable.mine_low,
mine = R.drawable.mine_pink,
mineExploded = R.drawable.mine_pink_exploded,
mineLow = R.drawable.mine_low
)
)
val PurpleTheme = AppTheme(
id = 10L,
theme = R.style.CustomPurpleTheme,
themeNoActionBar = R.style.CustomPurpleTheme_NoActionBar,
palette = AreaPalette(
border = 0x000000,
background = 0xFFFFFF,
covered = 0x6a1b9a,
coveredOdd = 0x6a1b9a,
uncovered = 0xd1c4e9,
uncoveredOdd = 0xd1c4e9,
minesAround1 = 0x616161,
minesAround2 = 0xe64a19,
minesAround3 = 0x8e24aa,
minesAround4 = 0x000000,
minesAround5 = 0x1e88e5,
minesAround6 = 0x424242,
minesAround7 = 0x616161,
minesAround8 = 0x000000,
highlight = 0xd1c4e9,
focus = 0xD32F2F
),
assets = Assets(
wrongFlag = R.drawable.flag,
flag = R.drawable.flag,
questionMark = R.drawable.question,
toolbarMine = R.drawable.mine_low,
mine = R.drawable.mine_pink,
mineExploded = R.drawable.mine_pink_exploded,
mineLow = R.drawable.mine_low
)
)
val BrownTheme = AppTheme(
id = 11L,
theme = R.style.CustomLightTheme,
themeNoActionBar = R.style.CustomLightTheme_NoActionBar,
palette = AreaPalette(
border = 0x000000,
background = 0xFFFFFF,
covered = 0x3e2723,
coveredOdd = 0x4e342e,
uncovered = 0xd7ccc8,
uncoveredOdd = 0xefebe9,
minesAround1 = 0x616161,
minesAround2 = 0xe64a19,
minesAround3 = 0x8e24aa,
minesAround4 = 0x000000,
minesAround5 = 0x1e88e5,
minesAround6 = 0x424242,
minesAround7 = 0x616161,
minesAround8 = 0x000000,
highlight = 0xd1c4e9,
focus = 0xD32F2F
),
assets = Assets(
wrongFlag = R.drawable.flag,
flag = R.drawable.flag,
questionMark = R.drawable.question,
toolbarMine = R.drawable.mine_low,
mine = R.drawable.mine,
mineExploded = R.drawable.mine_pink_exploded,
mineLow = R.drawable.mine_low
)
)
}

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF212121"
android:pathData="M14.4,6L14,4H5v17h2v-7h5.6l0.4,2h7V6z" />
</vector>

View file

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="512"
android:viewportHeight="512">
<path
android:fillColor="#450220"
android:pathData="M331.722,124.091l-33.743,-67.204l-83.901,0l-33.84,65.28l-80.22,0l-37.443,65.714l37.443,67.649l-37.443,66.12l37.42,67.746l80.243,0l39.239,65.717l75.084,0l37.161,-66.643l79.759,-0.019l37.942,-66.801l-40.501,-65.64l40.501,-68.129l-38.02,-63.79z"
android:strokeWidth="0.02435089" />
<path
android:fillAlpha="1"
android:fillColor="#450220"
android:pathData="M360.853,255.692l-52.193,91.05l-104.8,0.177l-52.713,-90.616l52.081,-90.835l104.896,-0.386z" />
</vector>

View file

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="512"
android:viewportHeight="512">
<path
android:fillColor="#450220"
android:pathData="M331.722,124.091l-33.743,-67.204l-83.901,0l-33.84,65.28l-80.22,0l-37.443,65.714l37.443,67.649l-37.443,66.12l37.42,67.746l80.243,0l39.239,65.717l75.084,0l37.161,-66.643l79.759,-0.019l37.942,-66.801l-40.501,-65.64l40.501,-68.129l-38.02,-63.79z"
android:strokeWidth="0.02435089" />
<path
android:fillAlpha="1"
android:fillColor="#d81b60"
android:pathData="M360.853,255.692l-52.193,91.05l-104.8,0.177l-52.713,-90.616l52.081,-90.835l104.896,-0.386z" />
</vector>

View file

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="512"
android:viewportHeight="512">
<path
android:fillColor="#ffffff"
android:pathData="M331.722,124.091l-33.743,-67.204l-83.901,0l-33.84,65.28l-80.22,0l-37.443,65.714l37.443,67.649l-37.443,66.12l37.42,67.746l80.243,0l39.239,65.717l75.084,0l37.161,-66.643l79.759,-0.019l37.942,-66.801l-40.501,-65.64l40.501,-68.129l-38.02,-63.79z"
android:strokeWidth="0.02435089" />
<path
android:fillAlpha="1"
android:fillColor="#666666"
android:pathData="M360.853,255.692l-52.193,91.05l-104.8,0.177l-52.713,-90.616l52.081,-90.835l104.896,-0.386z" />
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF212121"
android:pathData="M11,18h2v-2h-2v2zM12,6c-2.21,0 -4,1.79 -4,4h2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2c0,2 -3,1.75 -3,5h2c0,-2.25 3,-2.5 3,-5 0,-2.21 -1.79,-4 -4,-4z"/>
</vector>

View file

@ -1,116 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="Theme.AppCompat.DayNight">
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primary_dark</item>
<item name="colorAccent">@color/accent</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="AppTheme.NoActionBar" parent="AppTheme">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="Theme.Splash" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/splash</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomLightTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#9E9E9E</item>
<item name="colorAccent">#D32F2F</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomLightTheme.NoActionBar" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#9E9E9E</item>
<item name="colorAccent">#D32F2F</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomDarkTheme" parent="ThemeOverlay.AppCompat.Dark">
<item name="colorPrimary">#212121</item>
<item name="colorPrimaryDark">#212121</item>
<item name="colorAccent">#FFFFFF</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomDarkTheme.NoActionBar" parent="ThemeOverlay.AppCompat.Dark">
<item name="colorPrimary">#212121</item>
<item name="colorPrimaryDark">#212121</item>
<item name="colorAccent">#FFFFFF</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomGardenTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#FFFFFF</item>
<item name="colorAccent">#53b529</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomGardenTheme.NoActionBar" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#FFFFFF</item>
<item name="colorAccent">#53b529</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomMarineTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#FFFFFF</item>
<item name="colorAccent">#03a9f4</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomMarineTheme.NoActionBar" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#FFFFFF</item>
<item name="colorAccent">#03a9f4</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
</resources>

View file

@ -32,6 +32,7 @@
<string name="settings_large_areas">Use Large Areas</string>
<string name="size">Size</string>
<string name="system">System</string>
<string name="amoled" translatable="false">AMOLED</string>
<string name="rating">Feedback</string>
<string name="support">Help supporting us!</string>
<string name="support_description">It will allow us building new features and to keep our project active.</string>

View file

@ -4,86 +4,225 @@
<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:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="AppTheme.NoActionBar" parent="AppTheme">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="Theme.Splash" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/splash</item>
</style>
<style name="MyDialog" parent="Theme.AppCompat.DayNight.Dialog.Alert">
<item name="colorAccent">@color/accent</item>
</style>
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.DayNight.ActionBar" />
<style name="CustomLightTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#9E9E9E</item>
<item name="colorAccent">#D32F2F</item>
<item name="android:background">#FFFFFF</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomLightTheme.NoActionBar" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#9E9E9E</item>
<item name="colorAccent">#D32F2F</item>
<item name="android:background">#FFFFFF</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomDarkTheme" parent="ThemeOverlay.AppCompat.Dark">
<item name="colorPrimary">#212121</item>
<item name="colorPrimaryDark">#212121</item>
<item name="colorAccent">#FFFFFF</item>
<item name="android:background">#212121</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomDarkTheme.NoActionBar" parent="ThemeOverlay.AppCompat.Dark">
<item name="colorPrimary">#212121</item>
<item name="colorPrimaryDark">#212121</item>
<item name="colorAccent">#FFFFFF</item>
<item name="android:background">#212121</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomAmoledTheme" parent="ThemeOverlay.AppCompat.Dark">
<item name="colorPrimary">#000000</item>
<item name="colorPrimaryDark">#000000</item>
<item name="android:windowBackground">#000000</item>
<item name="colorAccent">#FFFFFF</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomAmoledTheme.NoActionBar" parent="ThemeOverlay.AppCompat.Dark">
<item name="colorPrimary">#000000</item>
<item name="colorPrimaryDark">#000000</item>
<item name="android:windowBackground">#000000</item>
<item name="colorAccent">#FFFFFF</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomGardenTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#19360d</item>
<item name="colorPrimaryDark">#001000</item>
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#FFFFFF</item>
<item name="colorAccent">#53b529</item>
<item name="android:background">#FFFFFF</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomGardenTheme.NoActionBar" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#19360d</item>
<item name="colorPrimaryDark">#001000</item>
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#FFFFFF</item>
<item name="colorAccent">#53b529</item>
<item name="android:background">#FFFFFF</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomMarineTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#01579b</item>
<item name="colorPrimaryDark">#002f6c</item>
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#FFFFFF</item>
<item name="colorAccent">#03a9f4</item>
<item name="android:background">#e1f5fe</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomMarineTheme.NoActionBar" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#01579b</item>
<item name="colorPrimaryDark">#002f6c</item>
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#FFFFFF</item>
<item name="colorAccent">#03a9f4</item>
<item name="android:background">#e1f5fe</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomBlueGreyTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#FFFFFF</item>
<item name="colorAccent">#42a5f5</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomBlueGreyTheme.NoActionBar" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#FFFFFF</item>
<item name="colorAccent">#42a5f5</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomOrangeTheme" parent="ThemeOverlay.AppCompat.Dark">
<item name="colorPrimary">#212121</item>
<item name="colorPrimaryDark">#212121</item>
<item name="colorAccent">#fb8c00</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomOrangeTheme.NoActionBar" parent="ThemeOverlay.AppCompat.Dark">
<item name="colorPrimary">#212121</item>
<item name="colorPrimaryDark">#212121</item>
<item name="colorAccent">#fb8c00</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomPinkTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#9E9E9E</item>
<item name="colorAccent">#f48fb1</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomPinkTheme.NoActionBar" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#9E9E9E</item>
<item name="colorAccent">#f48fb1</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomPurpleTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#9E9E9E</item>
<item name="colorAccent">#9c27b0</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="CustomPurpleTheme.NoActionBar" parent="ThemeOverlay.AppCompat.Light">
<item name="colorPrimary">#FFFFFF</item>
<item name="colorPrimaryDark">#9E9E9E</item>
<item name="colorAccent">#9c27b0</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
</resources>

View file

@ -138,25 +138,31 @@ class GameControllerTest {
@Test
fun testShowWrongFlags() = runBlockingTest {
withGameController { controller ->
controller.field().first { !it.hasMine }
.also { controller.fakeLongPress(it.id) }
controller.field().first { !it.hasMine && it.isCovered }.run {
controller.fakeLongPress(id)
}
val wrongFlag = controller.field().first { !it.hasMine }
controller.mines().first().run {
controller.fakeLongPress(id)
}
//val rightFlag = controller.mines().first().apply { controller.fakeLongPress(id) }
controller.showWrongFlags()
val wrongFlag = controller.field().first { !it.hasMine && it.isCovered }
val rightFlag = controller.mines().first()
assertTrue(wrongFlag.mistake)
//assertFalse(rightFlag.mistake)
assertFalse(rightFlag.mistake)
}
}
@Test
fun testRevealAllEmptyAreas() = runBlockingTest {
withGameController { controller ->
val covered = controller.field().filter { it.isCovered }
val covered = controller.field { it.isCovered }
assertTrue(covered.isNotEmpty())
controller.revealAllEmptyAreas()
assertEquals(controller.field().filter { it.hasMine }, controller.field().filter { it.isCovered })
assertEquals(controller.mines(), controller.field { it.isCovered })
}
}
@ -187,7 +193,14 @@ class GameControllerTest {
assertEquals(20, controller.remainingMines())
repeat(20) { flagCount ->
controller.field().filter { it.hasMine }.take(flagCount).forEach { controller.fakeLongPress(it.id) }
controller.field()
.filter { it.hasMine }
.take(flagCount)
.forEach {
if (!it.mark.isFlag()) {
controller.fakeLongPress(it.id)
}
}
assertEquals("flagging $flagCount mines", 20 - flagCount, controller.remainingMines())
}
}
@ -235,15 +248,16 @@ class GameControllerTest {
withGameController { controller ->
assertFalse(controller.checkVictory())
controller.field()
.filter { it.hasMine }
.forEach { controller.fakeLongPress(it.id) }
controller.mines().forEach { controller.fakeLongPress(it.id) }
assertFalse(controller.checkVictory())
controller.field().filterNot { it.hasMine }.forEach { controller.fakeSingleClick(it.id) }
controller.field { !it.hasMine }.forEach { controller.fakeSingleClick(it.id) }
assertTrue(controller.checkVictory())
controller.field().first { it.hasMine }.also { controller.fakeSingleClick(it.id) }
controller.mines().first().run {
controller.fakeSingleClick(id)
controller.fakeSingleClick(id)
}
assertFalse(controller.checkVictory())
}
}
@ -300,16 +314,17 @@ class GameControllerTest {
updateGameControl(GameControl.fromControlType(ControlStyle.Standard))
fakeSingleClick(14)
assertFalse(at(14).isCovered)
field().filterNeighborsOf(at(14)).forEach {
assertTrue(it.isCovered)
}
field().filter { it.hasMine }.forEach {
fakeLongPress(it.id)
assertTrue(it.mark.isFlag())
}
mines().forEach { fakeLongPress(it.id) }
mines().forEach { assertTrue(it.mark.isFlag()) }
fakeLongPress(14)
field().filterNeighborsOf(at(14)).forEach {
if (it.hasMine) {
assertTrue(it.isCovered)
@ -373,12 +388,16 @@ class GameControllerTest {
updateGameControl(GameControl.fromControlType(ControlStyle.FastFlag))
fakeLongPress(14)
assertFalse(at(14).isCovered)
field().filterNeighborsOf(at(14)).forEach {
assertTrue(it.isCovered)
}
field().filter { it.hasMine }.forEach {
mines().forEach {
fakeSingleClick(it.id)
}
mines().forEach {
assertTrue(it.mark.isFlag())
}
@ -456,9 +475,9 @@ class GameControllerTest {
assertTrue(it.isCovered)
}
field().filter { it.hasMine }
.onEach { fakeSingleClick(it.id) }
.onEach { assertTrue(it.mark.isFlag()) }
mines().forEach { fakeSingleClick(it.id) }
mines().forEach { assertTrue(it.mark.isFlag()) }
fakeDoubleClick(14)
field().filterNeighborsOf(at(14)).forEach {

View file

@ -73,6 +73,7 @@ class MinefieldFactoryTest {
fun testFromDifficultyPresetStandard() {
val dimensionRepository: IDimensionRepository = mock {
on { areaSize() } doReturn 10.0f
on { defaultAreaSize() } doReturn 10.0f
on { actionBarSize() } doReturn 10
on { displaySize() } doReturn Size(500, 1000)
}
@ -84,7 +85,7 @@ class MinefieldFactoryTest {
).run {
assertEquals(49, width)
assertEquals(96, height)
assertEquals(950, mines)
assertEquals(940, mines)
}
}
}

View file

@ -1,6 +1,5 @@
package dev.lucasnlm.antimine.common.level.logic
import dev.lucasnlm.antimine.common.level.models.Area
import dev.lucasnlm.antimine.common.level.models.Mark
import dev.lucasnlm.antimine.common.level.models.Minefield
import org.junit.Assert.assertEquals
@ -13,138 +12,162 @@ class MinefieldHandlerTest {
private fun handleMinefield(
useQuestionMark: Boolean = false,
useSafeZone: Boolean = false,
block: (MinefieldHandler, MutableList<Area>) -> Unit
block: (MinefieldHandler) -> Unit
) {
val creator = MinefieldCreator(Minefield(4, 4, 9), Random(200))
val minefield = creator.create(10, useSafeZone).toMutableList()
val minefieldHandler = MinefieldHandler(minefield, useQuestionMark)
block(minefieldHandler, minefield)
block(minefieldHandler)
}
@Test
fun testOpenArea() {
handleMinefield { handler, minefield ->
assertTrue(minefield[3].isCovered)
handleMinefield { handler ->
assertTrue(handler.result()[3].isCovered)
handler.openAt(3, false, openNeighbors = false)
assertFalse(minefield[3].isCovered)
assertEquals(Mark.None, minefield[3].mark)
assertFalse(handler.result()[3].isCovered)
assertEquals(Mark.None, handler.result()[3].mark)
}
}
@Test
fun testOpenAreaWithSafeZone() {
handleMinefield(useSafeZone = true) { handler, minefield ->
assertTrue(minefield[3].isCovered)
handleMinefield(useSafeZone = true) { handler ->
assertTrue(handler.result()[3].isCovered)
handler.openAt(3, false, openNeighbors = false)
assertFalse(minefield[3].isCovered)
assertEquals(Mark.None, minefield[3].mark)
assertFalse(handler.result()[3].isCovered)
assertEquals(Mark.None, handler.result()[3].mark)
}
}
@Test
fun testTurnOffHighlight() {
handleMinefield { handler, minefield ->
minefield[3] = minefield[3].copy(highlighted = true)
handleMinefield { handler ->
handler.highlightAt(3)
handler.turnOffAllHighlighted()
assertFalse(minefield[3].highlighted)
assertFalse(handler.result()[3].highlighted)
}
}
@Test
fun testRemoveMark() {
handleMinefield { handler, minefield ->
minefield[3] = minefield[3].copy(mark = Mark.Flag)
handleMinefield { handler ->
handler.switchMarkAt(3)
handler.removeMarkAt(3)
assertTrue(minefield[3].mark == Mark.PurposefulNone)
assertTrue(minefield[3].mark.isNone())
assertTrue(handler.result()[3].mark == Mark.PurposefulNone)
assertTrue(handler.result()[3].mark.isNone())
}
}
@Test
fun testSwitchMarkWithoutQuestionMark() {
handleMinefield { handler, minefield ->
assertTrue(minefield[3].mark.isNone())
handleMinefield { handler ->
assertTrue(handler.result()[3].mark.isNone())
handler.switchMarkAt(3)
assertTrue(minefield[3].mark.isFlag())
assertTrue(handler.result()[3].mark.isFlag())
handler.switchMarkAt(3)
assertTrue(minefield[3].mark.isNone())
assertTrue(handler.result()[3].mark.isNone())
}
}
@Test
fun testSwitchMarkWithQuestionMark() {
handleMinefield(useQuestionMark = true) { handler, minefield ->
assertTrue(minefield[3].mark.isNone())
handleMinefield(useQuestionMark = true) { handler ->
assertTrue(handler.result()[3].mark.isNone())
handler.switchMarkAt(3)
assertTrue(minefield[3].mark.isFlag())
assertTrue(handler.result()[3].mark.isFlag())
handler.switchMarkAt(3)
assertTrue(minefield[3].mark.isQuestion())
assertTrue(handler.result()[3].mark.isQuestion())
handler.switchMarkAt(3)
assertTrue(minefield[3].mark.isNone())
assertTrue(handler.result()[3].mark.isNone())
}
}
@Test
fun testHighlight() {
handleMinefield(useQuestionMark = true) { handler, minefield ->
assertEquals(0, minefield.count { it.highlighted })
handleMinefield(useQuestionMark = true) { handler ->
assertEquals(0, handler.result().count { it.highlighted })
// Before open
handler.highlightAt(5)
assertEquals(0, minefield.count { it.highlighted })
assertEquals(0, handler.result().count { it.highlighted })
// After Open
handler.openAt(5, false, openNeighbors = false)
val target = minefield.first { it.minesAround != 0 }
val target = handler.result().first { it.minesAround != 0 }
handler.highlightAt(target.id)
assertEquals(5, minefield.count { it.highlighted })
assertEquals(listOf(0, 1, 4, 8, 9), minefield.filter { it.highlighted }.map { it.id }.toList())
assertEquals(5, handler.result().count { it.highlighted })
assertEquals(listOf(0, 1, 4, 8, 9), handler.result().filter { it.highlighted }.map { it.id }.toList())
}
}
@Test
fun testOpenNeighborsClosedArea() {
handleMinefield { handler, minefield ->
handleMinefield { handler ->
handler.openOrFlagNeighborsOf(3)
assertEquals(0, minefield.count { !it.isCovered })
assertEquals(0, handler.result().count { !it.isCovered })
}
}
@Test
fun testOpenNeighbors() {
handleMinefield { handler, minefield ->
handleMinefield { handler ->
handler.openAt(5, false, openNeighbors = true)
handler.openOrFlagNeighborsOf(5)
assertEquals(9, minefield.count { !it.isCovered })
assertEquals(9, handler.result().count { !it.isCovered })
}
}
@Test
fun testOpenNeighborsWithFlags() {
handleMinefield { handler, minefield ->
handleMinefield { handler ->
handler.openAt(5, false, openNeighbors = true)
val neighbors = minefield.filterNeighborsOf(minefield.first { it.id == 5 })
neighbors.filter { it.hasMine }.forEach { handler.switchMarkAt(it.id) }
handler.result()
.filterNeighborsOf(handler.result().first { it.id == 5 })
.filter { it.hasMine }
.forEach { handler.switchMarkAt(it.id) }
handler.openOrFlagNeighborsOf(5)
assertEquals(4, minefield.count { !it.isCovered })
assertEquals(3, neighbors.count { !it.isCovered })
val remainCovered =
handler.result().count { !it.isCovered }
val remainCoveredNeighbors =
handler.result().filterNeighborsOf(handler.result().first { it.id == 5 }).count { !it.isCovered }
assertEquals(4, remainCovered)
assertEquals(3, remainCoveredNeighbors)
}
}
@Test
fun testOpenNeighborsWithQuestionMarks() {
handleMinefield(useQuestionMark = true) { handler, minefield ->
handler.openAt(5, false, openNeighbors = true)
val neighbors = minefield.filterNeighborsOf(minefield.first { it.id == 5 })
neighbors
handleMinefield(useQuestionMark = true) { handler ->
handler.openAt(5, false, openNeighbors = false)
handler.result()
.filterNeighborsOf(handler.result().first { it.id == 5 })
.filter { it.hasMine }
.forEach {
handler.switchMarkAt(it.id)
handler.switchMarkAt(it.id)
}
handler.openOrFlagNeighborsOf(5)
assertEquals(4, minefield.count { !it.isCovered })
assertEquals(3, neighbors.count { !it.isCovered })
val remainCovered =
handler.result().count { !it.isCovered }
val remainCoveredNeighbors =
handler.result().filterNeighborsOf(handler.result().first { it.id == 5 }).count { !it.isCovered }
assertEquals(4, remainCovered)
assertEquals(3, remainCoveredNeighbors)
}
}
}

View file

@ -2,7 +2,6 @@ package dev.lucasnlm.antimine.common.level.solver
import dev.lucasnlm.antimine.common.level.logic.MinefieldCreator
import dev.lucasnlm.antimine.common.level.logic.MinefieldHandler
import dev.lucasnlm.antimine.common.level.models.Area
import dev.lucasnlm.antimine.common.level.models.Minefield
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
@ -11,7 +10,7 @@ import org.junit.Test
import kotlin.random.Random
class BruteForceSolverTest {
private fun handleMinefield(block: (MinefieldHandler, MutableList<Area>) -> Unit) {
private fun handleMinefield(block: (MinefieldHandler) -> Unit) {
val creator = MinefieldCreator(
Minefield(9, 9, 12),
Random(200)
@ -19,21 +18,21 @@ class BruteForceSolverTest {
val minefield = creator.create(40, true).toMutableList()
val minefieldHandler =
MinefieldHandler(minefield, false)
block(minefieldHandler, minefield)
block(minefieldHandler)
}
@Test
fun isSolvable() {
handleMinefield { handler, minefield ->
handler.openAt(40, passive = false, openNeighbors = false)
handleMinefield { handler ->
handler.openAt(40, passive = false, openNeighbors = true)
val bruteForceSolver = BruteForceSolver()
assertTrue(bruteForceSolver.trySolve(minefield.toMutableList()))
assertTrue(bruteForceSolver.trySolve(handler.result().toMutableList()))
}
handleMinefield { handler, minefield ->
handleMinefield { handler ->
handler.openAt(0, passive = false, openNeighbors = false)
val bruteForceSolver = BruteForceSolver()
assertFalse(bruteForceSolver.trySolve(minefield.toMutableList()))
assertFalse(bruteForceSolver.trySolve(handler.result().toMutableList()))
}
}
}

View file

@ -2,7 +2,6 @@ package dev.lucasnlm.antimine.common.level.solver
import dev.lucasnlm.antimine.common.level.logic.MinefieldCreator
import dev.lucasnlm.antimine.common.level.logic.MinefieldHandler
import dev.lucasnlm.antimine.common.level.models.Area
import dev.lucasnlm.antimine.common.level.models.Minefield
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
@ -11,41 +10,40 @@ import java.lang.Thread.sleep
import kotlin.random.Random
class LimitedBruteForceSolverTest {
private fun handleMinefield(block: (MinefieldHandler, MutableList<Area>) -> Unit) {
private fun handleMinefield(block: (MinefieldHandler) -> Unit) {
val creator = MinefieldCreator(
Minefield(9, 9, 12),
Random(200)
)
val minefield = creator.create(40, true).toMutableList()
val minefieldHandler =
MinefieldHandler(minefield, false)
block(minefieldHandler, minefield)
val minefieldHandler = MinefieldHandler(minefield, false)
block(minefieldHandler)
}
@Test
fun isSolvable() {
handleMinefield { handler, minefield ->
handler.openAt(40, passive = false, openNeighbors = false)
handleMinefield { handler ->
handler.openAt(40, passive = false, openNeighbors = true)
val bruteForceSolver = LimitedBruteForceSolver()
assertTrue(bruteForceSolver.trySolve(minefield.toMutableList()))
assertTrue(bruteForceSolver.trySolve(handler.result().toMutableList()))
}
handleMinefield { handler, minefield ->
handler.openAt(0, passive = false, openNeighbors = false)
handleMinefield { handler ->
handler.openAt(0, passive = false, openNeighbors = true)
val bruteForceSolver = LimitedBruteForceSolver()
assertFalse(bruteForceSolver.trySolve(minefield.toMutableList()))
assertFalse(bruteForceSolver.trySolve(handler.result().toMutableList()))
}
}
@Test
fun shouldntKeepTryingAfterTimeout() {
handleMinefield { handler, _ ->
handleMinefield { handler ->
handler.openAt(40, passive = false, openNeighbors = false)
val bruteForceSolver = LimitedBruteForceSolver(1000L)
assertTrue(bruteForceSolver.keepTrying())
}
handleMinefield { handler, _ ->
handleMinefield { handler ->
handler.openAt(0, passive = false, openNeighbors = false)
val bruteForceSolver = LimitedBruteForceSolver(50)
sleep(100)

View file

@ -37,7 +37,7 @@ class PreferencesRepositoryTest {
@Test
fun testProgressValue() {
val preferenceManager = TestPreferenceManager()
val preferencesRepository = PreferencesRepository(preferenceManager)
val preferencesRepository = PreferencesRepository(preferenceManager, 400)
assertEquals(0, preferencesRepository.getProgressiveValue())
@ -63,7 +63,7 @@ class PreferencesRepositoryTest {
preferenceManager.putBoolean("preference_double_click_open", true)
assertTrue(preferenceManager.values["preference_double_click_open"] as Boolean)
val preferencesRepository = PreferencesRepository(preferenceManager)
val preferencesRepository = PreferencesRepository(preferenceManager, 400)
assertTrue(preferenceManager.values["preference_double_click_open"] == null)
assertEquals(1, preferenceManager.values["preference_control_style"])
@ -76,7 +76,7 @@ class PreferencesRepositoryTest {
preferenceManager.putBoolean("preference_double_click_open", false)
assertFalse(preferenceManager.values["preference_double_click_open"] as Boolean)
val preferencesRepository = PreferencesRepository(preferenceManager)
val preferencesRepository = PreferencesRepository(preferenceManager, 400)
assertTrue(preferenceManager.values["preference_double_click_open"] == null)
assertFalse(preferencesRepository.getBoolean("preference_double_click_open", false))
@ -88,7 +88,7 @@ class PreferencesRepositoryTest {
preferenceManager.putBoolean("preference_large_area", true)
assertTrue(preferenceManager.values["preference_large_area"] as Boolean)
val preferencesRepository = PreferencesRepository(preferenceManager)
val preferencesRepository = PreferencesRepository(preferenceManager, 400)
assertTrue(preferenceManager.values["preference_large_area"] == null)
assertEquals(63, preferencesRepository.getInt("preference_area_size", -1))
@ -97,7 +97,7 @@ class PreferencesRepositoryTest {
@Test
fun testMigrationLargeAreaOff() {
val preferenceManager = TestPreferenceManager()
val preferencesRepository = PreferencesRepository(preferenceManager)
val preferencesRepository = PreferencesRepository(preferenceManager, 400)
assertTrue(preferenceManager.values["preference_large_area"] == null)
assertEquals(50, preferencesRepository.getInt("preference_area_size", -1))
@ -109,7 +109,7 @@ class PreferencesRepositoryTest {
preferenceManager.putBoolean("preference_large_area", false)
assertEquals(false, preferenceManager.values["preference_large_area"] as Boolean)
val preferencesRepository = PreferencesRepository(preferenceManager)
val preferencesRepository = PreferencesRepository(preferenceManager, 400)
assertTrue(preferenceManager.values["preference_large_area"] == null)
assertEquals(50, preferencesRepository.getInt("preference_area_size", -1))

View file

@ -7,7 +7,7 @@ android {
compileSdkVersion 30
defaultConfig {
minSdkVersion 16
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName '1.0'

View file

@ -8,7 +8,7 @@ android {
defaultConfig {
versionCode 800051 // MMmmPPv
versionName '8.0.5'
minSdkVersion 16
minSdkVersion 21
targetSdkVersion 30
}

View file

@ -12,7 +12,7 @@ android {
defaultConfig {
versionCode 800051
versionName '8.0.5'
minSdkVersion 16
minSdkVersion 21
targetSdkVersion 30
}

View file

@ -63,12 +63,7 @@ class WatchLevelFragment : CommonLevelFragment(R.layout.fragment_level) {
}
}
)
fieldRefresh.observe(
viewLifecycleOwner,
Observer {
areaAdapter.notifyItemChanged(it)
}
)
eventObserver.observe(
viewLifecycleOwner,
Observer {