diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index dfa800a18..f770db0a4 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -4,3 +4,7 @@ updates:
directory: "/"
schedule:
interval: "monthly"
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "monthly"
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index b42512d32..88be81258 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -9,9 +9,10 @@ on:
jobs:
Test:
runs-on: self-hosted
+ timeout-minutes: 30
steps:
- name: Check out source code
- uses: actions/checkout@v1
+ uses: actions/checkout@v3
- name: Build project
run: ./build.sh build
@@ -21,7 +22,7 @@ jobs:
- name: Upload artifacts
if: always()
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: build
path: |
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6a9651df2..bbc344341 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,20 @@
# Changelog
+## [2.1.2] -- 2023-05-26
+### Fixed
+- Fix bug that caused widget to enter checkmark on wrong date (@iSoron, #1541)
+- Fix widget corners on Android 12 (@iSoron)
+- Fix bug that caused notes to be lost when editing a checkmark (@iSoron, #1566)
+- Prevent soft keyboard from covering entry popup (@iSoron)
+- Accept comma (instead of dot) in certain locales (@iSoron)
+
+### Changed
+- Remove update delay after entering a checkmark (@iSoron)
+
+### Removed
+- Remove stack widgets (@iSoron)
+
+
## [2.1.1] -- 2022-09-24
### Fixed
- Fix Tasker plugin (@iSoron, #1503)
diff --git a/README.md b/README.md
index 19e411c3a..9ebbb7380 100644
--- a/README.md
+++ b/README.md
@@ -17,8 +17,8 @@ show you how your habits improved over time. It is completely ad-free and open
source.
-
-
+
+
## Screenshots
diff --git a/build.gradle.kts b/build.gradle.kts
index 8bf47ca61..25e353b53 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,11 +1,11 @@
plugins {
val kotlinVersion = "1.7.21"
- id("com.android.application") version ("7.3.0-rc01") apply (false)
+ id("com.android.application") version "7.4.2" apply (false)
id("org.jetbrains.kotlin.android") version kotlinVersion apply (false)
id("org.jetbrains.kotlin.kapt") version kotlinVersion apply (false)
id("org.jetbrains.kotlin.android.extensions") version kotlinVersion apply (false)
id("org.jetbrains.kotlin.multiplatform") version kotlinVersion apply (false)
- id("org.jlleitschuh.gradle.ktlint") version "11.0.0"
+ id("org.jlleitschuh.gradle.ktlint") version "11.4.2"
}
apply {
diff --git a/build.sh b/build.sh
index 271a2ba61..ac81802e1 100755
--- a/build.sh
+++ b/build.sh
@@ -217,20 +217,28 @@ android_test_parallel() {
(
LOG=build/android-test-$API.log
log_info "API $API: Running tests..."
- if android_test $API 1>$LOG 2>&1; then
+ android_test $API 1>$LOG 2>&1
+ ret_code=$?
+ if [ $ret_code = 0 ]; then
log_info "API $API: Passed"
else
log_error "API $API: Failed"
fi
pkill -9 -f ${AVD_PREFIX}${API}
+ exit $ret_code
)&
PIDS+=" $!"
done
# Check exit codes
- RET_CODE=0
+ success=0
for pid in $PIDS; do
- wait $pid || RET_CODE=1
+ wait $pid
+ ret_code=$?
+ if [ $ret_code != 0 ]; then
+ success=1
+ fi
+ echo pid=$pid ret_code=$ret_code success=$success
done
# Print all logs
@@ -240,7 +248,7 @@ android_test_parallel() {
echo "::endgroup::"
done
- return $RET_CODE
+ return $success
}
android_build() {
diff --git a/uhabits-android/build.gradle.kts b/uhabits-android/build.gradle.kts
index 4c9ba6348..d8e3f4060 100644
--- a/uhabits-android/build.gradle.kts
+++ b/uhabits-android/build.gradle.kts
@@ -19,7 +19,7 @@
plugins {
id("com.github.triplet.play") version "3.7.0"
- id("com.android.application")
+ id("com.android.application") version "7.4.2"
id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.kapt")
id("org.jetbrains.kotlin.android.extensions")
@@ -35,8 +35,8 @@ android {
compileSdk = 32
defaultConfig {
- versionCode = 20101
- versionName = "2.1.1"
+ versionCode = 20200
+ versionName = "2.2.0"
minSdk = 28
targetSdk = 31
applicationId = "org.isoron.uhabits"
@@ -80,11 +80,11 @@ android {
}
dependencies {
- val daggerVersion = "2.43.2"
+ val daggerVersion = "2.46"
val kotlinVersion = "1.7.21"
val kxCoroutinesVersion = "1.6.4"
val ktorVersion = "1.6.8"
- val espressoVersion = "3.4.0"
+ val espressoVersion = "3.5.1"
androidTestImplementation("androidx.test.espresso:espresso-contrib:$espressoVersion")
androidTestImplementation("androidx.test.espresso:espresso-core:$espressoVersion")
@@ -92,11 +92,11 @@ dependencies {
androidTestImplementation("com.linkedin.dexmaker:dexmaker-mockito:2.28.3")
androidTestImplementation("io.ktor:ktor-client-mock:$ktorVersion")
androidTestImplementation("io.ktor:ktor-jackson:$ktorVersion")
- androidTestImplementation("androidx.annotation:annotation:1.4.0")
- androidTestImplementation("androidx.test.ext:junit:1.1.3")
+ androidTestImplementation("androidx.annotation:annotation:1.5.0")
+ androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.2.0")
- androidTestImplementation("androidx.test:rules:1.4.0")
- androidTestImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
+ androidTestImplementation("androidx.test:rules:1.5.0")
+ androidTestImplementation("org.mockito.kotlin:mockito-kotlin:2.2.11")
compileOnly("javax.annotation:jsr250-api:1.0")
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.2")
implementation("com.github.AppIntro:AppIntro:6.2.0")
@@ -113,14 +113,14 @@ dependencies {
implementation("androidx.appcompat:appcompat:1.5.1")
implementation("androidx.legacy:legacy-preference-v14:1.0.0")
implementation("androidx.legacy:legacy-support-v4:1.0.0")
- implementation("com.google.android.material:material:1.6.1")
+ implementation("com.google.android.material:material:1.8.0")
implementation("com.opencsv:opencsv:5.7.1")
implementation(project(":uhabits-core"))
kapt("com.google.dagger:dagger-compiler:$daggerVersion")
kaptAndroidTest("com.google.dagger:dagger-compiler:$daggerVersion")
testImplementation("com.google.dagger:dagger:$daggerVersion")
testImplementation("junit:junit:4.13.2")
- testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
+ testImplementation("org.mockito.kotlin:mockito-kotlin:2.2.11")
}
kapt {
diff --git a/uhabits-android/src/androidTest/assets/views/widgets/CheckmarkWidget/render.png b/uhabits-android/src/androidTest/assets/views/widgets/CheckmarkWidget/render.png
index 642264b62..2ffbb10ac 100644
Binary files a/uhabits-android/src/androidTest/assets/views/widgets/CheckmarkWidget/render.png and b/uhabits-android/src/androidTest/assets/views/widgets/CheckmarkWidget/render.png differ
diff --git a/uhabits-android/src/androidTest/assets/views/widgets/CheckmarkWidgetView/checked.png b/uhabits-android/src/androidTest/assets/views/widgets/CheckmarkWidgetView/checked.png
index f5a3df56e..a8bf398a3 100644
Binary files a/uhabits-android/src/androidTest/assets/views/widgets/CheckmarkWidgetView/checked.png and b/uhabits-android/src/androidTest/assets/views/widgets/CheckmarkWidgetView/checked.png differ
diff --git a/uhabits-android/src/androidTest/assets/views/widgets/CheckmarkWidgetView/large_size.png b/uhabits-android/src/androidTest/assets/views/widgets/CheckmarkWidgetView/large_size.png
index ea1aab565..bc7e34f20 100644
Binary files a/uhabits-android/src/androidTest/assets/views/widgets/CheckmarkWidgetView/large_size.png and b/uhabits-android/src/androidTest/assets/views/widgets/CheckmarkWidgetView/large_size.png differ
diff --git a/uhabits-android/src/androidTest/assets/views/widgets/FrequencyWidget/render.png b/uhabits-android/src/androidTest/assets/views/widgets/FrequencyWidget/render.png
index 3fb786226..e72c6bedf 100644
Binary files a/uhabits-android/src/androidTest/assets/views/widgets/FrequencyWidget/render.png and b/uhabits-android/src/androidTest/assets/views/widgets/FrequencyWidget/render.png differ
diff --git a/uhabits-android/src/androidTest/assets/views/widgets/HistoryWidget/render.png b/uhabits-android/src/androidTest/assets/views/widgets/HistoryWidget/render.png
index 5b71e7300..23e3c979e 100644
Binary files a/uhabits-android/src/androidTest/assets/views/widgets/HistoryWidget/render.png and b/uhabits-android/src/androidTest/assets/views/widgets/HistoryWidget/render.png differ
diff --git a/uhabits-android/src/androidTest/assets/views/widgets/ScoreWidget/render.png b/uhabits-android/src/androidTest/assets/views/widgets/ScoreWidget/render.png
index 35f65f59e..4f50ce820 100644
Binary files a/uhabits-android/src/androidTest/assets/views/widgets/ScoreWidget/render.png and b/uhabits-android/src/androidTest/assets/views/widgets/ScoreWidget/render.png differ
diff --git a/uhabits-android/src/androidTest/assets/views/widgets/TargetWidget/render.png b/uhabits-android/src/androidTest/assets/views/widgets/TargetWidget/render.png
index 4a8fa7f9f..5b3270649 100644
Binary files a/uhabits-android/src/androidTest/assets/views/widgets/TargetWidget/render.png and b/uhabits-android/src/androidTest/assets/views/widgets/TargetWidget/render.png differ
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/BaseUserInterfaceTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/BaseUserInterfaceTest.kt
index 657eaf086..5553c234a 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/BaseUserInterfaceTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/BaseUserInterfaceTest.kt
@@ -39,6 +39,7 @@ open class BaseUserInterfaceTest {
private lateinit var prefs: Preferences
private lateinit var fixtures: HabitFixtures
private lateinit var cache: HabitCardListCache
+
@Before
@Throws(Exception::class)
fun setUp() {
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/BaseViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/BaseViewTest.kt
index bcec69dfa..2f6daca23 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/BaseViewTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/BaseViewTest.kt
@@ -153,18 +153,22 @@ open class BaseViewTest : BaseAndroidTest() {
var filename = filename
var dir = getSDCardDir("test-screenshots")
if (dir == null) dir = AndroidDirFinder(targetContext).getFilesDir("test-screenshots")
- if (dir == null) throw RuntimeException(
- "Could not find suitable dir for screenshots"
- )
+ if (dir == null) {
+ throw RuntimeException(
+ "Could not find suitable dir for screenshots"
+ )
+ }
filename = filename.replace("\\.png$".toRegex(), "$suffix.png")
val absolutePath = String.format("%s/%s", dir.absolutePath, filename)
val parent = File(absolutePath).parentFile
- if (!parent.exists() && !parent.mkdirs()) throw RuntimeException(
- String.format(
- "Could not create dir: %s",
- parent.absolutePath
+ if (!parent.exists() && !parent.mkdirs()) {
+ throw RuntimeException(
+ String.format(
+ "Could not create dir: %s",
+ parent.absolutePath
+ )
)
- )
+ }
val out = FileOutputStream(absolutePath)
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)
return absolutePath
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/HabitsActivityTestComponent.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/HabitsActivityTestComponent.kt
index a7a1b2759..38df23db2 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/HabitsActivityTestComponent.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/HabitsActivityTestComponent.kt
@@ -19,7 +19,6 @@
package org.isoron.uhabits
-import com.nhaarman.mockitokotlin2.mock
import dagger.Component
import dagger.Module
import dagger.Provides
@@ -35,6 +34,7 @@ import org.isoron.uhabits.inject.ActivityScope
import org.isoron.uhabits.inject.HabitModule
import org.isoron.uhabits.inject.HabitsActivityModule
import org.isoron.uhabits.inject.HabitsApplicationComponent
+import org.mockito.kotlin.mock
@Module
class TestModule {
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/ScoreChartTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/ScoreChartTest.kt
index 3d71853ec..4f504d8be 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/ScoreChartTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/ScoreChartTest.kt
@@ -44,7 +44,7 @@ class ScoreChartTest : BaseViewTest() {
habit = habit,
firstWeekday = prefs.firstWeekdayInt,
spinnerPosition = 0,
- theme = LightTheme(),
+ theme = LightTheme()
)
view = ScoreChart(targetContext).apply {
setScores(state.scores)
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/StreakChartTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/StreakChartTest.kt
index 58ed5e7d3..ec11b27ed 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/StreakChartTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/StreakChartTest.kt
@@ -30,6 +30,7 @@ import org.junit.runner.RunWith
@MediumTest
class StreakChartTest : BaseViewTest() {
private lateinit var view: StreakChart
+
@Before
override fun setUp() {
super.setUp()
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/EntryButtonViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/EntryButtonViewTest.kt
index f37cc1838..32df08758 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/EntryButtonViewTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/EntryButtonViewTest.kt
@@ -44,7 +44,7 @@ class EntryButtonViewTest : BaseViewTest() {
view = component.getEntryButtonViewFactory().create().apply {
value = Entry.NO
color = PaletteUtils.getAndroidTestColor(5)
- onToggle = { _, _, _ -> toggled = true }
+ onToggle = { _, _ -> toggled = true }
onEdit = { edited = true }
}
measureView(view, dpToPixels(48), dpToPixels(48))
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/EntryPanelViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/EntryPanelViewTest.kt
index f09c48dba..de955deb8 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/EntryPanelViewTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/EntryPanelViewTest.kt
@@ -77,7 +77,7 @@ class EntryPanelViewTest : BaseViewTest() {
@Test
fun testToggle() {
val timestamps = mutableListOf()
- view.onToggle = { t, _, _, _ -> timestamps.add(t) }
+ view.onToggle = { t, _, _ -> timestamps.add(t) }
view.buttons[0].performLongClick()
view.buttons[2].performLongClick()
view.buttons[3].performLongClick()
@@ -88,7 +88,7 @@ class EntryPanelViewTest : BaseViewTest() {
fun testToggle_withOffset() {
val timestamps = mutableListOf()
view.dataOffset = 3
- view.onToggle = { t, _, _, _ -> timestamps += t }
+ view.onToggle = { t, _, _ -> timestamps += t }
view.buttons[0].performLongClick()
view.buttons[2].performLongClick()
view.buttons[3].performLongClick()
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HeaderViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HeaderViewTest.kt
index 6bf7e2a81..3a972a57c 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HeaderViewTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HeaderViewTest.kt
@@ -20,15 +20,15 @@ package org.isoron.uhabits.activities.habits.list.views
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
-import com.nhaarman.mockitokotlin2.doReturn
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.verify
-import com.nhaarman.mockitokotlin2.verifyNoMoreInteractions
-import com.nhaarman.mockitokotlin2.whenever
import org.isoron.uhabits.BaseViewTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.verifyNoMoreInteractions
+import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
@MediumTest
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HintViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HintViewTest.kt
index af1f30df8..f065d8c37 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HintViewTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HintViewTest.kt
@@ -20,9 +20,6 @@ package org.isoron.uhabits.activities.habits.list.views
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
-import com.nhaarman.mockitokotlin2.doReturn
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.whenever
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat
import org.isoron.uhabits.BaseViewTest
@@ -30,6 +27,9 @@ import org.isoron.uhabits.core.ui.screens.habits.list.HintList
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
@MediumTest
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/FrequencyCardViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/FrequencyCardViewTest.kt
index c26b55775..66cc0a7d9 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/FrequencyCardViewTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/FrequencyCardViewTest.kt
@@ -48,7 +48,7 @@ class FrequencyCardViewTest : BaseViewTest() {
FrequencyCardPresenter.buildState(
habit = habit,
firstWeekday = 0,
- theme = LightTheme(),
+ theme = LightTheme()
)
)
measureView(view, 800f, 600f)
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardViewTest.kt
index 71fe4e751..249f56972 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardViewTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardViewTest.kt
@@ -49,7 +49,7 @@ class HistoryCardViewTest : BaseViewTest() {
HistoryCardPresenter.buildState(
habit = habit,
firstWeekday = SUNDAY,
- theme = LightTheme(),
+ theme = LightTheme()
)
)
measureView(view, 800f, 600f)
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/OverviewCardViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/OverviewCardViewTest.kt
index 9a5fc81d3..1018978f2 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/OverviewCardViewTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/OverviewCardViewTest.kt
@@ -51,7 +51,7 @@ class OverviewCardViewTest : BaseViewTest() {
scoreYearDiff = 0.74f,
totalCount = 44,
color = PaletteColor(7),
- theme = LightTheme(),
+ theme = LightTheme()
)
)
measureView(view, 800f, 300f)
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/ScoreCardViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/ScoreCardViewTest.kt
index 8bd2bc520..85f66add2 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/ScoreCardViewTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/ScoreCardViewTest.kt
@@ -49,7 +49,7 @@ class ScoreCardViewTest : BaseViewTest() {
habit = habit,
firstWeekday = 0,
spinnerPosition = 0,
- theme = LightTheme(),
+ theme = LightTheme()
)
)
measureView(view, 800f, 600f)
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/StreakCardViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/StreakCardViewTest.kt
index 2c70e3b92..14d5c3d27 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/StreakCardViewTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/StreakCardViewTest.kt
@@ -48,7 +48,7 @@ class StreakCardViewTest : BaseViewTest() {
StreakCardState(
bestStreaks = habit.streaks.getBest(10),
color = habit.color,
- theme = LightTheme(),
+ theme = LightTheme()
)
)
measureView(view, 800f, 600f)
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardViewTest.kt
index 3323f78df..642517827 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardViewTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardViewTest.kt
@@ -53,7 +53,7 @@ class SubtitleCardViewTest : BaseViewTest() {
isNumerical = false,
question = "Did you meditate this morning?",
reminder = Reminder(8, 30, EVERY_DAY),
- theme = LightTheme(),
+ theme = LightTheme()
)
)
measureView(view, 800f, 200f)
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/regression/ListHabitsRegressionTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/regression/ListHabitsRegressionTest.kt
index 551c76c17..d514fdbfb 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/regression/ListHabitsRegressionTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/regression/ListHabitsRegressionTest.kt
@@ -119,7 +119,7 @@ class ListHabitsRegressionTest : BaseUserInterfaceTest() {
"Wake up early",
"Meditate",
"Read books",
- "Track time",
+ "Track time"
)
}
}
diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/widgets/views/CheckmarkWidgetViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/widgets/views/CheckmarkWidgetViewTest.kt
index f3a842f04..628a2ebbf 100644
--- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/widgets/views/CheckmarkWidgetViewTest.kt
+++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/widgets/views/CheckmarkWidgetViewTest.kt
@@ -33,9 +33,11 @@ import java.io.IOException
@MediumTest
class CheckmarkWidgetViewTest : BaseViewTest() {
private lateinit var view: CheckmarkWidgetView
+
@Before
override fun setUp() {
super.setUp()
+ similarityCutoff = 0.00025
setTheme(R.style.WidgetTheme)
val habit = fixtures.createShortHabit()
val computedEntries = habit.computedEntries
diff --git a/uhabits-android/src/main/AndroidManifest.xml b/uhabits-android/src/main/AndroidManifest.xml
index e1809301c..9377e42c0 100644
--- a/uhabits-android/src/main/AndroidManifest.xml
+++ b/uhabits-android/src/main/AndroidManifest.xml
@@ -19,7 +19,6 @@
-
diff --git a/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidCanvas.kt b/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidCanvas.kt
index ae1d1f52f..36d79596e 100644
--- a/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidCanvas.kt
+++ b/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidCanvas.kt
@@ -60,7 +60,7 @@ class AndroidCanvas : Canvas {
y1.toDp(),
x2.toDp(),
y2.toDp(),
- paint,
+ paint
)
}
@@ -69,7 +69,7 @@ class AndroidCanvas : Canvas {
text,
x.toDp(),
y.toDp() + 0.6f * mHeight,
- textPaint,
+ textPaint
)
}
@@ -83,7 +83,7 @@ class AndroidCanvas : Canvas {
y: Double,
width: Double,
height: Double,
- cornerRadius: Double,
+ cornerRadius: Double
) {
paint.style = Paint.Style.FILL
innerCanvas.drawRoundRect(
@@ -93,7 +93,7 @@ class AndroidCanvas : Canvas {
(y + height).toDp(),
cornerRadius.toDp(),
cornerRadius.toDp(),
- paint,
+ paint
)
}
@@ -108,7 +108,7 @@ class AndroidCanvas : Canvas {
y.toDp(),
(x + width).toDp(),
(y + height).toDp(),
- paint,
+ paint
)
}
@@ -148,7 +148,7 @@ class AndroidCanvas : Canvas {
centerY: Double,
radius: Double,
startAngle: Double,
- swipeAngle: Double,
+ swipeAngle: Double
) {
paint.style = Paint.Style.FILL
innerCanvas.drawArc(
@@ -159,14 +159,14 @@ class AndroidCanvas : Canvas {
-startAngle.toFloat(),
-swipeAngle.toFloat(),
true,
- paint,
+ paint
)
}
override fun fillCircle(
centerX: Double,
centerY: Double,
- radius: Double,
+ radius: Double
) {
paint.style = Paint.Style.FILL
innerCanvas.drawCircle(centerX.toDp(), centerY.toDp(), radius.toDp(), paint)
diff --git a/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidDataView.kt b/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidDataView.kt
index 0a8c5ee68..990314a06 100644
--- a/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidDataView.kt
+++ b/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidDataView.kt
@@ -33,7 +33,7 @@ import kotlin.math.max
*/
class AndroidDataView(
context: Context,
- attrs: AttributeSet? = null,
+ attrs: AttributeSet? = null
) : AndroidView(context, attrs),
GestureDetector.OnGestureListener,
ValueAnimator.AnimatorUpdateListener {
@@ -60,7 +60,7 @@ class AndroidDataView(
e1: MotionEvent?,
e2: MotionEvent?,
dx: Float,
- dy: Float,
+ dy: Float
): Boolean {
if (abs(dx) > abs(dy)) {
val parent = parent
@@ -82,7 +82,7 @@ class AndroidDataView(
e1: MotionEvent?,
e2: MotionEvent?,
velocityX: Float,
- velocityY: Float,
+ velocityY: Float
): Boolean {
scroller.fling(
scroller.currX,
@@ -140,8 +140,11 @@ class AndroidDataView(
// e.getPointerId.
return false
}
- if (isSingleTap) view?.onClick(x / canvas.innerDensity, y / canvas.innerDensity)
- else view?.onLongClick(x / canvas.innerDensity, y / canvas.innerDensity)
+ if (isSingleTap) {
+ view?.onClick(x / canvas.innerDensity, y / canvas.innerDensity)
+ } else {
+ view?.onLongClick(x / canvas.innerDensity, y / canvas.innerDensity)
+ }
return true
}
}
diff --git a/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidImage.kt b/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidImage.kt
index 0b313f9a4..b382c220c 100644
--- a/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidImage.kt
+++ b/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidImage.kt
@@ -47,6 +47,6 @@ fun Color.toInt(): Int {
(255 * this.alpha).roundToInt(),
(255 * this.red).roundToInt(),
(255 * this.green).roundToInt(),
- (255 * this.blue).roundToInt(),
+ (255 * this.blue).roundToInt()
)
}
diff --git a/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidView.kt b/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidView.kt
index 4fd22541c..139989178 100644
--- a/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidView.kt
+++ b/uhabits-android/src/main/java/org/isoron/platform/gui/AndroidView.kt
@@ -24,7 +24,7 @@ import android.util.AttributeSet
open class AndroidView(
context: Context,
- attrs: AttributeSet? = null,
+ attrs: AttributeSet? = null
) : android.view.View(context, attrs) {
var view: T? = null
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/AndroidThemeSwitcher.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/AndroidThemeSwitcher.kt
index be9d0eb02..c47eb968d 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/AndroidThemeSwitcher.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/AndroidThemeSwitcher.kt
@@ -39,7 +39,7 @@ import org.isoron.uhabits.inject.ActivityScope
class AndroidThemeSwitcher
constructor(
@ActivityContext val context: Context,
- preferences: Preferences,
+ preferences: Preferences
) : ThemeSwitcher(preferences) {
override var currentTheme: Theme = LightTheme()
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/about/AboutScreen.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/about/AboutScreen.kt
index 8909431b2..04fa715fd 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/about/AboutScreen.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/about/AboutScreen.kt
@@ -27,7 +27,7 @@ import org.isoron.uhabits.utils.startActivitySafely
class AboutScreen(
private val activity: AboutActivity,
private val intents: IntentFactory,
- private val prefs: Preferences,
+ private val prefs: Preferences
) {
private var developerCountdown = 5
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/about/AboutView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/about/AboutView.kt
index 5eeb67f19..bc52f6fc0 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/about/AboutView.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/about/AboutView.kt
@@ -32,7 +32,7 @@ import org.isoron.uhabits.utils.setupToolbar
@SuppressLint("ViewConstructor")
class AboutView(
context: Context,
- private val screen: AboutScreen,
+ private val screen: AboutScreen
) : FrameLayout(context) {
private var binding = AboutBinding.inflate(LayoutInflater.from(context))
@@ -43,7 +43,7 @@ class AboutView(
toolbar = binding.toolbar,
color = PaletteColor(11),
title = resources.getString(R.string.about),
- theme = currentTheme(),
+ theme = currentTheme()
)
val version = resources.getString(R.string.version_n)
binding.tvContributors.setOnClickListener { screen.showCodeContributorsWebsite() }
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/CheckmarkPopup.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/CheckmarkDialog.kt
similarity index 54%
rename from uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/CheckmarkPopup.kt
rename to uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/CheckmarkDialog.kt
index fb7f43d51..5df8ffd7b 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/CheckmarkPopup.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/CheckmarkDialog.kt
@@ -20,109 +20,60 @@
package org.isoron.uhabits.activities.common.dialogs
import android.app.Dialog
-import android.content.Context
+import android.os.Bundle
import android.view.LayoutInflater
-import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
+import androidx.appcompat.app.AppCompatDialogFragment
+import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.Entry.Companion.NO
import org.isoron.uhabits.core.models.Entry.Companion.SKIP
import org.isoron.uhabits.core.models.Entry.Companion.UNKNOWN
-import org.isoron.uhabits.core.models.Entry.Companion.YES_AUTO
import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL
-import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.databinding.CheckmarkPopupBinding
import org.isoron.uhabits.utils.InterfaceUtils.getFontAwesome
-import org.isoron.uhabits.utils.dimBehind
-import org.isoron.uhabits.utils.dismissCurrentAndShow
-import org.isoron.uhabits.utils.dp
import org.isoron.uhabits.utils.sres
-const val POPUP_WIDTH = 4 * 48f + 16f
-const val POPUP_HEIGHT = 48f * 2.5f + 8f
-
-class CheckmarkPopup(
- private val context: Context,
- private val color: Int,
- private var notes: String,
- private var value: Int,
- private val prefs: Preferences,
- private val anchor: View,
-) {
+class CheckmarkDialog : AppCompatDialogFragment() {
var onToggle: (Int, String) -> Unit = { _, _ -> }
- private lateinit var dialog: Dialog
-
- private val view = CheckmarkPopupBinding.inflate(LayoutInflater.from(context)).apply {
- // Required for round corners
- container.clipToOutline = true
- }
- init {
- view.booleanButtons.visibility = VISIBLE
- initColors()
- initTypefaces()
- hideDisabledButtons()
- populate()
- }
-
- private fun initColors() {
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val appComponent = (requireActivity().application as HabitsApplication).component
+ val prefs = appComponent.preferences
+ val view = CheckmarkPopupBinding.inflate(LayoutInflater.from(context))
arrayOf(view.yesBtn, view.skipBtn).forEach {
- it.setTextColor(color)
+ it.setTextColor(requireArguments().getInt("color"))
}
arrayOf(view.noBtn, view.unknownBtn).forEach {
it.setTextColor(view.root.sres.getColor(R.attr.contrast60))
}
- }
-
- private fun initTypefaces() {
arrayOf(view.yesBtn, view.noBtn, view.skipBtn, view.unknownBtn).forEach {
- it.typeface = getFontAwesome(context)
+ it.typeface = getFontAwesome(requireContext())
}
- }
-
- private fun hideDisabledButtons() {
+ view.notes.setText(requireArguments().getString("notes")!!)
if (!prefs.isSkipEnabled) view.skipBtn.visibility = GONE
if (!prefs.areQuestionMarksEnabled) view.unknownBtn.visibility = GONE
- }
-
- private fun populate() {
- val selectedBtn = when (value) {
- YES_MANUAL -> view.yesBtn
- YES_AUTO -> view.noBtn
- NO -> view.noBtn
- UNKNOWN -> if (prefs.areQuestionMarksEnabled) view.unknownBtn else view.noBtn
- SKIP -> if (prefs.isSkipEnabled) view.skipBtn else view.noBtn
- else -> null
- }
- view.notes.setText(notes)
- }
-
- fun show() {
- dialog = Dialog(context, android.R.style.Theme_NoTitleBar)
+ view.booleanButtons.visibility = VISIBLE
+ val dialog = Dialog(requireContext())
dialog.setContentView(view.root)
dialog.window?.apply {
- setLayout(
- view.root.dp(POPUP_WIDTH).toInt(),
- view.root.dp(POPUP_HEIGHT).toInt()
- )
setBackgroundDrawableResource(android.R.color.transparent)
}
fun onClick(v: Int) {
- this.value = v
- save()
+ val notes = view.notes.text.toString().trim()
+ onToggle(v, notes)
+ requireDialog().dismiss()
}
view.yesBtn.setOnClickListener { onClick(YES_MANUAL) }
view.noBtn.setOnClickListener { onClick(NO) }
view.skipBtn.setOnClickListener { onClick(SKIP) }
view.unknownBtn.setOnClickListener { onClick(UNKNOWN) }
- dialog.setCanceledOnTouchOutside(true)
- dialog.dimBehind()
- dialog.dismissCurrentAndShow()
- }
+ view.notes.setOnEditorActionListener { v, actionId, event ->
+ onClick(requireArguments().getInt("value"))
+ true
+ }
- fun save() {
- onToggle(value, view.notes.text.toString().trim())
- dialog.dismiss()
+ return dialog
}
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/FrequencyPickerDialog.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/FrequencyPickerDialog.kt
index 5173aa6f9..6c1a941eb 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/FrequencyPickerDialog.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/FrequencyPickerDialog.kt
@@ -48,22 +48,22 @@ class FrequencyPickerDialog(
addBeforeAfterText(
this.getString(R.string.every_x_days),
- contentView.everyXDaysContainer,
+ contentView.everyXDaysContainer
)
addBeforeAfterText(
this.getString(R.string.x_times_per_week),
- contentView.xTimesPerWeekContainer,
+ contentView.xTimesPerWeekContainer
)
addBeforeAfterText(
this.getString(R.string.x_times_per_month),
- contentView.xTimesPerMonthContainer,
+ contentView.xTimesPerMonthContainer
)
addBeforeAfterText(
this.getString(R.string.x_times_per_y_days),
- contentView.xTimesPerYDaysContainer,
+ contentView.xTimesPerYDaysContainer
)
contentView.everyDayRadioButton.setOnClickListener {
@@ -124,7 +124,8 @@ class FrequencyPickerDialog(
val parts = str.split("%d")
for (i in parts.indices) {
container.addView(
- TextView(activity).apply { text = parts[i].trim() }, 2 * i + 1,
+ TextView(activity).apply { text = parts[i].trim() },
+ 2 * i + 1
)
}
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/HistoryEditorDialog.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/HistoryEditorDialog.kt
index 27898e87f..02796eca4 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/HistoryEditorDialog.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/HistoryEditorDialog.kt
@@ -69,7 +69,7 @@ class HistoryEditorDialog : AppCompatDialogFragment(), CommandRunner.Listener {
theme = themeSwitcher.currentTheme,
today = DateUtils.getTodayWithOffset().toLocalDate(),
onDateClickedListener = onDateClickedListener ?: object : OnDateClickedListener {},
- padding = 10.0,
+ padding = 10.0
)
dataView = AndroidDataView(requireContext(), null)
dataView.view = chart!!
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberDialog.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberDialog.kt
new file mode 100644
index 000000000..7e10baa51
--- /dev/null
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberDialog.kt
@@ -0,0 +1,104 @@
+package org.isoron.uhabits.activities.common.dialogs
+
+import android.app.Dialog
+import android.os.Bundle
+import android.text.method.DigitsKeyListener
+import android.view.KeyEvent
+import android.view.LayoutInflater
+import android.view.MotionEvent
+import android.view.View
+import androidx.appcompat.app.AppCompatDialogFragment
+import org.isoron.uhabits.HabitsApplication
+import org.isoron.uhabits.R
+import org.isoron.uhabits.core.models.Entry
+import org.isoron.uhabits.databinding.CheckmarkPopupBinding
+import org.isoron.uhabits.utils.InterfaceUtils
+import org.isoron.uhabits.utils.requestFocusWithKeyboard
+import org.isoron.uhabits.utils.sres
+import java.text.DecimalFormat
+import java.text.DecimalFormatSymbols
+import java.text.NumberFormat
+import java.text.ParseException
+
+class NumberDialog : AppCompatDialogFragment() {
+
+ var onToggle: (Double, String) -> Unit = { _, _ -> }
+ var onDismiss: () -> Unit = {}
+
+ private var originalNotes: String = ""
+ private var originalValue: Double = 0.0
+ private lateinit var view: CheckmarkPopupBinding
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val appComponent = (requireActivity().application as HabitsApplication).component
+ val prefs = appComponent.preferences
+ view = CheckmarkPopupBinding.inflate(LayoutInflater.from(context))
+ arrayOf(view.yesBtn, view.skipBtn).forEach {
+ it.setTextColor(requireArguments().getInt("color"))
+ }
+ arrayOf(view.noBtn, view.unknownBtn).forEach {
+ it.setTextColor(view.root.sres.getColor(R.attr.contrast60))
+ }
+ arrayOf(view.yesBtn, view.noBtn, view.skipBtn, view.unknownBtn).forEach {
+ it.typeface = InterfaceUtils.getFontAwesome(requireContext())
+ }
+ if (!prefs.isSkipEnabled) view.skipBtnNumber.visibility = View.GONE
+ view.numberButtons.visibility = View.VISIBLE
+ fixDecimalSeparator(view)
+ originalNotes = requireArguments().getString("notes")!!
+ originalValue = requireArguments().getDouble("value")
+ view.notes.setText(originalNotes)
+ view.value.setText(
+ when {
+ originalValue < 0.01 -> "0"
+ else -> DecimalFormat("#.##").format(originalValue)
+ }
+ )
+ view.value.setOnKeyListener { _, keyCode, event ->
+ if (event.action == MotionEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER) {
+ save()
+ return@setOnKeyListener true
+ }
+ return@setOnKeyListener false
+ }
+ view.saveBtn.setOnClickListener {
+ save()
+ }
+ view.skipBtnNumber.setOnClickListener {
+ view.value.setText((Entry.SKIP.toDouble() / 1000).toString())
+ save()
+ }
+ view.notes.setOnEditorActionListener { v, actionId, event ->
+ save()
+ true
+ }
+ view.value.requestFocusWithKeyboard()
+ val dialog = Dialog(requireContext())
+ dialog.setContentView(view.root)
+ dialog.window?.apply {
+ setBackgroundDrawableResource(android.R.color.transparent)
+ }
+ dialog.setOnDismissListener { onDismiss() }
+ return dialog
+ }
+
+ private fun fixDecimalSeparator(view: CheckmarkPopupBinding) {
+ // https://stackoverflow.com/a/34256139
+ val separator = DecimalFormatSymbols.getInstance().decimalSeparator
+ view.value.keyListener = DigitsKeyListener.getInstance("0123456789$separator")
+ }
+
+ fun save() {
+ var value = originalValue
+ try {
+ val numberFormat = NumberFormat.getInstance()
+ val valueStr = view.value.text.toString()
+ value = numberFormat.parse(valueStr)!!.toDouble()
+ } catch (e: ParseException) {
+ // NOP
+ }
+ val notes = view.notes.text.toString()
+ onToggle(value, notes)
+ requireDialog().dismiss()
+ }
+}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberPopup.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberPopup.kt
deleted file mode 100644
index c3a464311..000000000
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberPopup.kt
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2016-2021 Álinson Santos Xavier
- *
- * This file is part of Loop Habit Tracker.
- *
- * Loop Habit Tracker is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
- *
- * Loop Habit Tracker is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see .
- */
-
-package org.isoron.uhabits.activities.common.dialogs
-
-import android.app.Dialog
-import android.content.Context
-import android.view.KeyEvent.KEYCODE_ENTER
-import android.view.LayoutInflater
-import android.view.MotionEvent.ACTION_DOWN
-import android.view.View
-import android.view.View.GONE
-import android.view.View.VISIBLE
-import org.isoron.uhabits.core.models.Entry
-import org.isoron.uhabits.core.preferences.Preferences
-import org.isoron.uhabits.databinding.CheckmarkPopupBinding
-import org.isoron.uhabits.utils.dimBehind
-import org.isoron.uhabits.utils.dismissCurrentAndShow
-import org.isoron.uhabits.utils.dp
-import org.isoron.uhabits.utils.requestFocusWithKeyboard
-import java.text.DecimalFormat
-
-class NumberPopup(
- private val context: Context,
- private var notes: String,
- private var value: Double,
- private val prefs: Preferences,
- private val anchor: View,
-) {
- var onToggle: (Double, String) -> Unit = { _, _ -> }
- var onDismiss: () -> Unit = {}
- private val originalValue = value
- private lateinit var dialog: Dialog
-
- private val view = CheckmarkPopupBinding.inflate(LayoutInflater.from(context)).apply {
- // Required for round corners
- container.clipToOutline = true
- }
-
- init {
- view.numberButtons.visibility = VISIBLE
- hideDisabledButtons()
- populate()
- }
-
- private fun hideDisabledButtons() {
- if (!prefs.isSkipEnabled) view.skipBtnNumber.visibility = GONE
- }
-
- private fun populate() {
- view.notes.setText(notes)
- view.value.setText(
- when {
- value < 0.01 -> "0"
- else -> DecimalFormat("#.##").format(value)
- }
- )
- }
-
- fun show() {
- dialog = Dialog(context, android.R.style.Theme_NoTitleBar)
- dialog.setContentView(view.root)
- dialog.window?.apply {
- setLayout(
- view.root.dp(POPUP_WIDTH).toInt(),
- view.root.dp(POPUP_HEIGHT).toInt()
- )
- setBackgroundDrawableResource(android.R.color.transparent)
- }
- dialog.setOnDismissListener {
- onDismiss()
- }
-
- view.value.setOnKeyListener { _, keyCode, event ->
- if (event.action == ACTION_DOWN && keyCode == KEYCODE_ENTER) {
- save()
- return@setOnKeyListener true
- }
- return@setOnKeyListener false
- }
- view.saveBtn.setOnClickListener {
- save()
- }
- view.skipBtnNumber.setOnClickListener {
- view.value.setText((Entry.SKIP.toDouble() / 1000).toString())
- save()
- }
- view.value.requestFocusWithKeyboard()
- dialog.setCanceledOnTouchOutside(true)
- dialog.dimBehind()
- dialog.dismissCurrentAndShow()
- }
-
- fun save() {
- val value = view.value.text.toString().toDoubleOrNull() ?: originalValue
- val notes = view.notes.text.toString()
- onToggle(value, notes)
- dialog.dismiss()
- }
-}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/FrequencyChart.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/FrequencyChart.kt
index 41c67ff27..10aeaf29b 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/FrequencyChart.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/FrequencyChart.kt
@@ -181,8 +181,9 @@ class FrequencyChart : ScrollableChart {
rect[0f, 0f, baseSize.toFloat()] = baseSize.toFloat()
rect.offset(prevRect!!.left, prevRect!!.top + baseSize * j)
val i = localeWeekdayList[j] % 7
- if (values != null)
+ if (values != null) {
drawMarker(canvas, rect, values[i], weekDaysInMonth[i])
+ }
rect.offset(0f, rowHeight)
}
drawFooter(canvas, rect, date)
@@ -196,12 +197,14 @@ class FrequencyChart : ScrollableChart {
rect.centerY() - 0.1f * em,
pText!!
)
- if (date[Calendar.MONTH] == 1) canvas.drawText(
- dfYear!!.format(time),
- rect.centerX(),
- rect.centerY() + 0.9f * em,
- pText!!
- )
+ if (date[Calendar.MONTH] == 1) {
+ canvas.drawText(
+ dfYear!!.format(time),
+ rect.centerX(),
+ rect.centerY() + 0.9f * em,
+ pText!!
+ )
+ }
}
private fun drawGrid(canvas: Canvas, rGrid: RectF?) {
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/RingView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/RingView.kt
index 4a3b10679..870097800 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/RingView.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/RingView.kt
@@ -148,8 +148,12 @@ class RingView : View {
pRing!!.color = inactiveColor!!
activeCanvas.drawArc(rect!!, angle - 90, 360 - angle, true, pRing!!)
if (thickness > 0) {
- if (isTransparencyEnabled) pRing!!.xfermode = XFERMODE_CLEAR else pRing!!.color =
- backgroundColor!!
+ if (isTransparencyEnabled) {
+ pRing!!.xfermode = XFERMODE_CLEAR
+ } else {
+ pRing!!.color =
+ backgroundColor!!
+ }
rect!!.inset(thickness, thickness)
activeCanvas.drawArc(rect!!, 0f, 360f, true, pRing!!)
pRing!!.xfermode = null
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsActivity.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsActivity.kt
index e14bdefd5..b7ca3235f 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsActivity.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsActivity.kt
@@ -40,6 +40,7 @@ import org.isoron.uhabits.inject.ActivityContextModule
import org.isoron.uhabits.inject.DaggerHabitsActivityComponent
import org.isoron.uhabits.inject.HabitsActivityComponent
import org.isoron.uhabits.inject.HabitsApplicationComponent
+import org.isoron.uhabits.utils.dismissCurrentDialog
import org.isoron.uhabits.utils.restartWithFade
class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
@@ -91,6 +92,7 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
midnightTimer.onPause()
screen.onDetached()
adapter.cancelRefresh()
+ dismissCurrentDialog()
super.onPause()
}
@@ -99,6 +101,7 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
screen.onAttached()
rootView.postInvalidate()
midnightTimer.onResume()
+ appComponent.reminderScheduler.scheduleAll()
taskRunner.run {
try {
AutoBackup(this@ListHabitsActivity).run()
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsRootView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsRootView.kt
index faa13173a..62fe3f00c 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsRootView.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsRootView.kt
@@ -94,7 +94,7 @@ class ListHabitsRootView @Inject constructor(
title = resources.getString(R.string.main_activity_title),
color = PaletteColor(17),
displayHomeAsUpEnabled = false,
- theme = currentTheme(),
+ theme = currentTheme()
)
addView(rootView, MATCH_PARENT, MATCH_PARENT)
listAdapter.setListView(listView)
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsScreen.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsScreen.kt
index 731342974..c525e624a 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsScreen.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsScreen.kt
@@ -22,14 +22,15 @@ package org.isoron.uhabits.activities.habits.list
import android.app.Activity
import android.content.Context
import android.content.Intent
+import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import dagger.Lazy
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.R
-import org.isoron.uhabits.activities.common.dialogs.CheckmarkPopup
+import org.isoron.uhabits.activities.common.dialogs.CheckmarkDialog
import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialogFactory
import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog
-import org.isoron.uhabits.activities.common.dialogs.NumberPopup
+import org.isoron.uhabits.activities.common.dialogs.NumberDialog
import org.isoron.uhabits.activities.habits.edit.HabitTypeDialog
import org.isoron.uhabits.activities.habits.list.views.HabitCardListAdapter
import org.isoron.uhabits.core.commands.ArchiveHabitsCommand
@@ -95,7 +96,7 @@ class ListHabitsScreen
private val colorPickerFactory: ColorPickerDialogFactory,
private val behavior: Lazy,
private val preferences: Preferences,
- private val rootView: Lazy,
+ private val rootView: Lazy
) : CommandRunner.Listener,
ListHabitsBehavior.Screen,
ListHabitsMenuBehavior.Screen,
@@ -233,17 +234,14 @@ class ListHabitsScreen
notes: String,
callback: ListHabitsBehavior.NumberPickerCallback
) {
- val view = rootView.get()
- NumberPopup(
- context = context,
- prefs = preferences,
- anchor = view,
- notes = notes,
- value = value,
- ).apply {
- onToggle = { value, notes -> callback.onNumberPicked(value, notes) }
- show()
+ val fm = (context as AppCompatActivity).supportFragmentManager
+ val dialog = NumberDialog()
+ dialog.arguments = Bundle().apply {
+ putDouble("value", value)
+ putString("notes", notes)
}
+ dialog.onToggle = { v, n -> callback.onNumberPicked(v, n) }
+ dialog.dismissCurrentAndShow(fm, "numberDialog")
}
override fun showCheckmarkPopup(
@@ -252,18 +250,16 @@ class ListHabitsScreen
color: PaletteColor,
callback: ListHabitsBehavior.CheckMarkDialogCallback
) {
- val view = rootView.get()
- CheckmarkPopup(
- context = context,
- prefs = preferences,
- anchor = view,
- color = view.currentTheme().color(color).toInt(),
- notes = notes,
- value = selectedValue,
- ).apply {
- onToggle = { value, notes -> callback.onNotesSaved(value, notes) }
- show()
+ val theme = rootView.get().currentTheme()
+ val fm = (context as AppCompatActivity).supportFragmentManager
+ val dialog = CheckmarkDialog()
+ dialog.arguments = Bundle().apply {
+ putInt("color", theme.color(color).toInt())
+ putInt("value", selectedValue)
+ putString("notes", notes)
}
+ dialog.onToggle = { v, n -> callback.onNotesSaved(v, n) }
+ dialog.dismissCurrentAndShow(fm, "checkmarkDialog")
}
private fun getExecuteString(command: Command): String? {
@@ -325,8 +321,11 @@ class ListHabitsScreen
private fun onExportDB() {
taskRunner.execute(
exportDBFactory.create { filename ->
- if (filename != null) activity.showSendFileScreen(filename)
- else activity.showMessage(activity.resources.getString(R.string.could_not_export))
+ if (filename != null) {
+ activity.showSendFileScreen(filename)
+ } else {
+ activity.showMessage(activity.resources.getString(R.string.could_not_export))
+ }
}
)
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/ButtonPanelView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/ButtonPanelView.kt
index faf53b298..3218ea754 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/ButtonPanelView.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/ButtonPanelView.kt
@@ -60,8 +60,11 @@ abstract class ButtonPanelView(
repeat(buttonCount) { buttons.add(createButton()) }
removeAllViews()
- if (reverse) buttons.reversed().forEach { addView(it) }
- else buttons.forEach { addView(it) }
+ if (reverse) {
+ buttons.reversed().forEach { addView(it) }
+ } else {
+ buttons.forEach { addView(it) }
+ }
setupButtons()
requestLayout()
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkButtonView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkButtonView.kt
index 176cec62a..3cf77789e 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkButtonView.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkButtonView.kt
@@ -44,8 +44,6 @@ import org.isoron.uhabits.utils.sres
import org.isoron.uhabits.utils.toMeasureSpec
import javax.inject.Inject
-const val TOGGLE_DELAY_MILLIS = 2000L
-
class CheckmarkButtonViewFactory
@Inject constructor(
@ActivityContext val context: Context,
@@ -79,7 +77,7 @@ class CheckmarkButtonView(
invalidate()
}
- var onToggle: (Int, String, Long) -> Unit = { _, _, _ -> }
+ var onToggle: (Int, String) -> Unit = { _, _ -> }
var onEdit: () -> Unit = { }
@@ -90,25 +88,31 @@ class CheckmarkButtonView(
setOnLongClickListener(this)
}
- fun performToggle(delay: Long) {
+ fun performToggle() {
value = Entry.nextToggleValue(
value = value,
isSkipEnabled = preferences.isSkipEnabled,
areQuestionMarksEnabled = preferences.areQuestionMarksEnabled
)
- onToggle(value, notes, delay)
+ onToggle(value, notes)
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
invalidate()
}
override fun onClick(v: View) {
- if (preferences.isShortToggleEnabled) performToggle(TOGGLE_DELAY_MILLIS)
- else onEdit()
+ if (preferences.isShortToggleEnabled) {
+ performToggle()
+ } else {
+ onEdit()
+ }
}
override fun onLongClick(v: View): Boolean {
- if (preferences.isShortToggleEnabled) onEdit()
- else performToggle(TOGGLE_DELAY_MILLIS)
+ if (preferences.isShortToggleEnabled) {
+ onEdit()
+ } else {
+ performToggle()
+ }
return true
}
@@ -142,8 +146,11 @@ class CheckmarkButtonView(
paint.color = when (value) {
YES_MANUAL, YES_AUTO, SKIP -> color
NO -> {
- if (preferences.areQuestionMarksEnabled) mediumContrastColor
- else lowContrastColor
+ if (preferences.areQuestionMarksEnabled) {
+ mediumContrastColor
+ } else {
+ lowContrastColor
+ }
}
else -> lowContrastColor
}
@@ -151,8 +158,11 @@ class CheckmarkButtonView(
SKIP -> R.string.fa_skipped
NO -> R.string.fa_times
UNKNOWN -> {
- if (preferences.areQuestionMarksEnabled) R.string.fa_question
- else R.string.fa_times
+ if (preferences.areQuestionMarksEnabled) {
+ R.string.fa_question
+ } else {
+ R.string.fa_times
+ }
}
else -> R.string.fa_check
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkPanelView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkPanelView.kt
index 35f639691..525dac5ad 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkPanelView.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkPanelView.kt
@@ -60,7 +60,7 @@ class CheckmarkPanelView(
setupButtons()
}
- var onToggle: (Timestamp, Int, String, Long) -> Unit = { _, _, _, _ -> }
+ var onToggle: (Timestamp, Int, String) -> Unit = { _, _, _ -> }
set(value) {
field = value
setupButtons()
@@ -89,7 +89,7 @@ class CheckmarkPanelView(
else -> ""
}
button.color = color
- button.onToggle = { value, notes, delay -> onToggle(timestamp, value, notes, delay) }
+ button.onToggle = { value, notes -> onToggle(timestamp, value, notes) }
button.onEdit = { onEdit(timestamp) }
}
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardListController.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardListController.kt
index 1cb3462f9..a70805139 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardListController.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardListController.kt
@@ -156,10 +156,11 @@ class HabitCardListController @Inject constructor(
}
private fun notifyListener() {
- if (activeMode is SelectionMode)
+ if (activeMode is SelectionMode) {
selectionMenu.get().onSelectionChange()
- else
+ } else {
selectionMenu.get().onSelectionFinish()
+ }
}
}
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt
index 424aae50b..8e5e9d21e 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt
@@ -57,13 +57,6 @@ class HabitCardViewFactory
fun create() = HabitCardView(context, checkmarkPanelFactory, numberPanelFactory, behavior)
}
-data class DelayedToggle(
- var habit: Habit,
- var timestamp: Timestamp,
- var value: Int,
- var notes: String
-)
-
class HabitCardView(
@ActivityContext context: Context,
checkmarkPanelFactory: CheckmarkPanelViewFactory,
@@ -136,7 +129,6 @@ class HabitCardView(
private var scoreRing: RingView
private var currentToggleTaskId = 0
- private var queuedToggles = mutableListOf()
init {
scoreRing = RingView(context).apply {
@@ -160,12 +152,9 @@ class HabitCardView(
}
checkmarkPanel = checkmarkPanelFactory.create().apply {
- onToggle = { timestamp, value, notes, delay ->
- if (delay > 0) triggerRipple(timestamp)
- habit?.let {
- val taskId = queueToggle(it, timestamp, value, notes);
- { runPendingToggles(taskId) }.delay(delay)
- }
+ onToggle = { timestamp, value, notes ->
+ triggerRipple(timestamp)
+ habit?.let { behavior.onToggle(it, timestamp, value, notes) }
}
onEdit = { timestamp ->
triggerRipple(timestamp)
@@ -205,25 +194,6 @@ class HabitCardView(
addView(innerFrame)
}
- @Synchronized
- private fun runPendingToggles(id: Int) {
- if (currentToggleTaskId != id) return
- for ((h, t, v, n) in queuedToggles) behavior.onToggle(h, t, v, n)
- queuedToggles.clear()
- }
-
- @Synchronized
- private fun queueToggle(
- it: Habit,
- timestamp: Timestamp,
- value: Int,
- notes: String,
- ): Int {
- currentToggleTaskId += 1
- queuedToggles.add(DelayedToggle(it, timestamp, value, notes))
- return currentToggleTaskId
- }
-
override fun onModelChange() {
Handler(Looper.getMainLooper()).post {
habit?.let { copyAttributesFrom(it) }
@@ -255,7 +225,6 @@ class HabitCardView(
}
private fun copyAttributesFrom(h: Habit) {
-
fun getActiveColor(habit: Habit): Int {
return when (habit.isArchived) {
true -> sres.getColor(R.attr.contrast60)
@@ -301,7 +270,6 @@ class HabitCardView(
}
private fun updateBackground(isSelected: Boolean) {
-
val background = when (isSelected) {
true -> R.drawable.selected_box
false -> R.drawable.ripple
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HeaderView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HeaderView.kt
index fa81c1c59..c11c1bbba 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HeaderView.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HeaderView.kt
@@ -124,15 +124,20 @@ class HeaderView(
rect.set(0f, 0f, width, height)
rect.offset(canvas.width.toFloat() - dp(3.0f), 0f)
- if (isReversed) rect.offset(-(index + 1) * width, 0f)
- else rect.offset((index - buttonCount) * width, 0f)
-
- if (isRTL()) rect.set(
- canvas.width - rect.right,
- rect.top,
- canvas.width - rect.left,
- rect.bottom
- )
+ if (isReversed) {
+ rect.offset(-(index + 1) * width, 0f)
+ } else {
+ rect.offset((index - buttonCount) * width, 0f)
+ }
+
+ if (isRTL()) {
+ rect.set(
+ canvas.width - rect.right,
+ rect.top,
+ canvas.width - rect.left,
+ rect.bottom
+ )
+ }
val y1 = rect.centerY() - 0.25 * em
val y2 = rect.centerY() + 1.25 * em
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitActivity.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitActivity.kt
index 3ecca1494..21289a0bd 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitActivity.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitActivity.kt
@@ -34,10 +34,10 @@ import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher
import org.isoron.uhabits.activities.HabitsDirFinder
-import org.isoron.uhabits.activities.common.dialogs.CheckmarkPopup
+import org.isoron.uhabits.activities.common.dialogs.CheckmarkDialog
import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog
import org.isoron.uhabits.activities.common.dialogs.HistoryEditorDialog
-import org.isoron.uhabits.activities.common.dialogs.NumberPopup
+import org.isoron.uhabits.activities.common.dialogs.NumberDialog
import org.isoron.uhabits.core.commands.Command
import org.isoron.uhabits.core.commands.CommandRunner
import org.isoron.uhabits.core.models.Habit
@@ -51,6 +51,7 @@ import org.isoron.uhabits.core.ui.views.OnDateClickedListener
import org.isoron.uhabits.intents.IntentFactory
import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.dismissCurrentAndShow
+import org.isoron.uhabits.utils.dismissCurrentDialog
import org.isoron.uhabits.utils.showMessage
import org.isoron.uhabits.utils.showSendFileScreen
import org.isoron.uhabits.widgets.WidgetUpdater
@@ -87,7 +88,7 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
habit = habit,
habitList = habitList,
preferences = preferences,
- screen = screen,
+ screen = screen
)
view = ShowHabitView(this)
@@ -98,13 +99,13 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
habitList = habitList,
screen = screen,
system = HabitsDirFinder(AndroidDirFinder(this)),
- taskRunner = appComponent.taskRunner,
+ taskRunner = appComponent.taskRunner
)
menu = ShowHabitMenu(
activity = this,
presenter = menuPresenter,
- preferences = preferences,
+ preferences = preferences
)
view.setListener(presenter)
@@ -129,6 +130,7 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
}
override fun onPause() {
+ dismissCurrentDialog()
commandRunner.removeListener(this)
super.onPause()
}
@@ -148,7 +150,7 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
ShowHabitPresenter.buildState(
habit = habit,
preferences = preferences,
- theme = themeSwitcher.currentTheme,
+ theme = themeSwitcher.currentTheme
)
)
}
@@ -170,41 +172,32 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
override fun showNumberPopup(
value: Double,
notes: String,
- preferences: Preferences,
callback: ListHabitsBehavior.NumberPickerCallback
) {
- val anchor = getPopupAnchor() ?: return
- NumberPopup(
- context = this@ShowHabitActivity,
- prefs = preferences,
- notes = notes,
- anchor = anchor,
- value = value,
- ).apply {
- onToggle = { v, n -> callback.onNumberPicked(v, n) }
- show()
+ val dialog = NumberDialog()
+ dialog.arguments = Bundle().apply {
+ putDouble("value", value)
+ putString("notes", notes)
}
+ dialog.onToggle = { v, n -> callback.onNumberPicked(v, n) }
+ dialog.dismissCurrentAndShow(supportFragmentManager, "numberDialog")
}
override fun showCheckmarkPopup(
selectedValue: Int,
notes: String,
- preferences: Preferences,
color: PaletteColor,
callback: ListHabitsBehavior.CheckMarkDialogCallback
) {
- val anchor = getPopupAnchor() ?: return
- CheckmarkPopup(
- context = this@ShowHabitActivity,
- prefs = preferences,
- notes = notes,
- color = view.currentTheme().color(color).toInt(),
- anchor = anchor,
- value = selectedValue,
- ).apply {
- onToggle = { v, n -> callback.onNotesSaved(v, n) }
- show()
+ val theme = view.currentTheme()
+ val dialog = CheckmarkDialog()
+ dialog.arguments = Bundle().apply {
+ putInt("color", theme.color(color).toInt())
+ putInt("value", selectedValue)
+ putString("notes", notes)
}
+ dialog.onToggle = { v, n -> callback.onNotesSaved(v, n) }
+ dialog.dismissCurrentAndShow(supportFragmentManager, "checkmarkDialog")
}
private fun getPopupAnchor(): View? {
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitMenu.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitMenu.kt
index 5a4214610..60b079738 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitMenu.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitMenu.kt
@@ -28,7 +28,7 @@ import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitMenuPresenter
class ShowHabitMenu(
val activity: ShowHabitActivity,
val presenter: ShowHabitMenuPresenter,
- val preferences: Preferences,
+ val preferences: Preferences
) {
fun onCreateOptionsMenu(menu: Menu): Boolean {
activity.menuInflater.inflate(R.menu.show_habit, menu)
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitView.kt
index 38fba3baf..cbb85825e 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitView.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitView.kt
@@ -39,7 +39,7 @@ class ShowHabitView(context: Context) : FrameLayout(context) {
binding.toolbar,
title = data.title,
color = data.color,
- theme = data.theme,
+ theme = data.theme
)
binding.subtitleCard.setState(data.subtitle)
binding.overviewCard.setState(data.overview)
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/BarCardView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/BarCardView.kt
index fa3122ed3..980f6c1d1 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/BarCardView.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/BarCardView.kt
@@ -63,7 +63,7 @@ class BarCardView(context: Context, attrs: AttributeSet) : LinearLayout(context,
parent: AdapterView<*>?,
view: View?,
position: Int,
- id: Long,
+ id: Long
) {
presenter.onBoolSpinnerPosition(position)
}
@@ -77,7 +77,7 @@ class BarCardView(context: Context, attrs: AttributeSet) : LinearLayout(context,
parent: AdapterView<*>?,
view: View?,
position: Int,
- id: Long,
+ id: Long
) {
presenter.onNumericalSpinnerPosition(position)
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardView.kt
index 74e566fbb..f576a115a 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardView.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardView.kt
@@ -45,7 +45,7 @@ class HistoryCardView(context: Context, attrs: AttributeSet) : LinearLayout(cont
series = state.series,
defaultSquare = state.defaultSquare,
notesIndicators = state.notesIndicators,
- firstWeekday = state.firstWeekday,
+ firstWeekday = state.firstWeekday
)
binding.chart.postInvalidate()
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardView.kt
index 5bbfb46d6..c29894c18 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardView.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardView.kt
@@ -52,7 +52,7 @@ class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
binding.frequencyLabel.text = formatFrequency(
state.frequency.numerator,
state.frequency.denominator,
- resources,
+ resources
)
binding.questionLabel.setTextColor(color)
binding.questionLabel.text = state.question
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/settings/SettingsActivity.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/settings/SettingsActivity.kt
index 60a12ac17..0d5e25224 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/settings/SettingsActivity.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/settings/SettingsActivity.kt
@@ -40,7 +40,7 @@ class SettingsActivity : AppCompatActivity() {
toolbar = binding.toolbar,
title = resources.getString(R.string.settings),
color = PaletteColor(11),
- theme = themeSwitcher.currentTheme,
+ theme = themeSwitcher.currentTheme
)
setContentView(binding.root)
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/settings/SettingsFragment.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/settings/SettingsFragment.kt
index 28fbd63d8..e67f6a567 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/settings/SettingsFragment.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/settings/SettingsFragment.kt
@@ -22,6 +22,7 @@ import android.app.backup.BackupManager
import android.content.Intent
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
+import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.util.Log
@@ -43,6 +44,7 @@ import org.isoron.uhabits.core.utils.DateUtils.Companion.getLongWeekdayNames
import org.isoron.uhabits.notifications.AndroidNotificationTray.Companion.createAndroidNotificationChannel
import org.isoron.uhabits.notifications.RingtoneManager
import org.isoron.uhabits.utils.StyledResources
+import org.isoron.uhabits.utils.startActivitySafely
import org.isoron.uhabits.widgets.WidgetUpdater
import java.util.Calendar
@@ -92,16 +94,24 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
override fun onPreferenceTreeClick(preference: Preference): Boolean {
val key = preference.key ?: return false
- if (key == "reminderSound") {
- showRingtonePicker()
- return true
- } else if (key == "reminderCustomize") {
- createAndroidNotificationChannel(requireContext())
- val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
- intent.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
- intent.putExtra(Settings.EXTRA_CHANNEL_ID, NotificationTray.REMINDERS_CHANNEL_ID)
- startActivity(intent)
- return true
+ when (key) {
+ "reminderSound" -> {
+ showRingtonePicker()
+ return true
+ }
+ "reminderCustomize" -> {
+ createAndroidNotificationChannel(requireContext())
+ val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
+ intent.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
+ intent.putExtra(Settings.EXTRA_CHANNEL_ID, NotificationTray.REMINDERS_CHANNEL_ID)
+ startActivity(intent)
+ return true
+ }
+ "rateApp" -> {
+ val intent = Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.playStoreURL)))
+ activity?.startActivitySafely(intent)
+ return true
+ }
}
return super.onPreferenceTreeClick(preference)
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/automation/EditSettingActivity.kt b/uhabits-android/src/main/java/org/isoron/uhabits/automation/EditSettingActivity.kt
index 6361397ef..55468cfda 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/automation/EditSettingActivity.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/automation/EditSettingActivity.kt
@@ -32,7 +32,7 @@ class EditSettingActivity : AppCompatActivity() {
val habits = app.component.habitList.getFiltered(
HabitMatcher(
isArchivedAllowed = false,
- isCompletedAllowed = true,
+ isCompletedAllowed = true
)
)
AndroidThemeSwitcher(this, app.component.preferences).apply()
@@ -43,7 +43,7 @@ class EditSettingActivity : AppCompatActivity() {
context = this,
habitList = app.component.habitList,
onSave = controller::onSave,
- args = args,
+ args = args
)
setContentView(view)
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/automation/EditSettingRootView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/automation/EditSettingRootView.kt
index 30c13c95d..91aaccce9 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/automation/EditSettingRootView.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/automation/EditSettingRootView.kt
@@ -54,7 +54,7 @@ class EditSettingRootView(
title = resources.getString(R.string.app_name),
color = PaletteColor(11),
displayHomeAsUpEnabled = false,
- theme = currentTheme(),
+ theme = currentTheme()
)
populateHabitSpinner()
binding.habitSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
@@ -69,7 +69,7 @@ class EditSettingRootView(
val habit = habitList.getByPosition(binding.habitSpinner.selectedItemPosition)
val action = mapSpinnerPositionToAction(
isNumerical = habit.isNumerical,
- itemPosition = binding.actionSpinner.selectedItemPosition,
+ itemPosition = binding.actionSpinner.selectedItemPosition
)
onSave(habit, action)
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidCursor.kt b/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidCursor.kt
index cb0b9f894..ed2ee19a7 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidCursor.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidCursor.kt
@@ -27,22 +27,34 @@ class AndroidCursor(private val cursor: android.database.Cursor) : Cursor {
override fun moveToNext() = cursor.moveToNext()
override fun getInt(index: Int): Int? {
- return if (cursor.isNull(index)) null
- else cursor.getInt(index)
+ return if (cursor.isNull(index)) {
+ null
+ } else {
+ cursor.getInt(index)
+ }
}
override fun getLong(index: Int): Long? {
- return if (cursor.isNull(index)) null
- else cursor.getLong(index)
+ return if (cursor.isNull(index)) {
+ null
+ } else {
+ cursor.getLong(index)
+ }
}
override fun getDouble(index: Int): Double? {
- return if (cursor.isNull(index)) null
- else cursor.getDouble(index)
+ return if (cursor.isNull(index)) {
+ null
+ } else {
+ cursor.getDouble(index)
+ }
}
override fun getString(index: Int): String? {
- return if (cursor.isNull(index)) null
- else cursor.getString(index)
+ return if (cursor.isNull(index)) {
+ null
+ } else {
+ cursor.getString(index)
+ }
}
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidDatabase.kt b/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidDatabase.kt
index d764e7a63..3c8214d7a 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidDatabase.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidDatabase.kt
@@ -26,7 +26,7 @@ import java.io.File
class AndroidDatabase(
private val db: SQLiteDatabase,
- override val file: File?,
+ override val file: File?
) : Database {
override fun beginTransaction() = db.beginTransaction()
@@ -45,7 +45,7 @@ class AndroidDatabase(
tableName: String,
values: Map,
where: String,
- vararg params: String,
+ vararg params: String
): Int {
val contValues = mapToContentValues(values)
return db.update(tableName, contValues, where, params)
@@ -59,7 +59,7 @@ class AndroidDatabase(
override fun delete(
tableName: String,
where: String,
- vararg params: String,
+ vararg params: String
) {
db.delete(tableName, where, params)
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidDatabaseOpener.kt b/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidDatabaseOpener.kt
index 923ae1bf7..96d010aca 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidDatabaseOpener.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidDatabaseOpener.kt
@@ -30,7 +30,7 @@ class AndroidDatabaseOpener @Inject constructor() : DatabaseOpener {
db = SQLiteDatabase.openDatabase(
file.absolutePath,
null,
- SQLiteDatabase.OPEN_READWRITE,
+ SQLiteDatabase.OPEN_READWRITE
),
file = file
)
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/inject/ActivityContextModule.kt b/uhabits-android/src/main/java/org/isoron/uhabits/inject/ActivityContextModule.kt
index 89efc00af..29027d9e2 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/inject/ActivityContextModule.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/inject/ActivityContextModule.kt
@@ -25,5 +25,6 @@ import dagger.Provides
@Module
class ActivityContextModule(
@get:Provides
- @get:ActivityContext val context: Context
+ @get:ActivityContext
+ val context: Context
)
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/inject/AppContextModule.kt b/uhabits-android/src/main/java/org/isoron/uhabits/inject/AppContextModule.kt
index 74b433ea2..e7cc78f49 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/inject/AppContextModule.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/inject/AppContextModule.kt
@@ -26,5 +26,6 @@ import dagger.Provides
class AppContextModule(
@get:Provides
@get:AppContext
- @param:AppContext val context: Context
+ @param:AppContext
+ val context: Context
)
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentParser.kt b/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentParser.kt
index 6be35b4c9..c3981baf2 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentParser.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentParser.kt
@@ -53,8 +53,9 @@ class IntentParser
var timestamp = intent.getLongExtra("timestamp", today)
timestamp = DateUtils.getStartOfDay(timestamp)
- if (timestamp < 0 || timestamp > today)
+ if (timestamp < 0 || timestamp > today) {
throw IllegalArgumentException("timestamp is not valid")
+ }
return Timestamp(timestamp)
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.kt b/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.kt
index 09d8f8b46..a63982358 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.kt
@@ -96,7 +96,6 @@ class AndroidNotificationTray
timestamp: Timestamp,
disableSound: Boolean = false
): Notification {
-
val addRepetitionAction = Action(
R.drawable.ic_action_check,
context.getString(R.string.yes),
@@ -146,8 +145,9 @@ class AndroidNotificationTray
.addAction(removeRepetitionAction)
}
- if (!disableSound)
+ if (!disableSound) {
builder.setSound(ringtoneManager.getURI())
+ }
if (SDK_INT < Build.VERSION_CODES.S) {
val snoozeAction = Action(
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/notifications/RingtoneManager.kt b/uhabits-android/src/main/java/org/isoron/uhabits/notifications/RingtoneManager.kt
index 1e79ae857..0c30520d1 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/notifications/RingtoneManager.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/notifications/RingtoneManager.kt
@@ -61,8 +61,9 @@ class RingtoneManager
"pref_ringtone_uri",
defaultRingtoneUri.toString()
)!!
- if (prefRingtoneUri.isNotEmpty())
+ if (prefRingtoneUri.isNotEmpty()) {
ringtoneUri = Uri.parse(prefRingtoneUri)
+ }
return ringtoneUri
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/notifications/SnoozeDelayPickerActivity.kt b/uhabits-android/src/main/java/org/isoron/uhabits/notifications/SnoozeDelayPickerActivity.kt
index 42514b118..f7e532984 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/notifications/SnoozeDelayPickerActivity.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/notifications/SnoozeDelayPickerActivity.kt
@@ -33,7 +33,8 @@ import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher
import org.isoron.uhabits.core.models.Habit
-import org.isoron.uhabits.core.ui.ThemeSwitcher.Companion.THEME_LIGHT
+import org.isoron.uhabits.core.ui.views.DarkTheme
+import org.isoron.uhabits.core.ui.views.LightTheme
import org.isoron.uhabits.receivers.ReminderController
import org.isoron.uhabits.utils.SystemUtils
import java.util.Calendar
@@ -51,11 +52,8 @@ class SnoozeDelayPickerActivity : FragmentActivity(), OnItemClickListener {
val app = applicationContext as HabitsApplication
val appComponent = app.component
val themeSwitcher = AndroidThemeSwitcher(this, appComponent.preferences)
- if (themeSwitcher.getSystemTheme() == THEME_LIGHT) {
- setTheme(R.style.BaseDialog)
- } else {
- setTheme(R.style.BaseDialogDark)
- }
+ themeSwitcher.setTheme()
+
val data = intent.data
if (data == null) {
finish()
@@ -75,6 +73,16 @@ class SnoozeDelayPickerActivity : FragmentActivity(), OnItemClickListener {
SystemUtils.unlockScreen(this)
}
+ private fun AndroidThemeSwitcher.setTheme() {
+ if (this.isNightMode) {
+ setTheme(R.style.BaseDialogDark)
+ this.currentTheme = DarkTheme()
+ } else {
+ setTheme(R.style.BaseDialog)
+ this.currentTheme = LightTheme()
+ }
+ }
+
private fun showTimePicker() {
val calendar = Calendar.getInstance()
val dialog = TimePickerDialog.newInstance(
@@ -95,7 +103,9 @@ class SnoozeDelayPickerActivity : FragmentActivity(), OnItemClickListener {
if (snoozeValues[position] >= 0) {
reminderController!!.onSnoozeDelayPicked(habit!!, snoozeValues[position])
finish()
- } else showTimePicker()
+ } else {
+ showTimePicker()
+ }
}
override fun finish() {
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/tasks/ExportDBTaskFactory.kt b/uhabits-android/src/main/java/org/isoron/uhabits/tasks/ExportDBTaskFactory.kt
index 94481bb62..b1d031292 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/tasks/ExportDBTaskFactory.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/tasks/ExportDBTaskFactory.kt
@@ -27,7 +27,7 @@ import javax.inject.Inject
class ExportDBTaskFactory
@Inject constructor(
@AppContext private val context: Context,
- private val system: AndroidDirFinder,
+ private val system: AndroidDirFinder
) {
fun create(listener: ExportDBTask.Listener) = ExportDBTask(context, system, listener)
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/tasks/ImportDataTaskFactory.kt b/uhabits-android/src/main/java/org/isoron/uhabits/tasks/ImportDataTaskFactory.kt
index 5b3efe630..9a6287f02 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/tasks/ImportDataTaskFactory.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/tasks/ImportDataTaskFactory.kt
@@ -27,7 +27,7 @@ import javax.inject.Inject
class ImportDataTaskFactory
@Inject constructor(
private val importer: GenericImporter,
- private val modelFactory: ModelFactory,
+ private val modelFactory: ModelFactory
) {
fun create(file: File, listener: ImportDataTask.Listener) =
ImportDataTask(importer, modelFactory, file, listener)
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/utils/AttributeSetUtils.kt b/uhabits-android/src/main/java/org/isoron/uhabits/utils/AttributeSetUtils.kt
index 7ab5a1e34..34205fd5c 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/utils/AttributeSetUtils.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/utils/AttributeSetUtils.kt
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.Contract
object AttributeSetUtils {
const val ISORON_NAMESPACE = "http://isoron.org/android"
+
@JvmStatic
fun getAttribute(
context: Context,
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/utils/DatabaseUtils.kt b/uhabits-android/src/main/java/org/isoron/uhabits/utils/DatabaseUtils.kt
index db25f279d..81ea121db 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/utils/DatabaseUtils.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/utils/DatabaseUtils.kt
@@ -33,6 +33,7 @@ import java.text.SimpleDateFormat
object DatabaseUtils {
private var opener: HabitsDatabaseOpener? = null
+
@JvmStatic
fun getDatabaseFile(context: Context): File {
val databaseFilename = databaseFilename
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/utils/DialogUtils.kt b/uhabits-android/src/main/java/org/isoron/uhabits/utils/DialogUtils.kt
index 855f865c7..a1aefe16f 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/utils/DialogUtils.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/utils/DialogUtils.kt
@@ -6,16 +6,24 @@ import androidx.fragment.app.FragmentManager
import java.lang.ref.WeakReference
var currentDialog: WeakReference