Compare commits

..

16 Commits

Author SHA1 Message Date
22331ed364 Remove dependabot 2025-02-08 07:43:10 -06:00
d0a45eb523 Merge pull request #2028 from getgo-nobugs/dev
Fix the misalignment of "About" page in RTL language
2025-02-08 07:38:03 -06:00
getgo-nobugs
fec73af665 Update styles.xml 2024-07-28 11:16:23 +08:00
fc9cc423d0 Multiple fixes to edge-to-edge display (API 35) 2024-05-20 20:30:09 -05:00
e7165d993f Make compatible with edge-to-edge (API 35) 2024-05-20 09:33:00 -05:00
732ec1c70a Update AGP; disable lint 2024-05-19 20:36:43 -05:00
e823cd5758 Update lint-baseline 2024-05-19 20:01:32 -05:00
46fe683d71 Merge pull request #1942 from foralost/#1941_DateUtilsTest_failing
#1941 DateUtils test fix
2024-04-04 22:03:46 -05:00
7f6248123c DateUtilsTest: Simplify getCalendarUTC 2024-04-04 21:55:01 -05:00
2024277ebe Merge branch 'dev' into #1941_DateUtilsTest_failing 2024-04-04 21:52:27 -05:00
c216fb01d6 Merge pull request #1785 from hiqua/android_lint_baseline
Check android lint violations against current baseline
2024-04-04 21:45:37 -05:00
7cb32f486b lint: disable GradleDependency 2024-04-04 21:36:51 -05:00
093591fbaf Update lint baseline 2024-04-04 21:24:09 -05:00
985234cdf3 Merge branch 'dev' into android_lint_baseline 2024-04-04 21:18:22 -05:00
foralost
10074ded32 UTC Calendar fix 2024-03-04 11:31:45 +01:00
Quentin Hibon
25cff3d9b0 Check android lint violations against current baseline 2023-08-07 23:04:46 +02:00
19 changed files with 8325 additions and 31 deletions

View File

@@ -1,11 +0,0 @@
version: 2
updates:
- package-ecosystem: "gradle"
directory: "/"
schedule:
interval: "monthly"
open-pull-requests-limit: 10
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"

View File

