Compare commits

...

447 Commits

Author SHA1 Message Date
e8a4a9740e Merge branch 'dev' into feature/sync 2021-08-22 05:13:37 -05:00
f15c660d33 Merge branch 'master' into dev 2021-08-21 07:40:28 -05:00
1866743c47 Remove absolute path to flock; change PATH in GH Actions 2021-08-21 07:22:51 -05:00
6b9a7917b4 Merge branch 'hotfix/2.0.3' 2021-08-21 06:39:47 -05:00
2a5725f382 Small tweaks to CheckmarkWidget padding and aspect ratio 2021-08-21 06:17:13 -05:00
edeabb6ee3 Update CHANGELOG and release notes 2021-08-21 05:07:57 -05:00
24a9fbe414 Update translations 2021-08-21 04:57:07 -05:00
e5b8c4c3c4 Update translations 2021-08-21 04:54:06 -05:00
Ganessh Kumar
a781a1f947 Updating links in README
Updating http links to https links. By using http links from browser - all of them are getting redirected to https automatically except http://www.gnu.org/licenses, which displays a warning message that the connection is not secure. Switching to https makes the connection secure as well.
2021-08-16 07:21:15 -05:00
Quentin Hibon
13e57b5026 Test isFailedToday 2021-08-06 06:14:16 -05:00
Quentin Hibon
f8c7abfff4 Use 'entered' instead of 'completed' when ? or skips are enabled 2021-08-06 06:14:16 -05:00
Quentin Hibon
7fe3ce970c Hide failed habits along with completed ones 2021-08-06 06:14:16 -05:00
9c395243f4 Merge pull request #1050 from hiqua/968_IndexOutOfBoundsException
Check position before moving habit
2021-08-06 06:02:36 -05:00
Quentin Hibon
b9eb244b0b Introduce HabitType and NumericalHabitType enums 2021-08-06 05:48:15 -05:00
Quentin Hibon
420a99f1cf Check position before moving habit
Workaround for #968.
2021-08-06 08:01:30 +02:00
e756a639ae Merge pull request #1043 from hiqua/965_illegal_state_exception
Handle target widget type in stacked widget
2021-08-04 20:33:29 -05:00
Quentin Hibon
91ff5f7a0c Use empty array instead of sentinel value -1 as habitId 2021-08-03 08:38:07 +02:00
Quentin Hibon
67b55a4ecf Fix off-by-one bug in StackWidgetService 2021-08-03 08:38:07 +02:00
Quentin Hibon
a5ae2eaa63 Improve one 'when' 2021-08-03 08:37:44 +02:00
Quentin Hibon
0bc2a8b6d4 Handle target widget type in stacked widget
Fixes #965.
2021-08-03 08:28:29 +02:00
Quentin Hibon
95a1786c4a build.sh: use full path for flock
Fixes #1044.
2021-08-02 08:30:38 +02:00
dependabot[bot]
caa1c9d72e Bump daggerVersion from 2.37 to 2.38.1
Bumps `daggerVersion` from 2.37 to 2.38.1.

Updates `dagger` from 2.37 to 2.38.1
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.37...dagger-2.38.1)

Updates `dagger-compiler` from 2.37 to 2.38.1
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.37...dagger-2.38.1)

---
updated-dependencies:
- dependency-name: com.google.dagger:dagger
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: com.google.dagger:dagger-compiler
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-01 23:49:25 +02:00
dependabot[bot]
a7afe0b309 Bump logback-classic from 1.2.3 to 1.2.5
Bumps logback-classic from 1.2.3 to 1.2.5.

---
updated-dependencies:
- dependency-name: ch.qos.logback:logback-classic
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-01 22:53:41 +02:00
dependabot[bot]
9c03174eef Bump material from 1.3.0 to 1.4.0
Bumps [material](https://github.com/material-components/material-components-android) from 1.3.0 to 1.4.0.
- [Release notes](https://github.com/material-components/material-components-android/releases)
- [Commits](https://github.com/material-components/material-components-android/compare/1.3.0...1.4.0)

---
updated-dependencies:
- dependency-name: com.google.android.material:material
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-01 19:30:13 +02:00
dependabot[bot]
da02926fa6 Bump kotlin-stdlib-jdk8 from 1.5.20 to 1.5.21
Bumps [kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.5.20 to 1.5.21.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.5.20...v1.5.21)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-stdlib-jdk8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-01 18:31:57 +02:00
Quentin Hibon
250dabfe58 Bump com.github.triplet.play from 3.2.0 to 3.5.0 2021-08-01 18:07:06 +02:00
dependabot[bot]
0bba3b76bc Bump kotlinx-coroutines-core-jvm from 1.4.2 to 1.5.1
Bumps [kotlinx-coroutines-core-jvm](https://github.com/Kotlin/kotlinx.coroutines) from 1.4.2 to 1.5.1.
- [Release notes](https://github.com/Kotlin/kotlinx.coroutines/releases)
- [Changelog](https://github.com/Kotlin/kotlinx.coroutines/blob/master/CHANGES.md)
- [Commits](https://github.com/Kotlin/kotlinx.coroutines/compare/1.4.2...1.5.1)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-01 17:05:47 +02:00
dependabot[bot]
c2479278ba Bump ktorVersion from 1.6.1 to 1.6.2
Bumps `ktorVersion` from 1.6.1 to 1.6.2.

Updates `ktor-client-mock` from 1.6.1 to 1.6.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.1...1.6.2)

Updates `ktor-jackson` from 1.6.1 to 1.6.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.1...1.6.2)

Updates `ktor-client-android` from 1.6.1 to 1.6.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.1...1.6.2)

Updates `ktor-client-core` from 1.6.1 to 1.6.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.1...1.6.2)

Updates `ktor-client-jackson` from 1.6.1 to 1.6.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.1...1.6.2)

Updates `ktor-client-json` from 1.6.1 to 1.6.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.1...1.6.2)

Updates `ktor-server-netty` from 1.6.1 to 1.6.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.1...1.6.2)

Updates `ktor-server-core` from 1.6.1 to 1.6.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.1...1.6.2)

Updates `ktor-html-builder` from 1.6.1 to 1.6.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.1...1.6.2)

Updates `ktor-server-tests` from 1.6.1 to 1.6.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.1...1.6.2)

---
updated-dependencies:
- dependency-name: io.ktor:ktor-client-mock
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-jackson
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-client-android
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-client-core
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-client-jackson
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-client-json
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-server-netty
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-server-core
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-html-builder
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-server-tests
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-01 14:00:24 +02:00
dependabot[bot]
499a403a06 Bump kotlin-stdlib from 1.5.20 to 1.5.21
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.5.20 to 1.5.21.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.5.20...v1.5.21)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-stdlib
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-01 14:00:17 +02:00
dependabot[bot]
af5d622339 Bump opencsv from 5.4 to 5.5.1
Bumps opencsv from 5.4 to 5.5.1.

---
updated-dependencies:
- dependency-name: com.opencsv:opencsv
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-01 10:33:09 +02:00
dependabot[bot]
5eeb54bc47 Bump kxCoroutinesVersion from 1.4.2 to 1.5.1
Bumps `kxCoroutinesVersion` from 1.4.2 to 1.5.1.

Updates `kotlinx-coroutines-android` from 1.4.2 to 1.5.1
- [Release notes](https://github.com/Kotlin/kotlinx.coroutines/releases)
- [Changelog](https://github.com/Kotlin/kotlinx.coroutines/blob/master/CHANGES.md)
- [Commits](https://github.com/Kotlin/kotlinx.coroutines/compare/1.4.2...1.5.1)

Updates `kotlinx-coroutines-core` from 1.4.2 to 1.5.1
- [Release notes](https://github.com/Kotlin/kotlinx.coroutines/releases)
- [Changelog](https://github.com/Kotlin/kotlinx.coroutines/blob/master/CHANGES.md)
- [Commits](https://github.com/Kotlin/kotlinx.coroutines/compare/1.4.2...1.5.1)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlinx:kotlinx-coroutines-android
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.jetbrains.kotlinx:kotlinx-coroutines-core
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-01 10:32:46 +02:00
dependabot[bot]
e09e899aad Bump appcompat from 1.3.0 to 1.3.1
Bumps appcompat from 1.3.0 to 1.3.1.

---
updated-dependencies:
- dependency-name: androidx.appcompat:appcompat
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-01 10:32:19 +02:00
69f0fc6c3a Update CHANGELOG 2021-07-31 15:46:42 -05:00
705dfb9cbd Bitmap.createBitmap: Ensure width, height > 0
Fixes #966
2021-07-31 15:46:17 -05:00
d0ef749f19 StackWidget: Raise exception instead of returning invalid default value 2021-07-31 15:07:43 -05:00
b54711243f Remove color.toThemedAndroidColor
Fixes #907
2021-07-31 14:18:50 -05:00
37f03aca37 Merge branch 'hotfix/2.0.3' into dev 2021-07-31 12:49:01 -05:00
Quentin Hibon
271de59a94 Use notification timestamp when pressing "no"
Fixes #969.
2021-07-31 12:47:09 -05:00
Quentin Hibon
0ab55f6f5a Remove useless nullability 2021-07-30 21:12:33 +02:00
dependabot[bot]
43921721d4 Bump espressoVersion from 3.3.0 to 3.4.0
Bumps `espressoVersion` from 3.3.0 to 3.4.0.

Updates `espresso-contrib` from 3.3.0 to 3.4.0

Updates `espresso-core` from 3.3.0 to 3.4.0

---
updated-dependencies:
- dependency-name: androidx.test.espresso:espresso-contrib
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: androidx.test.espresso:espresso-core
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-03 23:37:26 +02:00
dependabot[bot]
33c88cded3 Bump rules from 1.3.0 to 1.4.0
Bumps rules from 1.3.0 to 1.4.0.

---
updated-dependencies:
- dependency-name: androidx.test:rules
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-03 18:48:12 +02:00
dependabot[bot]
aecce891ea Bump sqlite-jdbc from 3.36.0 to 3.36.0.1
Bumps [sqlite-jdbc](https://github.com/xerial/sqlite-jdbc) from 3.36.0 to 3.36.0.1.
- [Release notes](https://github.com/xerial/sqlite-jdbc/releases)
- [Changelog](https://github.com/xerial/sqlite-jdbc/blob/master/CHANGELOG)
- [Commits](https://github.com/xerial/sqlite-jdbc/compare/3.36.0...3.36.0.1)

---
updated-dependencies:
- dependency-name: org.xerial:sqlite-jdbc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-03 18:47:59 +02:00
dependabot[bot]
2ea98a7756 Bump ktorVersion from 1.6.0 to 1.6.1
Bumps `ktorVersion` from 1.6.0 to 1.6.1.

Updates `ktor-client-mock` from 1.6.0 to 1.6.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.0...1.6.1)

Updates `ktor-jackson` from 1.6.0 to 1.6.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.0...1.6.1)

Updates `ktor-client-android` from 1.6.0 to 1.6.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.0...1.6.1)

Updates `ktor-client-core` from 1.6.0 to 1.6.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.0...1.6.1)

Updates `ktor-client-jackson` from 1.6.0 to 1.6.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.0...1.6.1)

Updates `ktor-client-json` from 1.6.0 to 1.6.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.0...1.6.1)

Updates `ktor-server-netty` from 1.6.0 to 1.6.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.0...1.6.1)

Updates `ktor-server-core` from 1.6.0 to 1.6.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.0...1.6.1)

Updates `ktor-html-builder` from 1.6.0 to 1.6.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.0...1.6.1)

Updates `ktor-server-tests` from 1.6.0 to 1.6.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.6.0...1.6.1)

---
updated-dependencies:
- dependency-name: io.ktor:ktor-client-mock
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-jackson
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-client-android
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-client-core
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-client-jackson
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-client-json
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-server-netty
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-server-core
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-html-builder
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.ktor:ktor-server-tests
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-03 18:47:52 +02:00
dependabot[bot]
e667872d83 Bump junit from 1.1.2 to 1.1.3
Bumps junit from 1.1.2 to 1.1.3.

---
updated-dependencies:
- dependency-name: androidx.test.ext:junit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-03 18:47:47 +02:00
Quentin Hibon
3602a614c4 dependabot: do monthly checks rather than daily 2021-07-01 08:02:40 +02:00
dependabot[bot]
d8c5f4d93c Bump sqlite-jdbc from 3.34.0 to 3.36.0
Bumps [sqlite-jdbc](https://github.com/xerial/sqlite-jdbc) from 3.34.0 to 3.36.0.
- [Release notes](https://github.com/xerial/sqlite-jdbc/releases)
- [Changelog](https://github.com/xerial/sqlite-jdbc/blob/master/CHANGELOG)
- [Commits](https://github.com/xerial/sqlite-jdbc/compare/3.34.0...3.36.0)

---
updated-dependencies:
- dependency-name: org.xerial:sqlite-jdbc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-28 08:23:03 +02:00
dependabot[bot]
c9f4df9dae Bump kotlin-stdlib-jdk8 from 1.5.10 to 1.5.20
Bumps [kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.5.10 to 1.5.20.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.5.20/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.5.10...v1.5.20)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-stdlib-jdk8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-25 08:26:27 +02:00
dependabot[bot]
feb384bca6 Bump kotlin-stdlib from 1.5.10 to 1.5.20
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.5.10 to 1.5.20.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.5.20/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.5.10...v1.5.20)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-stdlib
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-25 08:26:21 +02:00
dependabot[bot]
71e9160460 Bump daggerVersion from 2.36 to 2.37
Bumps `daggerVersion` from 2.36 to 2.37.

Updates `dagger` from 2.36 to 2.37
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.36...dagger-2.37)

Updates `dagger-compiler` from 2.36 to 2.37
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.36...dagger-2.37)

---
updated-dependencies:
- dependency-name: com.google.dagger:dagger
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: com.google.dagger:dagger-compiler
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-11 10:37:47 +02:00
Quentin Hibon
64966d3c86 Bumps org.jlleitschuh.gradle.ktlint from 10.0.0 to 10.1.0 2021-06-09 12:06:35 +02:00
dependabot[bot]
4787df4074 Bump simpleclient_hotspot from 0.10.0 to 0.11.0
Bumps [simpleclient_hotspot](https://github.com/prometheus/client_java) from 0.10.0 to 0.11.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.10.0...parent-0.11.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-09 11:57:42 +02:00
92291fd919 Fix dates before the year 2000 2021-06-05 18:45:15 -05:00
be51538704 Avoid calling textPaint.getTextBounds repeatedly
This operation seems to be very expensive on some Samsung phones,
which causes ANRs.

Fixes #962
2021-06-05 18:19:03 -05:00
89b24911ba Fix imports 2021-06-05 18:18:25 -05:00
1cf71b3973 Use dark theme in HabitPickerDialog.kt
Fixes #916
2021-06-05 17:26:55 -05:00
2fe3b15806 Fix small issues with the pure black theme 2021-06-05 17:17:27 -05:00
33468bfc1c Improve automatic checkmarks for monthly habits
Fixes #947
2021-06-05 16:54:13 -05:00
dependabot[bot]
5908692a5c Bump ktorVersion from 1.5.4 to 1.6.0 (#943)
Bumps `ktorVersion` from 1.5.4 to 1.6.0.

Updates `ktor-client-mock` from 1.5.4 to 1.6.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.4...1.6.0)

Updates `ktor-jackson` from 1.5.4 to 1.6.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.4...1.6.0)

Updates `ktor-client-android` from 1.5.4 to 1.6.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.4...1.6.0)

Updates `ktor-client-core` from 1.5.4 to 1.6.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.4...1.6.0)

Updates `ktor-client-jackson` from 1.5.4 to 1.6.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.4...1.6.0)

Updates `ktor-client-json` from 1.5.4 to 1.6.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.4...1.6.0)

Updates `ktor-server-netty` from 1.5.4 to 1.6.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.4...1.6.0)

Updates `ktor-server-core` from 1.5.4 to 1.6.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.4...1.6.0)

Updates `ktor-html-builder` from 1.5.4 to 1.6.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.4...1.6.0)

Updates `ktor-server-tests` from 1.5.4 to 1.6.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.4...1.6.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-05 10:08:34 -05:00
dependabot[bot]
693dce8719 Bump simpleclient_httpserver from 0.10.0 to 0.11.0 (#942)
Bumps [simpleclient_httpserver](https://github.com/prometheus/client_java) from 0.10.0 to 0.11.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.10.0...parent-0.11.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-05 10:08:09 -05:00
b232827dfd Update bug_report.md 2021-05-31 13:14:30 -05:00
dependabot[bot]
02f9f411ce Bump simpleclient from 0.10.0 to 0.11.0 (#941)
Bumps [simpleclient](https://github.com/prometheus/client_java) from 0.10.0 to 0.11.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.10.0...parent-0.11.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-31 13:12:25 -05:00
bbf9da44e1 Update bug_report.md 2021-05-29 08:07:17 -05:00
dependabot[bot]
ee896fb4f9 Bump kotlin-stdlib from 1.5.0 to 1.5.10 (#931)
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.5.0 to 1.5.10.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.5.0...v1.5.10)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-26 20:40:31 -05:00
dependabot[bot]
4d7d8b6206 Bump kotlin-stdlib-jdk8 from 1.5.0 to 1.5.10 (#932)
Bumps [kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.5.0 to 1.5.10.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.5.0...v1.5.10)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-26 20:40:18 -05:00
dependabot[bot]
55b841a8b4 Bump daggerVersion from 2.35.1 to 2.36 (#933)
Bumps `daggerVersion` from 2.35.1 to 2.36.

Updates `dagger` from 2.35.1 to 2.36
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.35.1...dagger-2.36)

Updates `dagger-compiler` from 2.35.1 to 2.36
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.35.1...dagger-2.36)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-26 06:47:10 -05:00
7fac86b617 Update bug_report.md 2021-05-23 19:04:32 -05:00
dependabot[bot]
c31d42be2d Bump com.github.johnrengelman.shadow from 6.1.0 to 7.0.0
Bumps com.github.johnrengelman.shadow from 6.1.0 to 7.0.0.

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-23 18:45:05 -05:00
31c09b9c0b Upgrade to Gradle 7.0 and Kotlin 1.5.0 2021-05-23 18:33:57 -05:00
dependabot[bot]
db91dce57f Bump appcompat from 1.2.0 to 1.3.0 (#912)
Bumps appcompat from 1.2.0 to 1.3.0.

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-23 18:01:18 -05:00
12c76245e6 Merge branch 'master' into dev 2021-05-23 17:47:14 -05:00
2163a2b93b Update CHANGELOG.md 2021-05-23 17:39:34 -05:00
afad56ab91 Update test screenshots; automatically fetch 2021-05-23 15:34:59 -05:00
ece1b93f8d GitHub Actions: Increase number of attempts 2021-05-23 11:56:50 -05:00
10416e40fa Update CHANGELOG.md 2021-05-23 11:51:39 -05:00
88f8581acc Make CheckmarkWidget resizable; remove fixed aspect ratio 2021-05-23 11:49:49 -05:00
b33dd2a994 Ensure RingView.diameter is never zero
In rare cases, it seems either that `onDraw` is called before `onMeasure` or
that `onMeasure` is called with a view that has zero height/width. This causes
`reallocateCache` to produce an IllegalArgumentException. This patch ensures
that diameter is never zero.

Fixes #904
2021-05-23 11:21:49 -05:00
d87961d800 Fix missing placeholder in some translations; update remaining ones
Fixes #926
2021-05-23 10:50:26 -05:00
38d2606d6d Fix IllegalStateException in androidx.customview.view
Fixes #906
2021-05-22 12:53:03 -05:00
0a91c097e8 Update CHANGELOG 2021-05-21 19:42:37 -05:00
sumanabhi
b1c53bd820 Added the Decimal Support while entering target for any Habit. 2021-05-21 19:40:47 -05:00
c973f93424 Fix small issues with font size 2021-05-15 20:22:42 -05:00
fcadbe7c38 Handle numerical habits with target value of zero
Fixes #903
2021-05-15 20:11:20 -05:00
7f1a1add8c Revert "Temporarily remove device sync"
This reverts commit da018fc64d.
2021-05-09 18:22:15 -05:00
59a4d7552c Update translations; reorganize play/listings 2021-05-09 18:03:04 -05:00
9d7840bdd1 Merge branch 'master' into dev 2021-05-09 17:24:50 -05:00
89e3dd7655 Update CHANGELOG 2021-05-09 17:18:16 -05:00
df56608a5d Re-add signing config 2021-05-09 17:04:42 -05:00
3489f176d6 translators: Remove debug statements 2021-05-09 17:04:16 -05:00
75fdd9d2b1 Temporarily remove outdated publish.yml workflow 2021-05-09 16:31:23 -05:00
dd1999681f Small adjustments to numeric checkmark widget 2021-05-09 16:24:59 -05:00
Quentin Hibon
32db4e363b Add missing dependency to github workflow (#894) 2021-05-02 18:41:34 -05:00
dependabot[bot]
004bb8d71c Bump daggerVersion from 2.34.1 to 2.35.1
Bumps `daggerVersion` from 2.34.1 to 2.35.1.

Updates `dagger` from 2.34.1 to 2.35.1
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.34.1...dagger-2.35.1)

Updates `dagger-compiler` from 2.34.1 to 2.35.1
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.34.1...dagger-2.35.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-01 16:07:49 +02:00
dependabot[bot]
21a1e88c47 Bump ktorVersion from 1.5.3 to 1.5.4
Bumps `ktorVersion` from 1.5.3 to 1.5.4.

Updates `ktor-client-mock` from 1.5.3 to 1.5.4
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.3...1.5.4)

Updates `ktor-jackson` from 1.5.3 to 1.5.4
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.3...1.5.4)

Updates `ktor-client-android` from 1.5.3 to 1.5.4
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.3...1.5.4)

Updates `ktor-client-core` from 1.5.3 to 1.5.4
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.3...1.5.4)

Updates `ktor-client-jackson` from 1.5.3 to 1.5.4
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.3...1.5.4)

Updates `ktor-client-json` from 1.5.3 to 1.5.4
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.3...1.5.4)

Updates `ktor-server-netty` from 1.5.2 to 1.5.4
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.2...1.5.4)

Updates `ktor-server-core` from 1.5.2 to 1.5.4
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.2...1.5.4)

Updates `ktor-html-builder` from 1.5.2 to 1.5.4
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.2...1.5.4)