@@ -1,6 +1,6 @@
plugins { plugins {
val kotlinVersion = "1.9.22" val kotlinVersion = "1.9.22"
id("com.android.application") version "8.1.4" apply (false) id("com.android.application") version "8.4.0" apply (false)
id("org.jetbrains.kotlin.android") version kotlinVersion apply (false) id("org.jetbrains.kotlin.android") version kotlinVersion apply (false)
id("org.jetbrains.kotlin.kapt") version kotlinVersion apply (false) id("org.jetbrains.kotlin.kapt") version kotlinVersion apply (false)
id("org.jetbrains.kotlin.multiplatform") version kotlinVersion apply (false) id("org.jetbrains.kotlin.multiplatform") version kotlinVersion apply (false)

View File

@@ -64,6 +64,7 @@ fail() {
core_build() { core_build() {
log_info "Building uhabits-core..." log_info "Building uhabits-core..."
$GRADLE ktlintCheck || fail $GRADLE ktlintCheck || fail
$GRADLE lintDebug || fail
$GRADLE :uhabits-core:build || fail $GRADLE :uhabits-core:build || fail
} }

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -19,7 +19,7 @@
plugins { plugins {
id("com.github.triplet.play") version "3.8.6" id("com.github.triplet.play") version "3.8.6"
id("com.android.application") version "8.1.4" id("com.android.application") version "8.4.0"
id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.kapt") id("org.jetbrains.kotlin.kapt")
id("org.jlleitschuh.gradle.ktlint") id("org.jlleitschuh.gradle.ktlint")
@@ -44,12 +44,14 @@ android {
namespace = "org.isoron.uhabits" namespace = "org.isoron.uhabits"
compileSdk = 34 compileSdk = 34
// compileSdkPreview = "VanillaIceCream"
defaultConfig { defaultConfig {
versionCode = 20200 versionCode = 20200
versionName = "2.2.0" versionName = "2.2.0"
minSdk = 28 minSdk = 28
targetSdk = 34 targetSdk = 34
// targetSdkPreview = "VanillaIceCream"
applicationId = "org.isoron.uhabits" applicationId = "org.isoron.uhabits"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }
@@ -91,6 +93,10 @@ android {
buildFeatures { buildFeatures {
viewBinding = true viewBinding = true
} }
lint {
abortOnError = false
}
} }
dependencies { dependencies {

File diff suppressed because it is too large Load Diff

View File

@@ -132,7 +132,7 @@ object CommonSteps : BaseUserInterfaceTest() {
} }
@Throws(Exception::class) @Throws(Exception::class)
fun verifyOpensWebsite(url: String) { fun verifyOpensWebsite(url: String?) {
var browserPkg = "org.chromium.webview_shell" var browserPkg = "org.chromium.webview_shell"
if (SDK_INT <= Build.VERSION_CODES.M) { if (SDK_INT <= Build.VERSION_CODES.M) {
browserPkg = "com.android.browser" browserPkg = "com.android.browser"

View File

@@ -26,6 +26,7 @@ import org.isoron.uhabits.BuildConfig
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.databinding.AboutBinding import org.isoron.uhabits.databinding.AboutBinding
import org.isoron.uhabits.utils.applyRootViewInsets
import org.isoron.uhabits.utils.currentTheme import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.setupToolbar import org.isoron.uhabits.utils.setupToolbar
@@ -54,5 +55,6 @@ class AboutView(
binding.tvTranslate.setOnClickListener { screen.showTranslationWebsite() } binding.tvTranslate.setOnClickListener { screen.showTranslationWebsite() }
binding.tvVersion.setOnClickListener { screen.onPressDeveloperCountdown() } binding.tvVersion.setOnClickListener { screen.onPressDeveloperCountdown() }
binding.tvVersion.text = String.format(version, BuildConfig.VERSION_NAME) binding.tvVersion.text = String.format(version, BuildConfig.VERSION_NAME)
applyRootViewInsets()
} }
} }

View File

@@ -22,7 +22,6 @@ package org.isoron.uhabits.activities.habits.edit
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.content.res.Resources import android.content.res.Resources
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.text.Html import android.text.Html
import android.text.Spanned import android.text.Spanned
@@ -53,7 +52,8 @@ import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.models.Reminder import org.isoron.uhabits.core.models.Reminder
import org.isoron.uhabits.core.models.WeekdayList import org.isoron.uhabits.core.models.WeekdayList
import org.isoron.uhabits.databinding.ActivityEditHabitBinding import org.isoron.uhabits.databinding.ActivityEditHabitBinding
import org.isoron.uhabits.utils.ColorUtils import org.isoron.uhabits.utils.applyRootViewInsets
import org.isoron.uhabits.utils.applyToolbarInsets
import org.isoron.uhabits.utils.dismissCurrentAndShow import org.isoron.uhabits.utils.dismissCurrentAndShow
import org.isoron.uhabits.utils.formatTime import org.isoron.uhabits.utils.formatTime
import org.isoron.uhabits.utils.toFormattedString import org.isoron.uhabits.utils.toFormattedString
@@ -94,6 +94,8 @@ class EditHabitActivity : AppCompatActivity() {
themeSwitcher.apply() themeSwitcher.apply()
binding = ActivityEditHabitBinding.inflate(layoutInflater) binding = ActivityEditHabitBinding.inflate(layoutInflater)
binding.root.applyRootViewInsets()
binding.toolbar.applyToolbarInsets()
setContentView(binding.root) setContentView(binding.root)
if (intent.hasExtra("habitId")) { if (intent.hasExtra("habitId")) {
@@ -352,8 +354,7 @@ class EditHabitActivity : AppCompatActivity() {
androidColor = themeSwitcher.currentTheme.color(color).toInt() androidColor = themeSwitcher.currentTheme.color(color).toInt()
binding.colorButton.backgroundTintList = ColorStateList.valueOf(androidColor) binding.colorButton.backgroundTintList = ColorStateList.valueOf(androidColor)
if (!themeSwitcher.isNightMode) { if (!themeSwitcher.isNightMode) {
val darkerAndroidColor = ColorUtils.mixColors(Color.BLACK, androidColor, 0.15f) window.statusBarColor = androidColor
window.statusBarColor = darkerAndroidColor
binding.toolbar.setBackgroundColor(androidColor) binding.toolbar.setBackgroundColor(androidColor)
} }
} }

View File

@@ -45,6 +45,7 @@ import org.isoron.uhabits.inject.ActivityContextModule
import org.isoron.uhabits.inject.DaggerHabitsActivityComponent import org.isoron.uhabits.inject.DaggerHabitsActivityComponent
import org.isoron.uhabits.inject.HabitsActivityComponent import org.isoron.uhabits.inject.HabitsActivityComponent
import org.isoron.uhabits.inject.HabitsApplicationComponent import org.isoron.uhabits.inject.HabitsApplicationComponent
import org.isoron.uhabits.utils.applyRootViewInsets
import org.isoron.uhabits.utils.dismissCurrentDialog import org.isoron.uhabits.utils.dismissCurrentDialog
import org.isoron.uhabits.utils.restartWithFade import org.isoron.uhabits.utils.restartWithFade
@@ -100,6 +101,7 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
menu = component.listHabitsMenu menu = component.listHabitsMenu
Thread.setDefaultUncaughtExceptionHandler(BaseExceptionHandler(this)) Thread.setDefaultUncaughtExceptionHandler(BaseExceptionHandler(this))
component.listHabitsBehavior.onStartup() component.listHabitsBehavior.onStartup()
rootView.applyRootViewInsets()
setContentView(rootView) setContentView(rootView)
} }

View File

@@ -49,6 +49,7 @@ import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitMenuPresenter
import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitPresenter import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitPresenter
import org.isoron.uhabits.core.ui.views.OnDateClickedListener import org.isoron.uhabits.core.ui.views.OnDateClickedListener
import org.isoron.uhabits.intents.IntentFactory import org.isoron.uhabits.intents.IntentFactory
import org.isoron.uhabits.utils.applyRootViewInsets
import org.isoron.uhabits.utils.currentTheme import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.dismissCurrentAndShow import org.isoron.uhabits.utils.dismissCurrentAndShow
import org.isoron.uhabits.utils.dismissCurrentDialog import org.isoron.uhabits.utils.dismissCurrentDialog
@@ -109,6 +110,7 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
) )
view.setListener(presenter) view.setListener(presenter)
view.applyRootViewInsets()
setContentView(view) setContentView(view)
} }

View File

@@ -25,12 +25,14 @@ import android.widget.FrameLayout
import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitPresenter import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitPresenter
import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitState import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitState
import org.isoron.uhabits.databinding.ShowHabitBinding import org.isoron.uhabits.databinding.ShowHabitBinding
import org.isoron.uhabits.utils.applyToolbarInsets
import org.isoron.uhabits.utils.setupToolbar import org.isoron.uhabits.utils.setupToolbar
class ShowHabitView(context: Context) : FrameLayout(context) { class ShowHabitView(context: Context) : FrameLayout(context) {
private val binding = ShowHabitBinding.inflate(LayoutInflater.from(context)) private val binding = ShowHabitBinding.inflate(LayoutInflater.from(context))
init { init {
binding.toolbar.applyToolbarInsets()
addView(binding.root) addView(binding.root)
} }

View File

@@ -26,6 +26,7 @@ import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher import org.isoron.uhabits.activities.AndroidThemeSwitcher
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.databinding.SettingsActivityBinding import org.isoron.uhabits.databinding.SettingsActivityBinding
import org.isoron.uhabits.utils.applyRootViewInsets
import org.isoron.uhabits.utils.setupToolbar import org.isoron.uhabits.utils.setupToolbar
class SettingsActivity : AppCompatActivity() { class SettingsActivity : AppCompatActivity() {
@@ -42,6 +43,7 @@ class SettingsActivity : AppCompatActivity() {
color = PaletteColor(11), color = PaletteColor(11),
theme = themeSwitcher.currentTheme theme = themeSwitcher.currentTheme
) )
binding.root.applyRootViewInsets()
setContentView(binding.root) setContentView(binding.root)
} }
} }

View File

@@ -24,6 +24,7 @@ import androidx.appcompat.app.AppCompatActivity
import org.isoron.uhabits.HabitsApplication import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.activities.AndroidThemeSwitcher import org.isoron.uhabits.activities.AndroidThemeSwitcher
import org.isoron.uhabits.core.models.HabitMatcher import org.isoron.uhabits.core.models.HabitMatcher
import org.isoron.uhabits.utils.applyRootViewInsets
class EditSettingActivity : AppCompatActivity() { class EditSettingActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@@ -45,6 +46,7 @@ class EditSettingActivity : AppCompatActivity() {
onSave = controller::onSave, onSave = controller::onSave,
args = args args = args
) )
view.applyRootViewInsets()
setContentView(view) setContentView(view)
} }
} }

View File

@@ -46,6 +46,8 @@ import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import org.isoron.platform.gui.toInt import org.isoron.platform.gui.toInt
import org.isoron.uhabits.HabitsApplication import org.isoron.uhabits.HabitsApplication
@@ -180,10 +182,10 @@ fun View.setupToolbar(
} else { } else {
theme.color(color).toInt() theme.color(color).toInt()
} }
val darkerColor = ColorUtils.mixColors(toolbarColor, Color.BLACK, 0.75f)
toolbar.background = ColorDrawable(toolbarColor) toolbar.background = ColorDrawable(toolbarColor)
toolbar.applyToolbarInsets()
val activity = context as AppCompatActivity val activity = context as AppCompatActivity
activity.window.statusBarColor = darkerColor activity.window.statusBarColor = toolbarColor
activity.setSupportActionBar(toolbar) activity.setSupportActionBar(toolbar)
activity.supportActionBar?.setDisplayHomeAsUpEnabled(displayHomeAsUpEnabled) activity.supportActionBar?.setDisplayHomeAsUpEnabled(displayHomeAsUpEnabled)
} }
@@ -245,3 +247,25 @@ fun View.getCenter(): PointF {
viewLocation[1] -= this.height / 2 viewLocation[1] -= this.height / 2
return PointF(viewLocation[0].toFloat(), viewLocation[1].toFloat()) return PointF(viewLocation[0].toFloat(), viewLocation[1].toFloat())
} }
fun View.applyRootViewInsets() {
ViewCompat.setOnApplyWindowInsetsListener(this) { view, insets ->
val systemBarsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
val displayCutoutInsets = insets.getInsets(WindowInsetsCompat.Type.displayCutout())
val left = maxOf(systemBarsInsets.left, displayCutoutInsets.left)
val right = maxOf(systemBarsInsets.right, displayCutoutInsets.right)
view.setPadding(left, 0, right, 0)
view.background = ColorDrawable(Color.BLACK)
insets
}
}
fun View.applyToolbarInsets() {
ViewCompat.setOnApplyWindowInsetsListener(this) { view, insets ->
val systemBarsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
val displayCutoutInsets = insets.getInsets(WindowInsetsCompat.Type.displayCutout())
val top = maxOf(systemBarsInsets.top, displayCutoutInsets.top)
view.setPadding(0, top, 0, 0)
insets
}
}