Updates `ktor-server-tests` from 1.5.2 to 1.5.4
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.2...1.5.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-01 00:38:37 +02:00
dependabot[bot]
86fb718896 Bump appintro from 3.4.0 to 4.1.0
Bumps [appintro](https://github.com/PaoloRotolo/AppIntro) from 3.4.0 to 4.1.0.
- [Release notes](https://github.com/PaoloRotolo/AppIntro/releases)
- [Changelog](https://github.com/AppIntro/AppIntro/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PaoloRotolo/AppIntro/commits/v4.1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-01 00:38:10 +02:00
dependabot[bot]
a4e9b2f874 Bump kotlin-stdlib-jdk8 from 1.4.32 to 1.5.0
Bumps [kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.4.32 to 1.5.0.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-30 17:09:04 +02:00
dependabot[bot]
ac924470b8 Bump kotlin-stdlib from 1.4.32 to 1.5.0
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.4.32 to 1.5.0.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-30 17:08:54 +02:00
63883032c4 Update screenshots and description 2021-04-29 21:32:17 -05:00
a8c9b1b71c Update CHANGELOG 2021-04-29 19:35:46 -05:00
61529fde4d Update translations 2021-04-29 19:02:35 -05:00
1050cc4e47 GitHub Actions: Enable APIs 23 to 28 2021-04-26 21:24:29 -05:00
a7845c9290 Make large-tests pass on API 23 2021-04-26 21:21:51 -05:00
1feefe107c Make large-tests pass on API 25 2021-04-26 18:28:37 -05:00
1654ff9af3 GitHub Actions: Enable API 26 2021-04-25 23:56:53 -05:00
58adff6a22 build.sh: Run tests in parallel 2021-04-25 23:46:34 -05:00
2728c311d8 Large tests: Make compatible with API 27 2021-04-25 19:45:02 -05:00
b561dfe90d GitHub Actions: Large tests 2021-04-24 21:27:01 -05:00
53a40b2cfa Update translations 2021-04-22 23:18:42 -05:00
98ce802f87 Remove useless statement 2021-04-22 23:11:41 -05:00
853b4275be Parse translators from Crowdin report; group by language
Fixes #669
2021-04-22 23:06:35 -05:00
df4355c072 Switch to androidx.preference.PreferenceManger 2021-04-18 22:17:25 -05:00
33c3feb11a Make FrequencyPickerDialog translatable 2021-04-18 10:34:35 -05:00
f88a9bd46a Remove -alpha from version name 2021-04-18 10:04:56 -05:00
5dd9f43464 Update translations 2021-04-18 09:57:34 -05:00
4a13623b2c Update translations 2021-04-18 09:26:12 -05:00
6b368bffdf Update measurable_example 2021-04-18 09:09:46 -05:00
8d87988871 Add arrows to sort menu 2021-04-18 09:02:40 -05:00
256ca13dca Small tweaks to preferences screen; restore default accent color 2021-04-18 07:29:03 -05:00
b0c5552cfa Remove unused imports 2021-04-17 22:01:17 -05:00
616ab4861d CheckmarkWidget: Always show circle
Fixes #790
2021-04-17 21:56:50 -05:00
fcff067b2e DatePicker: Implement dark theme
Fixes #858
2021-04-17 21:52:00 -05:00
da018fc64d Temporarily remove device sync 2021-04-17 19:53:24 -05:00
f27a9f9103 Revert to ktor 1.5.2
Newer version seems to require unpublished dependencies.
2021-04-17 19:35:28 -05:00
engineering4good
fe59565ded Fix app crash on habit deletion when sorted not manually. (#874) 2021-04-17 06:31:19 -05:00
dependabot[bot]
419d2faa78 Bump daggerVersion from 2.34 to 2.34.1
Bumps `daggerVersion` from 2.34 to 2.34.1.

Updates `dagger` from 2.34 to 2.34.1
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.34...dagger-2.34.1)

Updates `dagger-compiler` from 2.34 to 2.34.1
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.34...dagger-2.34.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-14 09:13:26 +02:00
dependabot[bot]
55f3bab13a Bump daggerVersion from 2.33 to 2.34
Bumps `daggerVersion` from 2.33 to 2.34.

Updates `dagger` from 2.33 to 2.34
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.33...dagger-2.34)

Updates `dagger-compiler` from 2.33 to 2.34
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.33...dagger-2.34)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-08 11:54:09 +02:00
dependabot[bot]
212cc4259b Bump ktorVersion from 1.5.2 to 1.5.3
Bumps `ktorVersion` from 1.5.2 to 1.5.3.

Updates `ktor-client-mock` from 1.5.2 to 1.5.3
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/commits)

Updates `ktor-jackson` from 1.5.2 to 1.5.3
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/commits)

Updates `ktor-client-android` from 1.5.2 to 1.5.3
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/commits)

Updates `ktor-client-core` from 1.5.2 to 1.5.3
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/commits)

Updates `ktor-client-jackson` from 1.5.2 to 1.5.3
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/commits)

Updates `ktor-client-json` from 1.5.2 to 1.5.3
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/commits)

Updates `ktor-server-netty` from 1.5.2 to 1.5.3
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/commits)

Updates `ktor-server-core` from 1.5.2 to 1.5.3
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/commits)

Updates `ktor-html-builder` from 1.5.2 to 1.5.3
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/commits)

Updates `ktor-server-tests` from 1.5.2 to 1.5.3
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-05 11:09:10 +02:00
Quentin Hibon
e1ec8cfa10 Fix build instructions link in README.md
Fixes #871
2021-04-04 17:16:57 +02:00
Quentin Hibon
6af2edb690 Delete v21 resources (#864) 2021-04-01 06:12:37 -05:00
dependabot[bot]
9d6b3ebb25 Bump annotation from 1.1.0 to 1.2.0
Bumps annotation from 1.1.0 to 1.2.0.

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-25 09:38:54 +01:00
dependabot[bot]
ed0744d5ab Bump kotlin-stdlib-jdk8 from 1.4.31 to 1.4.32
Bumps [kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.4.31 to 1.4.32.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-25 09:38:32 +01:00
dependabot[bot]
b59886dc77 Bump kotlin-stdlib from 1.4.31 to 1.4.32
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.4.31 to 1.4.32.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-23 18:40:03 +01:00
dependabot[bot]
23954eed27 Bump guava from 30.1-android to 30.1.1-android
Bumps [guava](https://github.com/google/guava) from 30.1-android to 30.1.1-android.
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-22 14:12:50 +01:00
071b6bd090 HeaderView: Fix padding 2021-03-18 22:23:58 -05:00
298bf1a538 BarChart: Fix small bars 2021-03-18 22:16:26 -05:00
8b2285787c Fix numerical spinner in BarCardView 2021-03-18 22:09:54 -05:00
c83cd5fd10 Render YES_AUTO as outlined checkmark 2021-03-18 22:04:23 -05:00
381c67d020 Allow unitless numerical habits 2021-03-18 22:04:23 -05:00
81cffc7253 Fix dialog text color 2021-03-18 22:04:23 -05:00
e745b959ca Fix multiple selection 2021-03-18 22:04:23 -05:00
dependabot[bot]
d2ee210376 Bump opencsv from 5.3 to 5.4 (#849)
Bumps opencsv from 5.3 to 5.4.

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-03-15 16:56:19 -05:00
Quentin Hibon
9c81f22a4d Start snooze activity after later is selected from lock screen (#840)
Fixes #787.
2021-03-15 08:34:42 -05:00
51947576aa HistoryEditorDialog: Use system theme 2021-03-14 09:17:26 -05:00
dependabot[bot]
6411f65fa5 Bump commons-lang3 from 3.11 to 3.12.0 (#833)
Bumps commons-lang3 from 3.11 to 3.12.0.

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-03-13 19:57:40 -06:00
dependabot[bot]
a04349bfaa Bump ktorVersion from 1.5.1 to 1.5.2 (#832)
Bumps `ktorVersion` from 1.5.1 to 1.5.2.

Updates `ktor-client-mock` from 1.5.1 to 1.5.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.1...1.5.2)

Updates `ktor-jackson` from 1.5.1 to 1.5.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.1...1.5.2)

Updates `ktor-client-android` from 1.5.1 to 1.5.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.1...1.5.2)

Updates `ktor-client-core` from 1.5.1 to 1.5.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.1...1.5.2)

Updates `ktor-client-jackson` from 1.5.1 to 1.5.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.1...1.5.2)

Updates `ktor-client-json` from 1.5.1 to 1.5.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.1...1.5.2)

Updates `ktor-server-netty` from 1.5.1 to 1.5.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.1...1.5.2)

Updates `ktor-server-core` from 1.5.1 to 1.5.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.1...1.5.2)

Updates `ktor-html-builder` from 1.5.1 to 1.5.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.1...1.5.2)

Updates `ktor-server-tests` from 1.5.1 to 1.5.2
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.1...1.5.2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-03-13 19:31:56 -06:00
7b68938e14 ButtonView: Adjust size of question marks 2021-03-13 18:45:18 -06:00
ee462715de Use different colors for YES_AUTO and NO; increase contrast slightly 2021-03-13 18:44:04 -06:00
a95da72e19 Attempt to make EntryPanelViewTest less flaky 2021-03-13 16:58:27 -06:00
3ece80f3da Remove unused class and resource 2021-03-13 16:35:27 -06:00
dependabot[bot]
e00ff99af7 Bump kotlin-stdlib-jdk8 from 1.4.30 to 1.4.31 (#821) 2021-03-11 06:20:02 -06:00
Quentin Hibon
fc26d7967f Make validation errors readable (#837)
Fixes #757.
2021-03-10 20:37:43 -06:00
9b753b07f8 Temporarily disable flaky test 2021-03-10 20:25:06 -06:00
dependabot[bot]
73deb535ef Bump kotlin-stdlib from 1.4.30 to 1.4.31 (#820)
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.4.30 to 1.4.31.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/commits)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-03-07 11:01:03 -06:00
dependabot[bot]
a733e6ddf0 Bump daggerVersion from 2.32 to 2.33 (#819)
Bumps `daggerVersion` from 2.32 to 2.33.

Updates `dagger` from 2.32 to 2.33
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.32...dagger-2.33)

Updates `dagger-compiler` from 2.32 to 2.33
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.32...dagger-2.33)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-03-07 11:00:49 -06:00
dependabot[bot]
86c7200e6b Bump desugar_jdk_libs from 1.1.1 to 1.1.5 (#818)
Bumps [desugar_jdk_libs](https://github.com/google/desugar_jdk_libs) from 1.1.1 to 1.1.5.
- [Release notes](https://github.com/google/desugar_jdk_libs/releases)
- [Changelog](https://github.com/google/desugar_jdk_libs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/desugar_jdk_libs/commits)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-03-07 11:00:35 -06:00
dependabot[bot]
15282e7ea6 Bump kotlin-css-jvm (#809)
Bumps kotlin-css-jvm from 1.0.0-pre.144-kotlin-1.4.30 to 1.0.0-pre.148-kotlin-1.4.30.

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-22 07:49:12 -06:00
Quentin Hibon
96f87df052 Implement task to generate translator layout from a text file (#759)
Related to #669
2021-02-22 07:46:52 -06:00
dependabot[bot]
bc623f044d Bump dexmaker-mockito from 2.28.0 to 2.28.1
Bumps [dexmaker-mockito](https://github.com/linkedin/dexmaker) from 2.28.0 to 2.28.1.
- [Release notes](https://github.com/linkedin/dexmaker/releases)
- [Changelog](https://github.com/linkedin/dexmaker/blob/master/CHANGELOG.md)
- [Commits](https://github.com/linkedin/dexmaker/compare/2.28.0...2.28.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-15 21:03:51 -06:00
dependabot[bot]
773eef26e7 Bump junit from 4.13.1 to 4.13.2
Bumps [junit](https://github.com/junit-team/junit4) from 4.13.1 to 4.13.2.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.13.1.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.13.1...r4.13.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-15 21:03:22 -06:00
b58af03a7c HabitBullCSVImporter: Accept multiple date formats
Fixes 762
2021-02-13 18:00:22 -06:00
c53997ffcc Update fa_star_half_o unicode 2021-02-13 09:02:17 -06:00
11d55bbf02 Write failing tests for EmptyListViewTest 2021-02-13 09:01:54 -06:00
Quentin Hibon
50ebff3edf Adapt message when all habits are completed
Closes #700.
2021-02-13 08:14:40 -06:00
8e1aa3d01e Merge pull request #784 from hiqua/fontawesome
Upgrade fontawesome to 5.15.2
2021-02-13 08:12:25 -06:00
dependabot[bot]
ea66cf04b3 Bump test-butler-library from 2.1.1 to 2.2.1 (#788)
Bumps [test-butler-library](https://github.com/linkedin/test-butler) from 2.1.1 to 2.2.1.
- [Release notes](https://github.com/linkedin/test-butler/releases)
- [Changelog](https://github.com/linkedin/test-butler/blob/master/CHANGELOG.md)
- [Commits](https://github.com/linkedin/test-butler/compare/2.1.1...2.2.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-12 07:09:11 -06:00
Quentin Hibon
b1da72dc3a Bump org.jlleitschuh.gradle.ktlint from 9.4.1 to 10.0.0 (#786) 2021-02-12 07:07:39 -06:00
Quentin Hibon
91bd17bb9e Upgrade fontawesome to 5.15.2 2021-02-10 16:06:55 +01:00
fca9557108 Merge pull request #776 from hiqua/fix_766
Restore notification sound customization setting
2021-02-09 07:36:31 -06:00
dependabot[bot]
d76a4a84d0 Bump daggerVersion from 2.31.2 to 2.32 (#779)
Bumps `daggerVersion` from 2.31.2 to 2.32.

Updates `dagger` from 2.31.2 to 2.32
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.31.2...dagger-2.32)

Updates `dagger-compiler` from 2.31.2 to 2.32
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.31.2...dagger-2.32)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-09 07:33:57 -06:00
Quentin Hibon
8790c0e87b Delete snooze_interval preference 2021-02-09 10:14:25 +01:00
Quentin Hibon
bc461e1239 Restore notification sound customization setting
For devices older than Android Oreo, notification sound customization has been
disabled since aadfac68cd. We enable it again.

Fixes #766.
2021-02-09 09:22:53 +01:00
589fd2f0f1 build.sh: Restore fetch-images and accept-images 2021-02-08 21:38:15 -06:00
dependabot[bot]
2e94bebcac Bump material from 1.2.1 to 1.3.0 (#764)
Bumps [material](https://github.com/material-components/material-components-android) from 1.2.1 to 1.3.0.
- [Release notes](https://github.com/material-components/material-components-android/releases)
- [Commits](https://github.com/material-components/material-components-android/compare/1.2.1...1.3.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-08 21:26:35 -06:00
dependabot[bot]
ff748b27a5 Bump kotlin-css-jvm (#763)
Bumps kotlin-css-jvm from 1.0.0-pre.144-kotlin-1.4.21 to 1.0.0-pre.144-kotlin-1.4.30.

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-08 21:26:20 -06:00
dependabot[bot]
8522318ed1 Bump kotlin-stdlib from 1.4.21 to 1.4.30 (#761)
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.4.21 to 1.4.30.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.4.21...v1.4.30)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-08 21:25:56 -06:00
dependabot[bot]
1f08d2f71c Bump kotlin-stdlib-jdk8 from 1.4.21 to 1.4.30 (#760)
Bumps [kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.4.21 to 1.4.30.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.4.21...v1.4.30)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-08 21:25:48 -06:00
Quentin Hibon
7fb3489ca8 Fix shellcheck warnings (#778) 2021-02-08 21:23:26 -06:00
129c86a030 about.xml: Sort developers by number of commits 2021-01-31 11:35:44 -06:00
e4121b2564 Merge branch 'master' into dev 2021-01-30 21:41:14 -06:00
98abebe099 Merge branch 'hotfix/v1.8.12' 2021-01-30 20:47:36 -06:00
0f86cb4d53 Update list of developers 2021-01-30 20:39:19 -06:00
Kristian Tashkov
4dd77463fb Update widgets at midnight (#634) 2021-01-30 20:36:37 -06:00
Quentin Hibon
2cf3347f8c Set dataOffset when attaching a new CardView
Fixes #713.
2021-01-30 20:15:26 -06:00
5516f40571 Bump version to 1.8.12; update CHANGELOG and release notes 2021-01-30 19:53:57 -06:00
c006659ba4 Use Nexus 4 screen size in build.sh; adjust BackupSteps accordingly 2021-01-30 19:42:10 -06:00
5be2c51d79 Regression tests: minor code cleanup 2021-01-30 19:22:32 -06:00
Quentin Hibon
2dcce080d3 Set dataOffset when attaching a new CardView
Fixes #713.
2021-01-30 18:36:07 -06:00
Quentin Hibon
6c3b4135c2 Implement test reproducing #713 2021-01-30 18:36:07 -06:00
48c1adb3bb HabitCardListAdapter: Return copy of list of selected items
Previously, HabitCardListAdapter returned a pointer to the list, instead of a
copy. By the time other parts of the application were reading the list, its
contents had already changed. This prevented the user from deleting or
archiving habits.
2021-01-30 10:28:42 -06:00
89bde4c9ae verifyDisplayGraphs: Update class names 2021-01-30 09:49:35 -06:00
a7e2e0e8da Acceptance tests: fix imports; remove unused function 2021-01-30 08:45:43 -06:00
64d77fbb6b build.sh: Use avdmanager from cmdline-tools 2021-01-30 08:30:14 -06:00
Quentin Hibon
4b80e60b2b Fix typo (#755) 2021-01-30 07:48:09 -06:00
dependabot[bot]
0f80505735 Bump guava from 30.0-android to 30.1-android (#750)
Bumps [guava](https://github.com/google/guava) from 30.0-android to 30.1-android.
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-28 21:37:59 -06:00
dependabot[bot]
c26c140310 Bump ktorVersion from 1.5.0 to 1.5.1 (#751)
Bumps `ktorVersion` from 1.5.0 to 1.5.1.

Updates `ktor-client-mock` from 1.5.0 to 1.5.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.0...1.5.1)

Updates `ktor-jackson` from 1.5.0 to 1.5.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.0...1.5.1)

Updates `ktor-client-android` from 1.5.0 to 1.5.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.0...1.5.1)

Updates `ktor-client-core` from 1.5.0 to 1.5.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.0...1.5.1)

Updates `ktor-client-jackson` from 1.5.0 to 1.5.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.0...1.5.1)

Updates `ktor-client-json` from 1.5.0 to 1.5.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.0...1.5.1)

Updates `ktor-server-netty` from 1.5.0 to 1.5.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.0...1.5.1)

Updates `ktor-server-core` from 1.5.0 to 1.5.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.0...1.5.1)

Updates `ktor-html-builder` from 1.5.0 to 1.5.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.0...1.5.1)

Updates `ktor-server-tests` from 1.5.0 to 1.5.1
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/1.5.0...1.5.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-28 21:37:22 -06:00
dependabot[bot]
c05e008569 Bump sqlite-jdbc from 3.25.2 to 3.34.0 (#748)
Bumps [sqlite-jdbc](https://github.com/xerial/sqlite-jdbc) from 3.25.2 to 3.34.0.
- [Release notes](https://github.com/xerial/sqlite-jdbc/releases)
- [Changelog](https://github.com/xerial/sqlite-jdbc/blob/master/CHANGELOG)
- [Commits](https://github.com/xerial/sqlite-jdbc/compare/3.25.2...3.34.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-28 21:35:48 -06:00
a5255690ed Revert to Kotlin 1.4.21
Kotlin 1.4.21-2 seems to be a pre-release.
2021-01-28 21:35:08 -06:00
56f0bbb7bd Remove unused equalsverifier dependency 2021-01-28 21:35:08 -06:00
4e72bf93f8 Issue templates: sort feature requests by popularity 2021-01-28 08:04:07 -06:00
d31e42446e Add "Help & FAQ" to issue template 2021-01-28 07:59:25 -06:00
dependabot[bot]
8ea71dc2b5 Bump kotlin-css-jvm (#744)
Bumps kotlin-css-jvm from 1.0.0-pre.143-kotlin-1.4.21 to 1.0.0-pre.144-kotlin-1.4.21.

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-28 07:11:08 -06:00
3ba26ac67e Merge pull request #747 from iSoron/dependabot/gradle/org.hamcrest-hamcrest-2.2
Bump hamcrest from 2.1 to 2.2
2021-01-28 07:01:51 -06:00
dependabot[bot]
8537e0f910 Bump hamcrest from 2.1 to 2.2
Bumps [hamcrest](https://github.com/hamcrest/JavaHamcrest) from 2.1 to 2.2.
- [Release notes](https://github.com/hamcrest/JavaHamcrest/releases)
- [Changelog](https://github.com/hamcrest/JavaHamcrest/blob/master/CHANGES.md)
- [Commits](https://github.com/hamcrest/JavaHamcrest/compare/v2.1...v2.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-28 07:17:40 +00:00
a6c9ea22e6 Merge branch 'midnight_delay_option_2' into dev 2021-01-27 20:06:44 -06:00
5767817de2 Midnight delay: Make text shorter 2021-01-27 20:06:31 -06:00
b80344a443 Merge pull request #743 from hiqua/update_mockito
Delete obsolete mockito dependencies
2021-01-27 20:01:40 -06:00
f36bc788c7 Merge pull request #740 from hiqua/sdk_30
Increase targetSdk to 30
2021-01-27 19:59:13 -06:00
dependabot[bot]
22136774de Bump simpleclient_hotspot from 0.9.0 to 0.10.0 (#742)
Bumps [simpleclient_hotspot](https://github.com/prometheus/client_java) from 0.9.0 to 0.10.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.9.0...parent-0.10.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-27 19:57:38 -06:00
dependabot[bot]
be39237a22 Bump simpleclient from 0.9.0 to 0.10.0 (#741)
Bumps [simpleclient](https://github.com/prometheus/client_java) from 0.9.0 to 0.10.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.9.0...parent-0.10.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-27 19:56:24 -06:00
dependabot[bot]
836eebd20b Bump kotlin-stdlib-jdk8 from 1.4.21 to 1.4.21-2 (#738)
Bumps [kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.4.21 to 1.4.21-2.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.4.21...v1.4.21-2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-27 19:54:55 -06:00
Quentin Hibon
8d2aebaf7f Delete obsolete mockito dependencies 2021-01-27 15:44:22 +01:00
dependabot[bot]
1c2efb6c22 Bump junit from 4.12 to 4.13.1 (#737) 2021-01-27 07:13:46 -06:00
dependabot[bot]
784877871a Bump opencsv from 3.10 to 5.3 (#735) 2021-01-27 07:13:27 -06:00
Quentin Hibon
4a2fb2ac47 Fix visual glitch on popups when using dark theme (#730) 2021-01-27 07:11:40 -06:00
dependabot[bot]
7caf22bd7a Bump ktorVersion from 1.4.2 to 1.5.0 (#728) 2021-01-27 07:11:06 -06:00
Quentin Hibon
2d943b5942 Fix signature of onSharedPreferenceChanged
The 'key' argument is null when called from android.app.SharedPreferencesImpl.
2021-01-27 12:09:23 +01:00
Quentin Hibon
dd4e0ee6f9 Increase targetSdk to 30 2021-01-27 11:00:50 +01:00
Quentin Hibon
bb8d4abb9e Implement the midnight delay option
Closes #694.
2021-01-27 09:52:28 +01:00
dependabot[bot]
64069a6e7f Bump kotlin-stdlib from 1.4.21 to 1.4.21-2 (#734)
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.4.21 to 1.4.21-2.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.4.21...v1.4.21-2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-26 22:12:35 -06:00
dependabot[bot]
9ead803b6c Bump logback-classic from 1.2.1 to 1.2.3 (#733)
Bumps logback-classic from 1.2.1 to 1.2.3.

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-26 22:12:19 -06:00
dependabot[bot]
af6387f1fc Bump kotlin-css-jvm (#731)
Bumps kotlin-css-jvm from 1.0.0-pre.31-kotlin-1.2.41 to 1.0.0-pre.143-kotlin-1.4.21.

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-26 22:12:03 -06:00
dependabot[bot]
6d0764bbb8 Bump simpleclient_httpserver from 0.9.0 to 0.10.0
Bumps [simpleclient_httpserver](https://github.com/prometheus/client_java) from 0.9.0 to 0.10.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.9.0...parent-0.10.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-26 20:10:44 -06:00
dependabot[bot]
eb9d017882 Bump commons-lang3 from 3.5 to 3.11
Bumps commons-lang3 from 3.5 to 3.11.

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-26 20:07:14 -06:00
dependabot[bot]
ec630ad1b1 Bump test-butler-library from 1.3.1 to 2.1.1
Bumps [test-butler-library](https://github.com/linkedin/test-butler) from 1.3.1 to 2.1.1.
- [Release notes](https://github.com/linkedin/test-butler/releases)
- [Changelog](https://github.com/linkedin/test-butler/blob/master/CHANGELOG.md)
- [Commits](https://github.com/linkedin/test-butler/compare/1.3.1...2.1.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-26 20:06:59 -06:00
Quentin Hibon
df30c7c764 Disable transparency for stacked widgets
Closes #687.
2021-01-26 20:06:12 -06:00
dependabot[bot]
7a73f9c8c7 Bump daggerVersion from 2.25.4 to 2.31.2 (#725) 2021-01-25 08:04:49 -06:00
045612c00f Add Dependabot configuration file 2021-01-25 07:10:40 -06:00
25d3587545 Add hiqua to list of developers 2021-01-25 06:51:26 -06:00
4ffd78545d Merge pull request #716 from hiqua/dev 2021-01-25 06:43:13 -06:00
Quentin Hibon
14d018c327 Convert Timestamp to data class 2021-01-25 12:18:05 +01:00
Quentin Hibon
f1c88797a3 Clean up code after conversions 2021-01-25 12:18:05 +01:00
Quentin Hibon
f882e18be9 Convert BaseUserInterfaceTest 2021-01-25 12:18:05 +01:00
Quentin Hibon
0fc9bb57ae Convert BaseViewTest 2021-01-25 12:18:05 +01:00
Quentin Hibon
22dcd9f7ae Convert AndroidTaskRunner 2021-01-25 12:18:05 +01:00
Quentin Hibon
7d361b2203 Convert Task and TaskRunner 2021-01-25 12:18:05 +01:00
Quentin Hibon
8131d37d8e Convert SingleThreadTaskRunner 2021-01-25 12:18:05 +01:00
Quentin Hibon
6485c3efee Convert ExportCSVTask 2021-01-25 12:18:05 +01:00
Quentin Hibon
2bfbff9b14 Convert ExportDBTask and ImportDataTask 2021-01-25 12:18:05 +01:00
Quentin Hibon
9a72141567 Convert PerformanceTest 2021-01-25 12:18:05 +01:00
Quentin Hibon
6992b5186e Clean up code after conversions 2021-01-25 12:18:05 +01:00
Quentin Hibon
18db571507 Properly check that a setter is never used 2021-01-25 12:18:05 +01:00
Quentin Hibon
09794ccb68 Move ThingRecord back into RepositoryTest 2021-01-25 12:18:05 +01:00
Quentin Hibon
7644f52dfd Don't open ThingRecord 2021-01-25 12:18:05 +01:00
Quentin Hibon
21fa636e0c Convert BaseAndroidTest 2021-01-25 12:18:05 +01:00
Quentin Hibon
df755d30ee Convert HabitsApplicationTest 2021-01-25 12:18:05 +01:00
Quentin Hibon
7f0c4626b0 Convert HabitFixtures (androidtest) 2021-01-25 12:18:05 +01:00
Quentin Hibon
ec42fda336 Convert AndroidDatabaseTest 2021-01-25 12:18:05 +01:00
Quentin Hibon
def9ff9746 Convert activities.common.views (androidTest) 2021-01-25 12:18:05 +01:00
Quentin Hibon
a7df0bde3e Convert core.models.sqlite 2021-01-25 12:18:05 +01:00
Quentin Hibon
1cec5a6067 Convert model memory 2021-01-25 12:18:05 +01:00
Quentin Hibon
a58cbffb81 Convert HabitList and ModelObservable 2021-01-25 12:18:05 +01:00
Quentin Hibon
30630c3358 Convert Timestamp 2021-01-25 12:18:05 +01:00
Quentin Hibon
98f9693cff Convert views 2021-01-25 12:18:05 +01:00
Quentin Hibon
228be95f9c convert widget tests 2021-01-25 12:18:05 +01:00
Quentin Hibon
457c58a660 Convert RepositoryTest 2021-01-25 12:18:05 +01:00
Quentin Hibon
39cec6f11d Convert Preferences 2021-01-25 12:18:05 +01:00
Quentin Hibon
8f5f72d9fd Convert ReminderScheduler 2021-01-25 10:56:59 +01:00
Quentin Hibon
b21eb3f118 Finish uhabits-core ui conversion 2021-01-25 10:56:59 +01:00
Quentin Hibon
136ec5b49b Convert most of code remaining in uhabits-core 2021-01-25 10:56:59 +01:00
Quentin Hibon
e84cc8e8b1 Convert HabitCardListCache 2021-01-25 10:56:59 +01:00
Quentin Hibon
26fb76f95f Add mockitokotlin dependency to androidTest 2021-01-25 10:56:59 +01:00
Quentin Hibon
68a8f9d356 Enable mockito inline extension 2021-01-25 10:56:59 +01:00
Quentin Hibon
f541f47476 Use correct BREAK_STRATEGY_BALANCED constant 2021-01-25 10:56:59 +01:00
Quentin Hibon
9d4cfbd270 Fix preferences 2021-01-25 10:56:59 +01:00
1869d05591 ScoreTest: Use static imports for hamcrest 2021-01-21 06:46:23 -06:00
3f8b1008b4 Merge branch 'feature/gradle.kts' into dev 2021-01-21 06:41:34 -06:00
e671949dd2 Merge pull request #709 from hiqua/dev 2021-01-21 06:24:11 -06:00
Quentin Hibon
dedeb13f46 Clean up kotlin code
* static imports
* less nullable types
* format
2021-01-19 14:06:18 +01:00
Quentin Hibon
9d0fbb9ea9 Convert WeekdayList 2021-01-18 16:13:19 +01:00
Quentin Hibon
97dcf98e2b Convert org.isoron.uhabits.utils 2021-01-18 16:13:19 +01:00
Quentin Hibon
25b25acc94 Convert org.isoron.uhabits.acceptance 2021-01-18 16:13:19 +01:00
Quentin Hibon
ac6df47818 Convert uhabits-core (jvmTest) 2021-01-18 16:13:19 +01:00
Quentin Hibon
0f828cbd3a Convert uhabits-android (test) 2021-01-18 16:13:19 +01:00
Quentin Hibon
eb8d39fbe3 Convert org.isoron.uhabits.core.ui.widgets 2021-01-18 16:13:19 +01:00
Quentin Hibon
11831a2b24 Convert org.isoron.uhabits.inject 2021-01-18 16:13:19 +01:00
Quentin Hibon
e9816a22a3 Convert SettingsFragment 2021-01-18 16:13:19 +01:00
Quentin Hibon
8165b5417f Convert HabitCardListAdapter 2021-01-18 16:13:19 +01:00
Quentin Hibon
714771fbc3 Convert org.isoron.uhabits.activities.common.dialogs 2021-01-18 16:13:19 +01:00
Quentin Hibon
a2a8dc4489 Mention git pre-commit hook in GUIDELINES.md 2021-01-18 16:13:19 +01:00
Quentin Hibon
bbe39f8523 Replace appendln with appendLine 2021-01-18 16:13:19 +01:00
Quentin Hibon
a69490a23a Update kotlin version 2021-01-18 16:02:48 +01:00
Quentin Hibon
b6223c3805 Fix outdated javadocs 2021-01-18 16:02:48 +01:00
e3524c112a Convert uhabits-android/build.gradle to Kotlin 2021-01-16 15:31:22 -06:00
8c0141508d Convert uhabits-server/build.gradle to Kotlin; use standard paths 2021-01-16 14:44:24 -06:00
8206450456 Convert top-level build.gradle to Kotlin 2021-01-16 13:55:26 -06:00
a5dfe0ec51 Convert uhabits-core/build.gradle to Kotlin 2021-01-16 09:45:23 -06:00
9a4aaf47bc Merge pull request #707 from hiqua/dev 2021-01-14 06:41:37 -06:00
Quentin Hibon
485e4245ff Fix kotlin null check 2021-01-12 18:25:08 +01:00
Quentin Hibon
72a7cd9685 Fix ambiguous @Module 2021-01-12 18:25:00 +01:00
Quentin Hibon
95a7c4f474 Fix gradle task 'ktlintApplyToIdea' 2021-01-12 17:36:11 +01:00
Quentin Hibon
f208601bc4 Convert uhabits.receivers to kotlin 2021-01-12 17:33:53 +01:00
Quentin Hibon
d5b9fda636 Convert SnoozeDelayPickerActivity to kotlin 2021-01-12 17:33:53 +01:00
99277491c8 Remove unused imports 2021-01-05 23:09:34 -06:00
2828dfcc75 Update copyright notices 2021-01-05 23:05:48 -06:00
b14aa668c2 Update BUILD.md 2021-01-05 22:57:11 -06:00
47de6243d3 Update GUIDELINES.md 2021-01-05 22:54:56 -06:00
7bad2c886b Fix GitHub Actions script 2021-01-05 22:31:49 -06:00
c4e496a5ff Update build scripts 2021-01-05 22:18:35 -06:00
7ee3e00e49 Create top-level gradle project; remove duplicated gradle wrappers 2021-01-05 22:03:01 -06:00
2f39b63723 Add ktlint to uhabits-core; clean up build.gradle 2021-01-05 21:24:20 -06:00
d279388884 Merge branch 'dev' into feature/kmm-merge 2021-01-05 20:43:37 -06:00
Marco Zanetti
358e1ccf42 Convert org.isoron.uhabits.core.utils to Kotlin (#699) 2021-01-05 20:33:49 -06:00
236d56bbf0 Remove unused files 2021-01-03 20:47:21 -06:00
68f9b8339f Flatten uhabits-android into a single gradle module 2021-01-03 20:44:55 -06:00
4a4356b72a Update build scripts 2021-01-03 17:35:31 -06:00
b71675585c Update path to uhabits-core-legacy 2021-01-03 14:52:17 -06:00
bebb356425 Reorganize top level directory 2021-01-03 14:43:49 -06:00
9fd36d8d53 Move uhabits-core to top level; all Java files to uhabits-core:jvmMain/jvmTest 2021-01-03 13:21:02 -06:00
1137088e20 Merge branch 'dev' into canvas 2021-01-03 12:02:32 -06:00
6f2b2ab883 Remove Google AutoFactory; expand Dagger imports
Fixes #681
2021-01-03 11:31:55 -06:00
d8fcc9160d Make uhabits-core a Kotlin multiplatform module 2021-01-03 10:21:28 -06:00
cb6843e08b Remove ShowHabitScreen and ShowHabitBehavior 2021-01-02 00:45:16 -06:00
162eac3bdf HistoryChart: Fix HistoryEditorDialog 2021-01-01 23:20:20 -06:00
e2d2b5b4b3 HistoryChart: Customizable first day of week 2021-01-01 17:47:28 -06:00
de3668db96 HistoryChart: Fix transparency 2021-01-01 11:32:38 -06:00
93a2ec3186 Replace HistoryChart by new Kotlin implementation 2021-01-01 09:36:23 -06:00
354c930d85 Replace BarChart by new Kotlin implementation 2020-12-31 15:20:00 -06:00
e97cdce467 Copy platform.{gui,io,time} from core; implement AndroidCanvas 2020-12-31 13:29:43 -06:00
13826f4934 ShowHabitActivity: Move presenters and view models to uhabits-core 2020-12-31 00:10:29 -06:00
1cdbc53dc5 EntryList: simplify groupBy 2020-12-30 22:45:33 -06:00
51b9517897 EntryList: remove getValues 2020-12-30 17:28:10 -06:00
a74a4b390b StreakList: Return copy of list, instead of a view to original list 2020-12-30 16:44:26 -06:00
79b134164a Convert remaining core.io classes to Kotlin 2020-12-30 16:36:27 -06:00
ced78e0b1f Update guidelines on code style 2020-12-30 15:29:26 -06:00
9087025418 Reformat all Kotlin files with ktlint; add check to build script 2020-12-30 15:15:12 -06:00
9a5263e508 Update GUIDELINES.md 2020-12-30 12:26:39 -06:00
75571e2eb0 Fix link 2020-12-30 12:23:21 -06:00
b5ed4b9a9c Merge branch 'dev' of github.com:iSoron/uhabits into dev 2020-12-30 12:19:42 -06:00
2daf08d22d Update developer guidelines 2020-12-30 12:18:19 -06:00
2e51c73ac0 Update README.md 2020-12-30 09:14:11 -06:00
298bb01762 Convert some core.io classes to Kotlin 2020-12-29 22:18:53 -06:00
a02c7bdc44 Convert core.database classes to Kotlin 2020-12-29 21:50:45 -06:00
feb3c98459 Convert HabitMatcher, Reminder and Streak to Kotlin 2020-12-29 20:21:38 -06:00
823d8bed7e Merge branch 'dev' of github.com:iSoron/uhabits into dev 2020-12-29 20:04:05 -06:00
68813580eb Merge branch 'master' into dev 2020-12-29 19:28:56 -06:00
6bc1b91cc6 Update README.md 2020-12-29 19:23:49 -06:00
56f91526e6 Update CHANGELOG 2020-12-29 18:51:12 -06:00
dbc6a16a98 Set forceDarkAllowed to false 2020-12-29 18:43:09 -06:00
4d3c5ad732 Convert HabitNotFoundException to Kotlin 2020-12-29 16:51:26 -06:00
307ff5c1ca Convert Frequency to Kotlin 2020-12-29 16:51:16 -06:00
3b86a17b49 Simplify StreakList 2020-12-29 16:20:45 -06:00
54fe849eef Remove MemoryStreakList.java 2020-12-29 15:04:18 -06:00
c023711d16 Convert ScoreList to Kotlin 2020-12-29 14:17:52 -06:00
9bc0f44777 ScoreList: Remove groupBy functions 2020-12-29 14:10:27 -06:00
4a3a767cb2 ScoreList: Recompute given interval 2020-12-29 13:42:11 -06:00
d0c37fef67 ScoreList: Remove reference to Habit 2020-12-29 13:24:12 -06:00
11863cd7b0 Simplify ScoreList 2020-12-29 12:53:14 -06:00
1c696e2561 Remove MemoryScoreList 2020-12-29 09:08:08 -06:00
43c5e450a8 Convert Score to Kotlin 2020-12-29 09:01:41 -06:00
0a84d8a1d8 ScoreList: Remove ModelObservable 2020-12-29 08:58:11 -06:00
354a4d08be buildEntriesFromInterval: selectively copy over 2020-12-29 08:50:46 -06:00
af93c0e488 BarChart: Update tests and images 2020-12-29 08:22:32 -06:00
b8aa322691 EntryList: Fix tests 2020-12-29 08:19:39 -06:00
a87987da87 Remove target from HistoryChart and BarChart 2020-12-29 08:14:17 -06:00
8b8e9d3980 EntryList: Make groupBy always return thousandths 2020-12-29 08:09:02 -06:00
a19f39308e Fixes to BarCard 2020-12-29 08:00:04 -06:00
0b23fbed86 Fix tests 2020-12-28 23:08:11 -06:00
d1eeb559cb Reorganize theme attributes; minor fixes to dialog style 2020-12-28 22:52:41 -06:00
2e4a82418f Fix usage of singular/plural in alert messages
Closes #405
Closes #131
2020-12-28 22:28:58 -06:00
fcdb400edf Merge branch 'Nirvyz/dev' into dev 2020-12-28 21:40:12 -06:00
Armand Dc
f80fb35e35 Fix color and font inconsistencies 2020-12-28 21:39:36 -06:00
056a7b722b build.sh: Replace wait by repeated checks 2020-12-28 21:17:35 -06:00
f4c0f353f3 Fix large tests for API 28 2020-12-28 21:12:03 -06:00
3fb7fbac51 build.sh: Create fresh AVD for large-tests 2020-12-28 21:11:41 -06:00
bd70746278 Fix UUID generation 2020-12-28 18:51:17 -06:00
c744d945a4 Redirect Help & FAQ to GitHub Discussions 2020-12-28 15:31:29 -06:00
f0696b3f60 Don't run actions when markdown files are changed 2020-12-28 14:50:39 -06:00
bc36f24551 FAQ: Fix typo 2020-12-28 14:47:14 -06:00
82b68b5f4e Update bug_report.md 2020-12-28 10:55:02 -06:00
e8238b5ed7 Enable widget stacks for all users 2020-12-28 10:35:30 -06:00
599f21fabb Delete feature_request.md 2020-12-27 21:18:15 -06:00
e91e2c1c96 Create config.yml 2020-12-27 21:17:48 -06:00
9f421bfd6d Add landing page source code 2020-12-27 19:18:42 -06:00
3a4071505e Update issue templates 2020-12-27 17:43:20 -06:00
344c4a324c Update README.md 2020-12-27 17:41:01 -06:00
0aca118546 Update bug_report.md 2020-12-27 17:25:34 -06:00
124c490f25 Update issue templates 2020-12-27 17:23:08 -06:00
0a5622c78e Simplify all command and convert them to Kotlin 2020-12-26 22:22:04 -06:00
373f21e247 Simplify CommandRunner and convert it to Kotlin 2020-12-26 22:01:23 -06:00
e80292e75d NumberButtonView: Display missing data as question marks 2020-12-26 12:14:18 -06:00
7173381d9b Rename Entries to EntryList 2020-12-26 11:59:27 -06:00
78f31a65d4 Remove EntryList 2020-12-26 11:54:05 -06:00
2e19fee83c Replace invalidateNewerThan by recompute; add newComputedEntries 2020-12-25 13:28:52 -06:00
f6754ff180 Implement Entries.getValues 2020-12-25 13:14:36 -06:00
3f74c77755 Replace RepetitionList by Entries 2020-12-24 20:35:33 -06:00
c904e22c0f Implement SQLiteEntries; rename RepetitionRecord to EntryRecord 2020-12-24 12:51:58 -06:00
27023e50ae HistoryEditorDialog: Listen to commands 2020-12-24 11:15:22 -06:00
0f2f010f94 EditHabitCommand: Notify listeners 2020-12-24 10:49:28 -06:00
cf2989d587 Refactor Habit 2020-12-24 10:41:01 -06:00
94c78ebb72 Write cleaner version of EntryList 2020-12-24 09:43:03 -06:00
d9be39b839 Remove MemoryRepetitionList 2020-12-23 19:56:34 -06:00
7fcad7b5c5 Remove MemoryEntryList 2020-12-23 19:47:41 -06:00
cfeef3651f Remove ModelObservable from EntryList 2020-12-23 19:25:42 -06:00
e849e8a5c2 Remove ModelObservable from RepetitionList 2020-12-23 19:17:54 -06:00
5bd21e68df Rename CheckmarkList to EntryList 2020-12-23 19:12:26 -06:00
71597ca89b Rename Checkmark to Entry 2020-12-23 19:08:31 -06:00
a3cf2877b8 Unify Checkmarks and Repetitions 2020-12-23 18:40:20 -06:00
23e9ccb236 Convert Repetition to Kotlin 2020-12-23 18:09:38 -06:00
7d97554cb1 Convert Checkmark to Kotlin 2020-12-23 17:59:09 -06:00
5f8c0d67b8 Convert AppScope to Kotlin 2020-12-23 17:45:12 -06:00
b468325f64 Replace Config.java by Constants.kt 2020-12-23 17:44:38 -06:00
39d23424d6 Remove CancelableTask 2020-12-23 15:51:45 -06:00
eba2dd0171 Remove HabitsActivity 2020-12-23 15:16:32 -06:00
1bdd44085c Clean up and update dependencies 2020-12-23 14:26:07 -06:00
596af6afe6 Remove android-base; move Dagger classes to uhabits.inject 2020-12-23 13:43:42 -06:00
3f3ddc3955 Remove BaseActivity and BaseScreen 2020-12-23 13:31:13 -06:00
a58c60b8ce Remove BaseRootView 2020-12-23 13:06:29 -06:00
b42ad0dd83 Refactor SettingsActivity; clean up BaseScreen 2020-12-23 12:50:14 -06:00
e0fbe841c1 Remove BaseSelectionMenu 2020-12-23 12:43:59 -06:00
3523b2c1a3 Remove BaseMenu 2020-12-23 12:23:23 -06:00
c15c14ffcd Simplify SyncActivity; make QR code always white 2020-12-23 11:27:59 -06:00
8cd729480f Remove ButterKnife 2020-12-23 11:18:25 -06:00
638bc2816f Refactor AboutActivity 2020-12-23 11:12:32 -06:00
826ea17cdd Refactor EditSettingActivity 2020-12-23 10:53:00 -06:00
19e221bb32 ShowHabitActivity: Re-enable menus and actions 2020-12-23 10:24:20 -06:00
85de69bca7 Remove unused HabitCard 2020-12-23 08:18:46 -06:00
7d5b9d0f63 Refactor BarCard 2020-12-23 08:15:40 -06:00
816ab71d83 Refactor HistoryCard 2020-12-22 20:09:00 -06:00
c230b5c40d Fix score widget name 2020-12-22 19:45:48 -06:00
71620a320d Refactor FrequencyCard 2020-12-22 19:41:38 -06:00
c016b0aecc Refactor ScoreCard 2020-12-22 19:21:05 -06:00
95b3028c95 Refactor StreakCard 2020-12-22 16:32:31 -06:00
ae4ac801a0 Restructure ShowHabitActivity 2020-12-22 16:17:40 -06:00
bda3e42e2b Create view-model and presenter for TargetCard; reduce boilerplate 2020-12-22 12:59:44 -06:00
4dc1df5887 Refactor TargetCard 2020-12-22 12:05:51 -06:00
302b9f5df4 Refactor SubtitleCard 2020-12-22 11:37:06 -06:00
c2d89c7a60 Refactor NotesCard 2020-12-22 10:37:49 -06:00
45574753c7 ShowHabitPresenter: Listen to commands and auto-update 2020-12-22 10:23:07 -06:00
c84c618ef0 Refactor OverviewCard 2020-12-22 10:07:45 -06:00
98d17d60a5 Refactor ShowHabitRootView; convert ShowHabitActivity to Kotlin 2020-12-22 09:17:39 -06:00
4c1c6e76fc Remove unused methods 2020-12-21 21:51:49 -06:00
ac1441aba5 Simplify commands 2020-12-21 21:49:12 -06:00
5d2ff40dc9 Replace primitive int by PaletteColor 2020-12-21 21:36:35 -06:00
63f2b80515 Remove AndroidDateUtils 2020-12-21 20:41:01 -06:00
52b25fbc72 Remove AndroidDateFormats 2020-12-21 20:29:41 -06:00
b94a887534 Remove redundant logError method 2020-12-21 20:25:48 -06:00
f6699fbfda Move SyncManager to uhabits-core 2020-12-21 18:20:43 -06:00
9743b05a78 Move sync package to org.isoron.uhabits.core 2020-12-21 17:13:08 -06:00
9681b7b5ef RemoteSyncServer: Improve logging 2020-12-21 17:08:55 -06:00
017bc50698 Move sync classes to uhabits-core 2020-12-21 17:08:55 -06:00
1e94456a74 Add server metrics 2020-12-21 17:08:55 -06:00
2fcba80f3a Server: Implement temporary links 2020-12-21 17:08:55 -06:00
fc4cbe84f0 Update README.md 2020-12-09 20:39:22 -06:00
011abf62a0 Bump version to 1.8.11 2020-12-09 20:01:35 -06:00
Sunxy88
9c96857262 Use dark theme in settings window. (#655) 2020-12-09 19:57:03 -06:00
4f55ec6ea8 Bump version number 2020-11-29 16:16:27 -06:00
8139088b39 Update README.md 2020-11-29 15:30:37 -06:00
44f7d13449 Include pre-release badge 2020-11-29 15:30:22 -06:00
1476 changed files with 34907 additions and 38105 deletions

36
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,36 @@
---
name: Bug report
about: Report something broken in the app
title: ''
labels: ''
assignees: ''
---
<!--
Please use the template below for your bug report. Issues that do not follow this
template, or that do not contain all necessary information (namely, description of
the problem, steps to reproduce, phone, phone operating system, and app version)
will be closed without further consideration.
-->
## Pre-submission checklist
- [ ] I am submitting a bug report, not a feature request.
- [ ] I have searched for similar issues, but did not find any matches.
## Description
A clear and concise description of what the problem is.
## Steps to reproduce
1. Go to ...
2. Click on ....
3. Scroll down to ....
4. See error
## System information
- Phone: [e.g. Google Pixel 4]
- Phone Operating System: [e.g. Android 10]
- App version: [e.g. 2.0.2]
## Screenshots
If applicable, add screenshots to help explain your problem.

8
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Feature requests
url: https://github.com/iSoron/uhabits/discussions/categories/feature-requests?discussions_q=category%3A%22Feature+Requests%22+sort%3Atop
about: Submit ideas for new features and for improving existing features
- name: Help & FAQ
url: https://github.com/iSoron/uhabits/discussions/categories/help-faq
about: Ask questions about using the app or setting up the project

6
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "gradle"
directory: "/"
schedule:
interval: "monthly"

View File

@@ -1,7 +1,13 @@
name: Build & Test
on: [push, pull_request]
on:
pull_request:
paths-ignore:
- '**.md'
push:
paths-ignore:
- '**.md'
jobs:
build:
Build:
runs-on: ubuntu-latest
steps:
- name: Check out source code
@@ -12,39 +18,48 @@ jobs:
with:
java-version: 1.8
- name: Build APK & Run small tests
run: android/build.sh build
- name: Build Project
run: ./build.sh build
- name: Upload APK
- name: Upload Build Artifacts
uses: actions/upload-artifact@v2
with:
name: debug-apk
path: android/build/*apk
name: uhabits-android
path: uhabits-android/build/outputs/
- name: Upload build outputs
uses: actions/upload-artifact@v2
with:
name: build
path: android/uhabits-android/build/outputs/
test:
needs: build
runs-on: macOS-latest
AndroidTest:
needs: Build
runs-on: macOS-10.15
timeout-minutes: 60
strategy:
matrix:
api-level: [23, 24, 25, 26, 27, 28, 29]
api: [
23,
24,
25,
26,
27,
28,
# 29, # Crashes constantly, see: https://issuetracker.google.com/issues/159732638
# 30, # Not available yet
# 31, # Not available yet
]
steps:
- name: Check out source code
uses: actions/checkout@v1
- name: Download previous build folder
- name: Download Previously Built APK
uses: actions/download-artifact@v2
with:
name: build
path: android/uhabits-android/build/outputs/
name: uhabits-android
path: uhabits-android/build/outputs/
- name: Install flock
run: |
brew install util-linux
echo "/usr/local/opt/util-linux/bin" >> $GITHUB_PATH
- name: Run Android Tests
run: ./build.sh android-tests ${{ matrix.api }}
- name: Run medium tests
uses: ReactiveCircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
script: android/build.sh medium-tests

View File

@@ -1,42 +0,0 @@
name: Build, Test & Publish
on:
push:
branches:
- master
jobs:
build:
runs-on: macOS-latest
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
steps:
- uses: actions/checkout@v1
- name: Install GPG
uses: olafurpg/setup-gpg@v2
- name: Decrypt secrets
env:
GPG_PASSWORD: ${{ secrets.GPG_PASSWORD }}
run: .secret/decrypt.sh
- name: Install Java Development Kit 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build APK & Run small tests
env:
RELEASE: 1
run: android/build.sh build
- name: Run medium tests
uses: ReactiveCircus/android-emulator-runner@v2.2.0
env:
RELEASE: 1
with:
api-level: 29
script: android/build.sh medium-tests
- name: Upload build to GitHub
uses: actions/upload-artifact@v1
with:
name: Build
path: android/uhabits-android/build/outputs/
- name: Upload APK to Google Play
run: cd android && ./gradlew publishReleaseApk

1
.gitignore vendored
View File

@@ -21,3 +21,4 @@ node_modules
/design
/releases
/screenshots
crowdin.yml

View File

@@ -1,235 +1,299 @@
# Changelog
### 2.0.0 (TBD)
## [2.0.3] - 2021-08-21
### Fixed
- Improve automatic checkmarks for monthly habits (@iSoron, #947)
- Fix small theme issues (@iSoron)
- Fix ANR on some Samsung phones (@iSoron, #962)
- Fix dates before the year 2000 (@iSoron, #967)
- Fix notification adding checkmarks to the wrong day (@hiqua, #969)
- Fix crashes in widgets (@hiqua, @iSoron, #907, #966, #965)
- Fix crash when moving habits (@hiqua, #968)
## [2.0.2] - 2021-05-23
### Changed
- Make checkmark widget resizable
* **New Features:**
* Track numerical habits (@iSoron, @namnl)
* Skip days without breaking streak (@KristianTashkov)
* Sort habits by status (@hiqua)
* Sort habits in reverse order (@iSoron)
* Add notes to habits (@recheej)
* Improve readibility of charts (@chennemann)
* Delay new day until 3am (@KristianTashkov)
* Export backups daily (@iSoron)
* **Bug fixes:**
* Reset chart offset when switching scale (@alxmjo)
* Don't show reminders from archived habits (@KristianTashkov)
* Lapses on non-daily habits decrease the score too much (@iSoron)
* Update widgets at midnight (@KristianTashkov)
* **Refactoring:**
* Convert files to Kotlin (@olegivo)
### Fixed
- Fix crash caused by numerical habits with zero target (@iSoron, #903)
- Fix small issues with font size (@iSoron)
- Allow fractional target values (@sumanabhi, #911)
- Fix IllegalStateException in androidx.customview.view (@iSoron, #906)
- Fix crash when selecting habit frequency in some languages (@iSoron, #926)
- Fix IllegalArgumentException in RingView (@iSoron, #904)
### 1.8.10 (Nov 26, 2020)
## [2.0.1] - 2021-05-09
* Update translations
### Added
- Make midnight delay optional and disabled by default (@hiqua)
- Add arrows to sort menu (@iSoron)
### 1.8.9 (Nov 18, 2020)
### Removed
- Temporarily remove experimental device sync functionality. This feature will be re-added in
Loop 2.1.
* Manage exceptions when activities don't exist to handle intents (#181)
* MemoryHabitList: Inherit parent's order (#598)
* Remove notification groups; revert to default system behavior
* Remove SyncManager and Internet permission
### Changed
- Make implicit checkmarks easier to read (@iSoron)
- Update and improve list of translators (@hiqua, @iSoron)
### 1.8.8 (June 21, 2020)
### Fixed
- Disable transparency for stacked widgets (@hiqua)
- Fix various color issues on the dark theme (@hiqua, @iSoron)
- Fix "customize notifications" on older devices (@hiqua)
- Fix snooze button in notifications when device is locked (@hiqua)
- Fix a crash when deleting habits (@engineering4good)
- Fix checkmark widget not rendering properly on some Samsung phones (@iSoron)
* Make small changes to the habit scheduling algorithm, so that "1 time every x days" habits work more predictably.
* Fix crash when saving habit
### Refactoring & Testing
- Finish conversion of the entire project to Kotlin (@hiqua, @iSoron, @MarKco)
- Automatically run large tests on GitHub Actions (@iSoron)
- Remove unused v21 resources (@hiqua)
### 1.8.0 (Jan 1, 2020)
## [2.0.0-alpha] - 2020-11-29
* New bar chart showing number of repetitions performed in each week, month, quarter or year.
* Improved calculation of streaks for non-daily habits: performing habits on irregular weekdays will no longer break your streak.
* Many more colors to choose from (now 20 in total).
* Ability to customize how transparent the widgets are on your home screen.
* Ability to customize the first day of the week.
* Yes/No buttons on notifications, instead of just "Check".
* Automatic dark theme according to phone settings (Android 10).
* Smaller APK and backup files.
* Many other internal code changes improving performance and stability.
### Added
- Track numeric habits (@iSoron, @namnl)
- Skip days without breaking streak (@KristianTashkov)
- Sort habits by status (@hiqua)
- Sort habits in reverse order (@iSoron)
- Add notes to habits (@recheej)
- Improve readibility of charts (@chennemann)
- Delay new day until 3am (@KristianTashkov)
- Export backups daily (@iSoron)
### 1.7.11 (Aug 10, 2019)
### Removed
- Drop support to devices older than Android 6.0 (API 23)
* Fix bug that produced corrupted CSV files in some countries
### Fixed
- Reset chart offset when switching scale (@alxmjo)
- Don't show reminders from archived habits (@KristianTashkov)
- Lapses on non-daily habits decrease the score too much (@iSoron)
- Update widgets at midnight (@KristianTashkov)
### 1.7.10 (June 15, 2019)
### Refactoring
- Convert files to Kotlin (@olegivo)
* Fix bug that prevented some devices from showing notifications.
* Update targetSdk to Android Pie (API level 28)
## [1.8.12] - 2021-01-30
### 1.7.8 (April 21, 2018)
- Fix bug that caused incorrect check marks to show after scrolling (#713)
- Fix issue preventing widgets from updating at midnight (#680)
* Add support for adaptive icons (Oreo)
* Add support for notification channels (Oreo)
* Update translations
## [1.8.11] - 2020-12-29
### 1.7.7 (September 30, 2017)
- Fix theme issues on Xiaomi phones
* Fix bug that caused reminders to show repeatedly on DST changes
## [1.8.10] - 2020-11-26
### 1.7.6 (July 18, 2017)
- Update translations
* Fix bug that caused widgets not to render sometimes
* Fix other minor bugs
* Update translations
## [1.8.9] - 2020-11-18
### 1.7.3 (May 30, 2017)
- Manage exceptions when activities don't exist to handle intents (#181)
- MemoryHabitList: Inherit parent's order (#598)
- Remove notification groups; revert to default system behavior
- Remove SyncManager and Internet permission
* Improve performance of 'sort by score'
* Other minor bug fixes
## [1.8.8] - 2020-06-21
### 1.7.2 (May 27, 2017)
- Make small changes to the habit scheduling algorithm, so that "1 time every x days" habits work more predictably.
- Fix crash when saving habit
* Fix crash at startup
## [1.8.0] - 2020-01-01
### 1.7.1 (May 21, 2017)
- New bar chart showing number of repetitions performed in each week, month, quarter or year.
- Improved calculation of streaks for non-daily habits: performing habits on irregular weekdays will no longer break your streak.
- Many more colors to choose from (now 20 in total).
- Ability to customize how transparent the widgets are on your home screen.
- Ability to customize the first day of the week.
- Yes/No buttons on notifications, instead of just "Check".
- Automatic dark theme according to phone settings (Android 10).
- Smaller APK and backup files.
- Many other internal code changes improving performance and stability.
* Fix crash (BadParcelableException)
* Fix layout for RTL languages such as Arabic
* Automatically detect and reject invalid database files
* Add Hebrew translation
## [1.7.11] - 2019-08-10
### 1.7.0 (Mar 31, 2017)
- Fix bug that produced corrupted CSV files in some countries
* Sort habits automatically
* Allow swiping the header to see previous days
* Import backups directly from Google Drive or Dropbox
* Refresh data automatically at midnight
* Other minor bug fixes and enhancements
## [1.7.10] - 2019-06-15
### 1.6.2 (Oct 13, 2016)
- Fix bug that prevented some devices from showing notifications.
- Update targetSdk to Android Pie (API level 28)
* Fix crash on Android 4.1
## [1.7.8] - 2018-04-21
### 1.6.1 (Oct 10, 2016)
- Add support for adaptive icons (Oreo)
- Add support for notification channels (Oreo)
- Update translations
* Fix a crash at startup when database is corrupted
## [1.7.7] - 2017-09-30
### 1.6.0 (Oct 10, 2016)
- Fix bug that caused reminders to show repeatedly on DST changes
* Add option to make notifications sticky
* Add option to hide completed habits
* Display total number of repetitions for each habit
* Pebble integration: check/snooze habits from the watch
* Tasker/Locale integration: allow third-party apps to add checkmarks
* Export an unified CSV file, with checkmarks for all the habits
* Increase width of name column according to screen size
* Stop showing reminders for archived habits
* Add Danish, Dutch, Greek, Hindi and Portuguese (PT) translations
* Other minor fixes and enhancements
## [1.7.6] - 2017-07-18
### 1.5.6 (Jun 19, 2016)
- Fix bug that caused widgets not to render sometimes
- Fix other minor bugs
- Update translations
* Fix bug that prevented checkmark widget from working
## [1.7.3] - 2017-05-30
### 1.5.5 (Jun 19, 2016)
- Improve performance of 'sort by score'
- Other minor bug fixes
* Fix bug that prevented check button on notification to work sometimes
* Fix bug that caused back button to apparently erase some checkmarks
* Complete French translation
* Add Croatian and Slovenian translations
## [1.7.2] - 2017-05-27
### 1.5.4 (May 29, 2016)
- Fix crash at startup
* Fix crash upon opening settings screen in some phones
* Fix missing folders in CSV archive
* Add Serbian translation
## [1.7.1] - 2017-05-21
### 1.5.3 (May 22, 2016)
- Fix crash (BadParcelableException)
- Fix layout for RTL languages such as Arabic
- Automatically detect and reject invalid database files
- Add Hebrew translation
* Complete Arabic and Czech translations
* Fix crash at startup
* Fix checkmark widget on custom launchers
## [1.7.0] - 2017-03-31
### 1.5.2 (May 19, 2016)
- Sort habits automatically
- Allow swiping the header to see previous days
- Import backups directly from Google Drive or Dropbox
- Refresh data automatically at midnight
- Other minor bug fixes and enhancements
* Fix missing attachment on bug reports
* Fix bug that prevents some widgets from rendering
* Complete Japanese translation
## [1.6.2] - 2016-10-13
### 1.5.1 (May 17, 2016)
- Fix crash on Android 4.1
* Fix build on F-Droid
## [1.6.1] - 2016-10-10
### 1.5.0 (May 15, 2016)
- Fix a crash at startup when database is corrupted
* Add night mode, with AMOLED support
* Backport material design to older devices
* Display more information on statistics screen
* Display score on main screen and checkmark widget
* Make widgets react immediately to touch
* Reschedule reminders after reboot
* Pick first day of the week according to country
* Add option to reverse order of days on main screen
* Add option to change notification sounds
* Add Catalan, Indonesian, Turkish, Ukrainian translations
* Switch between Simplified/Traditional Chinese according to country
## [1.6.0] - 2016-10-10
### 1.4.1 (April 9, 2016)
- Add option to make notifications sticky
- Add option to hide completed habits
- Display total number of repetitions for each habit
- Pebble integration: check/snooze habits from the watch
- Tasker/Locale integration: allow third-party apps to add checkmarks
- Export an unified CSV file, with checkmarks for all the habits
- Increase width of name column according to screen size
- Stop showing reminders for archived habits
- Add Danish, Dutch, Greek, Hindi and Portuguese (PT) translations
- Other minor fixes and enhancements
* Show error message on widgets, instead of crashing
* Complete French translation
* Minor fixes to other translations
## [1.5.6] - 2016-06-19
### 1.4.0 (April 7, 2016)
- Fix bug that prevented checkmark widget from working
* Ability to import data from third-party apps
* Ability to save and restore full database backup
* Show more information on streak chart
* Simplify interface for creating habits
* Add link to Frequently Asked Questions (FAQ)
* Reduce app loading time and lag on widgets
* Generate bug reports on crash and from settings screen
* Disable vibration according to phone settings
* Add Czech translation
* Fix wrong month names for some languages
## [1.5.5] - 2016-06-19
### 1.3.3 (March 20, 2016)
- Fix bug that prevented check button on notification to work sometimes
- Fix bug that caused back button to apparently erase some checkmarks
- Complete French translation
- Add Croatian and Slovenian translations
* Add Spanish and Korean translations
* Make small corrections to other translations
* Fix incorrect date in history calendar
## [1.5.4] - 2016-05-29
### 1.3.2 (March 18, 2016)
- Fix crash upon opening settings screen in some phones
- Fix missing folders in CSV archive
- Add Serbian translation
* Add Arabic, Italian, Polish, Russian and Swedish translations
* Minor fixes to German and French translations
* Minor bug fixes
## [1.5.3] - 2016-05-22
### 1.3.1 (March 15, 2016)
- Complete Arabic and Czech translations
- Fix crash at startup
- Fix checkmark widget on custom launchers
* Fixes crash on devices with large screen, such as the Nexus 10
* Fixes crash when clicking widgets and reminders of deleted habits
* Other minor bug fixes
## [1.5.2] - 2016-05-19
### 1.3.0 (March 12, 2016)
- Fix missing attachment on bug reports
- Fix bug that prevents some widgets from rendering
- Complete Japanese translation
* New frequency plot: view total repetitions per day of week
* New history editor: put checkmarks in the past
* Add German, French and Japanese translations
* Add about screen, with credits to all contributors
* Fix small bug that prevented habit from being reordered
* Fix small bug caused by rotating the device
## [1.5.1] - 2016-05-17
### 1.2.0 (March 4, 2016)
- Fix build on F-Droid
* Ability to export habit data as CSV
* Widgets (checkmark, history, score and streaks)
* More natural scrolling on data views (fling)
* Minor UI improvements on pre-Lollipop devices
* Fix crash on Samsung Galaxy TabS 8.4
* Other minor bug fixes
## [1.5.0] - 2016-05-15
### 1.1.1 (February 24, 2016)
- Add night mode, with AMOLED support
- Backport material design to older devices
- Display more information on statistics screen
- Display score on main screen and checkmark widget
- Make widgets react immediately to touch
- Reschedule reminders after reboot
- Pick first day of the week according to country
- Add option to reverse order of days on main screen
- Add option to change notification sounds
- Add Catalan, Indonesian, Turkish, Ukrainian translations
- Switch between Simplified/Traditional Chinese according to country
* Show reminder only on chosen days of the week
* Rearrange habits by long-pressing then dragging
* Select and modify multiple habits simultaneously
* 12/24 hour format according to phone preferences
* Permanently delete habits
* Usage hints during startup
* Translation to Brazilian Portuguese and Chinese
* Other minor fixes
## [1.4.1] - 2016-04-09
### 1.0.0 (February 19, 2016)
- Show error message on widgets, instead of crashing
- Complete French translation
- Minor fixes to other translations
* Initial release
## [1.4.0] - 2016-04-07
- Ability to import data from third-party apps
- Ability to save and restore full database backup
- Show more information on streak chart
- Simplify interface for creating habits
- Add link to Frequently Asked Questions (FAQ)
- Reduce app loading time and lag on widgets
- Generate bug reports on crash and from settings screen
- Disable vibration according to phone settings
- Add Czech translation
- Fix wrong month names for some languages
## [1.3.3] - 2016-03-20
- Add Spanish and Korean translations
- Make small corrections to other translations
- Fix incorrect date in history calendar
## [1.3.2] - 2016-03-18
- Add Arabic, Italian, Polish, Russian and Swedish translations
- Minor fixes to German and French translations
- Minor bug fixes
## [1.3.1] - 2016-03-15
- Fixes crash on devices with large screen, such as the Nexus 10
- Fixes crash when clicking widgets and reminders of deleted habits
- Other minor bug fixes
## [1.3.0] - 2016-03-12
- New frequency plot: view total repetitions per day of week
- New history editor: put checkmarks in the past
- Add German, French and Japanese translations
- Add about screen, with credits to all contributors
- Fix small bug that prevented habit from being reordered
- Fix small bug caused by rotating the device
## [1.2.0] - 2016-03-04
- Ability to export habit data as CSV
- Widgets (checkmark, history, score and streaks)
- More natural scrolling on data views (fling)
- Minor UI improvements on pre-Lollipop devices
- Fix crash on Samsung Galaxy TabS 8.4
- Other minor bug fixes
## [1.1.1] - 2016-02-24
- Show reminder only on chosen days of the week
- Rearrange habits by long-pressing then dragging
- Select and modify multiple habits simultaneously
- 12/24 hour format according to phone preferences
- Permanently delete habits
- Usage hints during startup
- Translation to Brazilian Portuguese and Chinese
- Other minor fixes
## [1.0.0] - 2016-02-19
- Initial release

View File

@@ -1,11 +1,15 @@
<a href="https://github.com/iSoron/uhabits/actions?query=workflow%3A%22Build+%26+Test%22">
<img src="https://github.com/iSoron/uhabits/workflows/Build%20&%20Test/badge.svg" />
</a>
<a href="https://github.com/iSoron/uhabits/releases">
<img src="https://img.shields.io/github/v/release/iSoron/uhabits" />
</a>
# Loop Habit Tracker
<h1 align="center">Loop Habit Tracker</h1>
<p align="center">
<a href="https://github.com/iSoron/uhabits/actions?query=workflow%3A%22Build+%26+Test%22">
<img src="https://github.com/iSoron/uhabits/workflows/Build%20&%20Test/badge.svg" />
</a>
<a href="https://github.com/iSoron/uhabits/releases/latest">
<img src="https://img.shields.io/github/v/release/iSoron/uhabits" />
</a>
<a href="https://github.com/iSoron/uhabits/discussions">
<img src="https://img.shields.io/badge/GitHub-Discussions-%23fc4ebc" />
</a>
</p>
Loop is a mobile app that helps you create and maintain good habits,
allowing you to achieve your long-term goals. Detailed graphs and statistics
@@ -14,7 +18,7 @@ source.
<p align="center">
<a href="https://play.google.com/store/apps/details?id=org.isoron.uhabits&utm_source=global_co&utm_medium=prtnr&utm_content=Mar2515&utm_campaign=PartBadge&pcampaignid=MKT-AC-global-none-all-co-pr-py-PartBadges-Oct1515-1"><img alt="Get it on Google Play" src="https://play.google.com/intl/en_us/badges/images/apps/en-play-badge-border.png" height="75px"/></a>
<a href="http://f-droid.org/app/org.isoron.uhabits"><img alt="Get it on F-Droid" src="http://i.imgur.com/baSPE7X.png" height="75px"/></a>
<a href="https://f-droid.org/app/org.isoron.uhabits"><img alt="Get it on F-Droid" src="https://i.imgur.com/baSPE7X.png" height="75px"/></a>
</p>
## Screenshots
@@ -70,8 +74,10 @@ contribute, even if you are not a software developer.
* **Report bugs, suggest features.** The easiest way to contribute is to simply
use the app and let us know if you find any problems or have any suggestions
to improve it. You can either use the link inside the app, or open an issue
at GitHub. If you would like to receive the newest versions of the app
to improve it. To report a problem, please [create a new bug report](https://github.com/iSoron/uhabits/issues/new/choose).
To request a new feature or vote on existing feature requests, please visit
our [GitHub Discussions page](https://github.com/iSoron/uhabits/discussions/categories/feature-requests).
If you would like to receive the newest versions of the app
earlier than everyone else, [join our open beta on Google Play][beta].
* **Spread the word.** If you like the app, share it with your family, friends
@@ -84,13 +90,13 @@ contribute, even if you are not a software developer.
is already completed, you are also very welcome to join and proofread it.
* **Write some code.** If you are an Android developer, you are very welcome to
contribute with code. Please, see the [developer guidelines][dev-guide] for more details.
contribute with code. Please see `docs/GUIDELINES.md`.
## License
<img align="right" src="https://www.gnu.org/graphics/gplv3-88x31.png">
Copyright (C) 2016-2019 Álinson Santos Xavier <isoron@gmail.com>
Copyright (C) 2016-2021 Álinson Santos Xavier <isoron@gmail.com>
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
@@ -103,24 +109,23 @@ contribute, even if you are not a software developer.
more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
with this program. If not, see <https://www.gnu.org/licenses/>.
[screen1]: screenshots/uhabits1.png
[screen2]: screenshots/uhabits2.png
[screen3]: screenshots/uhabits3.png
[screen4]: screenshots/uhabits4.png
[screen5]: screenshots/uhabits5.png
[screen6]: screenshots/uhabits6.png
[screen1th]: screenshots/uhabits1_th.png
[screen2th]: screenshots/uhabits2_th.png
[screen3th]: screenshots/uhabits3_th.png
[screen4th]: screenshots/uhabits4_th.png
[screen5th]: screenshots/uhabits5_th.png
[screen6th]: screenshots/uhabits6_th.png
[poedit]: http://translate.loophabits.org
[screen1]: screenshots/1.png
[screen2]: screenshots/2.png
[screen3]: screenshots/3.png
[screen4]: screenshots/4.png
[screen5]: screenshots/5.png
[screen6]: screenshots/6.png
[screen1th]: screenshots/1.thumb.png
[screen2th]: screenshots/2.thumb.png
[screen3th]: screenshots/3.thumb.png
[screen4th]: screenshots/4.thumb.png
[screen5th]: screenshots/5.thumb.png
[screen6th]: screenshots/6.thumb.png
[poedit]: https://translate.loophabits.org
[playstore]: https://play.google.com/store/apps/details?id=org.isoron.uhabits
[releases]: https://github.com/iSoron/uhabits/releases
[fdroid]: http://f-droid.org/app/org.isoron.uhabits
[dev-guide]: https://github.com/iSoron/uhabits/wiki/Developer-guidelines
[build]: https://github.com/iSoron/uhabits/wiki/Developer-guidelines#building
[fdroid]: https://f-droid.org/app/org.isoron.uhabits
[build]: https://github.com/iSoron/uhabits/blob/dev/docs/BUILD.md
[beta]: https://play.google.com/apps/testing/org.isoron.uhabits

View File

@@ -1 +0,0 @@
/build

View File

@@ -1,33 +0,0 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
compileSdkVersion COMPILE_SDK_VERSION as Integer
defaultConfig {
minSdkVersion MIN_SDK_VERSION as Integer
targetSdkVersion TARGET_SDK_VERSION as Integer
buildConfigField 'int', 'VERSION_CODE', "$VERSION_CODE"
buildConfigField 'String', 'VERSION_NAME', "\"$VERSION_NAME\""
}
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
checkReleaseBuilds false
abortOnError false
}
}
dependencies {
implementation "com.google.dagger:dagger:$DAGGER_VERSION"
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation "org.apache.commons:commons-lang3:3.5"
annotationProcessor "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$KOTLIN_VERSION"
}

View File

@@ -1,25 +0,0 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /gemini-b/opt/android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -1,2 +0,0 @@
<manifest package="org.isoron.androidbase"
xmlns:android="http://schemas.android.com/apk/res/android"/>

View File

@@ -1,48 +0,0 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.androidbase
import android.content.Context
import java.security.KeyStore
import java.security.cert.CertificateFactory
import javax.inject.Inject
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManagerFactory
class SSLContextProvider @Inject constructor(@param:AppContext private val context: Context) {
fun getCACertSSLContext(): SSLContext {
try {
val cf = CertificateFactory.getInstance("X.509")
val ca = cf.generateCertificate(context.assets.open("cacert.pem"))
val ks = KeyStore.getInstance(KeyStore.getDefaultType()).apply {
load(null, null)
setCertificateEntry("ca", ca)
}
val alg = TrustManagerFactory.getDefaultAlgorithm()
val tmf = TrustManagerFactory.getInstance(alg).apply {
init(ks)
}
return SSLContext.getInstance("TLS").apply {
init(null, tmf.trustManagers, null)
}
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}

View File

@@ -1,104 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.androidbase.activities
import android.R.anim
import android.content.*
import android.os.*
import android.view.*
import androidx.appcompat.app.*
import org.isoron.androidbase.*
/**
* Base class for all activities in the application.
*
* This class delegates the responsibilities of an Android activity to other classes. For example,
* callbacks related to menus are forwarded to a []BaseMenu], while callbacks related to activity
* results are forwarded to a [BaseScreen].
*
*
* A BaseActivity also installs an [java.lang.Thread.UncaughtExceptionHandler] to the main thread.
* By default, this handler is an instance of BaseExceptionHandler, which logs the exception to the
* disk before the application crashes. To the default handler, you should override the method
* getExceptionHandler.
*/
abstract class BaseActivity : AppCompatActivity() {
private var baseMenu: BaseMenu? = null
private var screen: BaseScreen? = null
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
if (menu != null) baseMenu?.onCreate(menuInflater, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
if (item == null) return false
return baseMenu?.onItemSelected(item) ?: false
}
fun restartWithFade(cls: Class<*>?) {
Handler().postDelayed({
finish()
overridePendingTransition(anim.fade_in, anim.fade_out)
startActivity(Intent(this, cls))
}, 500) // HACK: Let the menu disappear first
}
fun setBaseMenu(baseMenu: BaseMenu?) {
this.baseMenu = baseMenu
}
fun setScreen(screen: BaseScreen?) {
this.screen = screen
}
fun showDialog(dialog: AppCompatDialogFragment, tag: String?) {
dialog.show(supportFragmentManager, tag)
}
fun showDialog(dialog: AppCompatDialog) {
dialog.show()
}
override fun onActivityResult(request: Int, result: Int, data: Intent?) {
val screen = screen
if(screen == null) super.onActivityResult(request, result, data)
else screen.onResult(request, result, data)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Thread.setDefaultUncaughtExceptionHandler(getExceptionHandler())
}
private fun getExceptionHandler() = BaseExceptionHandler(this)
override fun onResume() {
super.onResume()
screen?.reattachDialogs()
}
override fun startActivity(intent: Intent?) {
try {
super.startActivity(intent)
} catch(e: ActivityNotFoundException) {
this.screen?.showMessage(R.string.activity_not_found)
}
}
}

View File

@@ -1,81 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.androidbase.activities
import android.view.*
import androidx.annotation.*
/**
* Base class for all the menus in the application.
*
* This class receives from BaseActivity all callbacks related to menus, such as
* menu creation and click events. It also handles some implementation details
* of creating menus in Android, such as inflating the resources.
*/
abstract class BaseMenu(private val activity: BaseActivity) {
/**
* Declare that the menu has changed, and should be recreated.
*/
fun invalidate() {
activity.invalidateOptionsMenu()
}
/**
* Called when the menu is first displayed.
*
* The given menu is already inflated and ready to receive items. The
* application should override this method and add items to the menu here.
*
* @param menu the menu that is being created.
*/
open fun onCreate(menu: Menu) {}
/**
* Called when the menu is first displayed.
*
* This method should not be overridden. The application should override
* the methods onCreate(Menu) and getMenuResourceId instead.
*
* @param inflater a menu inflater, for creating the menu
* @param menu the menu that is being created.
*/
fun onCreate(inflater: MenuInflater, menu: Menu) {
menu.clear()
inflater.inflate(getMenuResourceId(), menu)
onCreate(menu)
}
/**
* Called whenever an item on the menu is selected.
*
* @param item the item that was selected.
* @return true if the event was consumed, or false otherwise
*/
open fun onItemSelected(item: MenuItem): Boolean = false
/**
* Returns the id of the resource that should be used to inflate this menu.
*
* @return id of the menu resource.
*/
@MenuRes
protected abstract fun getMenuResourceId(): Int
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.androidbase.activities
import android.content.Context
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.view.View
import android.widget.FrameLayout
import androidx.appcompat.widget.Toolbar
import org.isoron.androidbase.R
import org.isoron.androidbase.utils.InterfaceUtils.dpToPixels
import org.isoron.androidbase.utils.StyledResources
/**
* Base class for all root views in the application.
*
*
* A root view is an Android view that is directly attached to an activity. This
* view usually includes a toolbar and a progress bar. This abstract class hides
* some of the complexity of setting these things up, for every version of
* Android.
*/
abstract class BaseRootView(context: Context) : FrameLayout(context) {
var displayHomeAsUp = false
var screen: BaseScreen? = null
private set
open fun getToolbar(): Toolbar {
return findViewById(R.id.toolbar)
?: throw RuntimeException("Your BaseRootView should have a toolbar with id R.id.toolbar")
}
open fun getToolbarColor(): Int = StyledResources(context).getColor(R.attr.colorPrimary)
protected open fun initToolbar() {
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
getToolbar().elevation = dpToPixels(context, 2f)
findViewById<View>(R.id.toolbarShadow)?.visibility = View.GONE
findViewById<View>(R.id.headerShadow)?.visibility = View.GONE
}
}
fun onAttachedToScreen(screen: BaseScreen?) {
this.screen = screen
}
}

View File

@@ -1,237 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.androidbase.activities
import android.content.*
import android.graphics.*
import android.graphics.drawable.*
import android.view.*
import android.widget.*
import androidx.annotation.*
import androidx.appcompat.app.*
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.Toolbar
import androidx.core.content.*
import com.google.android.material.snackbar.*
import org.isoron.androidbase.*
import org.isoron.androidbase.utils.*
import org.isoron.androidbase.utils.ColorUtils.mixColors
import org.isoron.androidbase.utils.InterfaceUtils.dpToPixels
import java.io.*
/**
* Base class for all screens in the application.
*
* Screens are responsible for deciding what root views and what menus should be attached to the
* main window. They are also responsible for showing other screens and for receiving their results.
*/
open class BaseScreen(@JvmField protected var activity: BaseActivity) {
private var rootView: BaseRootView? = null
private var selectionMenu: BaseSelectionMenu? = null
private var snackbar: Snackbar? = null
/**
* Notifies the screen that its contents should be updated.
*/
fun invalidate() {
rootView?.invalidate()
}
fun invalidateToolbar() {
rootView?.let { root ->
activity.runOnUiThread {
val toolbar = root.getToolbar()
activity.setSupportActionBar(toolbar)
activity.supportActionBar?.let { actionBar ->
actionBar.setDisplayHomeAsUpEnabled(root.displayHomeAsUp)
val color = root.getToolbarColor()
setActionBarColor(actionBar, color)
setStatusBarColor(color)
}
}
}
}
/**
* Called when another Activity has finished, and has returned some result.
*
* @param requestCode the request code originally supplied to startActivityForResult.
* @param resultCode the result code sent by the other activity.
* @param data an Intent containing extra data sent by the other
* activity.
* @see {@link android.app.Activity.onActivityResult
*/
open fun onResult(requestCode: Int, resultCode: Int, data: Intent?) {}
/**
* Called after activity has been recreated, and the dialogs should be
* reattached to their controllers.
*/
open fun reattachDialogs() {}
/**
* Sets the menu to be shown by this screen.
*
*
* This menu will be visible if when there is no active selection operation.
* If the provided menu is null, then no menu will be shown.
*
* @param menu the menu to be shown.
*/
fun setMenu(menu: BaseMenu?) {
activity.setBaseMenu(menu)
}
/**
* Sets the root view for this screen.
*
* @param rootView the root view for this screen.
*/
fun setRootView(rootView: BaseRootView?) {
this.rootView = rootView
activity.setContentView(rootView)
rootView?.let {
it.onAttachedToScreen(this)
invalidateToolbar()
}
}
/**
* Sets the menu to be shown when a selection is active on the screen.
*
* @param menu the menu to be shown during a selection
*/
fun setSelectionMenu(menu: BaseSelectionMenu?) {
selectionMenu = menu
}
/**
* Shows a message on the screen.
*
* @param stringId the string resource id for this message.
*/
fun showMessage(@StringRes stringId: Int?, rootView: View?) {
var snackbar = this.snackbar
if (stringId == null || rootView == null) return
if (snackbar == null) {
snackbar = Snackbar.make(rootView, stringId, Snackbar.LENGTH_SHORT)
val tvId = R.id.snackbar_text
val tv = snackbar.view.findViewById<TextView>(tvId)
tv.setTextColor(Color.WHITE)
this.snackbar = snackbar
}
snackbar.setText(stringId)
snackbar.show()
}
fun showMessage(@StringRes stringId: Int?) {
showMessage(stringId, this.rootView)
}
fun showSendEmailScreen(@StringRes toId: Int, @StringRes subjectId: Int, content: String?) {
val to = activity.getString(toId)
val subject = activity.getString(subjectId)
activity.startActivity(Intent().apply {
action = Intent.ACTION_SEND
type = "message/rfc822"
putExtra(Intent.EXTRA_EMAIL, arrayOf(to))
putExtra(Intent.EXTRA_SUBJECT, subject)
putExtra(Intent.EXTRA_TEXT, content)
})
}
fun showSendFileScreen(archiveFilename: String) {
val file = File(archiveFilename)
val fileUri = FileProvider.getUriForFile(activity, "org.isoron.uhabits", file)
activity.startActivity(Intent().apply {
action = Intent.ACTION_SEND
type = "application/zip"
putExtra(Intent.EXTRA_STREAM, fileUri)
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
})
}
/**
* Instructs the screen to start a selection.
*
* If a selection menu was provided, this menu will be shown instead of the regular one.
*/
fun startSelection() {
activity.startSupportActionMode(ActionModeWrapper())
}
private fun setActionBarColor(actionBar: ActionBar, color: Int) {
val drawable = ColorDrawable(color)
actionBar.setBackgroundDrawable(drawable)
}
private fun setStatusBarColor(baseColor: Int) {
val darkerColor = mixColors(baseColor, Color.BLACK, 0.75f)
activity.window.statusBarColor = darkerColor
}
private inner class ActionModeWrapper : ActionMode.Callback {
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
val selectionMenu = selectionMenu
if (item == null || selectionMenu == null) return false
return selectionMenu.onItemClicked(item)
}
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
if (mode == null || menu == null) return false
val selectionMenu = selectionMenu ?: return false
selectionMenu.onCreate(activity.menuInflater, mode, menu)
return true
}
override fun onDestroyActionMode(mode: ActionMode?) {
selectionMenu?.onFinish()
}
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
val selectionMenu = selectionMenu
if (selectionMenu == null || menu == null) return false
return selectionMenu.onPrepare(menu)
}
}
companion object {
@JvmStatic
@Deprecated("")
fun getDefaultActionBarColor(context: Context) =
StyledResources(context).getColor(R.attr.colorPrimary)
@JvmStatic
@Deprecated("")
fun setupActionBarColor(activity: AppCompatActivity, color: Int) {
val toolbar = activity.findViewById<Toolbar>(R.id.toolbar) ?: return
activity.setSupportActionBar(toolbar)
val supportActionBar = activity.supportActionBar ?: return
supportActionBar.setDisplayHomeAsUpEnabled(true)
val drawable = ColorDrawable(color)
supportActionBar.setBackgroundDrawable(drawable)
val darkerColor = mixColors(color, Color.BLACK, 0.75f)
activity.window.statusBarColor = darkerColor
toolbar.elevation = dpToPixels(activity, 2f)
activity.findViewById<View>(R.id.toolbarShadow)?.visibility = View.GONE
activity.findViewById<View>(R.id.headerShadow)?.visibility = View.GONE
}
}
}

View File

@@ -1,107 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.androidbase.activities
import android.view.*
import androidx.appcompat.view.ActionMode
/**
* Base class for all the selection menus in the application.
*
* A selection menu is a menu that appears when the screen starts a selection
* operation. It contains actions that modify the selected items, such as delete
* or archive. Since it replaces the toolbar, it also has a title.
*
* This class hides many implementation details of creating such menus in
* Android. The interface is supposed to look very similar to [BaseMenu],
* with a few additional methods, such as finishing the selection operation.
* Internally, it uses an [ActionMode].
*/
abstract class BaseSelectionMenu {
private var actionMode: ActionMode? = null
/**
* Finishes the selection operation.
*/
fun finish() {
actionMode?.finish()
}
/**
* Declare that the menu has changed, and should be recreated.
*/
fun invalidate() {
actionMode?.invalidate()
}
/**
* Called when the menu is first displayed.
*
* This method should not be overridden. The application should override
* the methods onCreate(Menu) and getMenuResourceId instead.
*
* @param inflater a menu inflater, for creating the menu
* @param mode the action mode associated with this menu.
* @param menu the menu that is being created.
*/
fun onCreate(inflater: MenuInflater, mode: ActionMode, menu: Menu) {
actionMode = mode
inflater.inflate(getResourceId(), menu)
onCreate(menu)
}
/**
* Called when the selection operation is about to finish.
*/
open fun onFinish() {}
/**
* Called whenever an item on the menu is selected.
*
* @param item the item that was selected.
* @return true if the event was consumed, or false otherwise
*/
open fun onItemClicked(item: MenuItem): Boolean = false
/**
* Called whenever the menu is invalidated.
*
* @param menu the menu to be refreshed
* @return true if the menu has changes, false otherwise
*/
open fun onPrepare(menu: Menu): Boolean = false
/**
* Sets the title of the selection menu.
*
* @param title the new title.
*/
fun setTitle(title: String?) {
actionMode?.title = title
}
protected abstract fun getResourceId(): Int
/**
* Called when the menu is first created.
*
* @param menu the menu being created
*/
protected fun onCreate(menu: Menu) {}
}

View File

@@ -1,6 +0,0 @@
<resources>
<item name="toolbar" type="id" />
<item name="toolbarShadow" type="id" />
<item name="headerShadow" type="id" />
<attr name="palette" format="reference"/>
</resources>

View File

@@ -1 +0,0 @@
/build

View File

@@ -1,24 +0,0 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion COMPILE_SDK_VERSION as Integer
defaultConfig {
minSdkVersion MIN_SDK_VERSION as Integer
targetSdkVersion TARGET_SDK_VERSION as Integer
}
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
checkReleaseBuilds false
abortOnError false
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.0.0'
}

View File

@@ -1,25 +0,0 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /gemini-b/opt/android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -1,2 +0,0 @@
<manifest package="com.android"
xmlns:android="http://schemas.android.com/apk/res/android"/>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="select_hours"/>
<string name="select_minutes"/>
<string name="color_picker_default_title"/>
<string name="clear"/>
<string name="clear_label"/>
<string name="done_label"/>
</resources>

View File

@@ -1,21 +0,0 @@
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:$BUILD_TOOLS_VERSION"
classpath "com.neenbedankt.gradle.plugins:android-apt:1.8"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$KOTLIN_VERSION"
classpath "org.ajoberstar:grgit:1.5.0"
}
}
allprojects {
repositories {
google()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
jcenter()
}
}

View File

@@ -1,283 +0,0 @@
#!/bin/bash
# Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
# 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 <http://www.gnu.org/licenses/>.
cd "$(dirname "$0")"
ADB="${ANDROID_HOME}/platform-tools/adb"
EMULATOR="${ANDROID_HOME}/tools/emulator"
GRADLE="./gradlew --stacktrace"
PACKAGE_NAME=org.isoron.uhabits
OUTPUTS_DIR=uhabits-android/build/outputs
VERSION=$(cat gradle.properties | grep VERSION_NAME | sed -e 's/.*=//g;s/ //g')
if [ ! -f "${ANDROID_HOME}/platform-tools/adb" ]; then
echo "Error: ANDROID_HOME is not set correctly"
exit 1
fi
log_error() {
if [ ! -z "$TEAMCITY_VERSION" ]; then
echo "###teamcity[progressMessage '$1']"
else
local COLOR='\033[1;31m'
local NC='\033[0m'
echo -e "$COLOR>>> $1 $NC"
fi
}
log_info() {
if [ ! -z "$TEAMCITY_VERSION" ]; then
echo "###teamcity[progressMessage '$1']"
else
local COLOR='\033[1;32m'
local NC='\033[0m'
echo -e "$COLOR>>> $1 $NC"
fi
}
fail() {
log_error "BUILD FAILED"
exit 1
}
if [ ! -z $RELEASE ]; then
log_info "Reading secret env variables from ../.secret/env"
source ../.secret/env || fail
fi
run_adb_as_root() {
log_info "Running adb as root"
$ADB root
}
build_apk() {
log_info "Removing old APKs..."
rm -vf build/*.apk
if [ ! -z $RELEASE ]; then
log_info "Building release APK"
$GRADLE assembleRelease
cp -v uhabits-android/build/outputs/apk/release/uhabits-android-release.apk build/loop-$VERSION-release.apk
fi
log_info "Building debug APK"
$GRADLE assembleDebug --stacktrace || fail
cp -v uhabits-android/build/outputs/apk/debug/uhabits-android-debug.apk build/loop-$VERSION-debug.apk
}
build_instrumentation_apk() {
log_info "Building instrumentation APK"
if [ ! -z $RELEASE ]; then
$GRADLE assembleAndroidTest \
-Pandroid.injected.signing.store.file=$LOOP_KEY_STORE \
-Pandroid.injected.signing.store.password=$LOOP_STORE_PASSWORD \
-Pandroid.injected.signing.key.alias=$LOOP_KEY_ALIAS \
-Pandroid.injected.signing.key.password=$LOOP_KEY_PASSWORD || fail
else
$GRADLE assembleAndroidTest || fail
fi
}
uninstall_apk() {
log_info "Uninstalling existing APK"
$ADB uninstall ${PACKAGE_NAME}
}
install_test_butler() {
log_info "Installing Test Butler"
$ADB uninstall com.linkedin.android.testbutler
$ADB install tools/test-butler-app-2.0.2.apk
}
install_apk() {
log_info "Installing APK"
if [ ! -z $RELEASE ]; then
$ADB install -r ${OUTPUTS_DIR}/apk/release/uhabits-android-release.apk || fail
else
$ADB install -t -r ${OUTPUTS_DIR}/apk/debug/uhabits-android-debug.apk || fail
fi
}
install_test_apk() {
log_info "Uninstalling existing test APK"
$ADB uninstall ${PACKAGE_NAME}.test
log_info "Installing test APK"
$ADB install -r ${OUTPUTS_DIR}/apk/androidTest/debug/uhabits-android-debug-androidTest.apk || fail
}
run_instrumented_tests() {
SIZE=$1
log_info "Running instrumented tests"
$ADB shell am instrument \
-r -e coverage true -e size $SIZE \
-w ${PACKAGE_NAME}.test/androidx.test.runner.AndroidJUnitRunner \
| tee ${OUTPUTS_DIR}/instrument.txt
if grep "\(INSTRUMENTATION_STATUS_CODE.*-1\|FAILURES\)" $OUTPUTS_DIR/instrument.txt; then
log_error "Some instrumented tests failed"
fetch_images
fetch_logcat
exit 1
fi
#mkdir -p ${OUTPUTS_DIR}/code-coverage/connected/
#$ADB pull /data/user/0/${PACKAGE_NAME}/files/coverage.ec \
# ${OUTPUTS_DIR}/code-coverage/connected/ \
# || log_error "COVERAGE REPORT NOT AVAILABLE"
}
parse_instrumentation_results() {
log_info "Parsing instrumented test results"
java -jar tools/automator-log-converter-1.5.0.jar ${OUTPUTS_DIR}/instrument.txt || fail
}
generate_coverage_badge() {
log_info "Generating code coverage badge"
CORE_REPORT=uhabits-core/build/reports/jacoco/test/jacocoTestReport.xml
rm -f ${OUTPUTS_DIR}/coverage-badge.svg
python3 tools/coverage-badge/badge.py -i $CORE_REPORT -o ${OUTPUTS_DIR}/coverage-badge
}
fetch_logcat() {
log_info "Fetching logcat"
$ADB logcat -d > ${OUTPUTS_DIR}/logcat.txt
}
run_jvm_tests() {
log_info "Running JVM tests"
if [ ! -z $RELEASE ]; then
$GRADLE testReleaseUnitTest :uhabits-core:check || fail
else
$GRADLE testDebugUnitTest :uhabits-core:check || fail
fi
}
uninstall_test_apk() {
log_info "Uninstalling test APK"
$ADB uninstall ${PACKAGE_NAME}.test
}
fetch_images() {
log_info "Fetching images"
rm -rf $OUTPUTS_DIR/test-screenshots
$ADB pull /sdcard/Android/data/${PACKAGE_NAME}/files/test-screenshots/ $OUTPUTS_DIR
$ADB shell rm -r /sdcard/Android/data/${PACKAGE_NAME}/files/test-screenshots/
}
accept_images() {
find $OUTPUTS_DIR/test-screenshots -name '*.expected*' -delete
rsync -av $OUTPUTS_DIR/test-screenshots/ uhabits-android/src/androidTest/assets/
}
run_tests() {
SIZE=$1
run_adb_as_root
install_test_butler
uninstall_apk
install_apk
install_test_apk
run_instrumented_tests $SIZE
parse_instrumentation_results
fetch_logcat
uninstall_test_apk
}
parse_opts() {
OPTS=`getopt -o r --long release -n 'build.sh' -- "$@"`
if [ $? != 0 ] ; then exit 1; fi
eval set -- "$OPTS"
while true; do
case "$1" in
-r | --release ) RELEASE=1; shift ;;
* ) break ;;
esac
done
}
remove_build_dir() {
rm -rfv .gradle
rm -rfv build
rm -rfv android-base/build
rm -rfv android-pickers/build
rm -rfv uhabits-android/build
rm -rfv uhabits-core/build
}
case "$1" in
build)
shift; parse_opts $*
build_apk
build_instrumentation_apk
run_jvm_tests
#generate_coverage_badge
;;
medium-tests)
shift; parse_opts $*
for attempt in {1..3}; do
(run_tests medium) && exit 0
done
exit 1
;;
large-tests)
shift; parse_opts $*
run_tests large
;;
fetch-images)
fetch_images
;;
accept-images)
accept_images
;;
install)
shift; parse_opts $*
build_apk
install_apk
;;
clean)
remove_build_dir
;;
*)
cat <<END
Usage: $0 <command> [options]
Builds, installs and tests Loop Habit Tracker
Commands:
accept-images Copies fetched images to corresponding assets folder
build Build APK and run JVM tests
clean Remove build directory
fetch-images Fetches failed view test images from device
install Install app on connected device
large-tests Run large-sized tests on connected device
medium-tests Run medium-sized tests on connected device
Options:
-r --release Build and test release APK, instead of debug
END
exit 1
;;
esac

View File

@@ -1,20 +0,0 @@
VERSION_CODE = 20000
VERSION_NAME = 2.0.0-alpha
MIN_SDK_VERSION = 23
TARGET_SDK_VERSION = 29
COMPILE_SDK_VERSION = 29
DAGGER_VERSION = 2.25.4
KOTLIN_VERSION = 1.4.0
KX_COROUTINES_VERSION = 1.4.2
SUPPORT_LIBRARY_VERSION = 28.0.0
AUTO_FACTORY_VERSION = 1.0-beta6
BUILD_TOOLS_VERSION = 4.1.0
KTOR_VERSION=1.4.2
org.gradle.parallel=false
org.gradle.daemon=true
org.gradle.jvmargs=-Xms2048m -Xmx2048m -XX:MaxPermSize=2048m
android.useAndroidX=true
android.enableJetifier=true

View File

@@ -1,6 +0,0 @@
#Sat Nov 28 09:55:24 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip

View File

@@ -1 +0,0 @@
uhabits-android/src/main/play/

View File

@@ -1 +0,0 @@
include ':uhabits-android', ':uhabits-core', ':android-base', ':android-pickers'

View File

@@ -1,157 +0,0 @@
"""
Generate coverage badges for Coverage.py.
Forked from https://github.com/dbrgn/coverage-badge
"""
# -*- coding: utf-8 -*-
from __future__ import print_function, division, absolute_import, unicode_literals
import os
import sys
import argparse
import pkg_resources
from bs4 import BeautifulSoup
__version__ = '0.2.0-uhabits'
DEFAULT_COLOR = '#a4a61d'
COLORS = {
'brightgreen': '#4c1',
'green': '#97CA00',
'yellowgreen': '#a4a61d',
'yellow': '#dfb317',
'orange': '#fe7d37',
'red': '#e05d44',
'lightgrey': '#9f9f9f',
}
COLOR_RANGES = [
(95, 'brightgreen'),
(90, 'green'),
(75, 'yellowgreen'),
(60, 'yellow'),
(40, 'orange'),
(0, 'red'),
]
class Devnull(object):
"""
A file like object that does nothing.
"""
def write(self, *args, **kwargs):
pass
def get_total(report):
missed = 0
covered = 0
for r in report.split(":"):
doc = BeautifulSoup(open(r), 'xml')
tag = doc.select("report > counter[type^INST]")[0]
missed = missed + float(tag['missed'])
covered = covered + float(tag['covered'])
return str(int(round(100 * covered / (missed + covered))))
def get_color(total):
"""
Return color for current coverage percent
"""
try:
xtotal = int(total)
except ValueError:
return COLORS['lightgrey']
for range_, color in COLOR_RANGES:
if xtotal >= range_:
return COLORS[color]
def get_badge(total, color=DEFAULT_COLOR):
"""
Read the SVG template from the package, update total, return SVG as a
string.
"""
template_path = os.path.join('templates', 'flat.svg')
template = pkg_resources.resource_string(__name__, template_path).decode('utf8')
return template.replace('{{ total }}', total).replace('{{ color }}', color)
def parse_args(argv=None):
"""
Parse the command line arguments.
"""
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('-o', dest='filepath',
help='Save the file to the specified path.')
parser.add_argument('-p', dest='plain_color', action='store_true',
help='Plain color mode. Standard green badge.')
parser.add_argument('-f', dest='force', action='store_true',
help='Force overwrite image, use with -o key.')
parser.add_argument('-q', dest='quiet', action='store_true',
help='Don\'t output any non-error messages.')
parser.add_argument('-v', dest='print_version', action='store_true',
help='Show version.')
parser.add_argument('-i', dest='reportFilename',
help='Jacoco report')
# If arguments have been passed in, use them.
if argv:
return parser.parse_args(argv)
# Otherwise, just use sys.argv directly.
else:
return parser.parse_args()
def save_badge(badge, filepath, force=False):
"""
Save badge to the specified path.
"""
# Validate path (part 1)
if filepath.endswith('/'):
print('Error: Filepath may not be a directory.')
sys.exit(1)
# Get absolute filepath
path = os.path.abspath(filepath)
if not path.lower().endswith('.svg'):
path += '.svg'
# Validate path (part 2)
if not force and os.path.exists(path):
print('Error: "{}" already exists.'.format(path))
sys.exit(1)
# Write file
with open(path, 'w') as f:
f.write(badge)
return path
def main(argv=None):
"""
Console scripts entry point.
"""
args = parse_args(argv)
# Print version
if args.print_version:
print('coverage-badge v{}'.format(__version__))
sys.exit(0)
total = get_total(args.reportFilename)
color = DEFAULT_COLOR if args.plain_color else get_color(total)
badge = get_badge(total, color)
# Show or save output
if args.filepath:
path = save_badge(badge, args.filepath, args.force)
if not args.quiet:
print('Saved badge to {}'.format(path))
else:
print(badge, end='')
if __name__ == '__main__':
main()

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="99" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<mask id="a">
<rect width="99" height="20" rx="3" fill="#fff"/>
</mask>
<g mask="url(#a)">
<path fill="#555" d="M0 0h63v20H0z"/>
<path fill="{{ color }}" d="M63 0h36v20H63z"/>
<path fill="url(#b)" d="M0 0h99v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="31.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
<text x="31.5" y="14">coverage</text>
<text x="80" y="15" fill="#010101" fill-opacity=".3">{{ total }}%</text>
<text x="80" y="14">{{ total }}%</text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 926 B

View File

@@ -1,156 +0,0 @@
plugins {
id 'idea'
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'com.github.triplet.play' version '2.6.2'
id 'kotlin-android-extensions'
}
android {
compileSdkVersion COMPILE_SDK_VERSION as Integer
def secretPropsFile = file("../../.secret/gradle.properties")
if (secretPropsFile.exists()) {
def secrets = new Properties()
secretPropsFile.withInputStream { secrets.load(it) }
signingConfigs {
release {
storeFile file(secrets.LOOP_KEY_STORE)
storePassword secrets.LOOP_STORE_PASSWORD
keyAlias secrets.LOOP_KEY_ALIAS
keyPassword secrets.LOOP_KEY_PASSWORD
}
}
buildTypes.release.signingConfig signingConfigs.release
}
defaultConfig {
versionCode VERSION_CODE as Integer
versionName "$VERSION_NAME"
minSdkVersion MIN_SDK_VERSION as Integer
targetSdkVersion TARGET_SDK_VERSION as Integer
applicationId "org.isoron.uhabits"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
debug {
testCoverageEnabled true
}
}
lintOptions {
checkReleaseBuilds false
abortOnError false
disable 'GoogleAppIndexingWarning'
}
compileOptions {
coreLibraryDesugaringEnabled true
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
testOptions {
unitTests.all {
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen { false }
showStandardStreams = true
}
}
}
sourceSets {
main.assets.srcDirs += '../uhabits-core/src/main/resources/'
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation project(":uhabits-core")
implementation project(":android-base")
implementation project(":android-pickers")
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation "com.github.paolorotolo:appintro:3.4.0"
implementation "com.google.dagger:dagger:$DAGGER_VERSION"
implementation "com.jakewharton:butterknife:8.6.1-SNAPSHOT"
implementation "org.apmem.tools:layouts:1.10"
implementation "com.google.code.gson:gson:2.8.5"
implementation "com.google.code.findbugs:jsr305:3.0.2"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$KOTLIN_VERSION"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$KX_COROUTINES_VERSION"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$KX_COROUTINES_VERSION"
implementation "androidx.constraintlayout:constraintlayout:2.0.0-beta4"
implementation 'com.google.zxing:core:3.4.1'
implementation "io.ktor:ktor-client-core:$KTOR_VERSION"
implementation "io.ktor:ktor-client-android:$KTOR_VERSION"
implementation "io.ktor:ktor-client-json:$KTOR_VERSION"
implementation "io.ktor:ktor-client-jackson:$KTOR_VERSION"
implementation "com.google.guava:guava:30.0-android"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
compileOnly "javax.annotation:jsr250-api:1.0"
compileOnly "com.google.auto.factory:auto-factory:$AUTO_FACTORY_VERSION"
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
kapt "com.jakewharton:butterknife-compiler:10.2.1"
annotationProcessor "com.google.auto.factory:auto-factory:$AUTO_FACTORY_VERSION"
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
androidTestImplementation "com.google.dagger:dagger:$DAGGER_VERSION"
androidTestImplementation "com.linkedin.testbutler:test-butler-library:1.3.1"
androidTestCompileOnly "com.google.auto.factory:auto-factory:$AUTO_FACTORY_VERSION"
androidTestAnnotationProcessor "com.google.auto.factory:auto-factory:$AUTO_FACTORY_VERSION"
androidTestImplementation 'androidx.annotation:annotation:1.0.0'
androidTestImplementation 'androidx.test:rules:1.1.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation "io.ktor:ktor-client-mock:$KTOR_VERSION"
androidTestImplementation "io.ktor:ktor-jackson:$KTOR_VERSION"
androidTestImplementation project(":uhabits-core")
kaptAndroidTest "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
// mockito-android 2+ includes net.bytebuddy, which causes tests to fail.
// Excluding the package net.bytebuddy on AndroidManifest.xml breaks some
// AndroidJUnitRunner functionality, such as running individual methods.
androidTestImplementation "org.mockito:mockito-core:1.10.19"
androidTestImplementation "com.google.dexmaker:dexmaker-mockito:1.2"
testImplementation "com.google.dagger:dagger:$DAGGER_VERSION"
testImplementation "org.mockito:mockito-core:2.8.9"
testImplementation "org.mockito:mockito-inline:2.8.9"
testImplementation "junit:junit:4.12"
implementation('com.opencsv:opencsv:3.10') {
exclude group: 'commons-logging', module: 'commons-logging'
}
implementation('io.socket:socket.io-client:0.8.3') {
exclude group: 'org.json', module: 'json'
}
}
kapt {
correctErrorTypes = true
}
play {
serviceAccountCredentials = file("../../.secret/gcp-key.json")
track = "alpha"
}

View File

@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<lint>
</lint>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,287 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits;
import android.appwidget.*;
import android.content.*;
import android.content.res.*;
import android.os.*;
import android.util.*;
import androidx.annotation.*;
import androidx.test.filters.*;
import androidx.test.platform.app.*;
import androidx.test.uiautomator.*;
import junit.framework.*;
import org.isoron.androidbase.*;
import org.isoron.androidbase.activities.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.preferences.*;
import org.isoron.uhabits.core.tasks.*;
import org.isoron.uhabits.core.utils.*;
import org.junit.*;
import java.io.*;
import java.time.*;
import java.util.*;
import java.util.concurrent.*;
import static androidx.test.platform.app.InstrumentationRegistry.*;
import static androidx.test.uiautomator.UiDevice.*;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*;
@MediumTest
public class BaseAndroidTest extends TestCase
{
// 8:00am, January 25th, 2015 (UTC)
public static final long FIXED_LOCAL_TIME = 1422172800000L;
protected Context testContext;
protected Context targetContext;
protected Preferences prefs;
protected HabitList habitList;
protected TaskRunner taskRunner;
protected HabitFixtures fixtures;
protected CountDownLatch latch;
protected HabitsApplicationTestComponent appComponent;
protected ModelFactory modelFactory;
protected HabitsActivityTestComponent component;
private boolean isDone = false;
private UiDevice device;
@Override
@Before
public void setUp()
{
if (Looper.myLooper() == null) Looper.prepare();
device = getInstance(getInstrumentation());
targetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
testContext = InstrumentationRegistry.getInstrumentation().getContext();
DateUtils.setFixedLocalTime(FIXED_LOCAL_TIME);
DateUtils.setStartDayOffset(0, 0);
setResolution(2.0f);
setTheme(R.style.AppBaseTheme);
setLocale("en", "US");
latch = new CountDownLatch(1);
appComponent = DaggerHabitsApplicationTestComponent
.builder()
.appContextModule(new AppContextModule(targetContext.getApplicationContext()))
.build();
HabitsApplication.Companion.setComponent(appComponent);
prefs = appComponent.getPreferences();
habitList = appComponent.getHabitList();
taskRunner = appComponent.getTaskRunner();
modelFactory = appComponent.getModelFactory();
prefs.clear();
fixtures = new HabitFixtures(modelFactory, habitList);
fixtures.purgeHabits(appComponent.getHabitList());
Habit habit = fixtures.createEmptyHabit();
component = DaggerHabitsActivityTestComponent
.builder()
.activityContextModule(new ActivityContextModule(targetContext))
.habitsApplicationComponent(appComponent)
.build();
}
protected void assertWidgetProviderIsInstalled(Class componentClass)
{
ComponentName provider =
new ComponentName(targetContext, componentClass);
AppWidgetManager manager = AppWidgetManager.getInstance(targetContext);
List<ComponentName> installedProviders = new LinkedList<>();
for (AppWidgetProviderInfo info : manager.getInstalledProviders())
installedProviders.add(info.provider);
assertThat(installedProviders, hasItems(provider));
}
protected void awaitLatch() throws InterruptedException
{
assertTrue(latch.await(1, TimeUnit.SECONDS));
}
protected void setLocale(@NonNull String language, @NonNull String country)
{
Locale locale = new Locale(language, country);
Locale.setDefault(locale);
Resources res = targetContext.getResources();
Configuration config = res.getConfiguration();
config.setLocale(locale);
}
protected void setResolution(float r)
{
DisplayMetrics dm = targetContext.getResources().getDisplayMetrics();
dm.density = r;
dm.scaledDensity = r;
InterfaceUtils.setFixedResolution(r);
}
protected void runConcurrently(Runnable... runnableList) throws Exception
{
isDone = false;
ExecutorService executor = Executors.newFixedThreadPool(100);
List<Future> futures = new LinkedList<>();
for (Runnable r : runnableList)
futures.add(executor.submit(() ->
{
while (!isDone) r.run();
return null;
}));
Thread.sleep(3000);
isDone = true;
executor.shutdown();
for(Future f : futures) f.get();
while (!executor.isTerminated()) Thread.sleep(50);
}
protected void setTheme(@StyleRes int themeId)
{
targetContext.setTheme(themeId);
StyledResources.setFixedTheme(themeId);
}
protected void sleep(int time)
{
try
{
Thread.sleep(time);
}
catch (InterruptedException e)
{
fail();
}
}
public long timestamp(int year, int month, int day)
{
GregorianCalendar cal = DateUtils.getStartOfTodayCalendar();
cal.set(year, month, day);
return cal.getTimeInMillis();
}
protected void startTracing()
{
File dir = new AndroidDirFinder(targetContext).getFilesDir("Profile");
assertNotNull(dir);
String tracePath = dir.getAbsolutePath() + "/performance.trace";
Log.d("PerformanceTest", String.format("Saving trace file to %s", tracePath));
Debug.startMethodTracingSampling(tracePath, 0, 1000);
}
protected void stopTracing()
{
Debug.stopMethodTracing();
}
protected Timestamp day(int offset)
{
return DateUtils.getToday().minus(offset);
}
public void setSystemTime(String tz,
int year,
int javaMonth,
int day,
int hourOfDay,
int minute) throws Exception
{
GregorianCalendar cal = new GregorianCalendar();
cal.set(Calendar.SECOND, 0);
cal.set(year, javaMonth, day, hourOfDay, minute);
cal.setTimeZone(TimeZone.getTimeZone(tz));
setSystemTime(cal);
}
private void setSystemTime(GregorianCalendar cal) throws Exception
{
ZoneId tz = cal.getTimeZone().toZoneId();
// Set time zone (temporary)
String command = String.format("service call alarm 3 s16 %s", tz);
device.executeShellCommand(command);
// Set time zone (permanent)
command = String.format("setprop persist.sys.timezone %s", tz);
device.executeShellCommand(command);
// Set time
String date = String.format("%02d%02d%02d%02d%02d.%02d",
cal.get(Calendar.MONTH) + 1,
cal.get(Calendar.DAY_OF_MONTH),
cal.get(Calendar.HOUR_OF_DAY),
cal.get(Calendar.MINUTE),
cal.get(Calendar.YEAR),
cal.get(Calendar.SECOND));
// Set time (method 1)
// Run twice to override daylight saving time
device.executeShellCommand("date " + date);
device.executeShellCommand("date " + date);
// Set time (method 2)
// Run in addition to the method above because one of these mail fail, depending
// on the Android API version.
command = String.format("date -u @%d", cal.getTimeInMillis() / 1000);
device.executeShellCommand(command);
// Wait for system events to settle
Thread.sleep(1000);
}
private GregorianCalendar savedCalendar = null;
public void saveSystemTime()
{
savedCalendar = new GregorianCalendar();
}
public void restoreSystemTime() throws Exception
{
if (savedCalendar == null) throw new NullPointerException();
setSystemTime(savedCalendar);
}
}

View File

@@ -1,135 +0,0 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits;
import android.content.*;
import androidx.test.uiautomator.*;
import com.linkedin.android.testbutler.*;
import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.preferences.*;
import org.isoron.uhabits.core.ui.screens.habits.list.*;
import org.isoron.uhabits.core.utils.*;
import org.junit.*;
import java.time.*;
import java.util.*;
import static androidx.test.core.app.ApplicationProvider.*;
import static androidx.test.platform.app.InstrumentationRegistry.*;
import static androidx.test.uiautomator.UiDevice.*;
public class BaseUserInterfaceTest
{
private static final String PKG = "org.isoron.uhabits";
public static final String EMPTY_DESCRIPTION_HABIT_NAME = "Read books";
public static UiDevice device;
private HabitsApplicationComponent component;
private HabitList habitList;
private Preferences prefs;
private HabitFixtures fixtures;
private HabitCardListCache cache;
public static void startActivity(Class cls)
{
Intent intent = new Intent();
intent.setComponent(new ComponentName(PKG, cls.getCanonicalName()));
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(intent);
}
@Before
public void setUp() throws Exception
{
device = getInstance(getInstrumentation());
TestButler.setup(getApplicationContext());
TestButler.verifyAnimationsDisabled(getApplicationContext());
HabitsApplication app =
(HabitsApplication) getApplicationContext().getApplicationContext();
component = app.getComponent();
habitList = component.getHabitList();
prefs = component.getPreferences();
cache = component.getHabitCardListCache();
fixtures = new HabitFixtures(component.getModelFactory(), habitList);
resetState();
}
@After
public void tearDown() throws Exception
{
for (int i = 0; i < 10; i++) device.pressBack();
TestButler.teardown(getApplicationContext());
}
private void resetState() throws Exception
{
prefs.clear();
prefs.setFirstRun(false);
prefs.updateLastHint(100, DateUtils.getToday());
habitList.removeAll();
cache.refreshAllHabits();
Thread.sleep(1000);
Habit h1 = fixtures.createEmptyHabit();
h1.setName("Wake up early");
h1.setQuestion("Did you wake up early today?");
h1.setDescription("test description 1");
h1.setColor(5);
habitList.update(h1);
Habit h2 = fixtures.createShortHabit();
h2.setName("Track time");
h2.setQuestion("Did you track your time?");
h2.setDescription("test description 2");
h2.setColor(5);
habitList.update(h2);
Habit h3 = fixtures.createLongHabit();
h3.setName("Meditate");
h3.setQuestion("Did meditate today?");
h3.setDescription("test description 3");
h3.setColor(10);
habitList.update(h3);
Habit h4 = fixtures.createEmptyHabit();
h4.setName(EMPTY_DESCRIPTION_HABIT_NAME);
h4.setQuestion("Did you read books today?");
h4.setDescription("");
h4.setColor(2);
habitList.update(h4);
}
protected void rotateDevice() throws Exception
{
device.setOrientationLeft();
device.setOrientationNatural();
}
}

View File

@@ -1,196 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits;
import android.graphics.*;
import android.view.*;
import android.widget.*;
import androidx.annotation.*;
import androidx.test.platform.app.*;
import org.isoron.androidbase.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.widgets.*;
import java.io.*;
import java.util.*;
import static android.view.View.MeasureSpec.*;
public class BaseViewTest extends BaseAndroidTest
{
public double similarityCutoff = 0.00018;
@Override
public void setUp()
{
super.setUp();
}
protected void assertRenders(View view, String expectedImagePath)
throws IOException
{
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
expectedImagePath = "views/" + expectedImagePath;
Bitmap actual = renderView(view);
if(actual == null) throw new IllegalStateException("actual is null");
try
{
Bitmap expected = getBitmapFromAssets(expectedImagePath);
double distance = distance(actual, expected);
if (distance > similarityCutoff)
{
saveBitmap(expectedImagePath, ".expected", expected);
String path = saveBitmap(expectedImagePath, "", actual);
fail(String.format("Image differs from expected " +
"(distance=%f). Actual rendered " +
"image saved to %s", distance, path));
}
expected.recycle();
}
catch (IOException e)
{
String path = saveBitmap(expectedImagePath, "", actual);
fail(String.format("Could not open expected image. Actual " +
"rendered image saved to %s", path));
throw e;
}
}
@NonNull
protected FrameLayout convertToView(BaseWidget widget,
int width,
int height)
{
widget.setDimensions(
new WidgetDimensions(width, height, width, height));
FrameLayout view = new FrameLayout(targetContext);
RemoteViews remoteViews = widget.getPortraitRemoteViews();
view.addView(remoteViews.apply(targetContext, view));
measureView(view, width, height);
return view;
}
protected float dpToPixels(int dp)
{
return InterfaceUtils.dpToPixels(targetContext, dp);
}
protected void measureView(View view, float width, float height)
{
int specWidth = makeMeasureSpec((int) width, View.MeasureSpec.EXACTLY);
int specHeight = makeMeasureSpec((int) height, View.MeasureSpec.EXACTLY);
view.setLayoutParams(new ViewGroup.LayoutParams((int) width, (int) height));
view.measure(specWidth, specHeight);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
}
protected void skipAnimation(View view)
{
ViewPropertyAnimator animator = view.animate();
animator.setDuration(0);
animator.start();
}
private int[] colorToArgb(int c1)
{
return new int[]{
(c1 >> 24) & 0xff, //alpha
(c1 >> 16) & 0xff, //red
(c1 >> 8) & 0xff, //green
(c1) & 0xff //blue
};
}
private double distance(Bitmap b1, Bitmap b2)
{
if (b1.getWidth() != b2.getWidth()) return 1.0;
if (b1.getHeight() != b2.getHeight()) return 1.0;
Random random = new Random();
double distance = 0.0;
for (int x = 0; x < b1.getWidth(); x++)
{
for (int y = 0; y < b1.getHeight(); y++)
{
if (random.nextInt(4) != 0) continue;
int[] argb1 = colorToArgb(b1.getPixel(x, y));
int[] argb2 = colorToArgb(b2.getPixel(x, y));
distance += Math.abs(argb1[0] - argb2[0]);
distance += Math.abs(argb1[1] - argb2[1]);
distance += Math.abs(argb1[2] - argb2[2]);
distance += Math.abs(argb1[3] - argb2[3]);
}
}
distance /= (0xff * 16) * b1.getWidth() * b1.getHeight();
return distance;
}
private Bitmap getBitmapFromAssets(String path) throws IOException
{
InputStream stream = testContext.getAssets().open(path);
return BitmapFactory.decodeStream(stream);
}
private String saveBitmap(String filename, String suffix, Bitmap bitmap)
throws IOException
{
File dir = FileUtils.getSDCardDir("test-screenshots");
if (dir == null)
dir = new AndroidDirFinder(targetContext).getFilesDir("test-screenshots");
if (dir == null) throw new RuntimeException(
"Could not find suitable dir for screenshots");
filename = filename.replaceAll("\\.png$", suffix + ".png");
String absolutePath =
String.format("%s/%s", dir.getAbsolutePath(), filename);
File parent = new File(absolutePath).getParentFile();
if (!parent.exists() && !parent.mkdirs()) throw new RuntimeException(
String.format("Could not create dir: %s",
parent.getAbsolutePath()));
FileOutputStream out = new FileOutputStream(absolutePath);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
return absolutePath;
}
public Bitmap renderView(View view)
{
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
if(view.isLayoutRequested())
measureView(view, width, height);
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.invalidate();
view.draw(canvas);
return bitmap;
}
}

View File

@@ -1,160 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits;
import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.utils.DateUtils;
import static org.isoron.uhabits.core.models.Checkmark.*;
public class HabitFixtures
{
public boolean LONG_HABIT_CHECKS[] = {
true, false, false, true, true, true, false, false, true, true
};
public int LONG_NUMERICAL_HABIT_CHECKS[] = {
200000, 0, 150000, 137000, 0, 0, 500000, 30000, 100000, 0, 300000,
100000, 0, 100000
};
private ModelFactory modelFactory;
private final HabitList habitList;
public HabitFixtures(ModelFactory modelFactory, HabitList habitList)
{
this.modelFactory = modelFactory;
this.habitList = habitList;
}
public Habit createEmptyHabit()
{
return createEmptyHabit(null);
}
public Habit createEmptyHabit(Long id)
{
Habit habit = modelFactory.buildHabit();
habit.setName("Meditate");
habit.setQuestion("Did you meditate this morning?");
habit.setDescription("This is a test description");
habit.setColor(5);
habit.setFrequency(Frequency.DAILY);
habit.setId(id);
habitList.add(habit);
return habit;
}
public Habit createLongHabit()
{
Habit habit = createEmptyHabit();
habit.setFrequency(new Frequency(3, 7));
habit.setColor(7);
Timestamp today = DateUtils.getToday();
int marks[] = { 0, 1, 3, 5, 7, 8, 9, 10, 12, 14, 15, 17, 19, 20, 26, 27,
28, 50, 51, 52, 53, 54, 58, 60, 63, 65, 70, 71, 72, 73, 74, 75, 80,
81, 83, 89, 90, 91, 95, 102, 103, 108, 109, 120};
for (int mark : marks)
habit.getRepetitions().setValue(today.minus(mark), YES_MANUAL);
return habit;
}
public Habit createVeryLongHabit()
{
Habit habit = createEmptyHabit();
habit.setFrequency(new Frequency(1, 2));
habit.setColor(11);
Timestamp today = DateUtils.getToday();
int marks[] = {0, 3, 5, 6, 7, 10, 13, 14, 15, 18, 21, 22, 23, 24, 27, 28, 30, 31, 34, 37,
39, 42, 43, 46, 47, 48, 51, 52, 54, 55, 57, 59, 62, 65, 68, 71, 73, 76, 79,
80, 81, 83, 85, 86, 89, 90, 91, 94, 96, 98, 100, 103, 104, 106, 109, 111,
112, 113, 115, 117, 120, 123, 126, 129, 132, 134, 136, 139, 141, 142, 145,
148, 149, 151, 152, 154, 156, 157, 159, 161, 162, 163, 164, 166, 168, 170,
172, 173, 174, 175, 176, 178, 180, 181, 184, 185, 188, 189, 190, 191, 194,
195, 197, 198, 199, 200, 202, 205, 208, 211, 213, 215, 216, 218, 220, 222,
223, 225, 227, 228, 230, 231, 232, 234, 235, 238, 241, 242, 244, 247, 250,
251, 253, 254, 257, 260, 261, 263, 264, 266, 269, 272, 273, 276, 279, 281,
284, 285, 288, 291, 292, 294, 296, 297, 299, 300, 301, 303, 306, 307, 308,
309, 310, 313, 316, 319, 322, 324, 326, 329, 330, 332, 334, 335, 337, 338,
341, 344, 345, 346, 347, 350, 352, 355, 358, 360, 361, 362, 363, 365, 368,
371, 373, 374, 376, 379, 380, 382, 384, 385, 387, 389, 390, 392, 393, 395,
396, 399, 401, 404, 407, 410, 411, 413, 414, 416, 417, 419, 420, 423, 424,
427, 429, 431, 433, 436, 439, 440, 442, 445, 447, 450, 453, 454, 456, 459,
460, 461, 464, 466, 468, 470, 473, 474, 475, 477, 479, 481, 482, 483, 486,
489, 491, 493, 495, 497, 498, 500, 503, 504, 507, 510, 511, 512, 515, 518,
519, 521, 522, 525, 528, 531, 532, 534, 537, 539, 541, 543, 544, 547, 550,
551, 554, 556, 557, 560, 561, 564, 567, 568, 569, 570, 572, 575, 576, 579,
582, 583, 584, 586, 589};
for (int mark : marks)
habit.getRepetitions().setValue(today.minus(mark), YES_MANUAL);
return habit;
}
public Habit createLongNumericalHabit()
{
Habit habit = modelFactory.buildHabit();
habit.setName("Read");
habit.setQuestion("How many pages did you walk today?");
habit.setType(Habit.NUMBER_HABIT);
habit.setTargetType(Habit.AT_LEAST);
habit.setTargetValue(200.0);
habit.setUnit("pages");
habitList.add(habit);
Timestamp timestamp = DateUtils.getToday();
for (int value : LONG_NUMERICAL_HABIT_CHECKS)
{
habit.getRepetitions().setValue(timestamp, value);
timestamp = timestamp.minus(1);
}
return habit;
}
public Habit createShortHabit()
{
Habit habit = modelFactory.buildHabit();
habit.setName("Wake up early");
habit.setQuestion("Did you wake up before 6am?");
habit.setFrequency(new Frequency(2, 3));
habitList.add(habit);
Timestamp timestamp = DateUtils.getToday();
for (boolean c : LONG_HABIT_CHECKS)
{
if (c) habit.getRepetitions().setValue(timestamp, YES_MANUAL);
timestamp = timestamp.minus(1);
}
return habit;
}
public synchronized void purgeHabits(HabitList habitList)
{
habitList.removeAll();
}
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits
import dagger.*
import org.isoron.androidbase.activities.*
import org.isoron.uhabits.activities.*
import org.isoron.uhabits.activities.habits.list.*
import org.isoron.uhabits.activities.habits.list.views.*
import org.isoron.uhabits.activities.habits.show.*
import org.isoron.uhabits.core.ui.screens.habits.list.*
import org.mockito.Mockito.*
@Module
class TestModule {
@Provides fun ListHabitsBehavior() = mock(ListHabitsBehavior::class.java)
}
@ActivityScope
@Component(modules = arrayOf(
ActivityContextModule::class,
HabitsActivityModule::class,
ListHabitsModule::class,
ShowHabitModule::class,
HabitModule::class,
TestModule::class
), dependencies = arrayOf(HabitsApplicationComponent::class))
interface HabitsActivityTestComponent {
fun getCheckmarkPanelViewFactory(): CheckmarkPanelViewFactory
fun getHabitCardViewFactory(): HabitCardViewFactory
fun getCheckmarkButtonViewFactory(): CheckmarkButtonViewFactory
fun getNumberButtonViewFactory(): NumberButtonViewFactory
fun getNumberPanelViewFactory(): NumberPanelViewFactory
}

View File

@@ -1,49 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits;
import androidx.test.filters.*;
import androidx.test.runner.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.androidbase.*;
import org.junit.*;
import org.junit.runner.*;
import java.io.*;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class HabitsApplicationTest extends BaseAndroidTest
{
@Test
public void test_getLogcat() throws IOException
{
String msg = "LOGCAT TEST";
new RuntimeException(msg).printStackTrace();
String log = new AndroidBugReporter(targetContext).getLogcat();
assertThat(log, containsString(msg));
}
}

View File

@@ -1,56 +0,0 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.acceptance;
import androidx.test.filters.*;
import androidx.test.runner.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.junit.*;
import org.junit.runner.*;
import static org.isoron.uhabits.acceptance.steps.CommonSteps.*;
import static org.isoron.uhabits.acceptance.steps.ListHabitsSteps.MenuItem.*;
import static org.isoron.uhabits.acceptance.steps.ListHabitsSteps.*;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class AboutTest extends BaseUserInterfaceTest
{
@Test
public void shouldDisplayAboutScreen() {
launchApp();
clickMenu(ABOUT);
verifyDisplaysText("Loop Habit Tracker");
verifyDisplaysText("Rate this app on Google Play");
verifyDisplaysText("Developers");
verifyDisplaysText("Translators");
}
@Test
public void shouldDisplayAboutScreenFromSettings() {
launchApp();
clickMenu(SETTINGS);
clickText("About");
verifyDisplaysText("Translators");
}
}

View File

@@ -1,208 +0,0 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.acceptance;
import androidx.test.filters.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.junit.*;
import org.junit.runner.*;
import static org.isoron.uhabits.acceptance.steps.CommonSteps.Screen.*;
import static org.isoron.uhabits.acceptance.steps.CommonSteps.*;
import static org.isoron.uhabits.acceptance.steps.EditHabitSteps.*;
import static org.isoron.uhabits.acceptance.steps.ListHabitsSteps.MenuItem.*;
import static org.isoron.uhabits.acceptance.steps.ListHabitsSteps.*;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class HabitsTest extends BaseUserInterfaceTest
{
@Test
public void shouldCreateHabit() throws Exception {
shouldCreateHabit("this is a test description");
}
@Test
public void shouldCreateHabitBlankDescription() throws Exception {
shouldCreateHabit("");
}
private void shouldCreateHabit(String description) throws Exception
{
launchApp();
verifyShowsScreen(LIST_HABITS);
clickMenu(ADD);
verifyShowsScreen(SELECT_HABIT_TYPE);
clickText("Yes or No");
verifyShowsScreen(EDIT_HABIT);
String testName = "Hello world";
typeName(testName);
typeQuestion("Did you say hello to the world today?");
typeDescription(description);
pickFrequency();
pickColor(5);
clickSave();
verifyShowsScreen(LIST_HABITS);
verifyDisplaysText(testName);
}
@Test
public void shouldShowHabitStatistics() throws Exception
{
launchApp();
verifyShowsScreen(LIST_HABITS);
clickText("Track time");
verifyShowsScreen(SHOW_HABIT);
verifyDisplayGraphs();
}
@Test
public void shouldDeleteHabit() throws Exception
{
launchApp();
verifyShowsScreen(LIST_HABITS);
longClickText("Track time");
clickMenu(DELETE);
clickOK();
verifyDoesNotDisplayText("Track time");
}
@Test
public void shouldEditHabit() throws Exception {
shouldEditHabit("this is a test description");
}
@Test
public void shouldEditHabitBlankDescription() throws Exception {
shouldEditHabit("");
}
private void shouldEditHabit(String description) throws Exception
{
launchApp();
verifyShowsScreen(LIST_HABITS);
longClickText("Track time");
clickMenu(EDIT);
verifyShowsScreen(EDIT_HABIT);
typeName("Take a walk");
typeQuestion("Did you take a walk today?");
typeDescription(description);
clickSave();
verifyShowsScreen(LIST_HABITS);
verifyDisplaysTextInSequence("Wake up early", "Take a walk", "Meditate");
verifyDoesNotDisplayText("Track time");
}
@Test
public void shouldEditHabit_fromStatisticsScreen() throws Exception
{
launchApp();
verifyShowsScreen(LIST_HABITS);
clickText("Track time");
verifyShowsScreen(SHOW_HABIT);
clickMenu(EDIT);
verifyShowsScreen(EDIT_HABIT);
typeName("Take a walk");
typeQuestion("Did you take a walk today?");
pickColor(10);
clickSave();
verifyShowsScreen(SHOW_HABIT);
verifyDisplaysText("Take a walk");
pressBack();
verifyShowsScreen(LIST_HABITS);
verifyDisplaysText("Take a walk");
verifyDoesNotDisplayText("Track time");
}
@Test
public void shouldArchiveAndUnarchiveHabits() throws Exception
{
launchApp();
verifyShowsScreen(LIST_HABITS);
longClickText("Track time");
clickMenu(ARCHIVE);
verifyDoesNotDisplayText("Track time");
clickMenu(TOGGLE_ARCHIVED);
verifyDisplaysText("Track time");
longClickText("Track time");
clickMenu(UNARCHIVE);
clickMenu(TOGGLE_ARCHIVED);
verifyDisplaysText("Track time");
}
@Test
public void shouldToggleCheckmarksAndUpdateScore() throws Exception
{
launchApp();
verifyShowsScreen(LIST_HABITS);
longPressCheckmarks("Wake up early", 2);
clickText("Wake up early");
verifyShowsScreen(SHOW_HABIT);
verifyDisplaysText("10%");
}
@Test
public void shouldHideCompleted() throws Exception
{
launchApp();
verifyShowsScreen(LIST_HABITS);
verifyDisplaysText("Track time");
verifyDisplaysText("Wake up early");
clickMenu(TOGGLE_COMPLETED);
verifyDoesNotDisplayText("Track time");
verifyDisplaysText("Wake up early");
longPressCheckmarks("Wake up early", 1);
verifyDoesNotDisplayText("Wake up early");
clickMenu(TOGGLE_COMPLETED);
verifyDisplaysText("Track time");
verifyDisplaysText("Wake up early");
}
@Test
public void shouldHideNotesCard() throws Exception
{
launchApp();
clickText(EMPTY_DESCRIPTION_HABIT_NAME);
verifyShowsScreen(SHOW_HABIT, false);
}
}

View File

@@ -1,71 +0,0 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.acceptance;
import androidx.test.filters.*;
import androidx.test.runner.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.junit.*;
import org.junit.runner.*;
import static org.isoron.uhabits.acceptance.steps.CommonSteps.*;
import static org.isoron.uhabits.acceptance.steps.ListHabitsSteps.MenuItem.*;
import static org.isoron.uhabits.acceptance.steps.ListHabitsSteps.*;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class LinksTest extends BaseUserInterfaceTest
{
@Test
public void shouldLinkToSourceCode() throws Exception
{
launchApp();
clickMenu(ABOUT);
clickText("View source code at GitHub");
verifyOpensWebsite("https://github.com/iSoron/uhabits");
}
// @Test
// public void shouldLinkToTranslationWebsite() throws Exception
// {
// launchApp();
// clickMenu(ABOUT);
// clickText("Help translate this app");
// verifyOpensWebsite("translate.loophabits.org");
// }
@Test
public void shouldLinkToHelp() throws Exception {
launchApp();
clickMenu(HELP);
verifyOpensWebsite("loophabits.org/faq.html");
}
@Test
public void shouldLinkToHelpFromSettings() throws Exception {
launchApp();
clickMenu(SETTINGS);
clickText("Help & FAQ");
verifyOpensWebsite("loophabits.org/faq.html");
}
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.acceptance;
import androidx.test.filters.*;
import org.isoron.uhabits.*;
import org.junit.*;
import static org.isoron.uhabits.acceptance.steps.CommonSteps.*;
import static org.isoron.uhabits.acceptance.steps.WidgetSteps.*;
import static org.isoron.uhabits.acceptance.steps.WidgetSteps.clickText;
@LargeTest
public class WidgetTest extends BaseUserInterfaceTest
{
@Test
public void shouldCreateAndToggleCheckmarkWidget() throws Exception
{
dragCheckmarkWidgetToHomeScreen();
clickText("Wake up early");
verifyCheckmarkWidgetIsShown();
clickCheckmarkWidget();
launchApp();
clickText("Wake up early");
verifyDisplaysText("5%");
pressHome();
clickCheckmarkWidget();
clickCheckmarkWidget();
launchApp();
clickText("Wake up early");
verifyDisplaysText("0%");
}
}

View File

@@ -1,189 +0,0 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.acceptance.steps;
import android.view.*;
import androidx.annotation.*;
import androidx.recyclerview.widget.*;
import androidx.test.espresso.*;
import androidx.test.espresso.contrib.*;
import androidx.test.uiautomator.*;
import org.hamcrest.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.R;
import org.isoron.uhabits.activities.habits.list.*;
import static android.os.Build.VERSION.*;
import static androidx.test.espresso.Espresso.*;
import static androidx.test.espresso.action.ViewActions.*;
import static androidx.test.espresso.assertion.PositionAssertions.*;
import static androidx.test.espresso.assertion.ViewAssertions.*;
import static androidx.test.espresso.matcher.ViewMatchers.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
public class CommonSteps extends BaseUserInterfaceTest
{
public static void clickOK()
{
clickText("OK");
}
public static void pressBack()
{
device.pressBack();
}
public static void clickText(String text)
{
scrollToText(text);
onView(withText(text)).perform(click());
}
public static void clickText(@StringRes int id)
{
onView(withText(id)).perform(click());
}
public static void launchApp()
{
startActivity(ListHabitsActivity.class);
assertTrue(
device.wait(Until.hasObject(By.pkg("org.isoron.uhabits")), 5000));
device.waitForIdle();
}
public static void longClickText(String text)
{
scrollToText(text);
onView(withText(text)).perform(longClick());
}
public static void pressHome()
{
device.pressHome();
device.waitForIdle();
}
public static void scrollToText(String text)
{
try
{
if (device
.findObject(new UiSelector().className(RecyclerView.class))
.exists())
{
onView(instanceOf(RecyclerView.class)).perform(
RecyclerViewActions.scrollTo(
hasDescendant(withText(text))));
}
else
{
onView(withText(text)).perform(scrollTo());
}
}
catch (PerformException e)
{
//ignored
}
}
public static void verifyDisplayGraphs()
{
verifyDisplaysView("HistoryCard");
verifyDisplaysView("ScoreCard");
}
public static void verifyDisplaysText(String text)
{
scrollToText(text);
onView(withText(text)).check(matches(isEnabled()));
}
public static void verifyDisplaysTextInSequence(String... text)
{
verifyDisplaysText(text[0]);
for(int i = 1; i < text.length; i++) {
verifyDisplaysText(text[i]);
onView(withText(text[i])).check(isCompletelyBelow(withText(text[i-1])));
}
}
private static void verifyDisplaysView(String className)
{
onView(withClassName(endsWith(className))).check(matches(isEnabled()));
}
public static void verifyDoesNotDisplayText(String text)
{
onView(withText(text)).check(doesNotExist());
}
public static void verifyOpensWebsite(String url) throws Exception
{
String browser_pkg = "org.chromium.webview_shell";
if(SDK_INT <= 23) {
browser_pkg = "com.android.browser";
}
assertTrue(device.wait(Until.hasObject(By.pkg(browser_pkg)), 5000));
device.waitForIdle();
assertTrue(device.findObject(new UiSelector().textContains(url)).exists());
}
public enum Screen
{
LIST_HABITS, SHOW_HABIT, EDIT_HABIT, SELECT_HABIT_TYPE
}
public static void verifyShowsScreen(Screen screen) {
verifyShowsScreen(screen, true);
}
public static void verifyShowsScreen(Screen screen, boolean notesCardVisibleExpected)
{
switch(screen)
{
case LIST_HABITS:
onView(withClassName(endsWith("ListHabitsRootView")))
.check(matches(isDisplayed()));
break;
case SHOW_HABIT:
Matcher<View> noteCardViewMatcher = notesCardVisibleExpected ? isDisplayed() :
withEffectiveVisibility(Visibility.GONE);
onView(withId(R.id.subtitleCard)).check(matches(isDisplayed()));
onView(withId(R.id.notesCard)).check(matches(noteCardViewMatcher));
break;
case EDIT_HABIT:
onView(withId(R.id.questionInput)).check(matches(isDisplayed()));
break;
case SELECT_HABIT_TYPE:
onView(withText(R.string.yes_or_no_example)).check(matches(isDisplayed()));
break;
default:
throw new IllegalStateException();
}
}
}

View File

@@ -1,92 +0,0 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.acceptance.steps;
import androidx.test.uiautomator.*;
import org.isoron.uhabits.*;
import static androidx.test.espresso.Espresso.*;
import static androidx.test.espresso.action.ViewActions.*;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.matcher.ViewMatchers.*;
import static org.isoron.uhabits.BaseUserInterfaceTest.*;
public class EditHabitSteps
{
public static void clickSave()
{
onView(withId(R.id.buttonSave)).perform(click());
}
public static void pickFrequency()
{
onView(withId(R.id.boolean_frequency_picker)).perform(click());
onView(withText("SAVE")).perform(click());
}
public static void pickColor(int color)
{
onView(withId(R.id.colorButton)).perform(click());
device.findObject(By.descStartsWith(String.format("Color %d", color))).click();
}
public static void typeName(String name)
{
typeTextWithId(R.id.nameInput, name);
}
public static void typeQuestion(String name)
{
typeTextWithId(R.id.questionInput, name);
}
public static void typeDescription(String description)
{
typeTextWithId(R.id.notesInput, description);
}
public static void setReminder()
{
onView(withId(R.id.reminderTimePicker)).perform(click());
onView(withId(R.id.done_button)).perform(click());
}
public static void clickReminderDays()
{
onView(withId(R.id.reminderDatePicker)).perform(click());
}
public static void unselectAllDays()
{
onView(withText("Saturday")).perform(click());
onView(withText("Sunday")).perform(click());
onView(withText("Monday")).perform(click());
onView(withText("Tuesday")).perform(click());
onView(withText("Wednesday")).perform(click());
onView(withText("Thursday")).perform(click());
onView(withText("Friday")).perform(click());
}
private static void typeTextWithId(int id, String name)
{
onView(withId(id)).perform(clearText(), typeText(name), closeSoftKeyboard());
}
}

View File

@@ -1,161 +0,0 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.acceptance.steps;
import androidx.test.espresso.*;
import android.view.*;
import org.hamcrest.*;
import org.isoron.uhabits.R;
import org.isoron.uhabits.activities.habits.list.views.*;
import java.util.*;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
import static androidx.test.espresso.matcher.ViewMatchers.withClassName;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withParent;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.CoreMatchers.*;
import static org.isoron.uhabits.BaseUserInterfaceTest.device;
import static org.isoron.uhabits.acceptance.steps.CommonSteps.clickText;
public abstract class ListHabitsSteps
{
public static void clickMenu(MenuItem item)
{
switch (item)
{
case ABOUT:
clickTextInsideOverflowMenu(R.string.about);
break;
case HELP:
clickTextInsideOverflowMenu(R.string.help);
break;
case SETTINGS:
clickTextInsideOverflowMenu(R.string.settings);
break;
case ADD:
clickViewWithId(R.id.actionCreateHabit);
break;
case EDIT:
clickViewWithId(R.id.action_edit_habit);
break;
case DELETE:
clickTextInsideOverflowMenu(R.string.delete);
break;
case ARCHIVE:
clickTextInsideOverflowMenu(R.string.archive);
break;
case UNARCHIVE:
clickTextInsideOverflowMenu(R.string.unarchive);
break;
case TOGGLE_ARCHIVED:
clickViewWithId(R.id.action_filter);
clickText(R.string.hide_archived);
break;
case TOGGLE_COMPLETED:
clickViewWithId(R.id.action_filter);
clickText(R.string.hide_completed);
break;
}
}
private static void clickTextInsideOverflowMenu(int id) {
onView(allOf(withContentDescription("More options"), withParent(withParent(withClassName(endsWith("Toolbar")))))).perform(click());
onView(withText(id)).perform(click());
}
private static void clickViewWithId(int id)
{
onView(withId(id)).perform(click());
}
private static ViewAction longClickDescendantWithClass(Class cls, int count)
{
return new ViewAction()
{
@Override
public Matcher<View> getConstraints()
{
return isEnabled();
}
@Override
public String getDescription()
{
return "perform on children";
}
@Override
public void perform(UiController uiController, View view)
{
LinkedList<ViewGroup> stack = new LinkedList<>();
if (view instanceof ViewGroup) stack.push((ViewGroup) view);
int countRemaining = count;
while (!stack.isEmpty())
{
ViewGroup vg = stack.pop();
for (int i = 0; i < vg.getChildCount(); i++)
{
View v = vg.getChildAt(i);
if (v instanceof ViewGroup) stack.push((ViewGroup) v);
if (cls.isInstance(v) && countRemaining > 0)
{
v.performLongClick();
uiController.loopMainThreadUntilIdle();
countRemaining--;
}
}
}
}
};
}
public static void longPressCheckmarks(String habit, int count)
{
CommonSteps.scrollToText(habit);
onView(allOf(hasDescendant(withText(habit)),
withClassName(endsWith("HabitCardView")))).perform(
longClickDescendantWithClass(CheckmarkButtonView.class, count));
device.waitForIdle();
}
public enum MenuItem
{
ABOUT, HELP, SETTINGS, EDIT, DELETE, ARCHIVE, TOGGLE_ARCHIVED,
UNARCHIVE, TOGGLE_COMPLETED, ADD
}
}

View File

@@ -1,87 +0,0 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.acceptance.steps;
import androidx.test.uiautomator.*;
import static android.os.Build.VERSION.SDK_INT;
import static org.junit.Assert.*;
import static org.isoron.uhabits.BaseUserInterfaceTest.*;
public class WidgetSteps {
public static void clickCheckmarkWidget() throws Exception {
String view_id = "org.isoron.uhabits:id/imageView";
device.findObject(new UiSelector().resourceId(view_id)).click();
}
public static void clickText(String s) throws Exception {
UiObject object = device.findObject(new UiSelector().text(s));
if (!object.waitForExists(1000)) {
object = device.findObject(new UiSelector().text(s.toUpperCase()));
}
object.click();
}
public static void dragCheckmarkWidgetToHomeScreen() throws Exception {
openWidgetScreen();
dragWidgetToHomeScreen();
}
private static void dragWidgetToHomeScreen() throws Exception {
int height = device.getDisplayHeight();
int width = device.getDisplayWidth();
device.findObject(new UiSelector().text("Checkmark"))
.dragTo(width / 2, height / 2, 8);
}
private static void openWidgetScreen() throws Exception {
int h = device.getDisplayHeight();
int w = device.getDisplayWidth();
if (SDK_INT <= 21) {
device.pressHome();
device.waitForIdle();
device.findObject(new UiSelector().description("Apps")).click();
device.findObject(new UiSelector().description("Apps")).click();
device.findObject(new UiSelector().description("Widgets")).click();
} else {
String list_id = "com.android.launcher3:id/widgets_list_view";
device.pressHome();
device.waitForIdle();
device.drag(w / 2, h / 2, w / 2, h / 2, 8);
UiObject button = device.findObject(new UiSelector().text("WIDGETS"));
if(!button.waitForExists(1000)) {
button = device.findObject(new UiSelector().text("Widgets"));
}
button.click();
if (SDK_INT >= 28) {
new UiScrollable(new UiSelector().resourceId(list_id))
.scrollForward();
}
new UiScrollable(new UiSelector().resourceId(list_id))
.scrollIntoView(new UiSelector().text("Checkmark"));
}
}
public static void verifyCheckmarkWidgetIsShown() throws Exception {
String view_id = "org.isoron.uhabits:id/imageView";
assertTrue(device.findObject(new UiSelector().resourceId(view_id)).exists());
assertFalse(device.findObject(new UiSelector().textStartsWith("Habit deleted")).exists());
}
}

View File

@@ -1,85 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.common.views;
import androidx.test.filters.*;
import androidx.test.runner.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.utils.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import org.junit.runner.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class BarChartTest extends BaseViewTest
{
private static final String BASE_PATH = "common/BarChart/";
private BarChart view;
@Override
@Before
public void setUp()
{
super.setUp();
Habit habit = fixtures.createLongNumericalHabit();
view = new BarChart(targetContext);
Timestamp today = DateUtils.getToday();
CheckmarkList checkmarks = habit.getCheckmarks();
view.setCheckmarks(checkmarks.getByInterval(today.minus(20), today));
view.setColor(PaletteUtils.getColor(targetContext, habit.getColor()));
view.setTarget(200.0);
measureView(view, dpToPixels(300), dpToPixels(200));
}
@Test
public void testRender() throws Throwable
{
assertRenders(view, BASE_PATH + "render.png");
}
@Test
public void testRender_withDataOffset() throws Throwable
{
view.onScroll(null, null, -dpToPixels(150), 0);
view.invalidate();
assertRenders(view, BASE_PATH + "renderDataOffset.png");
}
@Test
public void testRender_withDifferentSize() throws Throwable
{
measureView(view, dpToPixels(200), dpToPixels(200));
assertRenders(view, BASE_PATH + "renderDifferentSize.png");
}
@Test
public void testRender_withTransparentBackground() throws Throwable
{
view.setIsTransparencyEnabled(true);
assertRenders(view, BASE_PATH + "renderTransparent.png");
}
}

View File

@@ -1,84 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.common.views;
import androidx.test.filters.*;
import androidx.test.runner.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import org.junit.runner.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class FrequencyChartTest extends BaseViewTest
{
public static final String BASE_PATH = "common/FrequencyChart/";
private FrequencyChart view;
@Override
@Before
public void setUp()
{
super.setUp();
fixtures.purgeHabits(habitList);
Habit habit = fixtures.createLongHabit();
view = new FrequencyChart(targetContext);
view.setFrequency(habit.getRepetitions().getWeekdayFrequency());
view.setColor(PaletteUtils.getAndroidTestColor(habit.getColor()));
measureView(view, dpToPixels(300), dpToPixels(100));
}
@Test
public void testRender() throws Throwable
{
assertRenders(view, BASE_PATH + "render.png");
}
@Test
public void testRender_withDataOffset() throws Throwable
{
view.onScroll(null, null, -dpToPixels(150), 0);
view.invalidate();
assertRenders(view, BASE_PATH + "renderDataOffset.png");
}
@Test
public void testRender_withDifferentSize() throws Throwable
{
measureView(view, dpToPixels(200), dpToPixels(200));
assertRenders(view, BASE_PATH + "renderDifferentSize.png");
}
@Test
public void testRender_withTransparentBackground() throws Throwable
{
view.setIsBackgroundTransparent(true);
assertRenders(view, BASE_PATH + "renderTransparent.png");
}
}

View File

@@ -1,138 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.common.views;
import androidx.test.ext.junit.runners.*;
import androidx.test.filters.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.utils.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import org.junit.runner.*;
import static org.mockito.Mockito.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class HistoryChartTest extends BaseViewTest
{
private static final String BASE_PATH = "common/HistoryChart/";
private HistoryChart chart;
private Habit habit;
Timestamp today;
private HistoryChart.Controller controller;
@Override
@Before
public void setUp()
{
super.setUp();
fixtures.purgeHabits(habitList);
habit = fixtures.createLongHabit();
today = new Timestamp(DateUtils.getStartOfToday());
chart = new HistoryChart(targetContext);
chart.setSkipEnabled(true);
chart.setCheckmarks(habit.getCheckmarks().getAllValues());
chart.setColor(PaletteUtils.getAndroidTestColor(habit.getColor()));
measureView(chart, dpToPixels(400), dpToPixels(200));
controller = mock(HistoryChart.Controller.class);
chart.setController(controller);
}
@Test
public void tapDate_atInvalidLocations() throws Throwable
{
chart.setIsEditable(true);
chart.tap(dpToPixels(118), dpToPixels(13)); // header
chart.tap(dpToPixels(336), dpToPixels(60)); // tomorrow's square
chart.tap(dpToPixels(370), dpToPixels(60)); // right axis
verifyNoMoreInteractions(controller);
}
@Test
public void tapDate_withEditableView() throws Throwable
{
chart.setIsEditable(true);
chart.tap(dpToPixels(340), dpToPixels(40));
verify(controller).onToggleCheckmark(today, Checkmark.SKIP);
chart.tap(dpToPixels(340), dpToPixels(40));
verify(controller).onToggleCheckmark(today, Checkmark.NO);
chart.tap(dpToPixels(340), dpToPixels(40));
verify(controller).onToggleCheckmark(today, Checkmark.YES_MANUAL);
verifyNoMoreInteractions(controller);
}
@Test
public void tapDate_withEmptyHabit()
{
chart.setIsEditable(true);
chart.setCheckmarks(new int[]{});
chart.tap(dpToPixels(340), dpToPixels(40));
verify(controller).onToggleCheckmark(today, Checkmark.YES_MANUAL);
verifyNoMoreInteractions(controller);
}
@Test
public void tapDate_withReadOnlyView() throws Throwable
{
chart.setIsEditable(false);
chart.tap(dpToPixels(340), dpToPixels(40));
verifyNoMoreInteractions(controller);
}
@Test
public void testRender() throws Throwable
{
assertRenders(chart, BASE_PATH + "render.png");
}
@Test
public void testRender_withDataOffset() throws Throwable
{
chart.onScroll(null, null, -dpToPixels(150), 0);
chart.invalidate();
assertRenders(chart, BASE_PATH + "renderDataOffset.png");
}
@Test
public void testRender_withDifferentSize() throws Throwable
{
measureView(chart, dpToPixels(200), dpToPixels(200));
assertRenders(chart, BASE_PATH + "renderDifferentSize.png");
}
@Test
public void testRender_withTransparentBackground() throws Throwable
{
chart.setIsBackgroundTransparent(true);
assertRenders(chart, BASE_PATH + "renderTransparent.png");
}
}

View File

@@ -1,73 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.common.views;
import android.graphics.*;
import androidx.test.filters.*;
import androidx.test.runner.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import org.junit.runner.*;
import java.io.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class RingViewTest extends BaseViewTest
{
private static final String BASE_PATH = "common/RingView/";
private RingView view;
@Override
@Before
public void setUp()
{
super.setUp();
view = new RingView(targetContext);
view.setPercentage(0.6f);
view.setText("60%");
view.setColor(PaletteUtils.getAndroidTestColor(0));
view.setBackgroundColor(Color.WHITE);
view.setThickness(dpToPixels(3));
}
@Test
public void testRender_base() throws IOException
{
measureView(view, dpToPixels(100), dpToPixels(100));
assertRenders(view, BASE_PATH + "render.png");
}
@Test
public void testRender_withDifferentParams() throws IOException
{
view.setPercentage(0.25f);
view.setColor(PaletteUtils.getAndroidTestColor(5));
measureView(view, dpToPixels(200), dpToPixels(200));
assertRenders(view, BASE_PATH + "renderDifferentParams.png");
}
}

View File

@@ -1,110 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.common.views;
import androidx.test.filters.*;
import androidx.test.runner.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.utils.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import org.junit.runner.*;
import java.util.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class ScoreChartTest extends BaseViewTest
{
private static final String BASE_PATH = "common/ScoreChart/";
private Habit habit;
private ScoreChart view;
@Override
@Before
public void setUp()
{
super.setUp();
fixtures.purgeHabits(habitList);
habit = fixtures.createLongHabit();
view = new ScoreChart(targetContext);
view.setScores(habit.getScores().toList());
view.setColor(PaletteUtils.getColor(targetContext, habit.getColor()));
view.setBucketSize(7);
measureView(view, dpToPixels(300), dpToPixels(200));
}
@Test
public void testRender() throws Throwable
{
assertRenders(view, BASE_PATH + "render.png");
}
@Test
public void testRender_withDataOffset() throws Throwable
{
view.onScroll(null, null, -dpToPixels(150), 0);
view.invalidate();
assertRenders(view, BASE_PATH + "renderDataOffset.png");
}
@Test
public void testRender_withDifferentSize() throws Throwable
{
measureView(view, dpToPixels(200), dpToPixels(200));
assertRenders(view, BASE_PATH + "renderDifferentSize.png");
}
@Test
public void testRender_withMonthlyBucket() throws Throwable
{
view.setScores(habit.getScores().groupBy(DateUtils.TruncateField.MONTH, Calendar.SUNDAY));
view.setBucketSize(30);
view.invalidate();
assertRenders(view, BASE_PATH + "renderMonthly.png");
}
@Test
public void testRender_withTransparentBackground() throws Throwable
{
view.setIsTransparencyEnabled(true);
assertRenders(view, BASE_PATH + "renderTransparent.png");
}
@Test
public void testRender_withYearlyBucket() throws Throwable
{
view.setScores(habit.getScores().groupBy(DateUtils.TruncateField.YEAR, Calendar.SUNDAY));
view.setBucketSize(365);
view.invalidate();
assertRenders(view, BASE_PATH + "renderYearly.png");
}
}

View File

@@ -1,75 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.common.views;
import androidx.test.filters.*;
import androidx.test.runner.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import org.junit.runner.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class StreakChartTest extends BaseViewTest
{
private static final String BASE_PATH = "common/StreakChart/";
private StreakChart view;
@Override
@Before
public void setUp()
{
super.setUp();
fixtures.purgeHabits(habitList);
Habit habit = fixtures.createLongHabit();
view = new StreakChart(targetContext);
view.setColor(PaletteUtils.getAndroidTestColor(habit.getColor()));
view.setStreaks(habit.getStreaks().getBest(5));
measureView(view, dpToPixels(300), dpToPixels(100));
}
@Test
public void testRender() throws Throwable
{
assertRenders(view, BASE_PATH + "render.png");
}
@Test
public void testRender_withSmallSize() throws Throwable
{
measureView(view, dpToPixels(100), dpToPixels(100));
assertRenders(view, BASE_PATH + "renderSmallSize.png");
}
@Test
public void testRender_withTransparentBackground() throws Throwable
{
view.setIsBackgroundTransparent(true);
assertRenders(view, BASE_PATH + "renderTransparent.png");
}
}

View File

@@ -1,80 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.habits.list.views;
import androidx.test.filters.*;
import androidx.test.runner.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.isoron.uhabits.core.preferences.*;
import org.isoron.uhabits.core.utils.*;
import org.junit.*;
import org.junit.runner.*;
import static org.mockito.Mockito.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class HeaderViewTest extends BaseViewTest
{
public static final String PATH = "habits/list/HeaderView/";
private HeaderView view;
private Preferences prefs;
private MidnightTimer midnightTimer;
@Override
@Before
public void setUp()
{
super.setUp();
prefs = mock(Preferences.class);
midnightTimer = mock(MidnightTimer.class);
view = new HeaderView(targetContext, prefs, midnightTimer);
view.setButtonCount(5);
measureView(view, dpToPixels(600), dpToPixels(48));
}
@Test
public void testRender() throws Exception
{
when(prefs.isCheckmarkSequenceReversed()).thenReturn(false);
assertRenders(view, PATH + "render.png");
verify(prefs).isCheckmarkSequenceReversed();
verifyNoMoreInteractions(prefs);
}
@Test
public void testRender_reverse() throws Exception
{
when(prefs.isCheckmarkSequenceReversed()).thenReturn(true);
assertRenders(view, PATH + "render_reverse.png");
verify(prefs).isCheckmarkSequenceReversed();
verifyNoMoreInteractions(prefs);
}
}

View File

@@ -1,80 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.habits.list.views;
import androidx.test.filters.*;
import androidx.test.runner.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.isoron.uhabits.core.ui.screens.habits.list.*;
import org.junit.*;
import org.junit.runner.*;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*;
import static org.mockito.Mockito.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class HintViewTest extends BaseViewTest
{
public static final String PATH = "habits/list/HintView/";
private HintView view;
private HintList list;
@Before
@Override
public void setUp()
{
super.setUp();
list = mock(HintList.class);
view = new HintView(targetContext, list);
measureView(view, 400, 200);
String text =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
when(list.shouldShow()).thenReturn(true);
when(list.pop()).thenReturn(text);
view.showNext();
skipAnimation(view);
}
@Test
public void testRender() throws Exception
{
assertRenders(view, PATH + "render.png");
}
@Test
public void testClick() throws Exception
{
assertThat(view.getAlpha(), equalTo(1f));
view.performClick();
skipAnimation(view);
assertThat(view.getAlpha(), equalTo(0f));
}
}

View File

@@ -1,66 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.habits.show.views;
import androidx.test.filters.*;
import androidx.test.runner.*;
import android.view.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.isoron.uhabits.core.models.*;
import org.junit.*;
import org.junit.runner.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class FrequencyCardTest extends BaseViewTest
{
public static final String PATH = "habits/show/FrequencyCard/";
private FrequencyCard view;
private Habit habit;
@Before
@Override
public void setUp()
{
super.setUp();
habit = fixtures.createLongHabit();
view = (FrequencyCard) LayoutInflater
.from(targetContext)
.inflate(R.layout.show_habit, null)
.findViewById(R.id.frequencyCard);
view.setHabit(habit);
view.refreshData();
measureView(view, 800, 600);
}
@Test
public void testRender() throws Exception
{
assertRenders(view, PATH + "render.png");
}
}

View File

@@ -1,66 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.habits.show.views;
import androidx.test.filters.*;
import androidx.test.runner.*;
import android.view.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.isoron.uhabits.core.models.*;
import org.junit.*;
import org.junit.runner.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class HistoryCardTest extends BaseViewTest
{
public static final String PATH = "habits/show/HistoryCard/";
private HistoryCard view;
private Habit habit;
@Before
@Override
public void setUp()
{
super.setUp();
habit = fixtures.createLongHabit();
view = (HistoryCard) LayoutInflater
.from(targetContext)
.inflate(R.layout.show_habit, null)
.findViewById(R.id.historyCard);
view.setHabit(habit);
view.refreshData();
measureView(view, 800, 600);
}
@Test
public void testRender() throws Exception
{
assertRenders(view, PATH + "render.png");
}
}

View File

@@ -1,79 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.habits.show.views;
import android.view.LayoutInflater;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
import org.isoron.uhabits.BaseViewTest;
import org.isoron.uhabits.R;
import org.isoron.uhabits.core.models.Habit;
import org.isoron.uhabits.core.models.Reminder;
import org.isoron.uhabits.core.models.WeekdayList;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class NotesCardTest extends BaseViewTest
{
public static final String PATH = "habits/show/NotesCard/";
private NotesCard view;
private Habit habit;
@Before
@Override
public void setUp()
{
super.setUp();
habit = fixtures.createLongHabit();
habit.setReminder(new Reminder(8, 30, WeekdayList.EVERY_DAY));
view = LayoutInflater
.from(targetContext)
.inflate(R.layout.show_habit, null)
.findViewById(R.id.notesCard);
view.setHabit(habit);
view.refreshData();
measureView(view, 800, 200);
}
@Test
public void testRender() throws Exception
{
assertRenders(view, PATH + "render.png");
}
@Test
public void testRenderEmptyDescription() throws Exception
{
habit.setDescription("");
view.refreshData();
assertRenders(view, PATH + "render-empty-description.png");
}
}

View File

@@ -1,65 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.habits.show.views;
import androidx.test.filters.*;
import androidx.test.runner.*;
import android.view.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.isoron.uhabits.core.models.*;
import org.junit.*;
import org.junit.runner.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class OverviewCardTest extends BaseViewTest
{
public static final String PATH = "habits/show/OverviewCard/";
private OverviewCard view;
private Habit habit;
@Before
@Override
public void setUp()
{
super.setUp();
habit = fixtures.createLongHabit();
view = (OverviewCard) LayoutInflater
.from(targetContext)
.inflate(R.layout.show_habit, null)
.findViewById(R.id.overviewCard);
view.setHabit(habit);
view.refreshData();
measureView(view, 800, 300);
}
@Test
public void testRender() throws Exception
{
assertRenders(view, PATH + "render.png");
}
}

Some files were not shown because too many files have changed in this diff Show More