View File

@@ -18,7 +18,8 @@
~ with this program. If not, see <http://www.gnu.org/licenses/>. ~ with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -61,8 +62,10 @@
<ScrollView <ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="0dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior"> android:layout_weight="1"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:background="?attr/contrast0">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -265,4 +268,4 @@
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </LinearLayout>

View File

@@ -58,7 +58,10 @@
<LinearLayout <LinearLayout
android:id="@+id/formPanel" android:id="@+id/formPanel"
style="@style/dialogFormPanel"> style="@style/dialogFormPanel"
android:layout_height="0dp"
android:layout_weight="1"
android:background="?attr/contrast0">
<FrameLayout style="@style/FormOuterBox"> <FrameLayout style="@style/FormOuterBox">
<LinearLayout style="@style/FormInnerBox"> <LinearLayout style="@style/FormInnerBox">

View File

@@ -226,6 +226,7 @@
<item name="android:layout_height">wrap_content</item> <item name="android:layout_height">wrap_content</item>
<item name="android:paddingTop">6dp</item> <item name="android:paddingTop">6dp</item>
<item name="android:paddingBottom">6dp</item> <item name="android:paddingBottom">6dp</item>
<item name="android:textAlignment">viewStart</item>
</style> </style>
<style name="About.Item.Language"> <style name="About.Item.Language">
@@ -233,6 +234,7 @@
<item name="android:textSize">@dimen/smallTextSize</item> <item name="android:textSize">@dimen/smallTextSize</item>
<item name="android:gravity">center</item> <item name="android:gravity">center</item>
<item name="android:background">?attr/contrast20</item> <item name="android:background">?attr/contrast20</item>
<item name="android:textAlignment">viewStart</item>
</style> </style>
<style name="About.Item.Clickable"> <style name="About.Item.Clickable">
@@ -243,7 +245,7 @@
<style name="Toolbar"> <style name="Toolbar">
<item name="android:layout_width">match_parent</item> <item name="android:layout_width">match_parent</item>
<item name="android:layout_height">?actionBarSize</item> <item name="android:layout_height">wrap_content</item>
<item name="android:background">?colorPrimary</item> <item name="android:background">?colorPrimary</item>
<item name="android:theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item> <item name="android:theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
</style> </style>

View File

@@ -120,10 +120,15 @@ class DateUtilsTest : BaseUnitTest() {
@Test @Test
fun getWeekdaysInMonth() { fun getWeekdaysInMonth() {
val february = GregorianCalendar(2018, Calendar.FEBRUARY, 1) fun getCalendarUTC(year: Int, month: Int, dayOfMonth: Int) =
val leapFebruary = GregorianCalendar(2020, Calendar.FEBRUARY, 1) GregorianCalendar(year, month, dayOfMonth).apply {
val month = GregorianCalendar(2020, Calendar.APRIL, 1) timeZone = TimeZone.getTimeZone("UTC")
val longMonth = GregorianCalendar(2020, Calendar.AUGUST, 1) }
val february = getCalendarUTC(2018, Calendar.FEBRUARY, 1)
val leapFebruary = getCalendarUTC(2020, Calendar.FEBRUARY, 1)
val month = getCalendarUTC(2020, Calendar.APRIL, 1)
val longMonth = getCalendarUTC(2020, Calendar.AUGUST, 1)
assertThat( assertThat(
arrayOf(4, 4, 4, 4, 4, 4, 4), arrayOf(4, 4, 4, 4, 4, 4, 4),