Compare commits

..

329 Commits

Author SHA1 Message Date
dependabot[bot]
f074d0331d Bump sqlite-jdbc from 3.36.0.3 to 3.39.2.0 (#1449)
Bumps [sqlite-jdbc](https://github.com/xerial/sqlite-jdbc) from 3.36.0.3 to 3.39.2.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.36.0.3...3.39.2.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-15 06:36:31 -05:00
Jakub Kalinowski
f94bc62a94 Replaced activity!! with requireActivity, context!! with requireContext etc. (#1458) 2022-08-15 06:36:03 -05:00
b0097fa45e Merge pull request #1450 from iSoron/dependabot/gradle/daggerVersion-2.43.2
Bump daggerVersion from 2.43.1 to 2.43.2
2022-08-14 05:09:35 -05:00
dependabot[bot]
15fa1fea8c Bump daggerVersion from 2.43.1 to 2.43.2
Bumps `daggerVersion` from 2.43.1 to 2.43.2.

Updates `dagger` from 2.43.1 to 2.43.2
- [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.43.1...dagger-2.43.2)

Updates `dagger-compiler` from 2.43.1 to 2.43.2
- [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.43.1...dagger-2.43.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-13 16:00:55 +00:00
31368cff45 Merge pull request #1453 from iSoron/dependabot/gradle/org.jetbrains.kotlin-kotlin-stdlib-jdk8-1.7.10
Bump kotlin-stdlib-jdk8 from 1.7.0 to 1.7.10
2022-08-13 11:00:35 -05:00
b44dd96dd3 Merge pull request #1444 from iSoron/dependabot/gradle/org.jetbrains.kotlinx-kotlinx-coroutines-core-jvm-1.6.4
Bump kotlinx-coroutines-core-jvm from 1.6.3 to 1.6.4
2022-08-13 10:59:51 -05:00
dependabot[bot]
08fab0cd8d Bump kotlin-stdlib-jdk8 from 1.7.0 to 1.7.10
Bumps [kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.7.0 to 1.7.10.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.7.10/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.0...v1.7.10)

---
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>
2022-08-13 09:28:01 +00:00
dependabot[bot]
a142685d2e Bump kotlinx-coroutines-core-jvm from 1.6.3 to 1.6.4
Bumps [kotlinx-coroutines-core-jvm](https://github.com/Kotlin/kotlinx.coroutines) from 1.6.3 to 1.6.4.
- [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.6.3...1.6.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-13 09:27:25 +00:00
a7a95f2030 Merge pull request #1443 from iSoron/dependabot/gradle/org.jetbrains.kotlin-kotlin-stdlib-1.7.10
Bump kotlin-stdlib from 1.7.0 to 1.7.10
2022-08-13 04:26:42 -05:00
dependabot[bot]
d3c90481be Bump kotlin-stdlib from 1.7.0 to 1.7.10
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.7.0 to 1.7.10.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.7.10/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.0...v1.7.10)

---
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>
2022-08-11 10:22:15 +00:00
f9bb0d7d7b Merge pull request #1445 from iSoron/dependabot/gradle/com.linkedin.dexmaker-dexmaker-mockito-2.28.3
Bump dexmaker-mockito from 2.28.1 to 2.28.3
2022-08-11 05:20:29 -05:00
f23a1bedee Merge pull request #1442 from iSoron/dependabot/gradle/daggerVersion-2.43.1
Bump daggerVersion from 2.42 to 2.43.1
2022-08-11 05:20:16 -05:00
dcf31ba115 Merge pull request #1441 from iSoron/dependabot/gradle/kxCoroutinesVersion-1.6.4
Bump kxCoroutinesVersion from 1.6.3 to 1.6.4
2022-08-11 05:20:04 -05:00
dependabot[bot]
5409a324e8 Bump dexmaker-mockito from 2.28.1 to 2.28.3
Bumps [dexmaker-mockito](https://github.com/linkedin/dexmaker) from 2.28.1 to 2.28.3.
- [Release notes](https://github.com/linkedin/dexmaker/releases)
- [Changelog](https://github.com/linkedin/dexmaker/blob/main/CHANGELOG.md)
- [Commits](https://github.com/linkedin/dexmaker/compare/2.28.1...2.28.3)

---
updated-dependencies:
- dependency-name: com.linkedin.dexmaker:dexmaker-mockito
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-01 03:04:42 +00:00
dependabot[bot]
504362e680 Bump daggerVersion from 2.42 to 2.43.1
Bumps `daggerVersion` from 2.42 to 2.43.1.

Updates `dagger` from 2.42 to 2.43.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.42...dagger-2.43.1)

Updates `dagger-compiler` from 2.42 to 2.43.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.42...dagger-2.43.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>
2022-08-01 03:03:08 +00:00
dependabot[bot]
0ce2f8fae2 Bump kxCoroutinesVersion from 1.6.3 to 1.6.4
Bumps `kxCoroutinesVersion` from 1.6.3 to 1.6.4.

Updates `kotlinx-coroutines-android` from 1.6.3 to 1.6.4
- [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.6.3...1.6.4)

Updates `kotlinx-coroutines-core` from 1.6.3 to 1.6.4
- [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.6.3...1.6.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-01 03:02:48 +00:00
2fc6c67432 Merge pull request #1425 from eduebernal/freq-display-normal
fix marker scaling in frequency display
2022-07-30 18:30:53 -05:00
459cf02642 Merge pull request #1370 from iSoron/number-popup
Replace NumberPickerDialog by NumberPopup
2022-07-30 18:30:32 -05:00
44cb64601f Update test screenshots 2022-07-30 17:28:46 -05:00
e4b16f6d59 Replace PopupWindow by Dialog
Fixes issues with copy & paste, text selection and spell checking.
2022-07-30 16:33:16 -05:00
3021e408a7 Remove unused imports 2022-07-24 06:01:40 -05:00
7649119db7 Popup: Do not save on dismiss 2022-07-24 05:47:52 -05:00
b0a4f26e7a Popup: Fix crash on suggestions 2022-07-24 05:47:52 -05:00
eduebernal
dd47d4cf08 fix getWeekdaysInMonth test 2022-07-06 15:09:10 -07:00
eduebernal
8912a9d73c add test for getWeekdaysInMonth 2022-07-06 10:48:58 -07:00
eduebernal
9bd1c6f685 change getWeekdaysInMonth method 2022-07-06 10:48:19 -07:00
eduebernal
e15e06034c remove unused maxFreq var and get method 2022-07-06 10:46:50 -07:00
eduebernal
a6180a5049 fix marker scaling in freq display 2022-07-05 21:41:27 -07:00
dependabot[bot]
7c69b17e77 Bump kxCoroutinesVersion from 1.6.2 to 1.6.3
Bumps `kxCoroutinesVersion` from 1.6.2 to 1.6.3.

Updates `kotlinx-coroutines-android` from 1.6.2 to 1.6.3
- [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.6.2...1.6.3)

Updates `kotlinx-coroutines-core` from 1.6.2 to 1.6.3
- [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.6.2...1.6.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-04 07:42:04 +02:00
dependabot[bot]
602a40a532 Bump simpleclient_httpserver from 0.15.0 to 0.16.0
Bumps [simpleclient_httpserver](https://github.com/prometheus/client_java) from 0.15.0 to 0.16.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.15.0...parent-0.16.0)

---
updated-dependencies:
- dependency-name: io.prometheus:simpleclient_httpserver
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-03 21:27:22 +02:00
dependabot[bot]
e00998f913 Bump annotation from 1.3.0 to 1.4.0
Bumps annotation from 1.3.0 to 1.4.0.

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-03 21:26:54 +02:00
dependabot[bot]
af5914c2db Bump kotlinx-coroutines-core-jvm from 1.6.2 to 1.6.3
Bumps [kotlinx-coroutines-core-jvm](https://github.com/Kotlin/kotlinx.coroutines) from 1.6.2 to 1.6.3.
- [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.6.2...1.6.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-01 12:52:10 +02:00
dependabot[bot]
6c5f70638a Bump kotlin-stdlib-jdk8 from 1.6.21 to 1.7.0
Bumps [kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.6.21 to 1.7.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/compare/v1.6.21...v1.7.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-01 12:51:50 +02:00
dependabot[bot]
ba88552919 Bump appcompat from 1.4.1 to 1.4.2
Bumps appcompat from 1.4.1 to 1.4.2.

---
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>
2022-07-01 07:09:30 +02:00
dependabot[bot]
8c90c4f68d Bump kotlin-stdlib from 1.6.21 to 1.7.0
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.6.21 to 1.7.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/compare/v1.6.21...v1.7.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-01 07:09:11 +02:00
dependabot[bot]
08eb1a600d Bump simpleclient_hotspot from 0.15.0 to 0.16.0
Bumps [simpleclient_hotspot](https://github.com/prometheus/client_java) from 0.15.0 to 0.16.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.15.0...parent-0.16.0)

---
updated-dependencies:
- dependency-name: io.prometheus:simpleclient_hotspot
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-01 07:08:57 +02:00
dependabot[bot]
8ea0480d4a Bump simpleclient from 0.15.0 to 0.16.0
Bumps [simpleclient](https://github.com/prometheus/client_java) from 0.15.0 to 0.16.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.15.0...parent-0.16.0)

---
updated-dependencies:
- dependency-name: io.prometheus:simpleclient
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-01 07:08:46 +02:00
Hielke Morsink
36ee39589e Fix small typo in build instructions 2022-06-28 20:02:46 +02:00
dependabot[bot]
ac7a721940 Bump daggerVersion from 2.41 to 2.42
Bumps `daggerVersion` from 2.41 to 2.42.

Updates `dagger` from 2.41 to 2.42
- [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.41...dagger-2.42)

Updates `dagger-compiler` from 2.41 to 2.42
- [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.41...dagger-2.42)

---
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>
2022-06-02 10:30:33 +02:00
dependabot[bot]
b36ca8673a Bump kxCoroutinesVersion from 1.6.1 to 1.6.2
Bumps `kxCoroutinesVersion` from 1.6.1 to 1.6.2.

Updates `kotlinx-coroutines-android` from 1.6.1 to 1.6.2
- [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.6.1...1.6.2)

Updates `kotlinx-coroutines-core` from 1.6.1 to 1.6.2
- [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.6.1...1.6.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-02 10:30:27 +02:00
dependabot[bot]
7cfac486f9 Bump org.jlleitschuh.gradle.ktlint from 10.2.1 to 10.3.0
Bumps org.jlleitschuh.gradle.ktlint from 10.2.1 to 10.3.0.

---
updated-dependencies:
- dependency-name: org.jlleitschuh.gradle.ktlint
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-01 23:07:05 +02:00
dependabot[bot]
21dd413ab5 Bump material from 1.5.0 to 1.6.1
Bumps [material](https://github.com/material-components/material-components-android) from 1.5.0 to 1.6.1.
- [Release notes](https://github.com/material-components/material-components-android/releases)
- [Commits](https://github.com/material-components/material-components-android/compare/1.5.0...1.6.1)

---
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>
2022-06-01 23:04:11 +02:00
dependabot[bot]
39e10638b5 Bump kotlinx-coroutines-core-jvm from 1.6.1 to 1.6.2
Bumps [kotlinx-coroutines-core-jvm](https://github.com/Kotlin/kotlinx.coroutines) from 1.6.1 to 1.6.2.
- [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.6.1...1.6.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-01 23:04:01 +02:00
d2d45991b0 Always show popups at the center of the screen; remove ScreenLocation 2022-05-13 06:37:41 -05:00
25aeafb759 Remove unused imports 2022-05-13 05:21:29 -05:00
9045ae5c24 Remove previous NumberPicker 2022-05-13 05:21:29 -05:00
555873354c Use NumberPopup in HistoryCard 2022-05-13 05:21:29 -05:00
2a012619a7 Use NumberPopup in widgets 2022-05-13 05:21:28 -05:00
d1de3a852b Implement NumberPopup 2022-05-13 05:21:28 -05:00
f04e37e905 Remove CheckmarkDialog 2022-05-03 04:09:13 -05:00
825a5f2cb9 Implement CheckmarkPopup 2022-05-03 04:09:13 -05:00
0de6896691 Add notes to DelayedToggle, make delay skipable 2022-05-03 04:09:13 -05:00
7187214282 Replace notesIndicator by notes 2022-05-03 04:09:13 -05:00
Jakub Kalinowski
9d4161a255 Issue 1332: Multiple numeric dialogs appearing (#1356)
Co-authored-by: Jakub Kalinowski <kalj@netcompany.com>
2022-05-01 20:01:13 -05:00
dependabot[bot]
d82a3c145d Bump kotlin-stdlib-jdk8 from 1.6.10 to 1.6.21
Bumps [kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.6.10 to 1.6.21.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.6.21/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.6.10...v1.6.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>
2022-05-01 23:14:37 +02:00
dependabot[bot]
a6cbd44e42 Bump kotlinx-coroutines-core-jvm from 1.6.0 to 1.6.1
Bumps [kotlinx-coroutines-core-jvm](https://github.com/Kotlin/kotlinx.coroutines) from 1.6.0 to 1.6.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.6.0...1.6.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-01 23:14:28 +02:00
dependabot[bot]
45c62b4ab2 Bump kxCoroutinesVersion from 1.6.0 to 1.6.1
Bumps `kxCoroutinesVersion` from 1.6.0 to 1.6.1.

Updates `kotlinx-coroutines-android` from 1.6.0 to 1.6.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.6.0...1.6.1)

Updates `kotlinx-coroutines-core` from 1.6.0 to 1.6.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.6.0...1.6.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-01 19:44:14 +02:00
dependabot[bot]
d53312d261 Bump kotlin-stdlib from 1.6.10 to 1.6.21
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.6.10 to 1.6.21.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.6.21/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.6.10...v1.6.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>
2022-05-01 19:43:58 +02:00
Quentin Hibon
c453810785 Resort habit list after habit edit (#1350)
* Add regression test for #1131
* Resort habit list after habit edit

Fixes #1131.
2022-04-21 11:29:42 -05:00
Quentin Hibon
999057300b Bump kotlin from 1.5.0 to 1.6.10 (#1349) 2022-04-15 15:40:36 -05:00
Quentin Hibon
2245347e28 Clean up SDK_INT branches (#1348)
Fixes #1347.
2022-04-15 09:34:43 -05:00
Kürşad Bumin Giray Saka
b79f7850ed Add archive actions if there are archived habits (#1345) 2022-04-11 20:50:44 -05:00
dependabot[bot]
4469f86e46 Bump logback-classic from 1.2.10 to 1.2.11
Bumps logback-classic from 1.2.10 to 1.2.11.

---
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>
2022-04-01 21:44:03 +02:00
dependabot[bot]
bdeddb149e Bump ktorVersion from 1.6.7 to 1.6.8
Bumps `ktorVersion` from 1.6.7 to 1.6.8.

Updates `ktor-client-mock` from 1.6.7 to 1.6.8
- [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.7...1.6.8)

Updates `ktor-jackson` from 1.6.7 to 1.6.8
- [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.7...1.6.8)

Updates `ktor-client-android` from 1.6.7 to 1.6.8
- [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.7...1.6.8)

Updates `ktor-client-core` from 1.6.7 to 1.6.8
- [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.7...1.6.8)

Updates `ktor-client-jackson` from 1.6.7 to 1.6.8
- [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.7...1.6.8)

Updates `ktor-client-json` from 1.6.7 to 1.6.8
- [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.7...1.6.8)

Updates `ktor-server-netty` from 1.6.7 to 1.6.8
- [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.7...1.6.8)

Updates `ktor-server-core` from 1.6.7 to 1.6.8
- [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.7...1.6.8)

Updates `ktor-html-builder` from 1.6.7 to 1.6.8
- [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.7...1.6.8)

Updates `ktor-server-tests` from 1.6.7 to 1.6.8
- [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.7...1.6.8)

---
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>
2022-04-01 21:43:45 +02:00
Jakub Kalinowski
3b12ec4bfe Issue 1316: Skip measurable habit (#1319)
Co-authored-by: Jakub Kalinowski <kalj@netcompany.com>
2022-03-24 06:08:31 -05:00
ca4618579e Reduce toggle delay 2022-03-20 18:55:19 -05:00
2f13aba22c CheckmarkButtonView: Make focusable 2022-03-20 18:55:19 -05:00
dba5912ecd Remove leading/trailing whitespace from notes 2022-03-20 18:55:18 -05:00
88b8663484 Remove pref_led_notifications 2022-03-20 18:55:18 -05:00
609886fd09 Fix iOS build scripts 2022-03-20 11:14:53 -05:00
a4db997e06 Merge pull request #1314 from kalina559/feature/case_1282_calendar_bug
Fixed edit history calendar bug
2022-03-10 06:05:04 -06:00
Jakub Kalinowski
090216ccb7 Fixed edit history calendar bug 2022-03-05 19:54:48 +01:00
dependabot[bot]
472092d1bf Bump simpleclient from 0.14.1 to 0.15.0
Bumps [simpleclient](https://github.com/prometheus/client_java) from 0.14.1 to 0.15.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.14.1...parent-0.15.0)

---
updated-dependencies:
- dependency-name: io.prometheus:simpleclient
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-01 21:14:31 +01:00
dependabot[bot]
6d3791de31 Bump daggerVersion from 2.40.5 to 2.41
Bumps `daggerVersion` from 2.40.5 to 2.41.

Updates `dagger` from 2.40.5 to 2.41
- [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.40.5...dagger-2.41)

Updates `dagger-compiler` from 2.40.5 to 2.41
- [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.40.5...dagger-2.41)

---
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>
2022-03-01 18:17:46 +01:00
dependabot[bot]
24a99d5791 Bump simpleclient_httpserver from 0.14.1 to 0.15.0
Bumps [simpleclient_httpserver](https://github.com/prometheus/client_java) from 0.14.1 to 0.15.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.14.1...parent-0.15.0)

---
updated-dependencies:
- dependency-name: io.prometheus:simpleclient_httpserver
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-01 18:17:39 +01:00
dependabot[bot]
6c631b1cf6 Bump opencsv from 5.5.2 to 5.6
Bumps opencsv from 5.5.2 to 5.6.

---
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>
2022-03-01 10:11:09 +01:00
dependabot[bot]
5d7677b354 Bump guava from 31.0.1-android to 31.1-android
Bumps [guava](https://github.com/google/guava) from 31.0.1-android to 31.1-android.
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

---
updated-dependencies:
- dependency-name: com.google.guava:guava
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-01 10:05:35 +01:00
dependabot[bot]
22820f4f24 Bump simpleclient_hotspot from 0.14.1 to 0.15.0
Bumps [simpleclient_hotspot](https://github.com/prometheus/client_java) from 0.14.1 to 0.15.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.14.1...parent-0.15.0)

---
updated-dependencies:
- dependency-name: io.prometheus:simpleclient_hotspot
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-01 10:05:09 +01:00
1d3bd48535 Merge pull request #1278 from hiqua/fix_habit_bull_numerical
Handle numerical habits from HabitBull
2022-02-02 03:08:30 -06:00
dependabot[bot]
694446b7e3 Bump appcompat from 1.4.0 to 1.4.1
Bumps appcompat from 1.4.0 to 1.4.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>
2022-02-01 12:13:14 +01:00
dependabot[bot]
20ae9d247e Bump material from 1.4.0 to 1.5.0
Bumps [material](https://github.com/material-components/material-components-android) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/material-components/material-components-android/releases)
- [Commits](https://github.com/material-components/material-components-android/compare/1.4.0...1.5.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>
2022-02-01 10:39:54 +01:00
dependabot[bot]
1943fac610 Bump AppIntro from 6.1.0 to 6.2.0
Bumps [AppIntro](https://github.com/AppIntro/AppIntro) from 6.1.0 to 6.2.0.
- [Release notes](https://github.com/AppIntro/AppIntro/releases)
- [Changelog](https://github.com/AppIntro/AppIntro/blob/main/CHANGELOG.md)
- [Commits](https://github.com/AppIntro/AppIntro/compare/6.1.0...6.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-01 10:39:47 +01:00
Quentin Hibon
a07a50e635 Handle numerical habits from HabitBull
Fixes #1265.
2022-01-27 20:33:17 +01:00
Quentin Hibon
8ccb9bbab1 Bumps appcompat from 1.3.1 to 1.4.0. 2022-01-09 07:21:12 +01:00
Quentin Hibon
743b8d26ad gradle.properties: remove deprecated MaxPermSize parameter 2022-01-08 22:49:40 +01:00
dependabot[bot]
c47bd4c328 Bump kotlin-stdlib-jdk8 from 1.6.0 to 1.6.10
Bumps [kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.6.0 to 1.6.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.6.0...v1.6.10)

---
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>
2022-01-05 10:03:59 +01:00
dependabot[bot]
d84abc3a6a Bump com.github.johnrengelman.shadow from 7.1.0 to 7.1.2
Bumps com.github.johnrengelman.shadow from 7.1.0 to 7.1.2.

---
updated-dependencies:
- dependency-name: com.github.johnrengelman.shadow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-05 10:03:52 +01:00
dependabot[bot]
4ae85f1ec0 Bump kotlin-stdlib from 1.6.0 to 1.6.10
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.6.0 to 1.6.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.6.0...v1.6.10)

---
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>
2022-01-05 10:03:44 +01:00
dependabot[bot]
79d40d1d79 Bump simpleclient_hotspot from 0.12.0 to 0.14.1
Bumps [simpleclient_hotspot](https://github.com/prometheus/client_java) from 0.12.0 to 0.14.1.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.12.0...parent-0.14.1)

---
updated-dependencies:
- dependency-name: io.prometheus:simpleclient_hotspot
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 19:04:33 +01:00
dependabot[bot]
1902b8821e Bump kxCoroutinesVersion from 1.5.2 to 1.6.0
Bumps `kxCoroutinesVersion` from 1.5.2 to 1.6.0.

Updates `kotlinx-coroutines-android` from 1.5.2 to 1.6.0
- [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.5.2...1.6.0)

Updates `kotlinx-coroutines-core` from 1.5.2 to 1.6.0
- [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.5.2...1.6.0)

---
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>
2022-01-04 19:04:22 +01:00
dependabot[bot]
075542d605 Bump org.jlleitschuh.gradle.ktlint from 10.2.0 to 10.2.1
Bumps org.jlleitschuh.gradle.ktlint from 10.2.0 to 10.2.1.

---
updated-dependencies:
- dependency-name: org.jlleitschuh.gradle.ktlint
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 19:04:16 +01:00
dependabot[bot]
0b5894ee6d Bump daggerVersion from 2.40.3 to 2.40.5
Bumps `daggerVersion` from 2.40.3 to 2.40.5.

Updates `dagger` from 2.40.3 to 2.40.5
- [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.40.3...dagger-2.40.5)

Updates `dagger-compiler` from 2.40.3 to 2.40.5
- [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.40.3...dagger-2.40.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-03 22:49:41 +01:00
dependabot[bot]
92fb9dbdb6 Bump simpleclient_httpserver from 0.12.0 to 0.14.1
Bumps [simpleclient_httpserver](https://github.com/prometheus/client_java) from 0.12.0 to 0.14.1.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.12.0...parent-0.14.1)

---
updated-dependencies:
- dependency-name: io.prometheus:simpleclient_httpserver
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-03 22:49:29 +01:00
dependabot[bot]
1860abf532 Bump kotlinx-coroutines-core-jvm from 1.5.2 to 1.6.0
Bumps [kotlinx-coroutines-core-jvm](https://github.com/Kotlin/kotlinx.coroutines) from 1.5.2 to 1.6.0.
- [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.5.2...1.6.0)

---
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>
2022-01-02 21:42:17 +01:00
dependabot[bot]
3f4780c9fb Bump ktorVersion from 1.6.6 to 1.6.7
Bumps `ktorVersion` from 1.6.6 to 1.6.7.

Updates `ktor-client-mock` from 1.6.6 to 1.6.7
- [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.6...1.6.7)

Updates `ktor-jackson` from 1.6.6 to 1.6.7
- [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.6...1.6.7)

Updates `ktor-client-android` from 1.6.6 to 1.6.7
- [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.6...1.6.7)

Updates `ktor-client-core` from 1.6.6 to 1.6.7
- [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.6...1.6.7)

Updates `ktor-client-jackson` from 1.6.6 to 1.6.7
- [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.6...1.6.7)

Updates `ktor-client-json` from 1.6.6 to 1.6.7
- [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.6...1.6.7)

Updates `ktor-server-netty` from 1.6.6 to 1.6.7
- [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.6...1.6.7)

Updates `ktor-server-core` from 1.6.6 to 1.6.7
- [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.6...1.6.7)

Updates `ktor-html-builder` from 1.6.6 to 1.6.7
- [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.6...1.6.7)

Updates `ktor-server-tests` from 1.6.6 to 1.6.7
- [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.6...1.6.7)

---
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>
2022-01-02 21:42:00 +01:00
dependabot[bot]
d5d6e4616e Bump logback-classic from 1.2.7 to 1.2.10
Bumps logback-classic from 1.2.7 to 1.2.10.

---
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>
2022-01-02 21:41:52 +01:00
dependabot[bot]
18e267053d Bump simpleclient from 0.12.0 to 0.14.1
Bumps [simpleclient](https://github.com/prometheus/client_java) from 0.12.0 to 0.14.1.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.12.0...parent-0.14.1)

---
updated-dependencies:
- dependency-name: io.prometheus:simpleclient
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-02 21:41:44 +01:00
7ba9a7e4e7 Update translations 2022-01-02 11:16:21 -06:00
5b8a7c39e2 HistoryCard: Make colors more consistent for AT_MOST habits 2022-01-02 11:06:37 -06:00
d40a5a89cd Notes: Update test screenshots 2022-01-01 08:06:45 -06:00
308d558347 NumberPicker: Show keyboard more reliably 2022-01-01 07:36:40 -06:00
9770ce187a NumberPicker: Fix formatting 2022-01-01 07:28:40 -06:00
535bc03b70 NumberPicker: Clear focus of both pickers 2022-01-01 07:22:26 -06:00
642e45af89 NumberPicker: Replace "5" by "50" instead of "05" on decimal picker 2022-01-01 07:21:29 -06:00
56d2307b75 Habit notes: left align 2022-01-01 06:40:28 -06:00
d875af8a8e CheckmarkDialog: Format date using current locale 2022-01-01 06:30:57 -06:00
feeb4f057d Update translations 2021-12-29 10:10:09 -06:00
1ad5c6b896 Restore x_times_per_y_days translations 2021-12-29 10:01:22 -06:00
baee3b9f86 Merge branch 'sdk_30_31' into dev 2021-12-29 08:51:20 -06:00
e6167baab1 NotificationTray: Use isCompletedToday instead of value != UNKNOWN 2021-12-29 08:13:54 -06:00
Quentin Hibon
1c15e7742e Disable custom snoozing for recent Android 2021-12-11 15:22:37 +01:00
Quentin Hibon
072ba63789 Add immutable flag to pending intents 2021-12-11 15:22:37 +01:00
Quentin Hibon
0fa0daa058 Ask for SCHEDULE_EXACT_ALARM permission 2021-12-11 15:22:37 +01:00
Quentin Hibon
5a5ed3d631 Bump SDK from 30 to 31 2021-12-11 15:22:37 +01:00
Quentin Hibon
3dfa376f59 Remove deprecated bintray repositories 2021-12-11 13:51:30 +01:00
dependabot[bot]
7bf74634bb Bump kotlin-stdlib-jdk8 from 1.5.31 to 1.6.0
Bumps [kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.5.31 to 1.6.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/compare/v1.5.31...v1.6.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-02 08:40:02 +01:00
dependabot[bot]
fc645a81bc Bump kotlin-stdlib from 1.5.31 to 1.6.0
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.5.31 to 1.6.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/compare/v1.5.31...v1.6.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-01 21:58:08 +01:00
dependabot[bot]
35365bbdf3 Bump logback-classic from 1.2.6 to 1.2.7
Bumps logback-classic from 1.2.6 to 1.2.7.

---
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-12-01 21:57:46 +01:00
dependabot[bot]
779ef5dbee Bump com.github.triplet.play from 3.6.0 to 3.7.0
Bumps com.github.triplet.play from 3.6.0 to 3.7.0.

---
updated-dependencies:
- dependency-name: com.github.triplet.play
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-01 19:18:47 +01:00
dependabot[bot]
e82994c76b Bump annotation from 1.2.0 to 1.3.0
Bumps annotation from 1.2.0 to 1.3.0.

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-01 19:18:30 +01:00
dependabot[bot]
4e1d01d8d1 Bump daggerVersion from 2.40 to 2.40.3
Bumps `daggerVersion` from 2.40 to 2.40.3.

Updates `dagger` from 2.40 to 2.40.3
- [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.40...dagger-2.40.3)

Updates `dagger-compiler` from 2.40 to 2.40.3
- [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.40...dagger-2.40.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-01 19:18:25 +01:00
dependabot[bot]
5de0fc86e5 Bump ktorVersion from 1.6.4 to 1.6.6
Bumps `ktorVersion` from 1.6.4 to 1.6.6.

Updates `ktor-client-mock` from 1.6.4 to 1.6.6
- [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.4...1.6.6)

Updates `ktor-jackson` from 1.6.4 to 1.6.6
- [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.4...1.6.6)

Updates `ktor-client-android` from 1.6.4 to 1.6.6
- [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.4...1.6.6)

Updates `ktor-client-core` from 1.6.4 to 1.6.6
- [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.4...1.6.6)

Updates `ktor-client-jackson` from 1.6.4 to 1.6.6
- [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.4...1.6.6)

Updates `ktor-client-json` from 1.6.4 to 1.6.6
- [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.4...1.6.6)

Updates `ktor-server-netty` from 1.6.4 to 1.6.6
- [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.4...1.6.6)

Updates `ktor-server-core` from 1.6.4 to 1.6.6
- [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.4...1.6.6)

Updates `ktor-html-builder` from 1.6.4 to 1.6.6
- [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.4...1.6.6)

Updates `ktor-server-tests` from 1.6.4 to 1.6.6
- [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.4...1.6.6)

---
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-12-01 19:18:13 +01:00
e26b643423 HabitCardView: Remove flickering due to toggle delay 2021-11-11 17:57:21 -06:00
621534d610 Merge pull request #1184 from hiqua/unfocus_every_day
Don't unfocus after select 'every day' frequency
2021-11-11 07:37:52 -06:00
a01300e9c6 Update list of developers 2021-11-11 07:27:33 -06:00
ecb8ce105a Merge pull request #1103 from vbh/feat-1074
Add notes to specific dates
2021-11-11 07:10:16 -06:00
32ef3c14f7 Settings: Update short toggle description 2021-11-11 06:54:46 -06:00
4972257635 Merge branch 'dev' into feat-1074 2021-11-11 06:43:20 -06:00
c98cb50baa CheckmarkDialog: Always set up all buttons 2021-11-11 06:35:51 -06:00
c331f34fa9 HistoryCard: Swap short/long press 2021-11-11 06:08:03 -06:00
a1aea532b5 NumberPicker: Fix vertical alignment 2021-11-11 06:01:27 -06:00
43489aeb4c CheckmarkDialog: Replace setText by append
Replace `etNotes.setText` by `etNotes.append` so that the cursor moves
to the end of the line.
2021-11-11 05:54:45 -06:00
990c85aedd CheckmarkDialog: Use theme color instead of CSV 2021-11-11 05:25:47 -06:00
Quentin Hibon
64337b9bee Bump AGP from 7.0.2 to 7.0.3 2021-11-08 20:02:43 +01:00
Quentin Hibon
8bdfaa2434 Don't explicitly change focus while switching between frequencies 2021-11-07 14:43:22 +01:00
Quentin Hibon
5f6060858d Don't unfocus after select 'every day' frequency
Fixes #1182.
2021-11-07 14:35:39 +01:00
b62e436054 Fix "hide completed" for numerical habits
Fixes #1179
2021-11-07 11:47:25 +01:00
bf63b4dbcf Remove HabitMatcherBuilder 2021-11-06 06:50:28 -05:00
a82d940bcc Small tweaks to checkmark size 2021-11-06 06:19:13 -05:00
ba59dc7ca9 Merge pull request #1177 from hiqua/fix_csv_exporter
Use the value of the Entry during CSV export
2021-11-06 06:12:27 -05:00
181290a0f3 Merge pull request #1178 from hiqua/delete_unused_test_resources
Delete unused test resources
2021-11-06 06:09:51 -05:00
Quentin Hibon
d553c2f3f2 Delete unused test resources 2021-11-05 20:48:16 +01:00
Quentin Hibon
7776093217 Test CSV export file content 2021-11-05 20:47:23 +01:00
Quentin Hibon
b27f3f8540 Use the value of the Entry during CSV export
Fixes #1162.
2021-11-05 20:02:55 +01:00
eb041bf6b2 Merge pull request #1111 from sgallese/feature/file-extensions-test
Tests for DateUtils and FileExtensions
2021-11-03 20:01:42 -05:00
dependabot[bot]
e3c53bf07f Bump daggerVersion from 2.39 to 2.40
Bumps `daggerVersion` from 2.39 to 2.40.

Updates `dagger` from 2.39 to 2.40
- [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.39...dagger-2.40)

Updates `dagger-compiler` from 2.39 to 2.40
- [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.39...dagger-2.40)

---
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-11-01 09:02:34 +01:00
dependabot[bot]
9ddab6ee59 Bump com.github.johnrengelman.shadow from 7.0.0 to 7.1.0
Bumps com.github.johnrengelman.shadow from 7.0.0 to 7.1.0.

---
updated-dependencies:
- dependency-name: com.github.johnrengelman.shadow
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-01 09:02:23 +01:00
Sebastian Gallese
2615795402 Merge branch 'iSoron:dev' into feature/file-extensions-test 2021-10-31 12:05:38 -07:00
Jakub Kalinowski
6531445d7f Add delay after toggling a habit 2021-10-05 09:04:32 +02:00
sgallese
4fbf8a8ca2 DRYer offset tests 2021-10-03 22:32:14 -07:00
sgallese
707b2b4380 Add test helper for hour offset 2021-10-03 21:19:04 -07:00
sgallese
aae85c1170 Rename variable 2021-10-03 21:10:44 -07:00
sgallese
c12a6c6a4d Complete tests for DateUtils, move internal functions to private 2021-10-03 21:09:31 -07:00
sgallese
b15c02adbf Calendar tests for DateUtils 2021-10-03 21:09:31 -07:00
sgallese
9e24128675 DateUtils today offset tests 2021-10-03 21:09:31 -07:00
sgallese
66c61e2e6c More DateUtils tests 2021-10-03 21:09:31 -07:00
sgallese
7bddfbe5a7 Tests for DateUtils and FileExtensions 2021-10-03 21:09:31 -07:00
Bindu
8036b10ee6 improve yes/no dialog design 2021-10-03 04:43:53 -07:00
Bindu
71f400f587 improve numerical dialog design 2021-10-03 04:43:53 -07:00
Bindu
79e302f922 Change variable name 2021-10-03 04:43:53 -07:00
Bindu
af7f60fc4d Address review comments 2021-10-03 04:43:53 -07:00
Bindu
7cc4b66dfd Update HabitBullCSV test to accept notes 2021-10-03 04:43:53 -07:00
Bindu
a9fddf9963 Update tests and fix formatting. 2021-10-03 04:43:53 -07:00
Bindu
36c1504c6a Add dialog and notes indicator for HistoryChart 2021-10-03 04:43:53 -07:00
Bindu
d644170141 Implement dialog for Yes/No Habits 2021-10-03 04:43:53 -07:00
Bindu
d38f83e961 Added a notes field and implemented dialog for numeric habits 2021-10-03 04:43:53 -07:00
dependabot[bot]
c50c5af497 Bump logback-classic from 1.2.5 to 1.2.6
Bumps logback-classic from 1.2.5 to 1.2.6.

---
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-10-02 09:35:37 +02:00
Quentin Hibon
fa3774a32b Bump org.jlleitschuh.gradle.ktlint from 10.1.0 to 10.2.0 2021-10-01 23:32:02 +02:00
dependabot[bot]
fd124f2a6c Bump ktorVersion from 1.6.3 to 1.6.4
Bumps `ktorVersion` from 1.6.3 to 1.6.4.

Updates `ktor-client-mock` from 1.6.3 to 1.6.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.6.3...1.6.4)

Updates `ktor-jackson` from 1.6.3 to 1.6.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.6.3...1.6.4)

Updates `ktor-client-android` from 1.6.3 to 1.6.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.6.3...1.6.4)

Updates `ktor-client-core` from 1.6.3 to 1.6.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.6.3...1.6.4)

Updates `ktor-client-jackson` from 1.6.3 to 1.6.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.6.3...1.6.4)

Updates `ktor-client-json` from 1.6.3 to 1.6.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.6.3...1.6.4)

Updates `ktor-server-netty` from 1.6.3 to 1.6.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.6.3...1.6.4)

Updates `ktor-server-core` from 1.6.3 to 1.6.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.6.3...1.6.4)

Updates `ktor-html-builder` from 1.6.3 to 1.6.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.6.3...1.6.4)

Updates `ktor-server-tests` from 1.6.3 to 1.6.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.6.3...1.6.4)

---
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-10-01 22:55:56 +02:00
dependabot[bot]
265b65eb8a Bump guava from 30.1.1-android to 31.0.1-android
Bumps [guava](https://github.com/google/guava) from 30.1.1-android to 31.0.1-android.
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

---
updated-dependencies:
- dependency-name: com.google.guava:guava
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-01 22:55:50 +02:00
dependabot[bot]
4c269c55d2 Bump kotlin-stdlib-jdk8 from 1.5.30 to 1.5.31
Bumps [kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.5.30 to 1.5.31.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.5.31/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.5.30...v1.5.31)

---
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-10-01 17:39:37 +02:00
dependabot[bot]
c03305120e Bump daggerVersion from 2.38.1 to 2.39
Bumps `daggerVersion` from 2.38.1 to 2.39.

Updates `dagger` from 2.38.1 to 2.39
- [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.38.1...dagger-2.39)

Updates `dagger-compiler` from 2.38.1 to 2.39
- [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.38.1...dagger-2.39)

---
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-10-01 17:38:52 +02:00
dependabot[bot]
29615b670b Bump kxCoroutinesVersion from 1.5.1 to 1.5.2
Bumps `kxCoroutinesVersion` from 1.5.1 to 1.5.2.

Updates `kotlinx-coroutines-android` from 1.5.1 to 1.5.2
- [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.5.1...1.5.2)

Updates `kotlinx-coroutines-core` from 1.5.1 to 1.5.2
- [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.5.1...1.5.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-01 17:38:42 +02:00
dependabot[bot]
6ab4a696b6 Bump kotlin-stdlib from 1.5.30 to 1.5.31
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.5.30 to 1.5.31.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.5.31/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.5.30...v1.5.31)

---
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-10-01 17:38:35 +02:00
dependabot[bot]
23479c7765 Bump opencsv from 5.5.1 to 5.5.2
Bumps opencsv from 5.5.1 to 5.5.2.

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-01 08:06:26 +02:00
dependabot[bot]
6d98f7aafa Bump kotlinx-coroutines-core-jvm from 1.5.1 to 1.5.2
Bumps [kotlinx-coroutines-core-jvm](https://github.com/Kotlin/kotlinx.coroutines) from 1.5.1 to 1.5.2.
- [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.5.1...1.5.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-01 07:58:57 +02:00
75078ed52b Merge pull request #1101 from KristianTashkov/kris/implement_at_most
Implement numerical habits with AT_MOST target type
2021-09-29 04:20:13 -05:00
2a0afedb1d SubtitleCard: Show at-most icon 2021-09-29 03:22:38 -05:00
66a2b41250 Target type: use dropdown instead of radio button 2021-09-29 03:22:31 -05:00
KristianTashkov
d6a7fa3d7a Add unit tests for numerical habits 2021-09-27 00:36:02 +03:00
KristianTashkov
07e55f1c76 modify review comments 2021-09-26 22:58:24 +03:00
4ee5dd910b Merge pull request #1116 from sgallese/feature/update-app-intro
Implement skipPressed for Intro, update to latest version of AppIntro
2021-09-23 07:06:24 -05:00
87f071b5b4 Merge pull request #1108 from sgallese/feature/midnight-timer-remove-jvm
Place MidnightTimer under test
2021-09-23 07:04:08 -05:00
bb0b5e8adf Merge pull request #1113 from KristianTashkov/kris/create_habit_border
Add border to create habit buttons
2021-09-23 06:16:07 -05:00
sgallese
c79d1e82a5 Update AppIntro to latest version 2021-09-22 20:07:06 -07:00
sgallese
4aebeedec6 Finish intro when skipped pressed 2021-09-22 20:06:41 -07:00
KristianTashkov
7de94f2caf Add border to create habit buttons 2021-09-22 16:42:40 +03:00
KristianTashkov
17ed85fc1b fix test 2021-09-22 16:18:50 +03:00
KristianTashkov
4355fb4d68 start score from 1.0 for at most and reflect the same in history 2021-09-22 15:49:51 +03:00
sgallese
508200abeb Format classes with ktlint 2021-09-21 19:25:21 -07:00
sgallese
a29943e783 Simplify midnight timer interface for testing 2021-09-21 19:21:35 -07:00
sgallese
3e6a9181d6 Code review- keep timer offset to one second 2021-09-21 19:16:37 -07:00
1fe3a3d1ca Merge pull request #1107 from sgallese/feature/string-utils-remove-jvm
Removes JVM dependencies from StringUtils
2021-09-21 20:36:22 -05:00
sgallese
b2951a3475 Place MidnightTimer under test 2021-09-19 08:41:05 -07:00
sgallese
9d3c63cf62 Removes JVM dependencies from StringUtils
See Issue #1075
2021-09-18 23:19:34 -07:00
KristianTashkov
65d237254c simplify scoring code 2021-09-12 16:56:08 +03:00
KristianTashkov
fe1d5c66cb fix bug in history card 2021-09-12 16:23:42 +03:00
KristianTashkov
113a5028af Simplify the code 2021-09-12 15:27:03 +03:00
KristianTashkov
1a56260757 add more tests for AT_MOST 2021-09-12 14:35:05 +03:00
KristianTashkov
697fffbc99 fix tests 2021-09-12 13:50:27 +03:00
KristianTashkov
804edfa64e Implement numerical habits with AT_MOST target type 2021-09-12 00:51:54 +03:00
2ab6c396d0 Merge pull request #1100 from kalina559/vector_drawables
Replaced .png drawables with vector assets where possible
2021-09-11 15:14:08 -05:00
a55f467339 Minor changes to ic_colorpicker_swatch_selected 2021-09-11 07:21:45 -05:00
Jakub Kalinowski
cf682f68c9 Dialog's positive button has bigger font size now (#1096) 2021-09-11 07:03:06 -05:00
0e988e746c Merge pull request #1082 from hiqua/improve_number_picker
Make numpad work better in number picker dialog
2021-09-11 06:56:17 -05:00
Jakub Kalinowski
f119cbf8e7 Added copyright notice 2021-09-08 19:41:13 +02:00
Jakub Kalinowski
056f5f6fce Added last .svg icons 2021-09-08 19:39:59 +02:00
Jakub Kalinowski
42f6125d5e Removed last .png icons 2021-09-08 19:39:34 +02:00
Jakub Kalinowski
3e20fc4d1d Added new .svg icons 2021-09-08 18:09:26 +02:00
Jakub Kalinowski
1f763feb69 Removed .png icons 2021-09-08 18:09:04 +02:00
Jakub Kalinowski
6e7ad329fe Added copyright notice 2021-09-08 17:49:42 +02:00
Jakub Kalinowski
5cb241475d Corrected the dark theme icon color 2021-09-08 17:47:50 +02:00
Jakub Kalinowski
27e76c7243 New edit icon 2021-09-08 17:43:25 +02:00
Jakub Kalinowski
576ad04064 Deleted edit icon 2021-09-08 17:43:04 +02:00
Jakub Kalinowski
5f8187ef6d Replaced some more .png icons with vector assets 2021-09-06 22:26:08 +02:00
Jakub Kalinowski
f16f919e27 Resolved naming issue 2021-09-06 21:54:10 +02:00
Jakub Kalinowski
736bb8a75e Added new .svg icons 2021-09-06 21:47:38 +02:00
Jakub Kalinowski
de9ad6d4a4 Deleted some old .png icons 2021-09-06 21:47:10 +02:00
Quentin Hibon
1d37ce54ea Focus fractional part after entering a decimal separator 2021-09-04 17:14:57 +02:00
Quentin Hibon
f88f1cfb54 Improve NumberPicker usage in numerical habits 2021-09-04 17:14:57 +02:00
dependabot[bot]
fc1478645b Bump com.github.triplet.play from 3.5.0 to 3.6.0
Bumps com.github.triplet.play from 3.5.0 to 3.6.0.

---
updated-dependencies:
- dependency-name: com.github.triplet.play
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-03 09:56:03 +02:00
Quentin Hibon
ffab001b09 Bump JDK from 1.8 to 11 2021-09-03 08:08:34 +02:00
Quentin Hibon
a58a8005e1 Bump AGP from 4.2.2 to 7.0.2 2021-09-03 08:08:34 +02:00
Quentin Hibon
c884ada187 Bump gradle wrapper from 7.0 to 7.2 2021-09-03 08:08:34 +02:00
Quentin Hibon
e3d46ad5a0 Bump AGP from 4.2.0 to 4.2.2 2021-09-02 19:34:05 +02:00
dependabot[bot]
f4a2c03216 Bump ktorVersion from 1.6.2 to 1.6.3
Bumps `ktorVersion` from 1.6.2 to 1.6.3.

Updates `ktor-client-mock` from 1.6.2 to 1.6.3
- [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.2...1.6.3)

Updates `ktor-jackson` from 1.6.2 to 1.6.3
- [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.2...1.6.3)

Updates `ktor-client-android` from 1.6.2 to 1.6.3
- [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.2...1.6.3)

Updates `ktor-client-core` from 1.6.2 to 1.6.3
- [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.2...1.6.3)

Updates `ktor-client-jackson` from 1.6.2 to 1.6.3
- [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.2...1.6.3)

Updates `ktor-client-json` from 1.6.2 to 1.6.3
- [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.2...1.6.3)

Updates `ktor-server-netty` from 1.6.2 to 1.6.3
- [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.2...1.6.3)

Updates `ktor-server-core` from 1.6.2 to 1.6.3
- [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.2...1.6.3)

Updates `ktor-html-builder` from 1.6.2 to 1.6.3
- [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.2...1.6.3)

Updates `ktor-server-tests` from 1.6.2 to 1.6.3
- [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.2...1.6.3)

---
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-09-02 17:49:25 +02:00
dependabot[bot]
f2b8f2f98d Bump simpleclient_hotspot from 0.11.0 to 0.12.0
Bumps [simpleclient_hotspot](https://github.com/prometheus/client_java) from 0.11.0 to 0.12.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.11.0...parent-0.12.0)

---
updated-dependencies:
- dependency-name: io.prometheus:simpleclient_hotspot
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-02 17:49:18 +02:00
dependabot[bot]
2c5fd87a2a Bump simpleclient from 0.11.0 to 0.12.0
Bumps [simpleclient](https://github.com/prometheus/client_java) from 0.11.0 to 0.12.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.11.0...parent-0.12.0)

---
updated-dependencies:
- dependency-name: io.prometheus:simpleclient
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-02 07:54:39 +02:00
dependabot[bot]
39768f7f04 Bump kotlin-stdlib-jdk8 from 1.5.21 to 1.5.30
Bumps [kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.5.21 to 1.5.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.5.21...v1.5.30)

---
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-09-02 07:54:29 +02:00
dependabot[bot]
cc3e1ced15 Bump sqlite-jdbc from 3.36.0.1 to 3.36.0.3
Bumps [sqlite-jdbc](https://github.com/xerial/sqlite-jdbc) from 3.36.0.1 to 3.36.0.3.
- [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.1...3.36.0.3)

---
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-09-02 07:54:13 +02:00
dependabot[bot]
2e26cc104e Bump simpleclient_httpserver from 0.11.0 to 0.12.0
Bumps [simpleclient_httpserver](https://github.com/prometheus/client_java) from 0.11.0 to 0.12.0.
- [Release notes](https://github.com/prometheus/client_java/releases)
- [Commits](https://github.com/prometheus/client_java/compare/parent-0.11.0...parent-0.12.0)

---
updated-dependencies:
- dependency-name: io.prometheus:simpleclient_httpserver
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-01 08:12:08 +02:00
dependabot[bot]
42fd0926ef Bump kotlin-stdlib from 1.5.21 to 1.5.30
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.5.21 to 1.5.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.5.21...v1.5.30)

---
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-09-01 08:12:00 +02:00
ec202aa9a7 Merge pull request #1079 from hiqua/reimplement_custom_freq
Reimplement custom frequencies
2021-08-23 05:02:38 -05:00
Quentin Hibon
1fb56c8777 Fix typo 2021-08-22 17:36:59 +02:00
Quentin Hibon
a5d4a37da8 Improve digit constraints in frequency picker 2021-08-22 17:12:37 +02:00
Quentin Hibon
4804a48549 Reimplement custom frequencies
Closes #961.
2021-08-22 17:12:17 +02:00
Quentin Hibon
c892a845b4 Remove deprecated jcenter repository 2021-08-22 17:11:27 +02:00
Quentin Hibon
e98064b6a5 Update README.md: link guidelines 2021-08-22 15:11:42 +02:00
57f5f6ed5b Cycle through through all checkmark states 2021-08-22 06:23:06 -05:00
79f5b8b7e8 uhabits-server: Add missing dependencies 2021-08-22 05:15:45 -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
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
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
476 changed files with 6131 additions and 2951 deletions

View File

@@ -6,11 +6,16 @@ labels: ''
assignees: '' 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 ## Pre-submission checklist
- [ ] I am submitting a bug report, not a feature request. - [ ] I am submitting a bug report, not a feature request.
- [ ] I am running the latest version of Loop Habit Tracker. - [ ] I have searched for similar issues, but did not find any matches.
- [ ] I have have searched for similar issues, but did not find any matches.
## Description ## Description
A clear and concise description of what the problem is. A clear and concise description of what the problem is.
@@ -21,10 +26,11 @@ A clear and concise description of what the problem is.
3. Scroll down to .... 3. Scroll down to ....
4. See error 4. See error
## Screenshots
If applicable, add screenshots to help explain your problem.
## System information ## System information
- Phone: [e.g. Google Pixel 4] - Phone: [e.g. Google Pixel 4]
- Phone Operating System: [e.g. Android 10] - Phone Operating System: [e.g. Android 10]
- App version: [e.g. 1.8.9] - App version: [e.g. 2.0.2]
## Screenshots
If applicable, add screenshots to help explain your problem.

View File

@@ -3,4 +3,4 @@ updates:
- package-ecosystem: "gradle" - package-ecosystem: "gradle"
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "monthly"

View File

@@ -13,10 +13,10 @@ jobs:
- name: Check out source code - name: Check out source code
uses: actions/checkout@v1 uses: actions/checkout@v1
- name: Install Java Development Kit 1.8 - name: Install Java Development Kit 11
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
java-version: 1.8 java-version: 11
- name: Build Project - name: Build Project
run: ./build.sh build run: ./build.sh build
@@ -30,7 +30,7 @@ jobs:
AndroidTest: AndroidTest:
needs: Build needs: Build
runs-on: macOS-10.15 runs-on: macOS-10.15
timeout-minutes: 45 timeout-minutes: 60
strategy: strategy:
matrix: matrix:
api: [ api: [
@@ -55,6 +55,11 @@ jobs:
name: uhabits-android name: uhabits-android
path: uhabits-android/build/outputs/ 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 - name: Run Android Tests
run: ./build.sh android-tests ${{ matrix.api }} run: ./build.sh android-tests ${{ matrix.api }}

View File

@@ -1,5 +1,28 @@
# Changelog # Changelog
## [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
### 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)
## [2.0.1] - 2021-05-09 ## [2.0.1] - 2021-05-09
### Added ### Added

View File

@@ -18,7 +18,7 @@ source.
<p align="center"> <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="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> </p>
## Screenshots ## Screenshots
@@ -90,7 +90,7 @@ contribute, even if you are not a software developer.
is already completed, you are also very welcome to join and proofread it. 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 * **Write some code.** If you are an Android developer, you are very welcome to
contribute with code. Please see `docs/GUIDELINES.md`. contribute with code. Please see the [guidelines](https://github.com/iSoron/uhabits/blob/dev/docs/GUIDELINES.md).
## License ## License
@@ -109,7 +109,7 @@ contribute, even if you are not a software developer.
more details. more details.
You should have received a copy of the GNU General Public License along 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/1.png [screen1]: screenshots/1.png
[screen2]: screenshots/2.png [screen2]: screenshots/2.png
@@ -123,9 +123,9 @@ contribute, even if you are not a software developer.
[screen4th]: screenshots/4.thumb.png [screen4th]: screenshots/4.thumb.png
[screen5th]: screenshots/5.thumb.png [screen5th]: screenshots/5.thumb.png
[screen6th]: screenshots/6.thumb.png [screen6th]: screenshots/6.thumb.png
[poedit]: http://translate.loophabits.org [poedit]: https://translate.loophabits.org
[playstore]: https://play.google.com/store/apps/details?id=org.isoron.uhabits [playstore]: https://play.google.com/store/apps/details?id=org.isoron.uhabits
[releases]: https://github.com/iSoron/uhabits/releases [releases]: https://github.com/iSoron/uhabits/releases
[fdroid]: http://f-droid.org/app/org.isoron.uhabits [fdroid]: https://f-droid.org/app/org.isoron.uhabits
[build]: https://github.com/iSoron/uhabits/blob/dev/docs/BUILD.md [build]: https://github.com/iSoron/uhabits/blob/dev/docs/BUILD.md
[beta]: https://play.google.com/apps/testing/org.isoron.uhabits [beta]: https://play.google.com/apps/testing/org.isoron.uhabits

View File

@@ -1,11 +1,11 @@
plugins { plugins {
val kotlinVersion = "1.4.21" val kotlinVersion = "1.6.10"
id("com.android.application") version ("4.1.0") apply (false) id("com.android.application") version ("7.0.3") apply (false)
id("org.jetbrains.kotlin.android") version kotlinVersion apply (false) id("org.jetbrains.kotlin.android") version kotlinVersion apply (false)
id("org.jetbrains.kotlin.kapt") version kotlinVersion apply (false) id("org.jetbrains.kotlin.kapt") version kotlinVersion apply (false)
id("org.jetbrains.kotlin.android.extensions") version kotlinVersion apply (false) id("org.jetbrains.kotlin.android.extensions") version kotlinVersion apply (false)
id("org.jetbrains.kotlin.multiplatform") version kotlinVersion apply (false) id("org.jetbrains.kotlin.multiplatform") version kotlinVersion apply (false)
id("org.jlleitschuh.gradle.ktlint") version "10.0.0" id("org.jlleitschuh.gradle.ktlint") version "10.3.0"
} }
apply { apply {
@@ -15,11 +15,9 @@ apply {
allprojects { allprojects {
repositories { repositories {
google() google()
jcenter()
mavenCentral() mavenCentral()
maven(url = "https://plugins.gradle.org/m2/") maven(url = "https://plugins.gradle.org/m2/")
maven(url = "https://oss.sonatype.org/content/repositories/snapshots/") maven(url = "https://oss.sonatype.org/content/repositories/snapshots/")
maven(url = "https://kotlin.bintray.com/ktor") maven(url = "https://jitpack.io")
maven(url = "https://kotlin.bintray.com/kotlin-js-wrappers")
} }
} }

View File

@@ -133,6 +133,9 @@ android_test() {
log_error "Some $size instrumented tests failed." log_error "Some $size instrumented tests failed."
log_error "Saving logcat: $OUT_LOGCAT..." log_error "Saving logcat: $OUT_LOGCAT..."
$ADB logcat -d > $OUT_LOGCAT $ADB logcat -d > $OUT_LOGCAT
log_error "Fetching test screenshots..."
$ADB pull /sdcard/Android/data/${PACKAGE_NAME}/files/test-screenshots ${ANDROID_OUTPUTS_DIR}/
$ADB shell rm -r /sdcard/Android/data/${PACKAGE_NAME}/files/test-screenshots/
return 1 return 1
fi fi
log_info "$size tests passed." log_info "$size tests passed."
@@ -198,13 +201,6 @@ android_build() {
return 0 return 0
} }
android_fetch_images() {
log_info "Fetching images"
rm -rf ${ANDROID_OUTPUTS_DIR}/test-screenshots
$ADB pull /sdcard/Android/data/${PACKAGE_NAME}/files/test-screenshots ${ANDROID_OUTPUTS_DIR}/
$ADB shell rm -r /sdcard/Android/data/${PACKAGE_NAME}/files/test-screenshots/
}
android_accept_images() { android_accept_images() {
find ${ANDROID_OUTPUTS_DIR}/test-screenshots -name '*.expected*' -delete find ${ANDROID_OUTPUTS_DIR}/test-screenshots -name '*.expected*' -delete
rsync -av ${ANDROID_OUTPUTS_DIR}/test-screenshots/ uhabits-android/src/androidTest/assets/ rsync -av ${ANDROID_OUTPUTS_DIR}/test-screenshots/ uhabits-android/src/androidTest/assets/
@@ -233,18 +229,14 @@ CI/CD script for Loop Habit Tracker.
Usage: Usage:
build.sh build [options] build.sh build [options]
build.sh clean [options]
build.sh android-tests <API> [options] build.sh android-tests <API> [options]
build.sh android-tests-parallel <API> <API>... [options] build.sh android-tests-parallel <API> <API>... [options]
build.sh android-fetch-images [options]
build.sh android-accept-images [options] build.sh android-accept-images [options]
Commands: Commands:
build Build the app and run small tests build Build the app and run small tests
clean Remove all build directories
android-tests Run medium and large Android tests on an emulator android-tests Run medium and large Android tests on an emulator
android-tests-parallel Tests multiple API levels simultaneously android-tests-parallel Tests multiple API levels simultaneously
android-fetch-images Fetch failed view test images from device
android-accept-images Copy fetched images to corresponding assets folder android-accept-images Copy fetched images to corresponding assets folder
Options: Options:
@@ -274,19 +266,17 @@ main() {
case "$1" in case "$1" in
build) build)
shift; _parse_opts "$@" shift; _parse_opts "$@"
clean
core_build core_build
android_build android_build
;; ;;
clean)
clean
;;
android-tests) android-tests)
shift; _parse_opts "$@" shift; _parse_opts "$@"
if [ -z $1 ]; then if [ -z $1 ]; then
_print_usage _print_usage
exit 1 exit 1
fi fi
for attempt in {1..3}; do for attempt in {1..5}; do
log_info "Running Android tests (attempt $attempt)..." log_info "Running Android tests (attempt $attempt)..."
android_test $1 && return 0 android_test $1 && return 0
done done
@@ -297,9 +287,6 @@ main() {
shift; _parse_opts "$@" shift; _parse_opts "$@"
android_test_parallel $* android_test_parallel $*
;; ;;
android-fetch-images)
android_fetch_images
;;
android-accept-images) android-accept-images)
android_accept_images android_accept_images
;; ;;

View File

@@ -33,7 +33,7 @@ The repository will be downloaded to the directory `uhabits`.
2. When the IDE asks you for the project location, select `uhabits` and click "Ok". 2. When the IDE asks you for the project location, select `uhabits` and click "Ok".
3. Android Studio will spend some time indexing the project. When this is complete, click the toolbar icon "Sync Project with Gradle File", located near the right corner of the top toolbar. 3. Android Studio will spend some time indexing the project. When this is complete, click the toolbar icon "Sync Project with Gradle File", located near the right corner of the top toolbar.
4. The operation will likely fail several times due to missing Android SDK components. Each time it fails, click the link "Install missing platforms", "Install build tools", etc, and try again. 4. The operation will likely fail several times due to missing Android SDK components. Each time it fails, click the link "Install missing platforms", "Install build tools", etc, and try again.
5. To test the application, create a virtual Android device using the menu "Tools" and "AVD Manager". The default options should work fine, but free to customize the device. 5. To test the application, create a virtual Android device using the menu "Tools" and "AVD Manager". The default options should work fine, but feel free to customize the device.
6. Click the menu "Run" and "uhabits-android". The application should launch. 6. Click the menu "Run" and "uhabits-android". The application should launch.

View File

@@ -1,5 +1,5 @@
org.gradle.parallel=false org.gradle.parallel=false
org.gradle.daemon=true org.gradle.daemon=true
org.gradle.jvmargs=-Xms2048m -Xmx2048m -XX:MaxPermSize=2048m org.gradle.jvmargs=-Xms2048m -Xmx2048m
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true

Binary file not shown.

View File

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

2
gradlew vendored
View File

@@ -82,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -129,6 +130,7 @@ fi
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"` APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"` JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath # We build the pattern for arguments to be converted via cygpath

25
gradlew.bat vendored
View File

@@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@@ -37,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init if "%ERRORLEVEL%" == "0" goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -51,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -61,28 +64,14 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell

View File

@@ -1,7 +1,6 @@
pluginManagement { pluginManagement {
repositories { repositories {
gradlePluginPortal() gradlePluginPortal()
jcenter()
google() google()
} }
resolutionStrategy.eachPlugin { resolutionStrategy.eachPlugin {

View File

@@ -1,350 +1,377 @@
Name,Languages,"Translated (Words)","Target Words","Approved (Words)",Voted,"""+"" votes received","""-"" votes received","Winning (Words)" Name,Languages,"Translated (Words)","Target Words","Approved (Words)",Voted,"""+"" votes received","""-"" votes received","Winning (Words)",Joined
"Alinson Xavier (iSoron)","Portuguese, Brazilian; Japanese; Spanish; Portuguese; Italian; Chinese Simplified; French; Hungarian; German; Arabic; Hindi; Slovenian; Catalan; Greek; Korean; Bulgarian; Chinese Traditional; Polish; Russian; Serbian (Cyrillic); Turkish; Ukrainian; Czech; Indonesian; Croatian; Danish; Dutch; Romanian; Swedish; Basque; Persian; Vietnamese; Telugu; Finnish; Tamil; Afrikaans; Esperanto; Hebrew",14790,17211,1272,0,1707,70,4259 "Alinson Xavier (iSoron)","Portuguese, Brazilian; Japanese; Spanish; Portuguese; Italian; Chinese Simplified; French; Hungarian; German; Arabic; Hindi; Slovenian; Catalan; Greek; Korean; Bulgarian; Chinese Traditional; Polish; Russian; Serbian (Cyrillic); Turkish; Ukrainian; Czech; Indonesian; Croatian; Danish; Dutch; Romanian; Swedish; Basque; Persian; Finnish; Vietnamese; Telugu; Tamil; Afrikaans; Esperanto; Hebrew",14808,17227,1282,0,1779,80,4274,"2016-03-05 18:35:27"
"Slobodan Simić (Слободан Симић) (slsimic)","Serbian (Latin); Serbian (Cyrillic)",2053,1830,2105,12,33,0,1982 "Slobodan Simić (Слободан Симић) (slsimic)","Serbian (Latin); Serbian (Cyrillic)",2054,1831,2114,12,33,0,1991,"2021-02-03 14:26:07"
"Oglaigh Rystard (oglaignaheireann)","Ukrainian; Portuguese; Catalan; Greek; Basque; Romanian; Italian",1103,1037,1327,1,13,6,954 "Oglaigh Rystard (oglaignaheireann)","Ukrainian; Portuguese; Catalan; Greek; Basque; Romanian; Italian",1103,1037,1327,1,13,6,954,"2017-03-31 09:13:19"
"David (Cliff122)",Swedish,1040,1019,725,6,0,0,700 "David (Cliff122)",Swedish,1040,1019,725,6,0,0,700,"2020-01-21 13:56:55"
dukelc,Slovak,919,880,0,0,0,0,0 "Omer I.S. (omeritzics)",Hebrew,1000,900,1097,14,1,0,946,"2020-10-11 20:10:51"
KMakoto,"Chinese Traditional",745,1146,949,0,0,0,745 dukelc,Slovak,919,880,0,0,0,0,0,"2020-08-27 14:02:41"
"Evren (evrenkiymaz)",Turkish,688,604,0,71,4,0,0 "Intan Ayunda (Intan_Ayunda)",Indonesian,800,793,962,0,0,0,711,"2020-10-14 07:51:58"
"David Nos (david.nos)","Catalan; Spanish",667,731,0,0,0,0,0 KMakoto,"Chinese Traditional",745,1146,949,0,0,0,745,"2019-10-22 04:19:52"
androide74,Italian,644,659,0,2,0,0,0 "Evren (evrenkiymaz)",Turkish,688,604,0,71,5,1,0,"2020-10-04 03:39:16"
Tomairuka,Japanese,633,1636,909,43,0,0,564 "David Nos (david.nos)","Catalan; Spanish",667,731,0,0,1,0,0,"2020-01-04 10:15:36"
"Dmitriy Bogdanov (di72nn)",Russian,625,572,1175,0,34,0,519 "Antti Kallio (antti.kallio)",Finnish,650,525,0,0,0,0,0,"2021-07-03 05:54:44"
reyhoon,Persian,624,759,0,1,1,0,0 androide74,Italian,644,659,0,2,0,0,0,"2020-02-06 15:46:28"
Osoitz,Basque,610,545,0,9,0,0,3 Tomairuka,Japanese,633,1636,909,43,0,0,564,"2020-12-12 12:14:22"
fabian.bouchal,German,548,527,0,6,0,3,72 "Dmitriy Bogdanov (di72nn)",Russian,625,572,1197,0,36,0,515,"2017-03-31 10:00:48"
boban77,Czech,509,461,0,2,0,0,0 reyhoon,Persian,624,759,0,1,3,1,0,"2020-10-01 18:17:23"
"Yoav Argov (YoavArgov)",Hebrew,501,461,0,0,1,8,3 Osoitz,Basque,610,545,0,9,0,0,3,"2018-01-23 14:07:47"
REMOVED_USER,Norwegian,501,498,501,0,148,0,501 "Saeed Esmaili (saaeed.es20)",Persian,568,774,0,5,4,0,0,"2020-11-26 15:41:15"
"Martim Parente (Sharlimar)",Portuguese,497,534,0,38,0,0,0 fabian.bouchal,German,548,527,0,6,0,3,72,"2020-01-07 06:43:37"
"chrrris1987 (Chrrris1987)",Dutch,467,478,0,23,0,0,0 boban77,Czech,509,461,0,2,0,0,0,"2020-04-30 13:18:24"
"Huy Ngo (huyngo)",Vietnamese,461,695,0,1,0,0,0 "Yoav Argov (YoavArgov)",Hebrew,501,461,0,0,1,8,103,"2017-04-28 07:23:01"
"黄克 (hk13127)","Chinese Simplified",461,765,0,1,0,0,0 REMOVED_USER,Norwegian,501,498,501,0,148,0,501,"2017-07-05 19:02:25"
"Arkadiusz Bubak (epitek)",Polish,458,416,29,24,0,3,0 "Martim Parente (Sharlimar)",Portuguese,497,534,0,38,0,0,0,"2020-08-26 10:22:11"
marco.baturan,Esperanto,452,452,0,0,0,0,0 "chrrris1987 (Chrrris1987)",Dutch,467,478,0,23,0,0,0,"2020-02-03 05:26:04"
"Sief Tarek (sieftarek135)",Arabic,447,455,0,0,0,0,0 "Huy Ngo (huyngo)",Vietnamese,461,695,0,1,0,0,0,"2020-01-26 11:58:36"
"Omer I.S. (omeritzics)",Hebrew,428,366,0,14,1,0,0 "黄克 (hk13127)","Chinese Simplified",461,765,0,1,0,0,24,"2020-01-17 23:16:03"
"Samuel Guay (SamGuay)",French,426,486,0,6,0,0,0 "Arkadiusz Bubak (epitek)",Polish,458,416,29,24,0,3,0,"2020-11-05 05:11:58"
"Diana Karaseva (Sun_Dianka)",Russian,399,373,0,10,1,0,221 marco.baturan,Esperanto,452,452,0,0,0,0,0,"2020-06-23 02:49:46"
"Alexander Jansson (dalecarlian)",Swedish,396,406,507,0,0,3,399 "Sief Tarek (sieftarek135)",Arabic,447,455,0,0,0,0,0,"2021-02-07 14:35:21"
luiandresgonzalez,Spanish,383,403,0,1,0,0,0 "Samuel Guay (SamGuay)",French,426,486,0,6,0,0,0,"2020-06-25 07:14:38"
"Thamara Andrade (tkcandrade)","Portuguese, Brazilian",380,387,0,0,1,0,252 "Diana Karaseva (Sun_Dianka)",Russian,399,373,0,10,1,0,209,"2020-01-30 06:40:02"
"Sølv Ræven (soelvraeven)",Danish,370,370,0,0,0,0,0 "Alexander Jansson (dalecarlian)",Swedish,396,406,507,0,0,3,399,"2017-06-21 01:37:32"
"Isti (eisti)",Hungarian,367,329,0,0,0,0,0 luiandresgonzalez,Spanish,383,403,0,1,28,0,0,"2020-07-11 14:20:44"
"Anh Quân (dangquanuet)",Vietnamese,362,530,0,42,1,0,0 "Thamara Andrade (tkcandrade)","Portuguese, Brazilian",380,387,0,0,1,0,252,"2020-01-09 19:35:48"
gapszi,Hungarian,348,301,0,86,0,0,0 "Sølv Ræven (soelvraeven)",Danish,370,370,0,0,0,0,0,"2020-11-28 16:46:18"
"Mahdi Nasiri (mahdi.nasiri)",Persian,343,465,0,39,3,0,0 "Isti (eisti)",Hungarian,367,329,0,0,0,0,0,"2020-12-03 12:02:51"
Seoyul,Korean,339,825,0,0,27,0,0 "Anh Quân (dangquanuet)",Vietnamese,362,530,0,42,2,0,0,"2017-10-29 12:27:44"
"Magimai Prakasam (magimai)",Tamil,336,831,0,12,0,0,0 gapszi,Hungarian,348,301,0,86,0,0,0,"2019-04-08 01:35:54"
"Michael Malak (MichaelKMalak)",Arabic,304,271,0,0,0,0,0 JY3,"Chinese Simplified",345,585,278,0,1,0,207,"2021-03-08 08:53:35"
"Elina Salminen (salminen.elina.m)",Finnish,297,227,0,0,0,0,0 "Mahdi Nasiri (mahdi.nasiri)",Persian,343,465,0,39,3,1,0,"2017-07-14 09:17:25"
ayane.m,Japanese,292,863,0,1,2,0,22 Seoyul,Korean,339,825,0,0,27,0,0,"2017-06-21 08:11:39"
"Marius Teufelweich (teufelweich)",German,249,256,606,4,0,0,146 "Magimai Prakasam (magimai)",Tamil,336,831,0,12,0,0,0,"2018-04-15 21:16:08"
cobalt59,German,237,234,0,1,23,1,132 "Michael Malak (MichaelKMalak)",Arabic,304,271,0,0,0,0,0,"2020-05-26 19:47:58"
"QWERT (lurenjia01)","Chinese Simplified",236,407,0,0,0,0,0 "Elina Salminen (salminen.elina.m)",Finnish,297,227,0,0,0,0,0,"2021-01-06 01:28:57"
beriain,Basque,234,235,0,0,2,0,0 ayane.m,Japanese,292,863,0,1,3,0,22,"2019-11-20 03:28:26"
"Intan Ayunda (Intan_Ayunda)",Indonesian,228,239,336,0,0,0,135 Blinkin,Dutch,284,318,0,1,0,0,0,"2021-06-14 10:30:05"
pnhpnh,Vietnamese,225,343,0,1,3,0,0 "Marius Teufelweich (teufelweich)",German,249,256,606,4,2,0,146,"2021-03-12 04:11:38"
"Dika Fitrian Dwi Putra (OsamuDazai)",Indonesian,221,215,0,0,0,0,33 cobalt59,German,237,234,0,1,24,1,132,"2017-06-05 05:18:33"
easyrepro,Telugu,214,297,0,0,0,0,0 "QWERT (lurenjia01)","Chinese Simplified",236,407,0,0,8,0,19,"2020-03-08 01:46:25"
taras-ko,Ukrainian,211,183,0,1,4,0,19 beriain,Basque,234,235,0,0,2,0,0,"2017-03-31 15:42:28"
sojusnik,German,207,200,1,0,30,0,66 pnhpnh,Vietnamese,225,343,0,1,3,0,0,"2017-11-27 12:06:07"
axmed99,Ukrainian,203,177,0,40,0,0,53 "Dika Fitrian Dwi Putra (OsamuDazai)",Indonesian,221,215,0,0,0,0,48,"2020-07-13 04:40:27"
"Heru Yen (heruyen)",Indonesian,201,201,0,0,0,0,2 easyrepro,Telugu,214,297,0,0,0,0,0,"2020-06-12 12:52:10"
Ishmaeel,Turkish,193,174,0,129,6,0,0 taras-ko,Ukrainian,211,183,0,1,4,0,19,"2017-10-26 16:52:22"
fbruna17,Danish,181,179,0,1,0,0,0 sojusnik,German,207,200,1,0,30,0,66,"2017-04-03 17:11:56"
"Omry Cohen (omrycohen)",Hebrew,175,156,0,1,0,0,0 axmed99,Ukrainian,203,177,0,40,0,0,53,"2021-04-01 03:56:20"
Bryanx,Dutch,174,165,0,5,0,0,0 "Heru Yen (heruyen)",Indonesian,201,201,0,0,0,0,25,"2020-06-29 18:39:15"
"Pierre GALIEGUE (pierre.galiegue)",French,171,194,0,24,2,0,0 "Vijaykumar Borkar (vjkumar)",Hindi,200,364,0,11,0,0,0,"2021-08-06 16:12:15"
DionysosDV,Greek,165,153,0,0,0,0,0 Ishmaeel,Turkish,193,174,0,129,6,0,0,"2017-10-04 03:54:00"
"Gustavo Lima (GustavoLima)",Portuguese,158,177,0,1,4,10,0 "Aputsiak Niels Janussen (aputtu)",Danish,187,200,0,0,0,0,0,"2019-08-28 05:47:42"
"Aputsiak Niels Janussen (aputtu)",Danish,153,171,0,0,0,0,0 _translator,French,181,206,0,11,0,0,0,"2021-07-06 07:54:12"
plitwin,Polish,145,128,0,1,16,0,26 fbruna17,Danish,181,179,0,1,0,0,0,"2021-01-28 15:48:47"
"Lương Vĩnh Khang (LuongVinhKhang)",Vietnamese,144,256,0,0,46,1,0 "Omry Cohen (omrycohen)",Hebrew,175,156,0,1,0,0,33,"2021-01-18 07:33:23"
azzamsa,Indonesian,142,136,0,48,0,1,50 Bryanx,Dutch,174,165,0,5,0,0,0,"2019-11-21 17:08:12"
"Neysa Nasywa (neysanasywa)",Indonesian,140,141,0,0,0,0,35 "Pierre GALIEGUE (pierre.galiegue)",French,171,194,0,24,4,0,0,"2020-08-16 11:41:35"
JY3,"Chinese Simplified",136,217,80,0,0,0,80 bruhwut,Vietnamese,171,268,0,1,0,0,0,"2021-05-21 07:16:30"
"Mohammed Imthath (mimthath4)",Tamil,136,274,0,0,11,0,0 DionysosDV,Greek,165,153,0,0,0,0,0,"2021-02-27 19:05:25"
roptat,French,132,154,0,112,88,5,0 "Gustavo Lima (GustavoLima)",Portuguese,158,177,0,1,4,10,0,"2020-08-26 10:35:05"
"Trần Thái (tranhoangthai2001)",Vietnamese,127,186,0,8,1,0,0 oscfd,Spanish,155,166,0,1,4,0,0,"2021-05-21 17:58:22"
"OP Smosher (teenwolffan44)","Serbian (Cyrillic)",124,122,0,0,0,0,18 plitwin,Polish,145,128,0,1,16,0,26,"2021-01-20 06:18:37"
4001982248998,Esperanto,122,119,0,0,0,0,0 "Lương Vĩnh Khang (LuongVinhKhang)",Vietnamese,144,256,0,0,46,1,0,"2017-08-10 10:05:58"
"StoP4Me (Lcqp)",Romanian,121,119,0,0,3,0,0 azzamsa,Indonesian,142,136,0,48,0,1,26,"2017-06-16 18:29:45"
Sebastian05067,Spanish,114,133,0,55,18,0,0 "yoding (yodingc)","Chinese Traditional; Chinese Simplified",141,271,0,10,0,0,0,"2021-07-07 01:45:45"
"Tanya (MagicUnderHood)",Russian,114,98,0,19,0,0,32 "Neysa Nasywa (neysanasywa)",Indonesian,140,141,0,0,0,0,60,"2020-11-18 10:32:10"
REMOVED_USER,Arabic,111,106,0,22,21,2,0 "Mohammed Imthath (mimthath4)",Tamil,136,274,0,0,11,0,0,"2018-02-15 22:41:15"
mohmans,Arabic,109,103,0,2,0,0,0 roptat,French,132,154,0,112,89,5,0,"2017-04-19 16:54:47"
"Ivan Krušlin (krux3r)",Croatian,108,122,503,0,0,0,108 "Trần Thái (tranhoangthai2001)",Vietnamese,127,186,0,8,1,0,0,"2018-03-01 10:51:39"
"Iabin Arteaga (iabin)",Spanish,108,111,0,4,20,0,0 "OP Smosher (teenwolffan44)","Serbian (Cyrillic)",124,122,0,0,0,0,18,"2020-11-05 09:41:35"
2kaafone,Finnish,105,90,0,0,0,0,0 4001982248998,Esperanto,122,119,0,0,0,0,0,"2017-10-08 04:13:02"
"Adam Jurkiewicz (hasztagg)",Polish,104,105,529,0,0,0,104 "StoP4Me (Lcqp)",Romanian,121,119,0,0,3,0,0,"2018-05-06 18:51:59"
"Saeed Esmaili (saaeed.es20)",Persian,104,141,0,0,0,0,0 alalloush,Arabic,118,129,0,2,2,0,0,"2017-03-31 12:37:17"
"just a name bro (justanamebr0)",Danish,98,109,0,0,1,0,0 "Eilif Adelvice (adelvice)",Spanish,116,126,0,96,0,0,0,"2021-08-05 07:20:21"
"Nam Nguyen (namnl2706)",Vietnamese,95,137,0,0,0,0,0 Sebastian05067,Spanish,114,133,0,55,28,0,0,"2017-05-14 00:48:16"
"손유정 (yuwon1213)",Korean,95,57,0,0,0,0,0 "Tanya (MagicUnderHood)",Russian,114,98,0,19,0,0,54,"2019-04-21 10:44:03"
ranmagen,Hebrew,91,78,0,0,0,0,0 REMOVED_USER,Arabic,111,106,0,22,21,2,0,"2018-01-05 07:01:45"
LoneWanderer,"Chinese Traditional",90,137,0,4,0,0,0 mohmans,Arabic,109,103,0,2,0,0,0,"2020-11-23 02:48:00"
"Vo - (voyl)","Chinese Traditional",89,126,0,0,5,0,0 "Iabin Arteaga (iabin)",Spanish,108,111,0,4,21,0,0,"2017-08-26 21:08:54"
ikkaz,Indonesian,89,84,0,5,0,0,4 "Ivan Krušlin (krux3r)",Croatian,108,122,503,0,0,0,108,"2017-03-31 09:15:24"
"Irene K (Heaun)",Korean,88,75,0,25,0,0,0 2kaafone,Finnish,105,90,0,0,0,0,0,"2019-08-12 06:58:48"
"Kumar Anand (kumar0500)",Hindi,87,125,0,0,0,0,0 "Adam Jurkiewicz (hasztagg)",Polish,104,105,529,0,0,0,104,"2017-03-31 09:50:51"
Prosta4ok_ua,Ukrainian,87,84,0,1,0,0,17 "just a name bro (justanamebr0)",Danish,98,109,0,0,1,0,0,"2019-06-19 11:57:55"
"Ohad Edri (ohadalte)",Hebrew,85,79,0,0,1,3,0 "Nam Nguyen (namnl2706)",Vietnamese,95,137,0,0,0,0,0,"2020-08-18 23:02:33"
helectron,Persian,84,102,0,1,0,0,0 "손유정 (yuwon1213)",Korean,95,57,0,0,0,0,0,"2021-03-30 05:25:33"
"Radu Cebotari (wildProgrammer)",Romanian,84,92,0,1,0,0,0 ranmagen,Hebrew,91,78,0,0,0,0,0,"2021-02-16 05:44:31"
"Israa Z (sosozozo)",Arabic,79,87,0,43,11,0,3 LoneWanderer,"Chinese Traditional",90,137,0,4,0,0,0,"2020-09-29 05:24:48"
"Sofia Neves (sofiasonev)","Portuguese, Brazilian",79,84,0,1,0,0,46 "Vo - (voyl)","Chinese Traditional",89,126,0,0,5,0,0,"2020-09-02 23:34:42"
Tiralka,French,79,91,0,92,1,0,0 ikkaz,Indonesian,89,84,0,5,0,0,4,"2019-09-02 19:58:54"
"Jacob Roller (jdr28070)",Korean,79,61,0,0,0,0,0 "Irene K (Heaun)",Korean,88,75,0,25,0,0,0,"2020-03-16 11:31:12"
"Toni Mustonen (toni.mustonen)",Finnish,78,72,0,0,0,0,0 Prosta4ok_ua,Ukrainian,87,84,0,1,0,0,17,"2020-01-23 19:43:41"
"Michael (quelbs)",German,76,75,0,1,0,0,39 "Kumar Anand (kumar0500)",Hindi,87,125,0,0,0,0,0,"2020-11-07 02:46:09"
"Fauz Aladeem (topfauz)",Arabic,76,77,0,0,0,1,0 "Ohad Edri (ohadalte)",Hebrew,85,79,0,0,1,3,18,"2020-07-04 03:42:09"
RealDonald,Dutch,67,69,0,121,10,0,0 helectron,Persian,84,102,0,1,0,0,0,"2021-03-02 04:10:51"
sirekanyan,"Armenian; Russian",66,65,0,0,0,0,0 "Radu Cebotari (wildProgrammer)",Romanian,84,92,0,1,0,0,0,"2020-02-05 01:20:00"
"Константин К. (kocyak1991)",Russian,64,60,0,0,1,2,0 "Sofia Neves (sofiasonev)","Portuguese, Brazilian",79,84,0,1,0,0,46,"2020-03-12 18:19:46"
"Laura Sophie (laurasophie20)",German,62,67,0,4,0,0,0 "Jacob Roller (jdr28070)",Korean,79,61,0,0,0,0,0,"2020-01-03 11:36:40"
raden20,Indonesian,61,62,177,0,1,0,64 Tiralka,French,79,91,0,92,1,0,0,"2018-02-09 18:39:01"
"Jan Wojtecki (j4nw)",Polish,58,46,0,0,0,0,26 "Israa Z (sosozozo)",Arabic,79,87,0,43,12,0,3,"2017-11-27 14:10:50"
"Deepak Bharathi (deepakbharathi1994)",Tamil,56,107,0,0,11,4,0 "Toni Mustonen (toni.mustonen)",Finnish,78,72,0,0,0,0,0,"2017-09-02 05:34:12"
"Андрій Козицький (andriikozytskyi1108)",Ukrainian,52,52,0,0,1,0,0 "Fauz Aladeem (topfauz)",Arabic,76,77,0,0,0,1,0,"2020-02-21 22:46:12"
REMOVED_USER,Italian,51,52,0,2,0,0,0 "Michael (quelbs)",German,76,75,0,1,0,0,39,"2020-08-18 07:39:26"
govindap,"Japanese; Hindi",51,114,0,6,1,0,0 "Oliver Gronowski (OliverGronowski)",German,70,69,0,5,0,0,0,"2021-05-14 16:37:10"
"Mare Geldenhuys (mare.geldenhuys)",Afrikaans,50,57,0,0,0,0,0 RealDonald,Dutch,67,69,0,121,10,0,0,"2017-06-23 20:10:12"
"Peter Williams (williamspete001)",Japanese,49,133,0,1,0,0,3 sirekanyan,"Armenian; Russian",66,65,0,0,0,0,0,"2020-04-18 11:32:52"
"Behnood HRazy (behnoodhr)",Persian,49,70,0,0,0,0,0 "Константин К. (kocyak1991)",Russian,64,60,0,0,1,2,0,"2018-06-10 13:39:37"
J3ll3nl,Dutch,48,48,0,0,17,1,3 "Laura Sophie (laurasophie20)",German,62,67,0,4,0,0,0,"2018-01-06 14:21:24"
"tat bz (Tat_i)",German,48,56,0,55,0,0,27 "Alparslan Sakci (sakci)",Turkish,61,55,0,11,0,0,0,"2021-06-10 11:59:22"
vach,Armenian,47,36,0,0,0,0,0 raden20,Indonesian,61,62,177,0,1,0,64,"2017-04-09 22:04:23"
andowero,Czech,47,38,0,0,0,0,0 "Jan Wojtecki (j4nw)",Polish,58,46,0,0,0,0,26,"2017-11-02 05:42:14"
"Andrew Firnes (Anechan)",Russian,47,47,0,3,0,0,29 "Deepak Bharathi (deepakbharathi1994)",Tamil,56,107,0,0,11,4,0,"2017-09-17 08:00:31"
"Coni Ragni (coni2ragnii)",Spanish,46,46,0,0,0,0,0 "Peter Williams (williamspete001)",Japanese,55,147,0,2,0,0,3,"2020-01-01 13:17:44"
"Rahul Shishodia (rahul.shishodia.10)",Hindi,46,85,0,6,0,0,0 "Андрій Козицький (andriikozytskyi1108)",Ukrainian,52,52,0,0,1,0,0,"2018-10-22 01:45:08"
Cp0204,"Chinese Simplified",45,72,0,0,0,0,0 "Nil riera (nilriera2000)",Catalan,52,61,0,1,0,0,0,"2021-06-22 16:37:44"
"cc (cavaz)",Italian,44,41,0,0,0,0,0 REMOVED_USER,Italian,51,52,0,2,0,0,0,"2017-08-21 05:15:31"
"Kamil Dziadek (prso94)",Polish,43,39,0,0,2,0,0 govindap,"Japanese; Hindi",51,114,0,6,1,0,0,"2020-06-02 20:15:52"
"Boban Jagertraum (boban40)",Czech,43,38,0,2,1,1,0 "Mare Geldenhuys (mare.geldenhuys)",Afrikaans,50,57,0,0,0,0,0,"2017-10-20 18:00:14"
andreea.muscalagiu,Romanian,42,52,0,1,0,0,0 "Behnood HRazy (behnoodhr)",Persian,49,70,0,0,0,0,0,"2017-11-25 10:57:21"
"Me Me (gentelwom)",Arabic,42,40,0,0,0,0,0 "tat bz (Tat_i)",German,48,56,0,55,0,0,27,"2021-03-26 05:12:54"
"Balázs Keresztury (belidzs)",Hungarian,42,41,501,0,7,0,38 J3ll3nl,Dutch,48,48,0,0,17,1,3,"2017-03-31 11:56:09"
MStefanov,Bulgarian,41,55,2,0,2,0,2 "Andrew Firnes (Anechan)",Russian,47,47,0,3,0,0,29,"2019-09-18 09:51:59"
"Ali Zali (stm19951995)",Persian,40,60,0,0,0,0,0 andowero,Czech,47,38,0,0,0,0,0,"2020-01-20 02:29:01"
"Sofia Veijonen (Suklaa) (sofia.veijonen)",Finnish,40,33,0,0,0,0,0 vach,Armenian,47,36,0,0,0,0,0,"2020-04-18 16:53:12"
dusanstrgar,Slovenian,39,41,0,0,0,0,0 "Rahul Shishodia (rahul.shishodia.10)",Hindi,46,85,0,6,5,1,0,"2018-12-24 22:18:19"
"Limin Lu (liminlu)","Chinese Simplified",39,79,503,0,0,0,39 "Coni Ragni (coni2ragnii)",Spanish,46,46,0,0,0,0,0,"2021-02-28 20:18:37"
Anshoe,Tamil,38,65,0,14,0,0,0 Cp0204,"Chinese Simplified",45,72,0,0,0,0,0,"2019-08-20 11:04:27"
anasshm,Arabic,37,36,0,9,0,0,0 "cc (cavaz)",Italian,44,41,0,0,0,0,0,"2017-04-01 04:21:08"
hrexen,Armenian,37,37,0,0,0,0,0 "Boban Jagertraum (boban40)",Czech,43,38,0,2,1,1,0,"2017-03-31 09:39:16"
REMOVED_USER,Swedish,36,33,0,5,1,0,0 "Kamil Dziadek (prso94)",Polish,43,39,0,0,2,0,0,"2020-04-06 17:12:06"
"Abdulrahman (D7M)",Arabic,36,39,0,0,0,0,0 "Me Me (gentelwom)",Arabic,42,40,0,0,0,0,0,"2020-11-08 20:44:01"
"長谷川知里 (chase0213)",Japanese,34,138,0,13,0,0,24 "Ali Elsheikh (aelsheikh1987)",Arabic,42,41,0,0,0,0,0,"2021-06-16 10:17:26"
"Piotr Łuczyński (peterluczynski)",Polish,33,30,0,6,5,0,2 "Balázs Keresztury (belidzs)",Hungarian,42,41,501,0,7,0,38,"2017-04-06 02:40:24"
"milad farahani (miladfarmahini90)",Persian,33,44,0,18,0,0,3 andreea.muscalagiu,Romanian,42,52,0,1,0,0,0,"2017-10-22 07:19:49"
"Luis E. Perichon (luisperichon)",Spanish,33,40,0,104,0,0,0 "Mateusz Duda (MateuszDuda)",Polish,42,42,0,0,0,0,0,"2021-08-17 11:27:11"
andriikozytskyi2625,Ukrainian,31,23,0,0,0,0,0 MStefanov,Bulgarian,41,55,2,0,2,0,2,"2017-03-31 16:09:02"
JoeLi,"Chinese Traditional",31,70,0,12,0,0,24 "Sofia Veijonen (Suklaa) (sofia.veijonen)",Finnish,40,33,0,0,0,0,0,"2018-03-07 09:24:22"
Moastafa,Arabic,31,25,0,0,0,0,0 "Ali Zali (stm19951995)",Persian,40,60,0,0,0,0,0,"2020-03-23 19:57:26"
REMOVED_USER,Russian,31,30,0,2,4,0,3 "Limin Lu (liminlu)","Chinese Simplified",39,79,503,0,0,0,39,"2017-03-31 09:49:35"
"hamza gamal (hamzagamal4444)",Arabic,31,28,0,0,0,0,0 dusanstrgar,Slovenian,39,41,0,0,0,0,0,"2017-03-31 10:30:28"
yancyn,"Chinese Simplified",30,40,0,0,0,0,0 Anshoe,Tamil,38,65,0,14,0,0,0,"2018-01-02 11:06:52"
"비니몬youtube (khj01025276475)",Korean,29,25,0,0,0,0,0 anasshm,Arabic,37,36,0,9,0,0,0,"2019-01-27 04:07:22"
"Ruud Schouten (ruudschouten)",Dutch,29,32,0,41,3,0,0 hrexen,Armenian,37,37,0,0,0,0,0,"2020-12-09 02:30:34"
"Guillaume Collic (gcollic)",French,26,28,0,126,11,0,0 "Abdulrahman (D7M)",Arabic,36,39,0,0,0,0,0,"2020-01-29 18:55:30"
"Niraj Yadav (neverforgetniraj)",Hindi,26,48,0,0,0,0,0 "Maria Chushnyakova (maria.ch)",Russian,36,31,0,3,0,0,0,"2021-08-17 03:23:58"
"Radoslaw Biernacki (radoslaw.biernacki)",Polish,26,24,0,8,0,0,1 REMOVED_USER,Swedish,36,33,0,5,1,0,0,"2018-09-29 17:47:33"
"Jonny I (jonny99dj)",Italian,26,26,0,5,0,0,0 "長谷川知里 (chase0213)",Japanese,34,138,0,13,0,0,24,"2018-12-14 10:52:44"
"Aaron Dalton (Perlkonig)",French,26,25,0,141,1,0,0 "Luis E. Perichon (luisperichon)",Spanish,33,40,0,104,0,0,0,"2017-09-04 13:46:06"
"Eddie (eddieattaboy)","Chinese Traditional",25,34,0,1,0,0,0 "Piotr Łuczyński (peterluczynski)",Polish,33,30,0,6,5,0,2,"2020-01-29 07:27:40"
Pan_Filuta,Czech,25,21,0,5,4,0,3 "milad farahani (miladfarmahini90)",Persian,33,44,0,18,1,0,3,"2017-08-31 16:09:00"
"eduard83 (barbany.eduard)",Catalan,24,25,0,2,0,0,0 andriikozytskyi2625,Ukrainian,31,23,0,0,0,0,0,"2019-07-08 00:16:41"
"Ľuboš Čaky (lubos.caky)",Slovak,23,22,0,0,0,0,0 Moastafa,Arabic,31,25,0,0,0,0,0,"2020-07-06 11:37:53"
"Caner Başaran (basarancaner)",Turkish,23,21,0,0,20,0,0 "hamza gamal (hamzagamal4444)",Arabic,31,28,0,0,0,0,0,"2020-08-03 15:23:34"
hodanli,Turkish,22,26,0,0,1,0,0 REMOVED_USER,Russian,31,30,0,2,4,0,3,"2018-12-03 23:55:47"
"Neeraj Verma (verma.neeraj.in)",Hindi,22,37,0,0,1,0,0 JoeLi,"Chinese Traditional",31,70,0,12,0,0,24,"2017-06-25 05:32:48"
"Alcarkse (alexis.brusle)",French,21,25,0,7,11,0,0 yancyn,"Chinese Simplified",30,40,0,0,0,0,1,"2020-05-18 20:06:03"
"Shashwat (goforgold)",Hindi,20,33,0,0,0,0,0 "비니몬youtube (khj01025276475)",Korean,29,25,0,0,0,0,0,"2020-02-09 20:44:35"
"사자솥 (toke1597)",Korean,19,19,0,0,0,0,0 "Ruud Schouten (ruudschouten)",Dutch,29,32,0,41,3,0,0,"2017-07-22 17:49:17"
"İsa Eş (IsaEs)",Turkish,19,17,0,0,6,1,0 "Aaron Dalton (Perlkonig)",French,26,25,0,141,1,0,0,"2018-01-14 12:58:19"
sheeCesu,French,19,18,0,48,2,0,0 "Niraj Yadav (neverforgetniraj)",Hindi,26,48,0,0,0,0,0,"2017-04-11 02:26:50"
can13,Turkish,19,14,0,8,0,0,0 "Guillaume Collic (gcollic)",French,26,28,0,126,11,0,0,"2017-05-05 16:13:00"
"Magdalena Urbańczyk (madziia139)",Polish,19,19,0,0,0,0,0 "Radoslaw Biernacki (radoslaw.biernacki)",Polish,26,24,0,8,0,0,1,"2020-12-15 17:55:31"
axikman11111,Uyghur,18,19,0,0,0,0,0 "Jonny I (jonny99dj)",Italian,26,26,0,5,0,0,0,"2017-10-07 07:35:34"
Adeline31,French,17,20,0,3,0,0,0 "Eddie (eddieattaboy)","Chinese Traditional",25,34,0,1,0,0,0,"2020-11-04 21:48:05"
"Hoon Jung (hooni100)",Korean,17,10,0,0,0,0,0 Pan_Filuta,Czech,25,21,0,5,4,0,3,"2017-04-29 12:55:14"
"Ceara Lopez (cealopez)",Spanish,17,18,0,0,5,1,0 "eduard83 (barbany.eduard)",Catalan,24,25,0,2,0,0,0,"2019-06-26 14:59:47"
takoyakibento,Korean,17,13,0,3,0,0,0 "Ľuboš Čaky (lubos.caky)",Slovak,23,22,0,0,0,0,0,"2019-07-02 16:51:44"
bretzel15,German,16,20,0,0,0,0,0 "Caner Başaran (basarancaner)",Turkish,23,21,0,0,21,0,0,"2017-04-09 06:34:59"
engineeringforgood,Russian,16,15,0,0,0,0,0 hodanli,Turkish,22,26,0,0,1,0,0,"2017-11-03 14:33:41"
"Şamil Ateşoğlu (m.samilatesoglu)",Turkish,16,22,0,11,6,3,0 gnu-ewm,Polish,22,23,0,6,0,0,0,"2021-02-24 03:42:01"
DebatablySane,Bulgarian,16,15,0,48,0,0,0 "Neeraj Verma (verma.neeraj.in)",Hindi,22,37,0,0,1,0,0,"2018-07-23 07:16:41"
"Bhava Tharini (bhavidanush)",Tamil,15,37,0,0,0,0,0 "Alcarkse (alexis.brusle)",French,21,25,0,7,11,0,0,"2017-08-06 09:32:29"
"Anastasia Borchuk (al2.borchuk)",Russian,14,14,0,0,0,0,0 olbotta,Italian,20,25,0,2,0,0,0,"2021-06-06 04:22:55"
"EuiHo Hwang (euiho.hwang)",Korean,14,16,0,0,0,0,0 "Shashwat (goforgold)",Hindi,20,33,0,0,0,0,0,"2020-05-17 10:34:42"
iamsurajbobade,Hindi,14,30,0,0,0,0,0 "Magdalena Urbańczyk (madziia139)",Polish,19,19,0,0,0,0,0,"2017-10-21 03:01:04"
"Zeynep Esen (nezihaesen50)",Turkish,14,13,0,0,0,0,0 sheeCesu,French,19,18,0,48,4,0,0,"2017-12-21 17:01:39"
"Fikret Bilici (fikretbilici)",Turkish,14,13,0,0,0,0,0 can13,Turkish,19,14,0,8,0,0,0,"2021-01-03 10:39:03"
"Zeeshan Rabbani (Zeera)",Hindi,14,25,0,0,0,0,0 "İsa Eş (IsaEs)",Turkish,19,17,0,0,6,1,0,"2017-06-20 07:30:22"
"Sanji Vinsmock (mukanzhanbolat4)",Russian,14,14,0,0,0,0,0 "사자솥 (toke1597)",Korean,19,19,0,0,0,0,0,"2020-02-04 13:36:11"
"Nenad Vukotic (vukotic.nenad)","Serbian (Cyrillic)",13,13,0,1,2,6,0 axikman11111,Uyghur,18,19,0,0,0,0,0,"2018-10-13 12:25:31"
"Uwe Mönks (schirinowski)",German,13,12,0,0,0,0,0 "Hoon Jung (hooni100)",Korean,17,10,0,0,0,0,0,"2021-01-03 02:26:54"
"Dave (xdave)",Hungarian,13,11,0,0,0,0,0 "Ceara Lopez (cealopez)",Spanish,17,18,0,0,5,1,0,"2017-08-22 22:56:13"
soura2,Arabic,12,13,0,0,0,0,0 takoyakibento,Korean,17,13,0,3,0,0,0,"2020-08-01 08:44:15"
"shreyas (techiespace)",Hindi,12,20,0,0,0,0,0 Adeline31,French,17,20,0,3,0,0,0,"2019-12-06 00:00:11"
"Jo Chuang (josephch405)","Chinese Traditional",11,24,0,0,0,0,11 engineeringforgood,Russian,16,15,0,0,0,0,16,"2021-01-22 03:32:35"
Vmrc,French,11,12,0,2,0,0,0 bretzel15,German,16,20,0,0,0,0,0,"2020-04-06 02:49:14"
"sathvic k (sathvictripleseven)",Telugu,10,17,0,0,0,0,0 "Şamil Ateşoğlu (m.samilatesoglu)",Turkish,16,22,0,11,6,3,0,"2017-07-05 18:37:08"
"Edwin van Rooij (edwinvrooij)",Dutch,10,13,0,17,0,0,0 DebatablySane,Bulgarian,16,15,0,48,0,0,0,"2017-07-10 15:13:18"
"Brian Camacho (bmcamacho)",Polish,10,11,0,0,1,0,0 "Bhava Tharini (bhavidanush)",Tamil,15,37,0,0,0,0,0,"2019-10-09 05:43:11"
"Ahmed Mosaad (ahmed.mosaad2018)",Arabic,10,12,0,6,0,0,0 "Zeynep Esen (nezihaesen50)",Turkish,14,13,0,0,0,0,0,"2020-01-28 07:05:15"
"Mihael Wagner (miha.wagner)",Slovenian,10,9,0,7,0,0,0 "Fikret Bilici (fikretbilici)",Turkish,14,13,0,0,0,0,0,"2020-06-21 17:16:11"
"Anonymous edgy nerd (yamentaad)",Arabic,10,13,0,1,0,0,0 "EuiHo Hwang (euiho.hwang)",Korean,14,16,0,0,0,0,0,"2020-06-23 02:40:01"
"Martin Vostatek (martinvostatek)",Czech,9,8,0,32,2,0,0 "Zeeshan Rabbani (Zeera)",Hindi,14,25,0,0,0,0,0,"2020-09-15 11:32:01"
"Sourire Lucide (sourire_lucide)",Russian,9,10,0,0,1,0,0 "Faiz Ahamed (faiznewton)",Tamil,14,31,0,0,0,0,0,"2021-05-06 23:06:46"
"Suhaili Hassan (kucingsyg96)",Indonesian,9,10,0,0,0,0,0 "Anastasia Borchuk (al2.borchuk)",Russian,14,14,0,0,0,0,0,"2020-04-14 13:22:49"
"Seweryn Piotrowski (Draxxsx)",Polish,9,10,0,0,19,0,0 iamsurajbobade,Hindi,14,30,0,0,0,0,0,"2018-05-21 11:23:27"
Rex123,Persian,8,8,0,0,0,0,0 "Sanji Vinsmock (mukanzhanbolat4)",Russian,14,14,0,0,0,0,0,"2020-02-18 12:38:54"
"Konstantin (KZhidovinov)",Russian,7,7,0,0,0,0,0 "Maro Chr (caprisunglasses)",Greek,14,17,0,0,0,0,0,"2021-08-17 06:53:33"
pkorove,Greek,7,7,0,0,0,0,0 "Nenad Vukotic (vukotic.nenad)","Serbian (Cyrillic)",13,13,0,1,2,6,0,"2019-01-31 14:29:15"
ftfoi,Norwegian,7,6,0,0,0,0,0 "Uwe Mönks (schirinowski)",German,13,12,0,0,0,0,0,"2021-02-18 04:00:41"
"Андрій Козицький (andriikozytskyi3807)",Ukrainian,7,12,0,2,0,0,0 "Dave (xdave)",Hungarian,13,11,0,0,0,0,0,"2020-03-02 20:56:50"
"Vladimir Pavlychev (KeyJoo)",Russian,7,9,0,0,0,0,0 soura2,Arabic,12,13,0,0,0,0,0,"2020-01-13 19:23:47"
"Andrey ZaXeLoN (waragaa)",Russian,7,7,0,8,1,0,0 "shreyas (techiespace)",Hindi,12,20,0,0,0,0,0,"2018-06-10 01:14:26"
erfan2927,Persian,6,6,0,0,0,0,0 "Sonu Sharma (riteetude)",Hindi,11,23,0,0,0,0,0,"2021-05-30 19:38:00"
dragnus,Arabic,6,6,0,1,1,0,0 Vmrc,French,11,12,0,2,0,0,0,"2020-11-02 05:35:06"
"Sam (SorodonSorodon)",German,6,6,0,13,0,0,0 "Jo Chuang (josephch405)","Chinese Traditional",11,24,0,0,0,0,11,"2017-06-16 20:21:06"
ChloeLiang,Japanese,6,22,0,0,1,0,3 "sathvic k (sathvictripleseven)",Telugu,10,17,0,0,0,0,0,"2020-09-11 08:11:32"
"Burak Ceylan (7burakceylan)",Turkish,6,6,0,0,0,0,0 "Brian Camacho (bmcamacho)",Polish,10,11,0,0,1,0,0,"2020-08-03 02:27:28"
"닉닉 (seohu9466)",Korean,6,14,0,13,0,0,0 "Anonymous edgy nerd (yamentaad)",Arabic,10,13,0,1,0,0,0,"2018-05-06 09:23:57"
"Matthias Joly (joly.matt12)",French,5,8,0,27,1,0,0 "Edwin van Rooij (edwinvrooij)",Dutch,10,13,0,17,0,0,0,"2018-11-05 03:59:10"
"Guerra Ivaneth (rossanaiva-04)",Spanish,5,7,0,0,0,0,0 "Mihael Wagner (miha.wagner)",Slovenian,10,9,0,7,0,0,0,"2017-10-18 18:26:29"
"Manuel Tassi (Mannivu)",Italian,5,6,0,0,0,0,0 "Ahmed Mosaad (ahmed.mosaad2018)",Arabic,10,12,0,6,0,0,0,"2021-02-03 18:45:43"
"Micaela Pighin (micaelapiighin)",Spanish,5,6,0,1,0,0,0 "Suhaili Hassan (kucingsyg96)",Indonesian,9,10,0,0,0,0,0,"2018-06-10 11:55:09"
"Дмитрий Хапенков (d.khapenkov)",Russian,5,5,0,6,4,0,2 "Martin Vostatek (martinvostatek)",Czech,9,8,0,32,2,0,0,"2019-01-21 13:52:36"
andriikozytskyi2018,Ukrainian,5,5,0,0,0,0,0 "Seweryn Piotrowski (Draxxsx)",Polish,9,10,0,0,19,0,0,"2020-01-02 09:55:48"
"Neko123 (emandic11)","Serbian (Cyrillic)",4,4,0,57,0,0,0 "Sourire Lucide (sourire_lucide)",Russian,9,10,0,0,1,0,0,"2018-03-22 01:37:55"
marmo,German,4,4,0,0,0,0,0 Rex123,Persian,8,8,0,0,0,0,0,"2017-07-01 00:47:42"
"Eli Besirov (elibesirov07)",Turkish,4,4,0,0,0,0,0 "Andrey ZaXeLoN (waragaa)",Russian,7,7,0,8,1,0,0,"2017-09-18 21:37:42"
"Lopo Isaac Fernández (rocapata)",Spanish,4,3,0,0,0,0,0 "Konstantin (KZhidovinov)",Russian,7,7,0,0,0,0,0,"2020-01-29 13:35:12"
bziuum,Polish,4,4,0,0,0,0,0 "Андрій Козицький (andriikozytskyi3807)",Ukrainian,7,12,0,2,0,0,0,"2020-09-26 20:31:56"
"Thoum Ptrgnt (thomas.petrignet)",French,3,3,0,2,0,3,0 ftfoi,Norwegian,7,6,0,0,0,0,0,"2020-04-11 20:42:35"
"Vagner Roberto (vagner.trompete)","Portuguese, Brazilian",3,3,0,0,0,0,0 "Vladimir Pavlychev (KeyJoo)",Russian,7,9,0,0,0,0,0,"2017-12-18 02:46:56"
"Unnie Here (Carb)",Hindi,3,8,0,0,0,0,0 pkorove,Greek,7,7,0,0,0,0,0,"2020-03-07 11:36:12"
carsten_kafke,German,3,3,0,43,0,0,3 erfan2927,Persian,6,6,0,0,0,0,0,"2018-04-09 02:12:44"
Magidxz,Arabic,3,3,0,0,0,0,0 "Burak Ceylan (7burakceylan)",Turkish,6,6,0,0,0,0,0,"2018-05-20 17:24:19"
atomjani,Hungarian,3,3,0,0,0,0,0 "Sam (SorodonSorodon)",German,6,6,0,13,0,0,0,"2017-04-14 11:09:27"
"Péter Bernát (bernatp)",Hungarian,3,2,0,0,0,0,0 "닉닉 (seohu9466)",Korean,6,14,0,13,0,0,0,"2017-10-09 23:08:15"
"Igor Piskun (i_piskun)",Ukrainian,3,3,0,0,0,0,0 "Sarita Cajas (sarayanacajas)",Spanish,6,4,0,0,1,0,0,"2021-05-14 14:27:59"
"joabe gabriel (joabegabrielcma1)","Portuguese, Brazilian",3,4,0,0,0,0,0 ChloeLiang,Japanese,6,22,0,0,1,0,3,"2017-08-08 05:02:59"
"Oleg Kogut (kogut_oleg)",Ukrainian,3,3,0,0,0,0,0 "Manuel Tassi (Mannivu)",Italian,5,6,0,0,0,0,0,"2021-01-03 11:00:33"
"Andrea Bianchi (andreawhite1597)",Italian,3,1,0,1,0,0,0 "Tomáš Hrabáček (Hrabyyy)",Czech,5,3,0,0,0,0,0,"2021-05-27 11:58:11"
"Gabriel Cavalcante (gabrielc.alves14)","Portuguese, Brazilian",3,4,0,0,0,0,0 "Guerra Ivaneth (rossanaiva-04)",Spanish,5,7,0,0,0,0,0,"2019-02-03 16:48:59"
REMOVED_USER,"Portuguese, Brazilian",3,4,0,0,0,0,0 "Дмитрий Хапенков (d.khapenkov)",Russian,5,5,0,6,4,0,2,"2018-01-06 23:00:43"
"Martin Zimdahl (zimdahlmartin)",Swedish,3,2,0,0,1,0,3 "Matthias Joly (joly.matt12)",French,5,8,0,27,1,0,0,"2017-08-28 09:53:59"
"Hiohana Rilary (hiohanarilary)","Portuguese, Brazilian",3,4,0,0,0,0,0 "Micaela Pighin (micaelapiighin)",Spanish,5,6,0,1,0,0,0,"2019-10-09 23:32:42"
"Sarath S (CyberShark)",Tamil,3,7,0,0,0,0,0 andriikozytskyi2018,Ukrainian,5,5,0,0,0,0,0,"2017-09-03 05:24:43"
"Cláudio Bernardo (claudiobernardo.ti)","Portuguese, Brazilian",3,4,0,1,0,0,0 marmo,German,4,4,0,0,0,0,0,"2021-01-13 01:16:35"
"hesamiranii (esam.matouri)",Persian,2,2,0,0,0,0,0 "Eli Besirov (elibesirov07)",Turkish,4,4,0,0,0,0,0,"2019-03-25 07:12:34"
"조화정 (yunjoo337)",Korean,2,2,0,0,0,0,0 "Lopo Isaac Fernández (rocapata)",Spanish,4,3,0,0,0,0,0,"2018-09-20 11:46:22"
"Walid Baazia (walidbaazia2005)",Arabic,2,1,0,0,0,0,0 bziuum,Polish,4,4,0,0,0,0,0,"2020-09-01 09:08:01"
LNDDYL,"Chinese Traditional",2,4,0,0,0,0,2 "Neko123 (emandic11)","Serbian (Cyrillic)",4,4,0,57,0,0,0,"2021-04-21 15:33:29"
REMOVED_USER,Ukrainian,2,2,0,0,0,0,0 Magidxz,Arabic,3,3,0,0,0,0,0,"2021-01-05 05:02:54"
"fatemeh s (fargolseifoori3)",Persian,2,2,0,0,0,0,0 "mohammadali barati (mabaraty)",Persian,3,3,0,0,0,0,0,"2021-07-10 05:54:44"
"أم محمد تقي (souadboudia19)",Arabic,2,2,0,0,0,0,0 "Sarath S (CyberShark)",Tamil,3,7,0,0,0,0,0,"2020-08-27 22:43:16"
"Alex Stein (diefaust1993)",Russian,2,2,0,4,4,0,2 "Unnie Here (Carb)",Hindi,3,8,0,0,0,0,0,"2020-03-18 23:34:35"
"Danial Agh (danialagh)",Persian,2,3,0,0,0,0,0 REMOVED_USER,"Portuguese, Brazilian",3,4,0,0,0,0,0,"2018-11-18 09:02:37"
omerfarukbas,Turkish,2,3,0,19,2,0,0 "Thoum Ptrgnt (thomas.petrignet)",French,3,3,0,2,0,3,0,"2017-09-23 19:25:52"
"Valerij D (vala.dobler)",German,2,2,0,0,0,0,0 "Oleg Kogut (kogut_oleg)",Ukrainian,3,3,0,0,0,0,0,"2018-12-28 14:31:02"
"Naveen jai krishna (njsbpolymer1)",Tamil,2,5,0,0,0,0,0 carsten_kafke,German,3,3,0,43,0,0,3,"2017-10-27 13:27:47"
"Balthazar Aubard (Balatzar)",French,2,5,0,0,1,0,0 "Vagner Roberto (vagner.trompete)","Portuguese, Brazilian",3,3,0,0,0,0,0,"2017-12-30 17:54:26"
"FAy FAy (fayfayfay52)","Chinese Traditional",2,5,0,0,0,0,0 "Igor Piskun (i_piskun)",Ukrainian,3,3,0,0,0,0,0,"2018-01-19 15:20:27"
Soroor_SI,Persian,2,2,0,0,0,0,0 "Andrea Bianchi (andreawhite1597)",Italian,3,1,0,1,0,0,0,"2018-01-21 17:45:48"
chavs1997,Russian,2,2,0,9,0,0,0 "Cláudio Bernardo (claudiobernardo.ti)","Portuguese, Brazilian",3,4,0,1,0,0,0,"2019-01-08 14:41:10"
amei,"Portuguese, Brazilian",2,2,0,0,0,0,0 "Hiohana Rilary (hiohanarilary)","Portuguese, Brazilian",3,4,0,0,0,0,0,"2019-07-31 20:42:20"
"Ilyas Fekhar (il47yas)",Arabic,2,2,0,0,0,0,0 "joabe gabriel (joabegabrielcma1)","Portuguese, Brazilian",3,4,0,0,0,0,0,"2018-08-21 09:08:59"
"Ali Zaida (alizaeda92)",Arabic,2,2,0,0,0,0,0 "Péter Bernát (bernatp)",Hungarian,3,2,0,0,0,0,0,"2019-11-30 15:50:33"
gnu-ewm,Polish,1,1,0,6,0,0,0 "Martin Zimdahl (zimdahlmartin)",Swedish,3,2,0,0,1,0,3,"2018-09-15 04:39:22"
"Luca Gori (grolcu)",Italian,1,2,0,0,0,0,0 "Gabriel Cavalcante (gabrielc.alves14)","Portuguese, Brazilian",3,4,0,0,0,0,0,"2018-08-06 22:24:54"
"Alan Jeon (skyisle)",Korean,1,2,0,8,0,0,0 atomjani,Hungarian,3,3,0,0,0,0,0,"2019-01-19 00:49:25"
iSoron2,"Portuguese, Brazilian",1,1,0,0,0,0,0 "أم محمد تقي (souadboudia19)",Arabic,2,2,0,0,0,0,0,"2020-06-13 15:24:17"
"Anastasiia Bondarenko (nastasya.bondarenko.97)",Russian,1,1,0,0,0,0,0 "FAy FAy (fayfayfay52)","Chinese Traditional",2,5,0,0,0,0,0,"2017-10-06 08:53:21"
"Patrick Pimenta (trickap1)","Portuguese, Brazilian",1,1,0,0,0,0,0 chavs1997,Russian,2,2,0,9,0,0,0,"2018-05-18 16:58:19"
axd,Spanish,1,1,0,15,0,0,0 Soroor_SI,Persian,2,2,0,0,0,0,0,"2018-06-10 06:28:27"
jonesses,German,1,1,0,1,0,0,1 "Ilyas Fekhar (il47yas)",Arabic,2,2,0,0,0,0,0,"2018-04-17 22:00:41"
"박찌 (perpact20)",Korean,1,1,0,0,0,0,0 "hesamiranii (esam.matouri)",Persian,2,2,0,0,0,0,0,"2018-09-22 16:33:36"
"Kan Black (kanblack.va)",Vietnamese,1,2,0,0,0,1,0 "fatemeh s (fargolseifoori3)",Persian,2,2,0,0,0,0,0,"2019-01-31 12:06:57"
REMOVED_USER,Russian,1,2,0,6,1,0,1 amei,"Portuguese, Brazilian",2,2,0,0,0,0,0,"2018-04-19 19:42:28"
"Wibi Cahyo (wbcahyoh)",Indonesian,1,3,0,0,0,0,0 "Naveen jai krishna (njsbpolymer1)",Tamil,2,5,0,0,0,0,0,"2020-01-10 14:19:41"
"Anton (tT0NG)","Chinese Traditional",1,2,0,0,0,0,1 "Danial Agh (danialagh)",Persian,2,3,0,0,0,0,0,"2019-03-30 13:24:16"
"Maria Fefelova (mashafefel)",Russian,1,1,0,0,0,0,0 "Walid Baazia (walidbaazia2005)",Arabic,2,1,0,0,0,0,0,"2021-01-27 12:47:34"
Itch,,0,0,0,0,0,0,0 "Ali Zaida (alizaeda92)",Arabic,2,2,0,0,0,0,0,"2019-12-01 11:47:00"
"Muhammet Furkan ALMACI (furkan.almaci)",Turkish,0,0,0,1,0,0,0 LNDDYL,"Chinese Traditional",2,4,0,0,0,0,2,"2018-04-22 04:00:19"
Sandhu564.,,0,0,0,0,0,0,0 "Ño Bí Tã (pt614553)",Arabic,2,8,0,1,0,0,0,"2021-05-22 20:41:01"
"Quentin Hibon (hiq)",,0,0,0,0,0,0,0 "Judith Ayala (Azul1612)",Spanish,2,1,0,0,0,1,0,"2021-05-18 17:07:19"
mushin,,0,0,0,0,0,0,0 REMOVED_USER,Ukrainian,2,2,0,0,0,0,0,"2017-06-15 12:24:44"
"Balaji Jayaraman (jkbalaji1103)",,0,0,0,0,0,0,0 "Valerij D (vala.dobler)",German,2,2,0,0,0,0,0,"2018-09-22 09:38:27"
"Wellington Ribeiro (wellington.rib)",,0,0,0,0,0,0,0 "Alex Stein (diefaust1993)",Russian,2,2,0,4,4,0,2,"2017-07-13 06:56:17"
"Javid IRAN (twitteriran98)",Persian,0,0,0,1,0,0,0 "조화정 (yunjoo337)",Korean,2,2,0,0,0,0,0,"2019-06-16 22:25:31"
"박인호 (wphestiraid)",Korean,0,0,0,2,0,0,0 omerfarukbas,Turkish,2,3,0,19,2,0,0,"2017-08-14 16:10:35"
"Ahmed Nazir (ahmednazir333)",,0,0,0,0,0,0,0 "Balthazar Aubard (Balatzar)",French,2,5,0,0,1,0,0,"2017-09-23 01:42:57"
dimateos,,0,0,0,0,0,0,0 "Luca Gori (grolcu)",Italian,1,2,0,0,0,0,0,"2020-09-26 23:26:15"
AhmedDz,Arabic,0,0,0,1,0,0,0 axd,Spanish,1,1,0,15,0,0,0,"2017-09-12 05:48:51"
"reza golestanzadeh (reza.golestanzadeh)",Persian,0,0,0,1,0,0,0 iSoron2,"Portuguese, Brazilian",1,1,0,0,0,0,0,"2017-03-18 17:56:29"
"Petros Bleyan (coolbleyan)",Russian,0,0,0,14,0,0,0 REMOVED_USER,Russian,1,2,0,6,1,0,1,"2019-12-26 05:37:01"
Kamalakannan,,0,0,0,0,0,0,0 "Wibi Cahyo (wbcahyoh)",Indonesian,1,3,0,0,0,0,0,"2017-12-14 06:35:58"
"Dagna Q (dagnaq)",,0,0,0,0,0,0,0 jonesses,German,1,1,0,1,0,0,1,"2021-01-01 08:03:18"
"Thomas Orlita (Thomas995)",Czech,0,0,0,1,0,0,0 "Anton (tT0NG)","Chinese Traditional",1,2,0,0,0,0,1,"2017-07-06 14:18:39"
Fazy1380,,0,0,0,0,0,0,0 "박찌 (perpact20)",Korean,1,1,0,0,0,0,0,"2018-02-10 10:11:44"
"Rivo Zängov (Eraser)",,0,0,0,0,0,0,0 "Alan Jeon (skyisle)",Korean,1,2,0,8,0,0,0,"2018-01-09 10:46:00"
T-v-Gerwen,Dutch,0,0,0,47,0,0,0 "Maria Fefelova (mashafefel)",Russian,1,1,0,0,0,0,0,"2019-05-18 02:03:56"
"عبد الناصر سعيد الثبيتي (asaeed)",,0,0,0,0,0,0,0 "Anastasiia Bondarenko (nastasya.bondarenko.97)",Russian,1,1,0,0,0,0,0,"2019-06-07 17:43:08"
"Edmunds Edmundam (edmundam)",,0,0,0,0,0,0,0 "Kan Black (kanblack.va)",Vietnamese,1,2,0,0,0,1,0,"2019-01-15 03:50:10"
"vi ve (VimalV)",,0,0,0,0,0,0,0 "Patrick Pimenta (trickap1)","Portuguese, Brazilian",1,1,0,0,0,0,0,"2018-12-01 14:31:21"
"LeMeD (LeMeS)",French,0,0,0,2,0,0,0 "Dagna Q (dagnaq)",,0,0,0,0,0,0,0,"2017-08-06 01:42:52"
"Éjbãss Übbeî (littlebittlebottle)",Norwegian,0,0,0,152,0,0,0 Kamalakannan,,0,0,0,0,0,0,0,"2017-05-14 11:40:23"
EmanAmini,,0,0,0,0,0,0,0 "Éjbãss Übbeî (littlebittlebottle)",Norwegian,0,0,0,152,0,0,0,"2017-07-05 21:12:02"
AnggaRifandi,,0,0,0,0,0,0,0 "Равиль Мифтахов (ravilmif47)",Russian,0,0,0,1,0,0,0,"2019-08-12 21:58:30"
"Mateusz Teteruk (mttet)",Polish,0,0,0,1,0,0,0 sanyoniket,,0,0,0,0,0,0,0,"2019-07-23 12:58:40"
"Lori Amico (lavodkaclyde2323)",Italian,0,0,0,1,0,0,0 REMOVED_USER,,0,0,0,0,0,0,0,"2020-02-01 03:47:48"
"Florian Stuhlmann (stuhlmann)",German,0,0,0,10,0,0,0 "vi ve (VimalV)",,0,0,0,0,0,0,0,"2021-02-08 02:35:45"
"Yasin Okumus (lacivert)",Turkish,0,0,0,1,0,0,0 "George Merkulov (george142.emarket)",Russian,0,0,0,11,0,0,0,"2019-06-09 19:47:02"
NairaDNV,Spanish,0,0,0,9,0,0,0 "Yasin Okumus (lacivert)",Turkish,0,0,0,1,0,0,0,"2018-02-07 04:13:51"
REMOVED_USER,,0,0,0,0,0,0,0 "Petros Bleyan (coolbleyan)",Russian,0,0,0,14,0,0,0,"2017-08-18 18:37:18"
farbod66,Persian,0,0,0,1,0,0,0 "LeMeD (LeMeS)",French,0,0,0,2,0,0,0,"2021-02-06 15:35:00"
Raulbertassi,,0,0,0,0,0,0,0 ava_rfie,Persian,0,0,0,1,0,0,0,"2019-06-09 16:19:24"
"Равиль Мифтахов (ravilmif47)",Russian,0,0,0,1,0,0,0 "Mateusz Teteruk (mttet)",Polish,0,0,0,1,0,0,0,"2021-01-23 13:09:59"
"Pumpith Ungsupanit (pumpithu)",,0,0,0,0,0,0,0 EwanB,,0,0,0,0,0,0,0,"2019-11-19 10:04:38"
"Nat Fomicheva (natac)",Russian,0,0,0,3,0,0,0 Fazy1380,,0,0,0,0,0,0,0,"2021-04-10 11:02:53"
EwanB,,0,0,0,0,0,0,0 "Lori Amico (lavodkaclyde2323)",Italian,0,0,0,1,0,0,0,"2017-04-09 10:08:13"
ava_rfie,Persian,0,0,0,1,0,0,0 "Florian Stuhlmann (stuhlmann)",German,0,0,0,10,0,0,0,"2017-04-15 04:04:00"
"George Merkulov (george142.emarket)",Russian,0,0,0,11,0,0,0 "عبد الناصر سعيد الثبيتي (asaeed)",,0,0,0,0,0,0,0,"2018-03-13 02:09:35"
REMOVED_USER,,0,0,0,0,0,0,0 "Rivo Zängov (Eraser)",,0,0,0,0,0,0,0,"2020-10-13 04:38:26"
sanyoniket,,0,0,0,0,0,0,0 Hayder21,,0,0,0,0,0,0,0,"2019-12-31 10:56:24"
"Shuvashish Sahoo (shuvashish76)",,0,0,0,0,0,0,0 T-v-Gerwen,Dutch,0,0,0,47,0,0,0,"2018-03-02 10:26:33"
martyaberger,,0,0,0,0,0,0,0 "Eduard Boboc (edi.boboc33)",Romanian,0,0,0,4,0,0,0,"2019-12-16 09:08:39"
"Карлен Шаухаев (KarlenShaukhaev)",,0,0,0,0,0,0,0 "Samuel Przeździęk (samek22)",Polish,0,0,0,1,0,0,0,"2021-08-01 00:49:01"
"Elmo (oberknecht)",,0,0,0,0,0,0,0 "Saiprasath B (Saiprasath)",,0,0,0,0,0,0,0,"2021-07-11 11:10:41"
Irsgram,Russian,0,0,0,1,0,0,0 shuvo786,,0,0,0,0,0,0,0,"2019-11-13 00:18:12"
"Matus Zdansky (matuszdansky)",,0,0,0,0,0,0,0 "Edmunds Edmundam (edmundam)",,0,0,0,0,0,0,0,"2020-06-01 14:18:18"
shuvo786,,0,0,0,0,0,0,0 Itch,,0,0,0,0,0,0,0,"2017-10-16 09:18:42"
"Eduard Boboc (edi.boboc33)",Romanian,0,0,0,4,0,0,0 "Manny Farsangy (manifarsangi)",Persian,0,0,0,12,0,0,0,"2021-08-10 05:32:28"
Hayder21,,0,0,0,0,0,0,0 "Matus Zdansky (matuszdansky)",,0,0,0,0,0,0,0,"2019-10-20 13:52:24"
AsadullahIlyas,,0,0,0,0,0,0,0 "Thomas Orlita (Thomas995)",Czech,0,0,0,1,0,0,0,"2017-12-24 04:08:27"
"Никита Карамов (nikita.karamoff)",Russian,0,0,0,10,0,0,0 Irsgram,Russian,0,0,0,1,0,0,0,"2019-09-30 16:42:20"
"Katherine Alexandra Flórez Ramírez (katherine.florez12)",Spanish,0,0,0,46,0,0,0 EmanAmini,,0,0,0,0,0,0,0,"2017-03-31 13:27:43"
mdrobulis,,0,0,0,0,0,0,0 mushin,,0,0,0,0,0,0,0,"2020-02-02 04:08:05"
"Eliška Roubalová (roubaeli)",Czech,0,0,0,6,0,0,0 "Elmo (oberknecht)",,0,0,0,0,0,0,0,"2020-04-16 08:45:50"
droidahmed,Arabic,0,0,0,7,0,0,0 AnggaRifandi,,0,0,0,0,0,0,0,"2017-03-31 19:28:35"
"Arjun K. (arjunkdot)",,0,0,0,0,0,0,0 "darkkingredian (rediancool)",,0,0,0,0,0,0,0,"2021-07-27 16:04:32"
"Sarah BCNN (fsarahboucenna)",French,0,0,0,16,0,0,0 "Sri Harsha Bhogi (sriharshabhogi)",,0,0,0,0,0,0,0,"2018-09-02 05:31:53"
REMOVED_USER,Czech,0,0,0,18,0,0,0 "Nat Fomicheva (natac)",Russian,0,0,0,3,0,0,0,"2019-01-25 14:35:02"
BongTran,Vietnamese,0,0,0,2,0,0,0 mdrobulis,,0,0,0,0,0,0,0,"2018-05-24 01:40:42"
"Arttu Ylhävuori (arttu.ylhavuori)",,0,0,0,0,0,0,0 "Sarah BCNN (fsarahboucenna)",French,0,0,0,16,0,0,0,"2018-02-11 11:07:36"
valney.faria,"Portuguese, Brazilian",0,0,0,1,0,0,0 "Arjun K. (arjunkdot)",,0,0,0,0,0,0,0,"2020-09-20 11:16:18"
REMOVED_USER,,0,0,0,0,0,0,0 REMOVED_USER,Czech,0,0,0,18,0,0,0,"2018-03-27 06:19:52"
rooban23,,0,0,0,0,0,0,0 martyaberger,,0,0,0,0,0,0,0,"2019-01-01 18:48:08"
REMOVED_USER,,0,0,0,0,0,0,0 BongTran,Vietnamese,0,0,0,2,0,0,0,"2018-04-24 05:16:07"
"Алтынбек Наурызғали (altinbeknaurizgali)",Russian,0,0,0,1,0,0,0 "Arttu Ylhävuori (arttu.ylhavuori)",,0,0,0,0,0,0,0,"2019-07-24 15:03:42"
"Sri Harsha Bhogi (sriharshabhogi)",,0,0,0,0,0,0,0 "Никита Карамов (nikita.karamoff)",Russian,0,0,0,10,0,0,0,"2018-10-29 03:57:21"
"Ahnaf Tajwar (atn4404)",,0,0,0,0,0,0,0 rooban23,,0,0,0,0,0,0,0,"2020-09-15 11:49:14"
Elham1361,,0,0,0,0,0,0,0 "Eliška Roubalová (roubaeli)",Czech,0,0,0,6,0,0,0,"2019-12-31 12:47:29"
dongchen.yue,German,0,0,0,4,0,0,0 valney.faria,"Portuguese, Brazilian",0,0,0,1,0,0,0,"2020-02-02 14:45:02"
philfr49,French,0,0,0,2,0,0,0 "Алтынбек Наурызғали (altinbeknaurizgali)",Russian,0,0,0,1,0,0,0,"2020-08-12 13:03:49"
REMOVED_USER,,0,0,0,0,0,0,0,"2018-10-27 15:34:36"
REMOVED_USER,,0,0,0,0,0,0,0,"2018-08-24 00:17:43"
Elham1361,,0,0,0,0,0,0,0,"2018-10-27 12:01:06"
dongchen.yue,German,0,0,0,4,0,0,0,"2020-09-12 15:05:59"
"Ahnaf Tajwar (atn4404)",,0,0,0,0,0,0,0,"2018-10-16 11:13:30"
AsadullahIlyas,,0,0,0,0,0,0,0,"2019-01-04 06:14:15"
droidahmed,Arabic,0,0,0,7,0,0,0,"2018-01-31 02:18:49"
philfr49,French,0,0,0,2,0,0,0,"2018-09-03 14:20:32"
"Ahmed Nazir (ahmednazir333)",,0,0,0,0,0,0,0,"2018-05-06 12:10:27"
"Balaji Jayaraman (jkbalaji1103)",,0,0,0,0,0,0,0,"2017-10-30 22:12:27"
"Wellington Ribeiro (wellington.rib)",,0,0,0,0,0,0,0,"2017-11-16 07:32:25"
"Javid IRAN (twitteriran98)",Persian,0,0,0,1,0,0,0,"2017-11-25 16:47:25"
"박인호 (wphestiraid)",Korean,0,0,0,2,0,0,0,"2018-01-05 00:33:14"
"Pumpith Ungsupanit (pumpithu)",,0,0,0,0,0,0,0,"2019-01-19 23:47:57"
Sandhu564.,,0,0,0,0,0,0,0,"2020-12-14 01:27:45"
"Quentin Hibon (hiq)",,0,0,0,0,0,0,0,"2021-02-07 16:39:31"
AhmedDz,Arabic,0,0,0,1,0,0,0,"2017-12-31 10:12:31"
"Shuvashish Sahoo (shuvashish76)",,0,0,0,0,0,0,0,"2020-09-17 09:10:09"
REMOVED_USER,,0,0,0,0,0,0,0,"2018-01-05 16:56:12"
NairaDNV,Spanish,0,0,0,9,0,0,0,"2018-01-05 19:10:33"
Raulbertassi,,0,0,0,0,0,0,0,"2018-01-07 17:23:18"
"Карлен Шаухаев (KarlenShaukhaev)",,0,0,0,0,0,0,0,"2020-04-27 08:53:49"
dimateos,,0,0,0,0,0,0,0,"2021-01-10 06:29:52"
"Katherine Alexandra Flórez Ramírez (katherine.florez12)",Spanish,0,0,0,46,0,0,0,"2018-01-20 02:18:32"
"reza golestanzadeh (reza.golestanzadeh)",Persian,0,0,0,1,0,0,0,"2020-10-21 12:07:20"
farbod66,Persian,0,0,0,1,0,0,0,"2018-01-20 11:04:23"
"Muhammet Furkan ALMACI (furkan.almaci)",Turkish,0,0,0,1,0,0,0,"2017-10-29 13:44:56"
1 Name Languages Translated (Words) Target Words Approved (Words) Voted "+" votes received "-" votes received Winning (Words) Joined
2 Alinson Xavier (iSoron) Portuguese, Brazilian; Japanese; Spanish; Portuguese; Italian; Chinese Simplified; French; Hungarian; German; Arabic; Hindi; Slovenian; Catalan; Greek; Korean; Bulgarian; Chinese Traditional; Polish; Russian; Serbian (Cyrillic); Turkish; Ukrainian; Czech; Indonesian; Croatian; Danish; Dutch; Romanian; Swedish; Basque; Persian; Vietnamese; Telugu; Finnish; Tamil; Afrikaans; Esperanto; Hebrew Portuguese, Brazilian; Japanese; Spanish; Portuguese; Italian; Chinese Simplified; French; Hungarian; German; Arabic; Hindi; Slovenian; Catalan; Greek; Korean; Bulgarian; Chinese Traditional; Polish; Russian; Serbian (Cyrillic); Turkish; Ukrainian; Czech; Indonesian; Croatian; Danish; Dutch; Romanian; Swedish; Basque; Persian; Finnish; Vietnamese; Telugu; Tamil; Afrikaans; Esperanto; Hebrew 14790 14808 17211 17227 1272 1282 0 1707 1779 70 80 4259 4274 2016-03-05 18:35:27
3 Slobodan Simić (Слободан Симић) (slsimic) Serbian (Latin); Serbian (Cyrillic) 2053 2054 1830 1831 2105 2114 12 33 0 1982 1991 2021-02-03 14:26:07
4 Oglaigh Rystard (oglaignaheireann) Ukrainian; Portuguese; Catalan; Greek; Basque; Romanian; Italian 1103 1037 1327 1 13 6 954 2017-03-31 09:13:19
5 David (Cliff122) Swedish 1040 1019 725 6 0 0 700 2020-01-21 13:56:55
6 dukelc Omer I.S. (omeritzics) Slovak Hebrew 919 1000 880 900 0 1097 0 14 0 1 0 0 946 2020-10-11 20:10:51
7 KMakoto dukelc Chinese Traditional Slovak 745 919 1146 880 949 0 0 0 0 745 0 2020-08-27 14:02:41
8 Evren (evrenkiymaz) Intan Ayunda (Intan_Ayunda) Turkish Indonesian 688 800 604 793 0 962 71 0 4 0 0 0 711 2020-10-14 07:51:58
9 David Nos (david.nos) KMakoto Catalan; Spanish Chinese Traditional 667 745 731 1146 0 949 0 0 0 0 745 2019-10-22 04:19:52
10 androide74 Evren (evrenkiymaz) Italian Turkish 644 688 659 604 0 2 71 0 5 0 1 0 2020-10-04 03:39:16
11 Tomairuka David Nos (david.nos) Japanese Catalan; Spanish 633 667 1636 731 909 0 43 0 0 1 0 564 0 2020-01-04 10:15:36
12 Dmitriy Bogdanov (di72nn) Antti Kallio (antti.kallio) Russian Finnish 625 650 572 525 1175 0 0 34 0 0 519 0 2021-07-03 05:54:44
13 reyhoon androide74 Persian Italian 624 644 759 659 0 1 2 1 0 0 0 2020-02-06 15:46:28
14 Osoitz Tomairuka Basque Japanese 610 633 545 1636 0 909 9 43 0 0 3 564 2020-12-12 12:14:22
15 fabian.bouchal Dmitriy Bogdanov (di72nn) German Russian 548 625 527 572 0 1197 6 0 0 36 3 0 72 515 2017-03-31 10:00:48
16 boban77 reyhoon Czech Persian 509 624 461 759 0 2 1 0 3 0 1 0 2020-10-01 18:17:23
17 Yoav Argov (YoavArgov) Osoitz Hebrew Basque 501 610 461 545 0 0 9 1 0 8 0 3 2018-01-23 14:07:47
18 REMOVED_USER Saeed Esmaili (saaeed.es20) Norwegian Persian 501 568 498 774 501 0 0 5 148 4 0 501 0 2020-11-26 15:41:15
19 Martim Parente (Sharlimar) fabian.bouchal Portuguese German 497 548 534 527 0 38 6 0 0 3 0 72 2020-01-07 06:43:37
20 chrrris1987 (Chrrris1987) boban77 Dutch Czech 467 509 478 461 0 23 2 0 0 0 2020-04-30 13:18:24
21 Huy Ngo (huyngo) Yoav Argov (YoavArgov) Vietnamese Hebrew 461 501 695 461 0 1 0 0 1 0 8 0 103 2017-04-28 07:23:01
22 黄克 (hk13127) REMOVED_USER Chinese Simplified Norwegian 461 501 765 498 0 501 1 0 0 148 0 0 501 2017-07-05 19:02:25
23 Arkadiusz Bubak (epitek) Martim Parente (Sharlimar) Polish Portuguese 458 497 416 534 29 0 24 38 0 3 0 0 2020-08-26 10:22:11
24 marco.baturan chrrris1987 (Chrrris1987) Esperanto Dutch 452 467 452 478 0 0 23 0 0 0 2020-02-03 05:26:04
25 Sief Tarek (sieftarek135) Huy Ngo (huyngo) Arabic Vietnamese 447 461 455 695 0 0 1 0 0 0 2020-01-26 11:58:36
26 Omer I.S. (omeritzics) 黄克 (hk13127) Hebrew Chinese Simplified 428 461 366 765 0 14 1 1 0 0 0 24 2020-01-17 23:16:03
27 Samuel Guay (SamGuay) Arkadiusz Bubak (epitek) French Polish 426 458 486 416 0 29 6 24 0 0 3 0 2020-11-05 05:11:58
28 Diana Karaseva (Sun_Dianka) marco.baturan Russian Esperanto 399 452 373 452 0 10 0 1 0 0 221 0 2020-06-23 02:49:46
29 Alexander Jansson (dalecarlian) Sief Tarek (sieftarek135) Swedish Arabic 396 447 406 455 507 0 0 0 3 0 399 0 2021-02-07 14:35:21
30 luiandresgonzalez Samuel Guay (SamGuay) Spanish French 383 426 403 486 0 1 6 0 0 0 2020-06-25 07:14:38
31 Thamara Andrade (tkcandrade) Diana Karaseva (Sun_Dianka) Portuguese, Brazilian Russian 380 399 387 373 0 0 10 1 0 252 209 2020-01-30 06:40:02
32 Sølv Ræven (soelvraeven) Alexander Jansson (dalecarlian) Danish Swedish 370 396 370 406 0 507 0 0 0 3 0 399 2017-06-21 01:37:32
33 Isti (eisti) luiandresgonzalez Hungarian Spanish 367 383 329 403 0 0 1 0 28 0 0 2020-07-11 14:20:44
34 Anh Quân (dangquanuet) Thamara Andrade (tkcandrade) Vietnamese Portuguese, Brazilian 362 380 530 387 0 42 0 1 0 0 252 2020-01-09 19:35:48
35 gapszi Sølv Ræven (soelvraeven) Hungarian Danish 348 370 301 370 0 86 0 0 0 0 2020-11-28 16:46:18
36 Mahdi Nasiri (mahdi.nasiri) Isti (eisti) Persian Hungarian 343 367 465 329 0 39 0 3 0 0 0 2020-12-03 12:02:51
37 Seoyul Anh Quân (dangquanuet) Korean Vietnamese 339 362 825 530 0 0 42 27 2 0 0 2017-10-29 12:27:44
38 Magimai Prakasam (magimai) gapszi Tamil Hungarian 336 348 831 301 0 12 86 0 0 0 2019-04-08 01:35:54
39 Michael Malak (MichaelKMalak) JY3 Arabic Chinese Simplified 304 345 271 585 0 278 0 0 1 0 0 207 2021-03-08 08:53:35
40 Elina Salminen (salminen.elina.m) Mahdi Nasiri (mahdi.nasiri) Finnish Persian 297 343 227 465 0 0 39 0 3 0 1 0 2017-07-14 09:17:25
41 ayane.m Seoyul Japanese Korean 292 339 863 825 0 1 0 2 27 0 22 0 2017-06-21 08:11:39
42 Marius Teufelweich (teufelweich) Magimai Prakasam (magimai) German Tamil 249 336 256 831 606 0 4 12 0 0 146 0 2018-04-15 21:16:08
43 cobalt59 Michael Malak (MichaelKMalak) German Arabic 237 304 234 271 0 1 0 23 0 1 0 132 0 2020-05-26 19:47:58
44 QWERT (lurenjia01) Elina Salminen (salminen.elina.m) Chinese Simplified Finnish 236 297 407 227 0 0 0 0 0 2021-01-06 01:28:57
45 beriain ayane.m Basque Japanese 234 292 235 863 0 0 1 2 3 0 0 22 2019-11-20 03:28:26
46 Intan Ayunda (Intan_Ayunda) Blinkin Indonesian Dutch 228 284 239 318 336 0 0 1 0 0 135 0 2021-06-14 10:30:05
47 pnhpnh Marius Teufelweich (teufelweich) Vietnamese German 225 249 343 256 0 606 1 4 3 2 0 0 146 2021-03-12 04:11:38
48 Dika Fitrian Dwi Putra (OsamuDazai) cobalt59 Indonesian German 221 237 215 234 0 0 1 0 24 0 1 33 132 2017-06-05 05:18:33
49 easyrepro QWERT (lurenjia01) Telugu Chinese Simplified 214 236 297 407 0 0 0 8 0 0 19 2020-03-08 01:46:25
50 taras-ko beriain Ukrainian Basque 211 234 183 235 0 1 0 4 2 0 19 0 2017-03-31 15:42:28
51 sojusnik pnhpnh German Vietnamese 207 225 200 343 1 0 0 1 30 3 0 66 0 2017-11-27 12:06:07
52 axmed99 Dika Fitrian Dwi Putra (OsamuDazai) Ukrainian Indonesian 203 221 177 215 0 40 0 0 0 53 48 2020-07-13 04:40:27
53 Heru Yen (heruyen) easyrepro Indonesian Telugu 201 214 201 297 0 0 0 0 2 0 2020-06-12 12:52:10
54 Ishmaeel taras-ko Turkish Ukrainian 193 211 174 183 0 129 1 6 4 0 0 19 2017-10-26 16:52:22
55 fbruna17 sojusnik Danish German 181 207 179 200 0 1 1 0 0 30 0 0 66 2017-04-03 17:11:56
56 Omry Cohen (omrycohen) axmed99 Hebrew Ukrainian 175 203 156 177 0 1 40 0 0 0 53 2021-04-01 03:56:20
57 Bryanx Heru Yen (heruyen) Dutch Indonesian 174 201 165 201 0 5 0 0 0 0 25 2020-06-29 18:39:15
58 Pierre GALIEGUE (pierre.galiegue) Vijaykumar Borkar (vjkumar) French Hindi 171 200 194 364 0 24 11 2 0 0 0 2021-08-06 16:12:15
59 DionysosDV Ishmaeel Greek Turkish 165 193 153 174 0 0 129 0 6 0 0 2017-10-04 03:54:00
60 Gustavo Lima (GustavoLima) Aputsiak Niels Janussen (aputtu) Portuguese Danish 158 187 177 200 0 1 0 4 0 10 0 0 2019-08-28 05:47:42
61 Aputsiak Niels Janussen (aputtu) _translator Danish French 153 181 171 206 0 0 11 0 0 0 2021-07-06 07:54:12
62 plitwin fbruna17 Polish Danish 145 181 128 179 0 1 16 0 0 26 0 2021-01-28 15:48:47
63 Lương Vĩnh Khang (LuongVinhKhang) Omry Cohen (omrycohen) Vietnamese Hebrew 144 175 256 156 0 0 1 46 0 1 0 0 33 2021-01-18 07:33:23
64 azzamsa Bryanx Indonesian Dutch 142 174 136 165 0 48 5 0 1 0 50 0 2019-11-21 17:08:12
65 Neysa Nasywa (neysanasywa) Pierre GALIEGUE (pierre.galiegue) Indonesian French 140 171 141 194 0 0 24 0 4 0 35 0 2020-08-16 11:41:35
66 JY3 bruhwut Chinese Simplified Vietnamese 136 171 217 268 80 0 0 1 0 0 80 0 2021-05-21 07:16:30
67 Mohammed Imthath (mimthath4) DionysosDV Tamil Greek 136 165 274 153 0 0 11 0 0 0 2021-02-27 19:05:25
68 roptat Gustavo Lima (GustavoLima) French Portuguese 132 158 154 177 0 112 1 88 4 5 10 0 2020-08-26 10:35:05
69 Trần Thái (tranhoangthai2001) oscfd Vietnamese Spanish 127 155 186 166 0 8 1 1 4 0 0 2021-05-21 17:58:22
70 OP Smosher (teenwolffan44) plitwin Serbian (Cyrillic) Polish 124 145 122 128 0 0 1 0 16 0 18 26 2021-01-20 06:18:37
71 4001982248998 Lương Vĩnh Khang (LuongVinhKhang) Esperanto Vietnamese 122 144 119 256 0 0 0 46 0 1 0 2017-08-10 10:05:58
72 StoP4Me (Lcqp) azzamsa Romanian Indonesian 121 142 119 136 0 0 48 3 0 0 1 0 26 2017-06-16 18:29:45
73 Sebastian05067 yoding (yodingc) Spanish Chinese Traditional; Chinese Simplified 114 141 133 271 0 55 10 18 0 0 0 2021-07-07 01:45:45
74 Tanya (MagicUnderHood) Neysa Nasywa (neysanasywa) Russian Indonesian 114 140 98 141 0 19 0 0 0 32 60 2020-11-18 10:32:10
75 REMOVED_USER Mohammed Imthath (mimthath4) Arabic Tamil 111 136 106 274 0 22 0 21 11 2 0 0 2018-02-15 22:41:15
76 mohmans roptat Arabic French 109 132 103 154 0 2 112 0 89 0 5 0 2017-04-19 16:54:47
77 Ivan Krušlin (krux3r) Trần Thái (tranhoangthai2001) Croatian Vietnamese 108 127 122 186 503 0 0 8 0 1 0 108 0 2018-03-01 10:51:39
78 Iabin Arteaga (iabin) OP Smosher (teenwolffan44) Spanish Serbian (Cyrillic) 108 124 111 122 0 4 0 20 0 0 0 18 2020-11-05 09:41:35
79 2kaafone 4001982248998 Finnish Esperanto 105 122 90 119 0 0 0 0 0 2017-10-08 04:13:02
80 Adam Jurkiewicz (hasztagg) StoP4Me (Lcqp) Polish Romanian 104 121 105 119 529 0 0 0 3 0 104 0 2018-05-06 18:51:59
81 Saeed Esmaili (saaeed.es20) alalloush Persian Arabic 104 118 141 129 0 0 2 0 2 0 0 2017-03-31 12:37:17
82 just a name bro (justanamebr0) Eilif Adelvice (adelvice) Danish Spanish 98 116 109 126 0 0 96 1 0 0 0 2021-08-05 07:20:21
83 Nam Nguyen (namnl2706) Sebastian05067 Vietnamese Spanish 95 114 137 133 0 0 55 0 28 0 0 2017-05-14 00:48:16
84 손유정 (yuwon1213) Tanya (MagicUnderHood) Korean Russian 95 114 57 98 0 0 19 0 0 0 54 2019-04-21 10:44:03
85 ranmagen REMOVED_USER Hebrew Arabic 91 111 78 106 0 0 22 0 21 0 2 0 2018-01-05 07:01:45
86 LoneWanderer mohmans Chinese Traditional Arabic 90 109 137 103 0 4 2 0 0 0 2020-11-23 02:48:00
87 Vo - (voyl) Iabin Arteaga (iabin) Chinese Traditional Spanish 89 108 126 111 0 0 4 5 21 0 0 2017-08-26 21:08:54
88 ikkaz Ivan Krušlin (krux3r) Indonesian Croatian 89 108 84 122 0 503 5 0 0 0 4 108 2017-03-31 09:15:24
89 Irene K (Heaun) 2kaafone Korean Finnish 88 105 75 90 0 25 0 0 0 0 2019-08-12 06:58:48
90 Kumar Anand (kumar0500) Adam Jurkiewicz (hasztagg) Hindi Polish 87 104 125 105 0 529 0 0 0 0 104 2017-03-31 09:50:51
91 Prosta4ok_ua just a name bro (justanamebr0) Ukrainian Danish 87 98 84 109 0 1 0 0 1 0 17 0 2019-06-19 11:57:55
92 Ohad Edri (ohadalte) Nam Nguyen (namnl2706) Hebrew Vietnamese 85 95 79 137 0 0 1 0 3 0 0 2020-08-18 23:02:33
93 helectron 손유정 (yuwon1213) Persian Korean 84 95 102 57 0 1 0 0 0 0 2021-03-30 05:25:33
94 Radu Cebotari (wildProgrammer) ranmagen Romanian Hebrew 84 91 92 78 0 1 0 0 0 0 2021-02-16 05:44:31
95 Israa Z (sosozozo) LoneWanderer Arabic Chinese Traditional 79 90 87 137 0 43 4 11 0 0 3 0 2020-09-29 05:24:48
96 Sofia Neves (sofiasonev) Vo - (voyl) Portuguese, Brazilian Chinese Traditional 79 89 84 126 0 1 0 0 5 0 46 0 2020-09-02 23:34:42
97 Tiralka ikkaz French Indonesian 79 89 91 84 0 92 5 1 0 0 0 4 2019-09-02 19:58:54
98 Jacob Roller (jdr28070) Irene K (Heaun) Korean 79 88 61 75 0 0 25 0 0 0 2020-03-16 11:31:12
99 Toni Mustonen (toni.mustonen) Prosta4ok_ua Finnish Ukrainian 78 87 72 84 0 0 1 0 0 0 17 2020-01-23 19:43:41
100 Michael (quelbs) Kumar Anand (kumar0500) German Hindi 76 87 75 125 0 1 0 0 0 39 0 2020-11-07 02:46:09
101 Fauz Aladeem (topfauz) Ohad Edri (ohadalte) Arabic Hebrew 76 85 77 79 0 0 0 1 1 3 0 18 2020-07-04 03:42:09
102 RealDonald helectron Dutch Persian 67 84 69 102 0 121 1 10 0 0 0 2021-03-02 04:10:51
103 sirekanyan Radu Cebotari (wildProgrammer) Armenian; Russian Romanian 66 84 65 92 0 0 1 0 0 0 2020-02-05 01:20:00
104 Константин К. (kocyak1991) Sofia Neves (sofiasonev) Russian Portuguese, Brazilian 64 79 60 84 0 0 1 1 0 2 0 0 46 2020-03-12 18:19:46
105 Laura Sophie (laurasophie20) Jacob Roller (jdr28070) German Korean 62 79 67 61 0 4 0 0 0 0 2020-01-03 11:36:40
106 raden20 Tiralka Indonesian French 61 79 62 91 177 0 0 92 1 0 64 0 2018-02-09 18:39:01
107 Jan Wojtecki (j4nw) Israa Z (sosozozo) Polish Arabic 58 79 46 87 0 0 43 0 12 0 26 3 2017-11-27 14:10:50
108 Deepak Bharathi (deepakbharathi1994) Toni Mustonen (toni.mustonen) Tamil Finnish 56 78 107 72 0 0 11 0 4 0 0 2017-09-02 05:34:12
109 Андрій Козицький (andriikozytskyi1108) Fauz Aladeem (topfauz) Ukrainian Arabic 52 76 52 77 0 0 1 0 0 1 0 2020-02-21 22:46:12
110 REMOVED_USER Michael (quelbs) Italian German 51 76 52 75 0 2 1 0 0 0 39 2020-08-18 07:39:26
111 govindap Oliver Gronowski (OliverGronowski) Japanese; Hindi German 51 70 114 69 0 6 5 1 0 0 0 2021-05-14 16:37:10
112 Mare Geldenhuys (mare.geldenhuys) RealDonald Afrikaans Dutch 50 67 57 69 0 0 121 0 10 0 0 2017-06-23 20:10:12
113 Peter Williams (williamspete001) sirekanyan Japanese Armenian; Russian 49 66 133 65 0 1 0 0 0 3 0 2020-04-18 11:32:52
114 Behnood HRazy (behnoodhr) Константин К. (kocyak1991) Persian Russian 49 64 70 60 0 0 0 1 0 2 0 2018-06-10 13:39:37
115 J3ll3nl Laura Sophie (laurasophie20) Dutch German 48 62 48 67 0 0 4 17 0 1 0 3 0 2018-01-06 14:21:24
116 tat bz (Tat_i) Alparslan Sakci (sakci) German Turkish 48 61 56 55 0 55 11 0 0 27 0 2021-06-10 11:59:22
117 vach raden20 Armenian Indonesian 47 61 36 62 0 177 0 0 1 0 0 64 2017-04-09 22:04:23
118 andowero Jan Wojtecki (j4nw) Czech Polish 47 58 38 46 0 0 0 0 0 26 2017-11-02 05:42:14
119 Andrew Firnes (Anechan) Deepak Bharathi (deepakbharathi1994) Russian Tamil 47 56 47 107 0 3 0 0 11 0 4 29 0 2017-09-17 08:00:31
120 Coni Ragni (coni2ragnii) Peter Williams (williamspete001) Spanish Japanese 46 55 46 147 0 0 2 0 0 0 3 2020-01-01 13:17:44
121 Rahul Shishodia (rahul.shishodia.10) Андрій Козицький (andriikozytskyi1108) Hindi Ukrainian 46 52 85 52 0 6 0 0 1 0 0 2018-10-22 01:45:08
122 Cp0204 Nil riera (nilriera2000) Chinese Simplified Catalan 45 52 72 61 0 0 1 0 0 0 2021-06-22 16:37:44
123 cc (cavaz) REMOVED_USER Italian 44 51 41 52 0 0 2 0 0 0 2017-08-21 05:15:31
124 Kamil Dziadek (prso94) govindap Polish Japanese; Hindi 43 51 39 114 0 0 6 2 1 0 0 2020-06-02 20:15:52
125 Boban Jagertraum (boban40) Mare Geldenhuys (mare.geldenhuys) Czech Afrikaans 43 50 38 57 0 2 0 1 0 1 0 0 2017-10-20 18:00:14
126 andreea.muscalagiu Behnood HRazy (behnoodhr) Romanian Persian 42 49 52 70 0 1 0 0 0 0 2017-11-25 10:57:21
127 Me Me (gentelwom) tat bz (Tat_i) Arabic German 42 48 40 56 0 0 55 0 0 0 27 2021-03-26 05:12:54
128 Balázs Keresztury (belidzs) J3ll3nl Hungarian Dutch 42 48 41 48 501 0 0 7 17 0 1 38 3 2017-03-31 11:56:09
129 MStefanov Andrew Firnes (Anechan) Bulgarian Russian 41 47 55 47 2 0 0 3 2 0 0 2 29 2019-09-18 09:51:59
130 Ali Zali (stm19951995) andowero Persian Czech 40 47 60 38 0 0 0 0 0 2020-01-20 02:29:01
131 Sofia Veijonen (Suklaa) (sofia.veijonen) vach Finnish Armenian 40 47 33 36 0 0 0 0 0 2020-04-18 16:53:12
132 dusanstrgar Rahul Shishodia (rahul.shishodia.10) Slovenian Hindi 39 46 41 85 0 0 6 0 5 0 1 0 2018-12-24 22:18:19
133 Limin Lu (liminlu) Coni Ragni (coni2ragnii) Chinese Simplified Spanish 39 46 79 46 503 0 0 0 0 39 0 2021-02-28 20:18:37
134 Anshoe Cp0204 Tamil Chinese Simplified 38 45 65 72 0 14 0 0 0 0 2019-08-20 11:04:27
135 anasshm cc (cavaz) Arabic Italian 37 44 36 41 0 9 0 0 0 0 2017-04-01 04:21:08
136 hrexen Boban Jagertraum (boban40) Armenian Czech 37 43 37 38 0 0 2 0 1 0 1 0 2017-03-31 09:39:16
137 REMOVED_USER Kamil Dziadek (prso94) Swedish Polish 36 43 33 39 0 5 0 1 2 0 0 2020-04-06 17:12:06
138 Abdulrahman (D7M) Me Me (gentelwom) Arabic 36 42 39 40 0 0 0 0 0 2020-11-08 20:44:01
139 長谷川知里 (chase0213) Ali Elsheikh (aelsheikh1987) Japanese Arabic 34 42 138 41 0 13 0 0 0 24 0 2021-06-16 10:17:26
140 Piotr Łuczyński (peterluczynski) Balázs Keresztury (belidzs) Polish Hungarian 33 42 30 41 0 501 6 0 5 7 0 2 38 2017-04-06 02:40:24
141 milad farahani (miladfarmahini90) andreea.muscalagiu Persian Romanian 33 42 44 52 0 18 1 0 0 3 0 2017-10-22 07:19:49
142 Luis E. Perichon (luisperichon) Mateusz Duda (MateuszDuda) Spanish Polish 33 42 40 42 0 104 0 0 0 0 2021-08-17 11:27:11
143 andriikozytskyi2625 MStefanov Ukrainian Bulgarian 31 41 23 55 0 2 0 0 2 0 0 2 2017-03-31 16:09:02
144 JoeLi Sofia Veijonen (Suklaa) (sofia.veijonen) Chinese Traditional Finnish 31 40 70 33 0 12 0 0 0 24 0 2018-03-07 09:24:22
145 Moastafa Ali Zali (stm19951995) Arabic Persian 31 40 25 60 0 0 0 0 0 2020-03-23 19:57:26
146 REMOVED_USER Limin Lu (liminlu) Russian Chinese Simplified 31 39 30 79 0 503 2 0 4 0 0 3 39 2017-03-31 09:49:35
147 hamza gamal (hamzagamal4444) dusanstrgar Arabic Slovenian 31 39 28 41 0 0 0 0 0 2017-03-31 10:30:28
148 yancyn Anshoe Chinese Simplified Tamil 30 38 40 65 0 0 14 0 0 0 2018-01-02 11:06:52
149 비니몬youtube (khj01025276475) anasshm Korean Arabic 29 37 25 36 0 0 9 0 0 0 2019-01-27 04:07:22
150 Ruud Schouten (ruudschouten) hrexen Dutch Armenian 29 37 32 37 0 41 0 3 0 0 0 2020-12-09 02:30:34
151 Guillaume Collic (gcollic) Abdulrahman (D7M) French Arabic 26 36 28 39 0 126 0 11 0 0 0 2020-01-29 18:55:30
152 Niraj Yadav (neverforgetniraj) Maria Chushnyakova (maria.ch) Hindi Russian 26 36 48 31 0 0 3 0 0 0 2021-08-17 03:23:58
153 Radoslaw Biernacki (radoslaw.biernacki) REMOVED_USER Polish Swedish 26 36 24 33 0 8 5 0 1 0 1 0 2018-09-29 17:47:33
154 Jonny I (jonny99dj) 長谷川知里 (chase0213) Italian Japanese 26 34 26 138 0 5 13 0 0 0 24 2018-12-14 10:52:44
155 Aaron Dalton (Perlkonig) Luis E. Perichon (luisperichon) French Spanish 26 33 25 40 0 141 104 1 0 0 0 2017-09-04 13:46:06
156 Eddie (eddieattaboy) Piotr Łuczyński (peterluczynski) Chinese Traditional Polish 25 33 34 30 0 1 6 0 5 0 0 2 2020-01-29 07:27:40
157 Pan_Filuta milad farahani (miladfarmahini90) Czech Persian 25 33 21 44 0 5 18 4 1 0 3 2017-08-31 16:09:00
158 eduard83 (barbany.eduard) andriikozytskyi2625 Catalan Ukrainian 24 31 25 23 0 2 0 0 0 0 2019-07-08 00:16:41
159 Ľuboš Čaky (lubos.caky) Moastafa Slovak Arabic 23 31 22 25 0 0 0 0 0 2020-07-06 11:37:53
160 Caner Başaran (basarancaner) hamza gamal (hamzagamal4444) Turkish Arabic 23 31 21 28 0 0 20 0 0 0 2020-08-03 15:23:34
161 hodanli REMOVED_USER Turkish Russian 22 31 26 30 0 0 2 1 4 0 0 3 2018-12-03 23:55:47
162 Neeraj Verma (verma.neeraj.in) JoeLi Hindi Chinese Traditional 22 31 37 70 0 0 12 1 0 0 0 24 2017-06-25 05:32:48
163 Alcarkse (alexis.brusle) yancyn French Chinese Simplified 21 30 25 40 0 7 0 11 0 0 0 1 2020-05-18 20:06:03
164 Shashwat (goforgold) 비니몬youtube (khj01025276475) Hindi Korean 20 29 33 25 0 0 0 0 0 2020-02-09 20:44:35
165 사자솥 (toke1597) Ruud Schouten (ruudschouten) Korean Dutch 19 29 19 32 0 0 41 0 3 0 0 2017-07-22 17:49:17
166 İsa Eş (IsaEs) Aaron Dalton (Perlkonig) Turkish French 19 26 17 25 0 0 141 6 1 1 0 0 2018-01-14 12:58:19
167 sheeCesu Niraj Yadav (neverforgetniraj) French Hindi 19 26 18 48 0 48 0 2 0 0 0 2017-04-11 02:26:50
168 can13 Guillaume Collic (gcollic) Turkish French 19 26 14 28 0 8 126 0 11 0 0 2017-05-05 16:13:00
169 Magdalena Urbańczyk (madziia139) Radoslaw Biernacki (radoslaw.biernacki) Polish 19 26 19 24 0 0 8 0 0 0 1 2020-12-15 17:55:31
170 axikman11111 Jonny I (jonny99dj) Uyghur Italian 18 26 19 26 0 0 5 0 0 0 2017-10-07 07:35:34
171 Adeline31 Eddie (eddieattaboy) French Chinese Traditional 17 25 20 34 0 3 1 0 0 0 2020-11-04 21:48:05
172 Hoon Jung (hooni100) Pan_Filuta Korean Czech 17 25 10 21 0 0 5 0 4 0 0 3 2017-04-29 12:55:14
173 Ceara Lopez (cealopez) eduard83 (barbany.eduard) Spanish Catalan 17 24 18 25 0 0 2 5 0 1 0 0 2019-06-26 14:59:47
174 takoyakibento Ľuboš Čaky (lubos.caky) Korean Slovak 17 23 13 22 0 3 0 0 0 0 2019-07-02 16:51:44
175 bretzel15 Caner Başaran (basarancaner) German Turkish 16 23 20 21 0 0 0 21 0 0 2017-04-09 06:34:59
176 engineeringforgood hodanli Russian Turkish 16 22 15 26 0 0 0 1 0 0 2017-11-03 14:33:41
177 Şamil Ateşoğlu (m.samilatesoglu) gnu-ewm Turkish Polish 16 22 22 23 0 11 6 6 0 3 0 0 2021-02-24 03:42:01
178 DebatablySane Neeraj Verma (verma.neeraj.in) Bulgarian Hindi 16 22 15 37 0 48 0 0 1 0 0 2018-07-23 07:16:41
179 Bhava Tharini (bhavidanush) Alcarkse (alexis.brusle) Tamil French 15 21 37 25 0 0 7 0 11 0 0 2017-08-06 09:32:29
180 Anastasia Borchuk (al2.borchuk) olbotta Russian Italian 14 20 14 25 0 0 2 0 0 0 2021-06-06 04:22:55
181 EuiHo Hwang (euiho.hwang) Shashwat (goforgold) Korean Hindi 14 20 16 33 0 0 0 0 0 2020-05-17 10:34:42
182 iamsurajbobade Magdalena Urbańczyk (madziia139) Hindi Polish 14 19 30 19 0 0 0 0 0 2017-10-21 03:01:04
183 Zeynep Esen (nezihaesen50) sheeCesu Turkish French 14 19 13 18 0 0 48 0 4 0 0 2017-12-21 17:01:39
184 Fikret Bilici (fikretbilici) can13 Turkish 14 19 13 14 0 0 8 0 0 0 2021-01-03 10:39:03
185 Zeeshan Rabbani (Zeera) İsa Eş (IsaEs) Hindi Turkish 14 19 25 17 0 0 0 6 0 1 0 2017-06-20 07:30:22
186 Sanji Vinsmock (mukanzhanbolat4) 사자솥 (toke1597) Russian Korean 14 19 14 19 0 0 0 0 0 2020-02-04 13:36:11
187 Nenad Vukotic (vukotic.nenad) axikman11111 Serbian (Cyrillic) Uyghur 13 18 13 19 0 1 0 2 0 6 0 0 2018-10-13 12:25:31
188 Uwe Mönks (schirinowski) Hoon Jung (hooni100) German Korean 13 17 12 10 0 0 0 0 0 2021-01-03 02:26:54
189 Dave (xdave) Ceara Lopez (cealopez) Hungarian Spanish 13 17 11 18 0 0 0 5 0 1 0 2017-08-22 22:56:13
190 soura2 takoyakibento Arabic Korean 12 17 13 0 0 3 0 0 0 2020-08-01 08:44:15
191 shreyas (techiespace) Adeline31 Hindi French 12 17 20 0 0 3 0 0 0 2019-12-06 00:00:11
192 Jo Chuang (josephch405) engineeringforgood Chinese Traditional Russian 11 16 24 15 0 0 0 0 11 16 2021-01-22 03:32:35
193 Vmrc bretzel15 French German 11 16 12 20 0 2 0 0 0 0 2020-04-06 02:49:14
194 sathvic k (sathvictripleseven) Şamil Ateşoğlu (m.samilatesoglu) Telugu Turkish 10 16 17 22 0 0 11 0 6 0 3 0 2017-07-05 18:37:08
195 Edwin van Rooij (edwinvrooij) DebatablySane Dutch Bulgarian 10 16 13 15 0 17 48 0 0 0 2017-07-10 15:13:18
196 Brian Camacho (bmcamacho) Bhava Tharini (bhavidanush) Polish Tamil 10 15 11 37 0 0 1 0 0 0 2019-10-09 05:43:11
197 Ahmed Mosaad (ahmed.mosaad2018) Zeynep Esen (nezihaesen50) Arabic Turkish 10 14 12 13 0 6 0 0 0 0 2020-01-28 07:05:15
198 Mihael Wagner (miha.wagner) Fikret Bilici (fikretbilici) Slovenian Turkish 10 14 9 13 0 7 0 0 0 0 2020-06-21 17:16:11
199 Anonymous edgy nerd (yamentaad) EuiHo Hwang (euiho.hwang) Arabic Korean 10 14 13 16 0 1 0 0 0 0 2020-06-23 02:40:01
200 Martin Vostatek (martinvostatek) Zeeshan Rabbani (Zeera) Czech Hindi 9 14 8 25 0 32 0 2 0 0 0 2020-09-15 11:32:01
201 Sourire Lucide (sourire_lucide) Faiz Ahamed (faiznewton) Russian Tamil 9 14 10 31 0 0 1 0 0 0 2021-05-06 23:06:46
202 Suhaili Hassan (kucingsyg96) Anastasia Borchuk (al2.borchuk) Indonesian Russian 9 14 10 14 0 0 0 0 0 2020-04-14 13:22:49
203 Seweryn Piotrowski (Draxxsx) iamsurajbobade Polish Hindi 9 14 10 30 0 0 19 0 0 0 2018-05-21 11:23:27
204 Rex123 Sanji Vinsmock (mukanzhanbolat4) Persian Russian 8 14 8 14 0 0 0 0 0 2020-02-18 12:38:54
205 Konstantin (KZhidovinov) Maro Chr (caprisunglasses) Russian Greek 7 14 7 17 0 0 0 0 0 2021-08-17 06:53:33
206 pkorove Nenad Vukotic (vukotic.nenad) Greek Serbian (Cyrillic) 7 13 7 13 0 0 1 0 2 0 6 0 2019-01-31 14:29:15
207 ftfoi Uwe Mönks (schirinowski) Norwegian German 7 13 6 12 0 0 0 0 0 2021-02-18 04:00:41
208 Андрій Козицький (andriikozytskyi3807) Dave (xdave) Ukrainian Hungarian 7 13 12 11 0 2 0 0 0 0 2020-03-02 20:56:50
209 Vladimir Pavlychev (KeyJoo) soura2 Russian Arabic 7 12 9 13 0 0 0 0 0 2020-01-13 19:23:47
210 Andrey ZaXeLoN (waragaa) shreyas (techiespace) Russian Hindi 7 12 7 20 0 8 0 1 0 0 0 2018-06-10 01:14:26
211 erfan2927 Sonu Sharma (riteetude) Persian Hindi 6 11 6 23 0 0 0 0 0 2021-05-30 19:38:00
212 dragnus Vmrc Arabic French 6 11 6 12 0 1 2 1 0 0 0 2020-11-02 05:35:06
213 Sam (SorodonSorodon) Jo Chuang (josephch405) German Chinese Traditional 6 11 6 24 0 13 0 0 0 0 11 2017-06-16 20:21:06
214 ChloeLiang sathvic k (sathvictripleseven) Japanese Telugu 6 10 22 17 0 0 1 0 0 3 0 2020-09-11 08:11:32
215 Burak Ceylan (7burakceylan) Brian Camacho (bmcamacho) Turkish Polish 6 10 6 11 0 0 0 1 0 0 2020-08-03 02:27:28
216 닉닉 (seohu9466) Anonymous edgy nerd (yamentaad) Korean Arabic 6 10 14 13 0 13 1 0 0 0 2018-05-06 09:23:57
217 Matthias Joly (joly.matt12) Edwin van Rooij (edwinvrooij) French Dutch 5 10 8 13 0 27 17 1 0 0 0 2018-11-05 03:59:10
218 Guerra Ivaneth (rossanaiva-04) Mihael Wagner (miha.wagner) Spanish Slovenian 5 10 7 9 0 0 7 0 0 0 2017-10-18 18:26:29
219 Manuel Tassi (Mannivu) Ahmed Mosaad (ahmed.mosaad2018) Italian Arabic 5 10 6 12 0 0 6 0 0 0 2021-02-03 18:45:43
220 Micaela Pighin (micaelapiighin) Suhaili Hassan (kucingsyg96) Spanish Indonesian 5 9 6 10 0 1 0 0 0 0 2018-06-10 11:55:09
221 Дмитрий Хапенков (d.khapenkov) Martin Vostatek (martinvostatek) Russian Czech 5 9 5 8 0 6 32 4 2 0 2 0 2019-01-21 13:52:36
222 andriikozytskyi2018 Seweryn Piotrowski (Draxxsx) Ukrainian Polish 5 9 5 10 0 0 0 19 0 0 2020-01-02 09:55:48
223 Neko123 (emandic11) Sourire Lucide (sourire_lucide) Serbian (Cyrillic) Russian 4 9 4 10 0 57 0 0 1 0 0 2018-03-22 01:37:55
224 marmo Rex123 German Persian 4 8 4 8 0 0 0 0 0 2017-07-01 00:47:42
225 Eli Besirov (elibesirov07) Andrey ZaXeLoN (waragaa) Turkish Russian 4 7 4 7 0 0 8 0 1 0 0 2017-09-18 21:37:42
226 Lopo Isaac Fernández (rocapata) Konstantin (KZhidovinov) Spanish Russian 4 7 3 7 0 0 0 0 0 2020-01-29 13:35:12
227 bziuum Андрій Козицький (andriikozytskyi3807) Polish Ukrainian 4 7 4 12 0 0 2 0 0 0 2020-09-26 20:31:56
228 Thoum Ptrgnt (thomas.petrignet) ftfoi French Norwegian 3 7 3 6 0 2 0 0 3 0 0 2020-04-11 20:42:35
229 Vagner Roberto (vagner.trompete) Vladimir Pavlychev (KeyJoo) Portuguese, Brazilian Russian 3 7 3 9 0 0 0 0 0 2017-12-18 02:46:56
230 Unnie Here (Carb) pkorove Hindi Greek 3 7 8 7 0 0 0 0 0 2020-03-07 11:36:12
231 carsten_kafke erfan2927 German Persian 3 6 3 6 0 43 0 0 0 3 0 2018-04-09 02:12:44
232 Magidxz Burak Ceylan (7burakceylan) Arabic Turkish 3 6 3 6 0 0 0 0 0 2018-05-20 17:24:19
233 atomjani Sam (SorodonSorodon) Hungarian German 3 6 3 6 0 0 13 0 0 0 2017-04-14 11:09:27
234 Péter Bernát (bernatp) 닉닉 (seohu9466) Hungarian Korean 3 6 2 14 0 0 13 0 0 0 2017-10-09 23:08:15
235 Igor Piskun (i_piskun) Sarita Cajas (sarayanacajas) Ukrainian Spanish 3 6 3 4 0 0 0 1 0 0 2021-05-14 14:27:59
236 joabe gabriel (joabegabrielcma1) ChloeLiang Portuguese, Brazilian Japanese 3 6 4 22 0 0 0 1 0 0 3 2017-08-08 05:02:59
237 Oleg Kogut (kogut_oleg) Manuel Tassi (Mannivu) Ukrainian Italian 3 5 3 6 0 0 0 0 0 2021-01-03 11:00:33
238 Andrea Bianchi (andreawhite1597) Tomáš Hrabáček (Hrabyyy) Italian Czech 3 5 1 3 0 1 0 0 0 0 2021-05-27 11:58:11
239 Gabriel Cavalcante (gabrielc.alves14) Guerra Ivaneth (rossanaiva-04) Portuguese, Brazilian Spanish 3 5 4 7 0 0 0 0 0 2019-02-03 16:48:59
240 REMOVED_USER Дмитрий Хапенков (d.khapenkov) Portuguese, Brazilian Russian 3 5 4 5 0 0 6 0 4 0 0 2 2018-01-06 23:00:43
241 Martin Zimdahl (zimdahlmartin) Matthias Joly (joly.matt12) Swedish French 3 5 2 8 0 0 27 1 0 3 0 2017-08-28 09:53:59
242 Hiohana Rilary (hiohanarilary) Micaela Pighin (micaelapiighin) Portuguese, Brazilian Spanish 3 5 4 6 0 0 1 0 0 0 2019-10-09 23:32:42
243 Sarath S (CyberShark) andriikozytskyi2018 Tamil Ukrainian 3 5 7 5 0 0 0 0 0 2017-09-03 05:24:43
244 Cláudio Bernardo (claudiobernardo.ti) marmo Portuguese, Brazilian German 3 4 4 0 1 0 0 0 0 2021-01-13 01:16:35
245 hesamiranii (esam.matouri) Eli Besirov (elibesirov07) Persian Turkish 2 4 2 4 0 0 0 0 0 2019-03-25 07:12:34
246 조화정 (yunjoo337) Lopo Isaac Fernández (rocapata) Korean Spanish 2 4 2 3 0 0 0 0 0 2018-09-20 11:46:22
247 Walid Baazia (walidbaazia2005) bziuum Arabic Polish 2 4 1 4 0 0 0 0 0 2020-09-01 09:08:01
248 LNDDYL Neko123 (emandic11) Chinese Traditional Serbian (Cyrillic) 2 4 4 0 0 57 0 0 2 0 2021-04-21 15:33:29
249 REMOVED_USER Magidxz Ukrainian Arabic 2 3 2 3 0 0 0 0 0 2021-01-05 05:02:54
250 fatemeh s (fargolseifoori3) mohammadali barati (mabaraty) Persian 2 3 2 3 0 0 0 0 0 2021-07-10 05:54:44
251 أم محمد تقي (souadboudia19) Sarath S (CyberShark) Arabic Tamil 2 3 2 7 0 0 0 0 0 2020-08-27 22:43:16
252 Alex Stein (diefaust1993) Unnie Here (Carb) Russian Hindi 2 3 2 8 0 4 0 4 0 0 2 0 2020-03-18 23:34:35
253 Danial Agh (danialagh) REMOVED_USER Persian Portuguese, Brazilian 2 3 3 4 0 0 0 0 0 2018-11-18 09:02:37
254 omerfarukbas Thoum Ptrgnt (thomas.petrignet) Turkish French 2 3 3 0 19 2 2 0 0 3 0 2017-09-23 19:25:52
255 Valerij D (vala.dobler) Oleg Kogut (kogut_oleg) German Ukrainian 2 3 2 3 0 0 0 0 0 2018-12-28 14:31:02
256 Naveen jai krishna (njsbpolymer1) carsten_kafke Tamil German 2 3 5 3 0 0 43 0 0 0 3 2017-10-27 13:27:47
257 Balthazar Aubard (Balatzar) Vagner Roberto (vagner.trompete) French Portuguese, Brazilian 2 3 5 3 0 0 1 0 0 0 2017-12-30 17:54:26
258 FAy FAy (fayfayfay52) Igor Piskun (i_piskun) Chinese Traditional Ukrainian 2 3 5 3 0 0 0 0 0 2018-01-19 15:20:27
259 Soroor_SI Andrea Bianchi (andreawhite1597) Persian Italian 2 3 2 1 0 0 1 0 0 0 2018-01-21 17:45:48
260 chavs1997 Cláudio Bernardo (claudiobernardo.ti) Russian Portuguese, Brazilian 2 3 2 4 0 9 1 0 0 0 2019-01-08 14:41:10
261 amei Hiohana Rilary (hiohanarilary) Portuguese, Brazilian 2 3 2 4 0 0 0 0 0 2019-07-31 20:42:20
262 Ilyas Fekhar (il47yas) joabe gabriel (joabegabrielcma1) Arabic Portuguese, Brazilian 2 3 2 4 0 0 0 0 0 2018-08-21 09:08:59
263 Ali Zaida (alizaeda92) Péter Bernát (bernatp) Arabic Hungarian 2 3 2 0 0 0 0 0 2019-11-30 15:50:33
264 gnu-ewm Martin Zimdahl (zimdahlmartin) Polish Swedish 1 3 1 2 0 6 0 0 1 0 0 3 2018-09-15 04:39:22
265 Luca Gori (grolcu) Gabriel Cavalcante (gabrielc.alves14) Italian Portuguese, Brazilian 1 3 2 4 0 0 0 0 0 2018-08-06 22:24:54
266 Alan Jeon (skyisle) atomjani Korean Hungarian 1 3 2 3 0 8 0 0 0 0 2019-01-19 00:49:25
267 iSoron2 أم محمد تقي (souadboudia19) Portuguese, Brazilian Arabic 1 2 1 2 0 0 0 0 0 2020-06-13 15:24:17
268 Anastasiia Bondarenko (nastasya.bondarenko.97) FAy FAy (fayfayfay52) Russian Chinese Traditional 1 2 1 5 0 0 0 0 0 2017-10-06 08:53:21
269 Patrick Pimenta (trickap1) chavs1997 Portuguese, Brazilian Russian 1 2 1 2 0 0 9 0 0 0 2018-05-18 16:58:19
270 axd Soroor_SI Spanish Persian 1 2 1 2 0 15 0 0 0 0 2018-06-10 06:28:27
271 jonesses Ilyas Fekhar (il47yas) German Arabic 1 2 1 2 0 1 0 0 0 1 0 2018-04-17 22:00:41
272 박찌 (perpact20) hesamiranii (esam.matouri) Korean Persian 1 2 1 2 0 0 0 0 0 2018-09-22 16:33:36
273 Kan Black (kanblack.va) fatemeh s (fargolseifoori3) Vietnamese Persian 1 2 2 0 0 0 1 0 0 2019-01-31 12:06:57
274 REMOVED_USER amei Russian Portuguese, Brazilian 1 2 2 0 6 0 1 0 0 1 0 2018-04-19 19:42:28
275 Wibi Cahyo (wbcahyoh) Naveen jai krishna (njsbpolymer1) Indonesian Tamil 1 2 3 5 0 0 0 0 0 2020-01-10 14:19:41
276 Anton (tT0NG) Danial Agh (danialagh) Chinese Traditional Persian 1 2 2 3 0 0 0 0 1 0 2019-03-30 13:24:16
277 Maria Fefelova (mashafefel) Walid Baazia (walidbaazia2005) Russian Arabic 1 2 1 0 0 0 0 0 2021-01-27 12:47:34
278 Itch Ali Zaida (alizaeda92) Arabic 0 2 0 2 0 0 0 0 0 2019-12-01 11:47:00
279 Muhammet Furkan ALMACI (furkan.almaci) LNDDYL Turkish Chinese Traditional 0 2 0 4 0 1 0 0 0 0 2 2018-04-22 04:00:19
280 Sandhu564. Ño Bí Tã (pt614553) Arabic 0 2 0 8 0 0 1 0 0 0 2021-05-22 20:41:01
281 Quentin Hibon (hiq) Judith Ayala (Azul1612) Spanish 0 2 0 1 0 0 0 0 1 0 2021-05-18 17:07:19
282 mushin REMOVED_USER Ukrainian 0 2 0 2 0 0 0 0 0 2017-06-15 12:24:44
283 Balaji Jayaraman (jkbalaji1103) Valerij D (vala.dobler) German 0 2 0 2 0 0 0 0 0 2018-09-22 09:38:27
284 Wellington Ribeiro (wellington.rib) Alex Stein (diefaust1993) Russian 0 2 0 2 0 0 4 0 4 0 0 2 2017-07-13 06:56:17
285 Javid IRAN (twitteriran98) 조화정 (yunjoo337) Persian Korean 0 2 0 2 0 1 0 0 0 0 2019-06-16 22:25:31
286 박인호 (wphestiraid) omerfarukbas Korean Turkish 0 2 0 3 0 2 19 0 2 0 0 2017-08-14 16:10:35
287 Ahmed Nazir (ahmednazir333) Balthazar Aubard (Balatzar) French 0 2 0 5 0 0 0 1 0 0 2017-09-23 01:42:57
288 dimateos Luca Gori (grolcu) Italian 0 1 0 2 0 0 0 0 0 2020-09-26 23:26:15
289 AhmedDz axd Arabic Spanish 0 1 0 1 0 1 15 0 0 0 2017-09-12 05:48:51
290 reza golestanzadeh (reza.golestanzadeh) iSoron2 Persian Portuguese, Brazilian 0 1 0 1 0 1 0 0 0 0 2017-03-18 17:56:29
291 Petros Bleyan (coolbleyan) REMOVED_USER Russian 0 1 0 2 0 14 6 0 1 0 0 1 2019-12-26 05:37:01
292 Kamalakannan Wibi Cahyo (wbcahyoh) Indonesian 0 1 0 3 0 0 0 0 0 2017-12-14 06:35:58
293 Dagna Q (dagnaq) jonesses German 0 1 0 1 0 0 1 0 0 0 1 2021-01-01 08:03:18
294 Thomas Orlita (Thomas995) Anton (tT0NG) Czech Chinese Traditional 0 1 0 2 0 1 0 0 0 0 1 2017-07-06 14:18:39
295 Fazy1380 박찌 (perpact20) Korean 0 1 0 1 0 0 0 0 0 2018-02-10 10:11:44
296 Rivo Zängov (Eraser) Alan Jeon (skyisle) Korean 0 1 0 2 0 0 8 0 0 0 2018-01-09 10:46:00
297 T-v-Gerwen Maria Fefelova (mashafefel) Dutch Russian 0 1 0 1 0 47 0 0 0 0 2019-05-18 02:03:56
298 عبد الناصر سعيد الثبيتي (asaeed) Anastasiia Bondarenko (nastasya.bondarenko.97) Russian 0 1 0 1 0 0 0 0 0 2019-06-07 17:43:08
299 Edmunds Edmundam (edmundam) Kan Black (kanblack.va) Vietnamese 0 1 0 2 0 0 0 0 1 0 2019-01-15 03:50:10
300 vi ve (VimalV) Patrick Pimenta (trickap1) Portuguese, Brazilian 0 1 0 1 0 0 0 0 0 2018-12-01 14:31:21
301 LeMeD (LeMeS) Dagna Q (dagnaq) French 0 0 0 2 0 0 0 0 2017-08-06 01:42:52
302 Éjbãss Übbeî (littlebittlebottle) Kamalakannan Norwegian 0 0 0 152 0 0 0 0 2017-05-14 11:40:23
303 EmanAmini Éjbãss Übbeî (littlebittlebottle) Norwegian 0 0 0 0 152 0 0 0 2017-07-05 21:12:02
304 AnggaRifandi Равиль Мифтахов (ravilmif47) Russian 0 0 0 0 1 0 0 0 2019-08-12 21:58:30
305 Mateusz Teteruk (mttet) sanyoniket Polish 0 0 0 1 0 0 0 0 2019-07-23 12:58:40
306 Lori Amico (lavodkaclyde2323) REMOVED_USER Italian 0 0 0 1 0 0 0 0 2020-02-01 03:47:48
307 Florian Stuhlmann (stuhlmann) vi ve (VimalV) German 0 0 0 10 0 0 0 0 2021-02-08 02:35:45
308 Yasin Okumus (lacivert) George Merkulov (george142.emarket) Turkish Russian 0 0 0 1 11 0 0 0 2019-06-09 19:47:02
309 NairaDNV Yasin Okumus (lacivert) Spanish Turkish 0 0 0 9 1 0 0 0 2018-02-07 04:13:51
310 REMOVED_USER Petros Bleyan (coolbleyan) Russian 0 0 0 0 14 0 0 0 2017-08-18 18:37:18
311 farbod66 LeMeD (LeMeS) Persian French 0 0 0 1 2 0 0 0 2021-02-06 15:35:00
312 Raulbertassi ava_rfie Persian 0 0 0 0 1 0 0 0 2019-06-09 16:19:24
313 Равиль Мифтахов (ravilmif47) Mateusz Teteruk (mttet) Russian Polish 0 0 0 1 0 0 0 2021-01-23 13:09:59
314 Pumpith Ungsupanit (pumpithu) EwanB 0 0 0 0 0 0 0 2019-11-19 10:04:38
315 Nat Fomicheva (natac) Fazy1380 Russian 0 0 0 3 0 0 0 0 2021-04-10 11:02:53
316 EwanB Lori Amico (lavodkaclyde2323) Italian 0 0 0 0 1 0 0 0 2017-04-09 10:08:13
317 ava_rfie Florian Stuhlmann (stuhlmann) Persian German 0 0 0 1 10 0 0 0 2017-04-15 04:04:00
318 George Merkulov (george142.emarket) عبد الناصر سعيد الثبيتي (asaeed) Russian 0 0 0 11 0 0 0 0 2018-03-13 02:09:35
319 REMOVED_USER Rivo Zängov (Eraser) 0 0 0 0 0 0 0 2020-10-13 04:38:26
320 sanyoniket Hayder21 0 0 0 0 0 0 0 2019-12-31 10:56:24
321 Shuvashish Sahoo (shuvashish76) T-v-Gerwen Dutch 0 0 0 0 47 0 0 0 2018-03-02 10:26:33
322 martyaberger Eduard Boboc (edi.boboc33) Romanian 0 0 0 0 4 0 0 0 2019-12-16 09:08:39
323 Карлен Шаухаев (KarlenShaukhaev) Samuel Przeździęk (samek22) Polish 0 0 0 0 1 0 0 0 2021-08-01 00:49:01
324 Elmo (oberknecht) Saiprasath B (Saiprasath) 0 0 0 0 0 0 0 2021-07-11 11:10:41
325 Irsgram shuvo786 Russian 0 0 0 1 0 0 0 0 2019-11-13 00:18:12
326 Matus Zdansky (matuszdansky) Edmunds Edmundam (edmundam) 0 0 0 0 0 0 0 2020-06-01 14:18:18
327 shuvo786 Itch 0 0 0 0 0 0 0 2017-10-16 09:18:42
328 Eduard Boboc (edi.boboc33) Manny Farsangy (manifarsangi) Romanian Persian 0 0 0 4 12 0 0 0 2021-08-10 05:32:28
329 Hayder21 Matus Zdansky (matuszdansky) 0 0 0 0 0 0 0 2019-10-20 13:52:24
330 AsadullahIlyas Thomas Orlita (Thomas995) Czech 0 0 0 0 1 0 0 0 2017-12-24 04:08:27
331 Никита Карамов (nikita.karamoff) Irsgram Russian 0 0 0 10 1 0 0 0 2019-09-30 16:42:20
332 Katherine Alexandra Flórez Ramírez (katherine.florez12) EmanAmini Spanish 0 0 0 46 0 0 0 0 2017-03-31 13:27:43
333 mdrobulis mushin 0 0 0 0 0 0 0 2020-02-02 04:08:05
334 Eliška Roubalová (roubaeli) Elmo (oberknecht) Czech 0 0 0 6 0 0 0 0 2020-04-16 08:45:50
335 droidahmed AnggaRifandi Arabic 0 0 0 7 0 0 0 0 2017-03-31 19:28:35
336 Arjun K. (arjunkdot) darkkingredian (rediancool) 0 0 0 0 0 0 0 2021-07-27 16:04:32
337 Sarah BCNN (fsarahboucenna) Sri Harsha Bhogi (sriharshabhogi) French 0 0 0 16 0 0 0 0 2018-09-02 05:31:53
338 REMOVED_USER Nat Fomicheva (natac) Czech Russian 0 0 0 18 3 0 0 0 2019-01-25 14:35:02
339 BongTran mdrobulis Vietnamese 0 0 0 2 0 0 0 0 2018-05-24 01:40:42
340 Arttu Ylhävuori (arttu.ylhavuori) Sarah BCNN (fsarahboucenna) French 0 0 0 0 16 0 0 0 2018-02-11 11:07:36
341 valney.faria Arjun K. (arjunkdot) Portuguese, Brazilian 0 0 0 1 0 0 0 0 2020-09-20 11:16:18
342 REMOVED_USER Czech 0 0 0 0 18 0 0 0 2018-03-27 06:19:52
343 rooban23 martyaberger 0 0 0 0 0 0 0 2019-01-01 18:48:08
344 REMOVED_USER BongTran Vietnamese 0 0 0 0 2 0 0 0 2018-04-24 05:16:07
345 Алтынбек Наурызғали (altinbeknaurizgali) Arttu Ylhävuori (arttu.ylhavuori) Russian 0 0 0 1 0 0 0 0 2019-07-24 15:03:42
346 Sri Harsha Bhogi (sriharshabhogi) Никита Карамов (nikita.karamoff) Russian 0 0 0 0 10 0 0 0 2018-10-29 03:57:21
347 Ahnaf Tajwar (atn4404) rooban23 0 0 0 0 0 0 0 2020-09-15 11:49:14
348 Elham1361 Eliška Roubalová (roubaeli) Czech 0 0 0 0 6 0 0 0 2019-12-31 12:47:29
349 dongchen.yue valney.faria German Portuguese, Brazilian 0 0 0 4 1 0 0 0 2020-02-02 14:45:02
350 philfr49 Алтынбек Наурызғали (altinbeknaurizgali) French Russian 0 0 0 2 1 0 0 0 2020-08-12 13:03:49
351 REMOVED_USER 0 0 0 0 0 0 0 2018-10-27 15:34:36
352 REMOVED_USER 0 0 0 0 0 0 0 2018-08-24 00:17:43
353 Elham1361 0 0 0 0 0 0 0 2018-10-27 12:01:06
354 dongchen.yue German 0 0 0 4 0 0 0 2020-09-12 15:05:59
355 Ahnaf Tajwar (atn4404) 0 0 0 0 0 0 0 2018-10-16 11:13:30
356 AsadullahIlyas 0 0 0 0 0 0 0 2019-01-04 06:14:15
357 droidahmed Arabic 0 0 0 7 0 0 0 2018-01-31 02:18:49
358 philfr49 French 0 0 0 2 0 0 0 2018-09-03 14:20:32
359 Ahmed Nazir (ahmednazir333) 0 0 0 0 0 0 0 2018-05-06 12:10:27
360 Balaji Jayaraman (jkbalaji1103) 0 0 0 0 0 0 0 2017-10-30 22:12:27
361 Wellington Ribeiro (wellington.rib) 0 0 0 0 0 0 0 2017-11-16 07:32:25
362 Javid IRAN (twitteriran98) Persian 0 0 0 1 0 0 0 2017-11-25 16:47:25
363 박인호 (wphestiraid) Korean 0 0 0 2 0 0 0 2018-01-05 00:33:14
364 Pumpith Ungsupanit (pumpithu) 0 0 0 0 0 0 0 2019-01-19 23:47:57
365 Sandhu564. 0 0 0 0 0 0 0 2020-12-14 01:27:45
366 Quentin Hibon (hiq) 0 0 0 0 0 0 0 2021-02-07 16:39:31
367 AhmedDz Arabic 0 0 0 1 0 0 0 2017-12-31 10:12:31
368 Shuvashish Sahoo (shuvashish76) 0 0 0 0 0 0 0 2020-09-17 09:10:09
369 REMOVED_USER 0 0 0 0 0 0 0 2018-01-05 16:56:12
370 NairaDNV Spanish 0 0 0 9 0 0 0 2018-01-05 19:10:33
371 Raulbertassi 0 0 0 0 0 0 0 2018-01-07 17:23:18
372 Карлен Шаухаев (KarlenShaukhaev) 0 0 0 0 0 0 0 2020-04-27 08:53:49
373 dimateos 0 0 0 0 0 0 0 2021-01-10 06:29:52
374 Katherine Alexandra Flórez Ramírez (katherine.florez12) Spanish 0 0 0 46 0 0 0 2018-01-20 02:18:32
375 reza golestanzadeh (reza.golestanzadeh) Persian 0 0 0 1 0 0 0 2020-10-21 12:07:20
376 farbod66 Persian 0 0 0 1 0 0 0 2018-01-20 11:04:23
377 Muhammet Furkan ALMACI (furkan.almaci) Turkish 0 0 0 1 0 0 0 2017-10-29 13:44:56

View File

@@ -1,5 +1,3 @@
/* /*
* Copyright (C) 2016-2021 Álinson Santos Xavier <git@axavier.org> * Copyright (C) 2016-2021 Álinson Santos Xavier <git@axavier.org>
* *
@@ -20,7 +18,7 @@
*/ */
plugins { plugins {
id("com.github.triplet.play") version "3.2.0" id("com.github.triplet.play") version "3.7.0"
id("com.android.application") id("com.android.application")
id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.kapt") id("org.jetbrains.kotlin.kapt")
@@ -34,15 +32,15 @@ tasks.compileLint {
android { android {
compileSdkVersion(30) compileSdk = 31
defaultConfig { defaultConfig {
versionCode(20001) versionCode = 20003
versionName("2.0.1") versionName = "2.0.3"
minSdkVersion(23) minSdk = 23
targetSdkVersion(30) targetSdk = 31
applicationId("org.isoron.uhabits") applicationId = "org.isoron.uhabits"
testInstrumentationRunner("androidx.test.runner.AndroidJUnitRunner") testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }
signingConfigs { signingConfigs {
@@ -58,7 +56,7 @@ android {
buildTypes { buildTypes {
getByName("release") { getByName("release") {
minifyEnabled(true) isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.txt") proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.txt")
if (signingConfigs.findByName("release") != null) { if (signingConfigs.findByName("release") != null) {
signingConfig = signingConfigs.getByName("release") signingConfig = signingConfigs.getByName("release")
@@ -70,7 +68,7 @@ android {
} }
} }
lintOptions { lint {
isCheckReleaseBuilds = false isCheckReleaseBuilds = false
isAbortOnError = false isAbortOnError = false
disable("GoogleAppIndexingWarning") disable("GoogleAppIndexingWarning")
@@ -88,29 +86,29 @@ android {
} }
dependencies { dependencies {
val daggerVersion = "2.34.1" val daggerVersion = "2.43.2"
val kotlinVersion = "1.4.32" val kotlinVersion = "1.7.10"
val kxCoroutinesVersion = "1.4.2" val kxCoroutinesVersion = "1.6.4"
val ktorVersion = "1.5.3" val ktorVersion = "1.6.8"
val espressoVersion = "3.3.0" val espressoVersion = "3.4.0"
androidTestImplementation("androidx.test.espresso:espresso-contrib:$espressoVersion") androidTestImplementation("androidx.test.espresso:espresso-contrib:$espressoVersion")
androidTestImplementation("androidx.test.espresso:espresso-core:$espressoVersion") androidTestImplementation("androidx.test.espresso:espresso-core:$espressoVersion")
androidTestImplementation("com.google.dagger:dagger:$daggerVersion") androidTestImplementation("com.google.dagger:dagger:$daggerVersion")
androidTestImplementation("com.linkedin.dexmaker:dexmaker-mockito:2.28.1") androidTestImplementation("com.linkedin.dexmaker:dexmaker-mockito:2.28.3")
androidTestImplementation("io.ktor:ktor-client-mock:$ktorVersion") androidTestImplementation("io.ktor:ktor-client-mock:$ktorVersion")
androidTestImplementation("io.ktor:ktor-jackson:$ktorVersion") androidTestImplementation("io.ktor:ktor-jackson:$ktorVersion")
androidTestImplementation("androidx.annotation:annotation:1.2.0") androidTestImplementation("androidx.annotation:annotation:1.4.0")
androidTestImplementation("androidx.test.ext:junit:1.1.2") androidTestImplementation("androidx.test.ext:junit:1.1.3")
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.2.0") androidTestImplementation("androidx.test.uiautomator:uiautomator:2.2.0")
androidTestImplementation("androidx.test:rules:1.3.0") androidTestImplementation("androidx.test:rules:1.4.0")
androidTestImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0") androidTestImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
compileOnly("javax.annotation:jsr250-api:1.0") compileOnly("javax.annotation:jsr250-api:1.0")
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5") coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5")
implementation("com.github.paolorotolo:appintro:3.4.0") implementation("com.github.AppIntro:AppIntro:6.2.0")
implementation("com.google.code.findbugs:jsr305:3.0.2") implementation("com.google.code.findbugs:jsr305:3.0.2")
implementation("com.google.dagger:dagger:$daggerVersion") implementation("com.google.dagger:dagger:$daggerVersion")
implementation("com.google.guava:guava:30.1.1-android") implementation("com.google.guava:guava:31.1-android")
implementation("io.ktor:ktor-client-android:$ktorVersion") implementation("io.ktor:ktor-client-android:$ktorVersion")
implementation("io.ktor:ktor-client-core:$ktorVersion") implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-jackson:$ktorVersion") implementation("io.ktor:ktor-client-jackson:$ktorVersion")
@@ -118,11 +116,11 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$kxCoroutinesVersion") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$kxCoroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kxCoroutinesVersion") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kxCoroutinesVersion")
implementation("androidx.appcompat:appcompat:1.2.0") implementation("androidx.appcompat:appcompat:1.4.2")
implementation("androidx.legacy:legacy-preference-v14:1.0.0") implementation("androidx.legacy:legacy-preference-v14:1.0.0")
implementation("androidx.legacy:legacy-support-v4:1.0.0") implementation("androidx.legacy:legacy-support-v4:1.0.0")
implementation("com.google.android.material:material:1.3.0") implementation("com.google.android.material:material:1.6.1")
implementation("com.opencsv:opencsv:5.4") implementation("com.opencsv:opencsv:5.6")
implementation(project(":uhabits-core")) implementation(project(":uhabits-core"))
kapt("com.google.dagger:dagger-compiler:$daggerVersion") kapt("com.google.dagger:dagger-compiler:$daggerVersion")
kaptAndroidTest("com.google.dagger:dagger-compiler:$daggerVersion") kaptAndroidTest("com.google.dagger:dagger-compiler:$daggerVersion")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -23,10 +23,10 @@ import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL
import org.isoron.uhabits.core.models.Frequency import org.isoron.uhabits.core.models.Frequency
import org.isoron.uhabits.core.models.Frequency.Companion.DAILY import org.isoron.uhabits.core.models.Frequency.Companion.DAILY
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.Habit.Companion.AT_LEAST
import org.isoron.uhabits.core.models.Habit.Companion.NUMBER_HABIT
import org.isoron.uhabits.core.models.HabitList import org.isoron.uhabits.core.models.HabitList
import org.isoron.uhabits.core.models.HabitType
import org.isoron.uhabits.core.models.ModelFactory import org.isoron.uhabits.core.models.ModelFactory
import org.isoron.uhabits.core.models.NumericalHabitType
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.models.Timestamp import org.isoron.uhabits.core.models.Timestamp
import org.isoron.uhabits.core.utils.DateUtils.Companion.getToday import org.isoron.uhabits.core.utils.DateUtils.Companion.getToday
@@ -102,8 +102,8 @@ class HabitFixtures(private val modelFactory: ModelFactory, private val habitLis
val habit = modelFactory.buildHabit().apply { val habit = modelFactory.buildHabit().apply {
name = "Read" name = "Read"
question = "How many pages did you walk today?" question = "How many pages did you walk today?"
type = NUMBER_HABIT type = HabitType.NUMERICAL
targetType = AT_LEAST targetType = NumericalHabitType.AT_LEAST
targetValue = 200.0 targetValue = 200.0
unit = "pages" unit = "pages"
} }

View File

@@ -55,6 +55,7 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
@LargeTest @LargeTest
class HabitsTest : BaseUserInterfaceTest() { class HabitsTest : BaseUserInterfaceTest() {
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun shouldCreateHabit() { fun shouldCreateHabit() {
@@ -180,6 +181,8 @@ class HabitsTest : BaseUserInterfaceTest() {
longPressCheckmarks("Wake up early", count = 2) longPressCheckmarks("Wake up early", count = 2)
clickText("Wake up early") clickText("Wake up early")
verifyShowsScreen(SHOW_HABIT) verifyShowsScreen(SHOW_HABIT)
// TODO: find a better way than sleeping in tests
Thread.sleep(2001L)
verifyDisplaysText("10%") verifyDisplaysText("10%")
} }
@@ -194,6 +197,8 @@ class HabitsTest : BaseUserInterfaceTest() {
verifyDoesNotDisplayText("Track time") verifyDoesNotDisplayText("Track time")
verifyDisplaysText("Wake up early") verifyDisplaysText("Wake up early")
longPressCheckmarks("Wake up early", count = 1) longPressCheckmarks("Wake up early", count = 1)
// TODO: find a better way than sleeping in tests
Thread.sleep(2001L)
verifyDoesNotDisplayText("Wake up early") verifyDoesNotDisplayText("Wake up early")
clickMenu(TOGGLE_COMPLETED) clickMenu(TOGGLE_COMPLETED)
verifyDisplaysText("Track time") verifyDisplaysText("Track time")

View File

@@ -18,7 +18,8 @@
*/ */
package org.isoron.uhabits.acceptance.steps package org.isoron.uhabits.acceptance.steps
import android.os.Build.VERSION import android.os.Build
import android.os.Build.VERSION.SDK_INT
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso import androidx.test.espresso.Espresso
@@ -133,7 +134,7 @@ object CommonSteps : BaseUserInterfaceTest() {
@Throws(Exception::class) @Throws(Exception::class)
fun verifyOpensWebsite(url: String?) { fun verifyOpensWebsite(url: String?) {
var browserPkg = "org.chromium.webview_shell" var browserPkg = "org.chromium.webview_shell"
if (VERSION.SDK_INT <= 23) { if (SDK_INT <= Build.VERSION_CODES.M) {
browserPkg = "com.android.browser" browserPkg = "com.android.browser"
} }
assertTrue(device.wait(Until.hasObject(By.pkg(browserPkg)), 5000)) assertTrue(device.wait(Until.hasObject(By.pkg(browserPkg)), 5000))
@@ -178,6 +179,22 @@ object CommonSteps : BaseUserInterfaceTest() {
EditHabitSteps.clickSave() EditHabitSteps.clickSave()
} }
fun changeFrequencyToDaily(habitName: String) {
clickText(habitName)
Espresso.onView(ViewMatchers.withId(R.id.action_edit_habit)).perform(ViewActions.click())
EditHabitSteps.pickDailyFrequency()
EditHabitSteps.clickSave()
pressBack()
}
fun changeFrequencyToMonthly(habitName: String) {
clickText(habitName)
Espresso.onView(ViewMatchers.withId(R.id.action_edit_habit)).perform(ViewActions.click())
EditHabitSteps.pickMonthFrequency()
EditHabitSteps.clickSave()
pressBack()
}
enum class Screen { enum class Screen {
LIST_HABITS, SHOW_HABIT, EDIT_HABIT, SELECT_HABIT_TYPE LIST_HABITS, SHOW_HABIT, EDIT_HABIT, SELECT_HABIT_TYPE
} }

View File

@@ -36,6 +36,24 @@ object EditHabitSteps {
Espresso.onView(ViewMatchers.withText("SAVE")).perform(ViewActions.click()) Espresso.onView(ViewMatchers.withText("SAVE")).perform(ViewActions.click())
} }
fun pickMonthFrequency() {
Espresso.onView(ViewMatchers.withId(R.id.boolean_frequency_picker))
.perform(ViewActions.click())
Espresso.onView(ViewMatchers.withId(R.id.xTimesPerMonthRadioButton))
.perform(ViewActions.click())
Espresso.onView(ViewMatchers.withId(R.id.xTimesPerMonthTextView))
.perform(ViewActions.replaceText("1"))
Espresso.onView(ViewMatchers.withText("SAVE")).perform(ViewActions.click())
}
fun pickDailyFrequency() {
Espresso.onView(ViewMatchers.withId(R.id.boolean_frequency_picker))
.perform(ViewActions.click())
Espresso.onView(ViewMatchers.withId(R.id.everyDayRadioButton))
.perform(ViewActions.click())
Espresso.onView(ViewMatchers.withText("SAVE")).perform(ViewActions.click())
}
fun pickColor(color: Int) { fun pickColor(color: Int) {
Espresso.onView(ViewMatchers.withId(R.id.colorButton)).perform(ViewActions.click()) Espresso.onView(ViewMatchers.withId(R.id.colorButton)).perform(ViewActions.click())
BaseUserInterfaceTest.device.findObject(By.descStartsWith(String.format("Color %d", color))) BaseUserInterfaceTest.device.findObject(By.descStartsWith(String.format("Color %d", color)))

View File

@@ -120,6 +120,12 @@ object ListHabitsSteps {
BaseUserInterfaceTest.device.waitForIdle() BaseUserInterfaceTest.device.waitForIdle()
} }
fun changeSort(sortText: String) {
clickViewWithId(R.id.action_filter)
Espresso.onView(ViewMatchers.withText("Sort")).perform(ViewActions.click())
Espresso.onView(ViewMatchers.withText(sortText)).perform(ViewActions.click())
}
enum class MenuItem { enum class MenuItem {
ABOUT, HELP, SETTINGS, EDIT, DELETE, ARCHIVE, TOGGLE_ARCHIVED, UNARCHIVE, TOGGLE_COMPLETED, ADD ABOUT, HELP, SETTINGS, EDIT, DELETE, ARCHIVE, TOGGLE_ARCHIVED, UNARCHIVE, TOGGLE_COMPLETED, ADD
} }

View File

@@ -18,7 +18,7 @@
*/ */
package org.isoron.uhabits.acceptance.steps package org.isoron.uhabits.acceptance.steps
import android.os.Build.VERSION import android.os.Build.VERSION.SDK_INT
import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.UiSelector
import junit.framework.Assert.assertFalse import junit.framework.Assert.assertFalse
@@ -50,29 +50,21 @@ object WidgetSteps {
private fun openWidgetScreen() { private fun openWidgetScreen() {
val h = BaseUserInterfaceTest.device.displayHeight val h = BaseUserInterfaceTest.device.displayHeight
val w = BaseUserInterfaceTest.device.displayWidth val w = BaseUserInterfaceTest.device.displayWidth
if (VERSION.SDK_INT <= 21) { val listId = "com.android.launcher3:id/widgets_list_view"
BaseUserInterfaceTest.device.pressHome() BaseUserInterfaceTest.device.pressHome()
BaseUserInterfaceTest.device.waitForIdle() BaseUserInterfaceTest.device.waitForIdle()
BaseUserInterfaceTest.device.findObject(UiSelector().description("Apps")).click() BaseUserInterfaceTest.device.drag(w / 2, h / 2, w / 2, h / 2, 8)
BaseUserInterfaceTest.device.findObject(UiSelector().description("Apps")).click() var button = BaseUserInterfaceTest.device.findObject(UiSelector().text("WIDGETS"))
BaseUserInterfaceTest.device.findObject(UiSelector().description("Widgets")).click() if (!button.waitForExists(1000)) {
} else { button = BaseUserInterfaceTest.device.findObject(UiSelector().text("Widgets"))
val listId = "com.android.launcher3:id/widgets_list_view"
BaseUserInterfaceTest.device.pressHome()
BaseUserInterfaceTest.device.waitForIdle()
BaseUserInterfaceTest.device.drag(w / 2, h / 2, w / 2, h / 2, 8)
var button = BaseUserInterfaceTest.device.findObject(UiSelector().text("WIDGETS"))
if (!button.waitForExists(1000)) {
button = BaseUserInterfaceTest.device.findObject(UiSelector().text("Widgets"))
}
button.click()
if (VERSION.SDK_INT >= 28) {
UiScrollable(UiSelector().resourceId(listId))
.scrollForward()
}
UiScrollable(UiSelector().resourceId(listId))
.scrollIntoView(UiSelector().text("Checkmark"))
} }
button.click()
if (SDK_INT >= 28) {
UiScrollable(UiSelector().resourceId(listId))
.scrollForward()
}
UiScrollable(UiSelector().resourceId(listId))
.scrollIntoView(UiSelector().text("Checkmark"))
} }
@Throws(Exception::class) @Throws(Exception::class)

View File

@@ -23,6 +23,7 @@ import androidx.test.filters.MediumTest
import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.BaseViewTest
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter.Companion.buildState import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter.Companion.buildState
import org.isoron.uhabits.core.ui.views.LightTheme
import org.isoron.uhabits.utils.toFixedAndroidColor import org.isoron.uhabits.utils.toFixedAndroidColor
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
@@ -39,7 +40,12 @@ class ScoreChartTest : BaseViewTest() {
super.setUp() super.setUp()
fixtures.purgeHabits(habitList) fixtures.purgeHabits(habitList)
habit = fixtures.createLongHabit() habit = fixtures.createLongHabit()
val state = buildState(habit, prefs.firstWeekdayInt, 0) val state = buildState(
habit = habit,
firstWeekday = prefs.firstWeekdayInt,
spinnerPosition = 0,
theme = LightTheme(),
)
view = ScoreChart(targetContext).apply { view = ScoreChart(targetContext).apply {
setScores(state.scores) setScores(state.scores)
setColor(state.color.toFixedAndroidColor()) setColor(state.color.toFixedAndroidColor())
@@ -72,7 +78,7 @@ class ScoreChartTest : BaseViewTest() {
@Test @Test
@Throws(Throwable::class) @Throws(Throwable::class)
fun testRender_withMonthlyBucket() { fun testRender_withMonthlyBucket() {
val (scores, bucketSize) = buildState(habit, prefs.firstWeekdayInt, 2) val (scores, bucketSize) = buildState(habit, prefs.firstWeekdayInt, 2, LightTheme())
view.setScores(scores) view.setScores(scores)
view.setBucketSize(bucketSize) view.setBucketSize(bucketSize)
view.invalidate() view.invalidate()
@@ -89,7 +95,7 @@ class ScoreChartTest : BaseViewTest() {
@Test @Test
@Throws(Throwable::class) @Throws(Throwable::class)
fun testRender_withYearlyBucket() { fun testRender_withYearlyBucket() {
val state = buildState(habit, prefs.firstWeekdayInt, 4) val state = buildState(habit, prefs.firstWeekdayInt, 4, LightTheme())
view.setScores(state.scores) view.setScores(state.scores)
view.setBucketSize(state.bucketSize) view.setBucketSize(state.bucketSize)
view.invalidate() view.invalidate()

View File

@@ -36,6 +36,7 @@ class EntryButtonViewTest : BaseViewTest() {
lateinit var view: CheckmarkButtonView lateinit var view: CheckmarkButtonView
var toggled = false var toggled = false
var edited = false
@Before @Before
override fun setUp() { override fun setUp() {
@@ -43,7 +44,8 @@ class EntryButtonViewTest : BaseViewTest() {
view = component.getEntryButtonViewFactory().create().apply { view = component.getEntryButtonViewFactory().create().apply {
value = Entry.NO value = Entry.NO
color = PaletteUtils.getAndroidTestColor(5) color = PaletteUtils.getAndroidTestColor(5)
onToggle = { toggled = true } onToggle = { _, _, _ -> toggled = true }
onEdit = { edited = true }
} }
measureView(view, dpToPixels(48), dpToPixels(48)) measureView(view, dpToPixels(48), dpToPixels(48))
} }
@@ -70,20 +72,28 @@ class EntryButtonViewTest : BaseViewTest() {
fun testClick_withShortToggleDisabled() { fun testClick_withShortToggleDisabled() {
prefs.isShortToggleEnabled = false prefs.isShortToggleEnabled = false
view.performClick() view.performClick()
assertFalse(toggled) assertTrue(!toggled and edited)
} }
@Test @Test
fun testClick_withShortToggleEnabled() { fun testClick_withShortToggleEnabled() {
prefs.isShortToggleEnabled = true prefs.isShortToggleEnabled = true
view.performClick() view.performClick()
assertTrue(toggled) assertTrue(toggled and !edited)
} }
@Test @Test
fun testLongClick() { fun testLongClick_withShortToggleDisabled() {
prefs.isShortToggleEnabled = false
view.performLongClick() view.performLongClick()
assertTrue(toggled) assertTrue(toggled and !edited)
}
@Test
fun testLongClick_withShortToggleEnabled() {
prefs.isShortToggleEnabled = true
view.performLongClick()
assertTrue(!toggled and edited)
} }
private fun assertRendersCheckedExplicitly() { private fun assertRendersCheckedExplicitly() {

View File

@@ -77,7 +77,7 @@ class EntryPanelViewTest : BaseViewTest() {
@Test @Test
fun testToggle() { fun testToggle() {
val timestamps = mutableListOf<Timestamp>() val timestamps = mutableListOf<Timestamp>()
view.onToggle = { t, _ -> timestamps.add(t) } view.onToggle = { t, _, _, _ -> timestamps.add(t) }
view.buttons[0].performLongClick() view.buttons[0].performLongClick()
view.buttons[2].performLongClick() view.buttons[2].performLongClick()
view.buttons[3].performLongClick() view.buttons[3].performLongClick()
@@ -88,7 +88,7 @@ class EntryPanelViewTest : BaseViewTest() {
fun testToggle_withOffset() { fun testToggle_withOffset() {
val timestamps = mutableListOf<Timestamp>() val timestamps = mutableListOf<Timestamp>()
view.dataOffset = 3 view.dataOffset = 3
view.onToggle = { t, _ -> timestamps += t } view.onToggle = { t, _, _, _ -> timestamps += t }
view.buttons[0].performLongClick() view.buttons[0].performLongClick()
view.buttons[2].performLongClick() view.buttons[2].performLongClick()
view.buttons[3].performLongClick() view.buttons[3].performLongClick()

View File

@@ -24,6 +24,7 @@ import androidx.test.filters.MediumTest
import org.hamcrest.CoreMatchers.equalTo import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.BaseViewTest
import org.isoron.uhabits.core.models.NumericalHabitType
import org.isoron.uhabits.utils.PaletteUtils import org.isoron.uhabits.utils.PaletteUtils
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
@@ -42,6 +43,7 @@ class NumberButtonViewTest : BaseViewTest() {
super.setUp() super.setUp()
view = component.getNumberButtonViewFactory().create().apply { view = component.getNumberButtonViewFactory().create().apply {
units = "steps" units = "steps"
targetType = NumericalHabitType.AT_LEAST
threshold = 100.0 threshold = 100.0
color = PaletteUtils.getAndroidTestColor(8) color = PaletteUtils.getAndroidTestColor(8)
onEdit = { edited = true } onEdit = { edited = true }
@@ -74,10 +76,10 @@ class NumberButtonViewTest : BaseViewTest() {
} }
@Test @Test
fun testRender_emptyUnits() { fun testRender_atMostAboveThreshold() {
view.value = 500.0 view.value = 500.0
view.units = "" view.targetType = NumericalHabitType.AT_MOST
assertRenders(view, "$PATH/render_unitless.png") assertRenders(view, "$PATH/render_at_most_above.png")
} }
@Test @Test
@@ -86,6 +88,13 @@ class NumberButtonViewTest : BaseViewTest() {
assertRenders(view, "$PATH/render_below.png") assertRenders(view, "$PATH/render_below.png")
} }
@Test
fun testRender_atMostBetweenThresholds() {
view.value = 110.0
view.targetType = NumericalHabitType.AT_MOST
assertRenders(view, "$PATH/render_at_most_between.png")
}
@Test @Test
fun testRender_zero() { fun testRender_zero() {
view.value = 0.0 view.value = 0.0
@@ -93,15 +102,21 @@ class NumberButtonViewTest : BaseViewTest() {
} }
@Test @Test
fun testClick_shortToggleDisabled() { fun testRender_atMostBelowThreshold() {
prefs.isShortToggleEnabled = false view.value = 0.0
view.performClick() view.targetType = NumericalHabitType.AT_MOST
assertFalse(edited) assertRenders(view, "$PATH/render_at_most_below.png")
} }
@Test @Test
fun testClick_shortToggleEnabled() { fun testRender_emptyUnits() {
prefs.isShortToggleEnabled = true view.value = 500.0
view.units = ""
assertRenders(view, "$PATH/render_unitless.png")
}
@Test
fun testClick() {
view.performClick() view.performClick()
assertTrue(edited) assertTrue(edited)
} }

View File

@@ -24,6 +24,7 @@ import androidx.test.filters.MediumTest
import org.hamcrest.CoreMatchers.equalTo import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.BaseViewTest
import org.isoron.uhabits.core.models.NumericalHabitType
import org.isoron.uhabits.core.models.Timestamp import org.isoron.uhabits.core.models.Timestamp
import org.isoron.uhabits.utils.PaletteUtils import org.isoron.uhabits.utils.PaletteUtils
import org.junit.After import org.junit.After
@@ -55,6 +56,7 @@ class NumberPanelViewTest : BaseViewTest() {
buttonCount = 4 buttonCount = 4
color = PaletteUtils.getAndroidTestColor(7) color = PaletteUtils.getAndroidTestColor(7)
units = "steps" units = "steps"
targetType = NumericalHabitType.AT_LEAST
threshold = 5000.0 threshold = 5000.0
} }
view.onAttachedToWindow() view.onAttachedToWindow()
@@ -74,7 +76,7 @@ class NumberPanelViewTest : BaseViewTest() {
@Test @Test
fun testEdit() { fun testEdit() {
val timestamps = mutableListOf<Timestamp>() val timestamps = mutableListOf<Timestamp>()
view.onEdit = { timestamps.plusAssign(it) } view.onEdit = { t -> timestamps.plusAssign(t) }
view.buttons[0].performLongClick() view.buttons[0].performLongClick()
view.buttons[2].performLongClick() view.buttons[2].performLongClick()
view.buttons[3].performLongClick() view.buttons[3].performLongClick()
@@ -85,7 +87,7 @@ class NumberPanelViewTest : BaseViewTest() {
fun testEdit_withOffset() { fun testEdit_withOffset() {
val timestamps = mutableListOf<Timestamp>() val timestamps = mutableListOf<Timestamp>()
view.dataOffset = 3 view.dataOffset = 3
view.onEdit = { timestamps += it } view.onEdit = { t -> timestamps += t }
view.buttons[0].performLongClick() view.buttons[0].performLongClick()
view.buttons[2].performLongClick() view.buttons[2].performLongClick()
view.buttons[3].performLongClick() view.buttons[3].performLongClick()

View File

@@ -25,6 +25,7 @@ import androidx.test.filters.MediumTest
import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.BaseViewTest
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.ui.screens.habits.show.views.FrequencyCardPresenter import org.isoron.uhabits.core.ui.screens.habits.show.views.FrequencyCardPresenter
import org.isoron.uhabits.core.ui.views.LightTheme
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@@ -43,7 +44,13 @@ class FrequencyCardViewTest : BaseViewTest() {
.from(targetContext) .from(targetContext)
.inflate(R.layout.show_habit, null) .inflate(R.layout.show_habit, null)
.findViewById<View>(R.id.frequencyCard) as FrequencyCardView .findViewById<View>(R.id.frequencyCard) as FrequencyCardView
view.setState(FrequencyCardPresenter.buildState(habit = habit, firstWeekday = 0)) view.setState(
FrequencyCardPresenter.buildState(
habit = habit,
firstWeekday = 0,
theme = LightTheme(),
)
)
measureView(view, 800f, 600f) measureView(view, 800f, 600f)
} }

View File

@@ -26,6 +26,7 @@ import org.isoron.uhabits.BaseViewTest
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardState
import org.isoron.uhabits.core.ui.views.LightTheme
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@@ -50,6 +51,7 @@ class OverviewCardViewTest : BaseViewTest() {
scoreYearDiff = 0.74f, scoreYearDiff = 0.74f,
totalCount = 44, totalCount = 44,
color = PaletteColor(7), color = PaletteColor(7),
theme = LightTheme(),
) )
) )
measureView(view, 800f, 300f) measureView(view, 800f, 300f)

View File

@@ -25,6 +25,7 @@ import androidx.test.filters.MediumTest
import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.BaseViewTest
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter.Companion.buildState import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter.Companion.buildState
import org.isoron.uhabits.core.ui.views.LightTheme
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@@ -43,7 +44,14 @@ class ScoreCardViewTest : BaseViewTest() {
.from(targetContext) .from(targetContext)
.inflate(R.layout.show_habit, null) .inflate(R.layout.show_habit, null)
.findViewById<View>(R.id.scoreCard) as ScoreCardView .findViewById<View>(R.id.scoreCard) as ScoreCardView
view.setState(buildState(habit = habit, firstWeekday = 0, spinnerPosition = 0)) view.setState(
buildState(
habit = habit,
firstWeekday = 0,
spinnerPosition = 0,
theme = LightTheme(),
)
)
measureView(view, 800f, 600f) measureView(view, 800f, 600f)
} }

View File

@@ -25,6 +25,7 @@ import androidx.test.filters.MediumTest
import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.BaseViewTest
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCardState
import org.isoron.uhabits.core.ui.views.LightTheme
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@@ -47,6 +48,7 @@ class StreakCardViewTest : BaseViewTest() {
StreakCardState( StreakCardState(
bestStreaks = habit.streaks.getBest(10), bestStreaks = habit.streaks.getBest(10),
color = habit.color, color = habit.color,
theme = LightTheme(),
) )
) )
measureView(view, 800f, 600f) measureView(view, 800f, 600f)

View File

@@ -28,6 +28,7 @@ import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.models.Reminder import org.isoron.uhabits.core.models.Reminder
import org.isoron.uhabits.core.models.WeekdayList.Companion.EVERY_DAY import org.isoron.uhabits.core.models.WeekdayList.Companion.EVERY_DAY
import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardState
import org.isoron.uhabits.core.ui.views.LightTheme
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@@ -52,8 +53,7 @@ class SubtitleCardViewTest : BaseViewTest() {
isNumerical = false, isNumerical = false,
question = "Did you meditate this morning?", question = "Did you meditate this morning?",
reminder = Reminder(8, 30, EVERY_DAY), reminder = Reminder(8, 30, EVERY_DAY),
unit = "", theme = LightTheme(),
targetValue = 0.0,
) )
) )
measureView(view, 800f, 200f) measureView(view, 800f, 200f)

View File

@@ -61,7 +61,7 @@ class PerformanceTest : BaseAndroidTest() {
val habit = fixtures.createEmptyHabit() val habit = fixtures.createEmptyHabit()
for (i in 0..4999) { for (i in 0..4999) {
val timestamp: Timestamp = Timestamp(i * DAY_LENGTH) val timestamp: Timestamp = Timestamp(i * DAY_LENGTH)
CreateRepetitionCommand(habitList, habit, timestamp, 1).run() CreateRepetitionCommand(habitList, habit, timestamp, 1, "").run()
} }
db.setTransactionSuccessful() db.setTransactionSuccessful()
db.endTransaction() db.endTransaction()

View File

@@ -21,9 +21,12 @@ package org.isoron.uhabits.regression
import androidx.test.filters.LargeTest import androidx.test.filters.LargeTest
import org.isoron.uhabits.BaseUserInterfaceTest import org.isoron.uhabits.BaseUserInterfaceTest
import org.isoron.uhabits.acceptance.steps.CommonSteps
import org.isoron.uhabits.acceptance.steps.CommonSteps.Screen.EDIT_HABIT import org.isoron.uhabits.acceptance.steps.CommonSteps.Screen.EDIT_HABIT
import org.isoron.uhabits.acceptance.steps.CommonSteps.Screen.LIST_HABITS import org.isoron.uhabits.acceptance.steps.CommonSteps.Screen.LIST_HABITS
import org.isoron.uhabits.acceptance.steps.CommonSteps.Screen.SELECT_HABIT_TYPE import org.isoron.uhabits.acceptance.steps.CommonSteps.Screen.SELECT_HABIT_TYPE
import org.isoron.uhabits.acceptance.steps.CommonSteps.changeFrequencyToDaily
import org.isoron.uhabits.acceptance.steps.CommonSteps.changeFrequencyToMonthly
import org.isoron.uhabits.acceptance.steps.CommonSteps.clickText import org.isoron.uhabits.acceptance.steps.CommonSteps.clickText
import org.isoron.uhabits.acceptance.steps.CommonSteps.createHabit import org.isoron.uhabits.acceptance.steps.CommonSteps.createHabit
import org.isoron.uhabits.acceptance.steps.CommonSteps.launchApp import org.isoron.uhabits.acceptance.steps.CommonSteps.launchApp
@@ -37,9 +40,12 @@ import org.isoron.uhabits.acceptance.steps.EditHabitSteps.clickSave
import org.isoron.uhabits.acceptance.steps.EditHabitSteps.typeName import org.isoron.uhabits.acceptance.steps.EditHabitSteps.typeName
import org.isoron.uhabits.acceptance.steps.ListHabitsSteps.MenuItem.ADD import org.isoron.uhabits.acceptance.steps.ListHabitsSteps.MenuItem.ADD
import org.isoron.uhabits.acceptance.steps.ListHabitsSteps.MenuItem.DELETE import org.isoron.uhabits.acceptance.steps.ListHabitsSteps.MenuItem.DELETE
import org.isoron.uhabits.acceptance.steps.ListHabitsSteps.changeSort
import org.isoron.uhabits.acceptance.steps.ListHabitsSteps.clickMenu import org.isoron.uhabits.acceptance.steps.ListHabitsSteps.clickMenu
import org.isoron.uhabits.acceptance.steps.ListHabitsSteps.longPressCheckmarks import org.isoron.uhabits.acceptance.steps.ListHabitsSteps.longPressCheckmarks
import org.isoron.uhabits.core.models.Entry.Companion.NO
import org.isoron.uhabits.core.models.Entry.Companion.UNKNOWN import org.isoron.uhabits.core.models.Entry.Companion.UNKNOWN
import org.isoron.uhabits.core.models.Entry.Companion.YES_AUTO
import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL
import org.junit.Test import org.junit.Test
@@ -83,4 +89,37 @@ class ListHabitsRegressionTest : BaseUserInterfaceTest() {
offsetHeaders() offsetHeaders()
verifyDisplaysCheckmarks("Wake up early", listOf(UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN)) verifyDisplaysCheckmarks("Wake up early", listOf(UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN))
} }
/**
* https://github.com/iSoron/uhabits/issues/1131
*/
@Test
@Throws(Exception::class)
fun should_refresh_sort_after_habit_edit() {
launchApp()
verifyShowsScreen(LIST_HABITS)
changeSort("By score")
changeSort("By status")
longPressCheckmarks("Meditate", count = 1)
changeFrequencyToMonthly("Read books")
longPressCheckmarks("Read books", count = 2)
longPressCheckmarks("Read books", count = 1)
verifyDisplaysCheckmarks("Meditate", listOf(YES_AUTO, YES_MANUAL, YES_AUTO, YES_MANUAL))
CommonSteps.verifyDisplaysTextInSequence(
"Wake up early",
"Read books",
"Meditate",
"Track time"
)
changeFrequencyToDaily("Meditate")
verifyDisplaysCheckmarks("Meditate", listOf(NO, YES_MANUAL, UNKNOWN, YES_MANUAL))
CommonSteps.verifyDisplaysTextInSequence(
"Wake up early",
"Meditate",
"Read books",
"Track time",
)
}
} }

View File

@@ -24,8 +24,8 @@ import android.widget.FrameLayout
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest import androidx.test.filters.MediumTest
import org.hamcrest.CoreMatchers import org.hamcrest.CoreMatchers
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.equalTo import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.BaseViewTest
import org.isoron.uhabits.R import org.isoron.uhabits.R

View File

@@ -50,7 +50,7 @@ class CheckmarkWidgetViewTest : BaseViewTest() {
name = habit.name name = habit.name
} }
view.refresh() view.refresh()
measureView(view, dpToPixels(100), dpToPixels(200)) measureView(view, dpToPixels(100), dpToPixels(125))
} }
@Test @Test

View File

@@ -17,9 +17,10 @@
~ with this program. If not, see <http://www.gnu.org/licenses/>. ~ with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.isoron.uhabits"> package="org.isoron.uhabits">
<uses-permission android:name="android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
@@ -48,11 +49,11 @@
android:name=".activities.habits.list.ListHabitsActivity" android:name=".activities.habits.list.ListHabitsActivity"
android:exported="true" android:exported="true"
android:label="@string/main_activity_title" android:label="@string/main_activity_title"
android:launchMode="singleTop"> android:launchMode="singleTop" />
</activity>
<activity-alias <activity-alias
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true"
android:label="@string/main_activity_title" android:label="@string/main_activity_title"
android:launchMode="singleTop" android:launchMode="singleTop"
android:targetActivity=".activities.habits.list.ListHabitsActivity"> android:targetActivity=".activities.habits.list.ListHabitsActivity">
@@ -85,6 +86,7 @@
<activity <activity
android:name=".widgets.activities.HabitPickerDialog" android:name=".widgets.activities.HabitPickerDialog"
android:exported="true"
android:theme="@style/Theme.AppCompat.Light.Dialog"> android:theme="@style/Theme.AppCompat.Light.Dialog">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
@@ -93,6 +95,7 @@
<activity <activity
android:name=".widgets.activities.BooleanHabitPickerDialog" android:name=".widgets.activities.BooleanHabitPickerDialog"
android:exported="true"
android:theme="@style/Theme.AppCompat.Light.Dialog"> android:theme="@style/Theme.AppCompat.Light.Dialog">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
@@ -101,6 +104,7 @@
<activity <activity
android:name=".widgets.activities.NumericalHabitPickerDialog" android:name=".widgets.activities.NumericalHabitPickerDialog"
android:exported="true"
android:theme="@style/Theme.AppCompat.Light.Dialog"> android:theme="@style/Theme.AppCompat.Light.Dialog">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
@@ -117,10 +121,11 @@
<activity <activity
android:name=".widgets.activities.NumericalCheckmarkWidgetActivity" android:name=".widgets.activities.NumericalCheckmarkWidgetActivity"
android:excludeFromRecents="true"
android:exported="true"
android:label="NumericalCheckmarkWidget" android:label="NumericalCheckmarkWidget"
android:noHistory="true" android:noHistory="true"
android:excludeFromRecents="true" android:theme="@style/Theme.Transparent">
android:theme="@style/Theme.AppCompat.Light.Dialog">
<intent-filter> <intent-filter>
<action android:name="org.isoron.uhabits.ACTION_SHOW_NUMERICAL_VALUE_ACTIVITY" /> <action android:name="org.isoron.uhabits.ACTION_SHOW_NUMERICAL_VALUE_ACTIVITY" />
</intent-filter> </intent-filter>
@@ -128,13 +133,14 @@
<activity <activity
android:name=".notifications.SnoozeDelayPickerActivity" android:name=".notifications.SnoozeDelayPickerActivity"
android:taskAffinity=""
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:launchMode="singleInstance" android:launchMode="singleInstance"
android:taskAffinity=""
android:theme="@android:style/Theme.Translucent.NoTitleBar" /> android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<receiver <receiver
android:name=".widgets.CheckmarkWidgetProvider" android:name=".widgets.CheckmarkWidgetProvider"
android:exported="true"
android:label="@string/checkmark"> android:label="@string/checkmark">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -152,6 +158,7 @@
<receiver <receiver
android:name=".widgets.HistoryWidgetProvider" android:name=".widgets.HistoryWidgetProvider"
android:exported="true"
android:label="@string/history"> android:label="@string/history">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -164,6 +171,7 @@
<receiver <receiver
android:name=".widgets.ScoreWidgetProvider" android:name=".widgets.ScoreWidgetProvider"
android:exported="true"
android:label="@string/score"> android:label="@string/score">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -176,6 +184,7 @@
<receiver <receiver
android:name=".widgets.StreakWidgetProvider" android:name=".widgets.StreakWidgetProvider"
android:exported="true"
android:label="@string/streaks"> android:label="@string/streaks">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -188,6 +197,7 @@
<receiver <receiver
android:name=".widgets.FrequencyWidgetProvider" android:name=".widgets.FrequencyWidgetProvider"
android:exported="true"
android:label="@string/frequency"> android:label="@string/frequency">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -200,6 +210,7 @@
<receiver <receiver
android:name=".widgets.TargetWidgetProvider" android:name=".widgets.TargetWidgetProvider"
android:exported="true"
android:label="@string/target"> android:label="@string/target">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -210,13 +221,17 @@
android:resource="@xml/widget_target_info" /> android:resource="@xml/widget_target_info" />
</receiver> </receiver>
<receiver android:name=".receivers.ReminderReceiver"> <receiver
android:name=".receivers.ReminderReceiver"
android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".receivers.WidgetReceiver"> <receiver android:name=".receivers.WidgetReceiver"
android:exported="true"
android:permission="false">
<intent-filter> <intent-filter>
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<action android:name="org.isoron.uhabits.ACTION_SET_NUMERICAL_VALUE" /> <action android:name="org.isoron.uhabits.ACTION_SET_NUMERICAL_VALUE" />
@@ -267,7 +282,7 @@
<!-- Locale/Tasker --> <!-- Locale/Tasker -->
<receiver <receiver
android:name=".automation.FireSettingReceiver" android:name=".automation.FireSettingReceiver"
android:exported="true"> android:exported="false">
<intent-filter> <intent-filter>
<action android:name="com.twofortyfouram.locale.intent.action.FIRE_SETTING" /> <action android:name="com.twofortyfouram.locale.intent.action.FIRE_SETTING" />
</intent-filter> </intent-filter>

View File

@@ -36,6 +36,7 @@ class AndroidCanvas : Canvas {
var innerDensity = 1.0 var innerDensity = 1.0
var innerWidth = 0 var innerWidth = 0
var innerHeight = 0 var innerHeight = 0
var mHeight = 15
var paint = Paint().apply { var paint = Paint().apply {
isAntiAlias = true isAntiAlias = true
@@ -64,11 +65,10 @@ class AndroidCanvas : Canvas {
} }
override fun drawText(text: String, x: Double, y: Double) { override fun drawText(text: String, x: Double, y: Double) {
textPaint.getTextBounds(text, 0, text.length, textBounds)
innerCanvas.drawText( innerCanvas.drawText(
text, text,
x.toDp(), x.toDp(),
y.toDp() - textBounds.exactCenterY(), y.toDp() + 0.6f * mHeight,
textPaint, textPaint,
) )
} }
@@ -126,10 +126,17 @@ class AndroidCanvas : Canvas {
Font.BOLD -> Typeface.DEFAULT_BOLD Font.BOLD -> Typeface.DEFAULT_BOLD
Font.FONT_AWESOME -> getFontAwesome(context) Font.FONT_AWESOME -> getFontAwesome(context)
} }
updateMHeight()
} }
override fun setFontSize(size: Double) { override fun setFontSize(size: Double) {
textPaint.textSize = size.toDp() textPaint.textSize = size.toDp()
updateMHeight()
}
private fun updateMHeight() {
textPaint.getTextBounds("m", 0, 1, textBounds)
mHeight = textBounds.height()
} }
override fun setStrokeWidth(size: Double) { override fun setStrokeWidth(size: Double) {

View File

@@ -49,23 +49,12 @@ class AndroidDataView(
override fun onShowPress(e: MotionEvent?) = Unit override fun onShowPress(e: MotionEvent?) = Unit
override fun onSingleTapUp(e: MotionEvent?): Boolean { override fun onSingleTapUp(e: MotionEvent?): Boolean {
val x: Float return handleClick(e, true)
val y: Float
try {
val pointerId = e!!.getPointerId(0)
x = e.getX(pointerId)
y = e.getY(pointerId)
} catch (ex: RuntimeException) {
// Android often throws IllegalArgumentException here. Apparently,
// the pointer id may become invalid shortly after calling
// e.getPointerId.
return false
}
view?.onClick(x / canvas.innerDensity, y / canvas.innerDensity)
return true
} }
override fun onLongPress(e: MotionEvent?) = Unit override fun onLongPress(e: MotionEvent?) {
handleClick(e)
}
override fun onScroll( override fun onScroll(
e1: MotionEvent?, e1: MotionEvent?,
@@ -137,4 +126,22 @@ class AndroidDataView(
} }
} }
} }
private fun handleClick(e: MotionEvent?, isSingleTap: Boolean = false): Boolean {
val x: Float
val y: Float
try {
val pointerId = e!!.getPointerId(0)
x = e.getX(pointerId)
y = e.getY(pointerId)
} catch (ex: RuntimeException) {
// Android often throws IllegalArgumentException here. Apparently,
// the pointer id may become invalid shortly after calling
// e.getPointerId.
return false
}
if (isSingleTap) view?.onClick(x / canvas.innerDensity, y / canvas.innerDensity)
else view?.onLongClick(x / canvas.innerDensity, y / canvas.innerDensity)
return true
}
} }

View File

@@ -30,6 +30,7 @@ import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.ui.ThemeSwitcher import org.isoron.uhabits.core.ui.ThemeSwitcher
import org.isoron.uhabits.core.ui.views.DarkTheme import org.isoron.uhabits.core.ui.views.DarkTheme
import org.isoron.uhabits.core.ui.views.LightTheme import org.isoron.uhabits.core.ui.views.LightTheme
import org.isoron.uhabits.core.ui.views.PureBlackTheme
import org.isoron.uhabits.core.ui.views.Theme import org.isoron.uhabits.core.ui.views.Theme
import org.isoron.uhabits.inject.ActivityContext import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.inject.ActivityScope import org.isoron.uhabits.inject.ActivityScope
@@ -66,7 +67,7 @@ constructor(
} }
override fun applyPureBlackTheme() { override fun applyPureBlackTheme() {
currentTheme = DarkTheme() currentTheme = PureBlackTheme()
context.setTheme(R.style.AppBaseThemeDark_PureBlack) context.setTheme(R.style.AppBaseThemeDark_PureBlack)
(context as Activity).window.navigationBarColor = (context as Activity).window.navigationBarColor =
ContextCompat.getColor(context, R.color.black) ContextCompat.getColor(context, R.color.black)

View File

@@ -26,6 +26,7 @@ import org.isoron.uhabits.BuildConfig
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.databinding.AboutBinding import org.isoron.uhabits.databinding.AboutBinding
import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.setupToolbar import org.isoron.uhabits.utils.setupToolbar
@SuppressLint("ViewConstructor") @SuppressLint("ViewConstructor")
@@ -41,7 +42,8 @@ class AboutView(
setupToolbar( setupToolbar(
toolbar = binding.toolbar, toolbar = binding.toolbar,
color = PaletteColor(11), color = PaletteColor(11),
title = resources.getString(R.string.about) title = resources.getString(R.string.about),
theme = currentTheme(),
) )
val version = resources.getString(R.string.version_n) val version = resources.getString(R.string.version_n)
binding.tvContributors.setOnClickListener { screen.showCodeContributorsWebsite() } binding.tvContributors.setOnClickListener { screen.showCodeContributorsWebsite() }

View File

@@ -0,0 +1,127 @@
/*
* Copyright (C) 2016-2021 Álinson Santos Xavier <git@axavier.org>
*
* 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.dialogs
import android.app.Dialog
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.Entry.Companion.NO
import org.isoron.uhabits.core.models.Entry.Companion.SKIP
import org.isoron.uhabits.core.models.Entry.Companion.UNKNOWN
import org.isoron.uhabits.core.models.Entry.Companion.YES_AUTO
import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.databinding.CheckmarkPopupBinding
import org.isoron.uhabits.utils.InterfaceUtils.getFontAwesome
import org.isoron.uhabits.utils.dimBehind
import org.isoron.uhabits.utils.dp
import org.isoron.uhabits.utils.sres
const val POPUP_WIDTH = 4 * 48f + 16f
const val POPUP_HEIGHT = 48f * 2.5f + 8f
class CheckmarkPopup(
private val context: Context,
private val color: Int,
private var notes: String,
private var value: Int,
private val prefs: Preferences,
private val anchor: View,
) {
var onToggle: (Int, String) -> Unit = { _, _ -> }
private lateinit var dialog: Dialog
private val view = CheckmarkPopupBinding.inflate(LayoutInflater.from(context)).apply {
// Required for round corners
container.clipToOutline = true
}
init {
view.booleanButtons.visibility = VISIBLE
initColors()
initTypefaces()
hideDisabledButtons()
populate()
}
private fun initColors() {
arrayOf(view.yesBtn, view.skipBtn).forEach {
it.setTextColor(color)
}
arrayOf(view.noBtn, view.unknownBtn).forEach {
it.setTextColor(view.root.sres.getColor(R.attr.contrast60))
}
}
private fun initTypefaces() {
arrayOf(view.yesBtn, view.noBtn, view.skipBtn, view.unknownBtn).forEach {
it.typeface = getFontAwesome(context)
}
}
private fun hideDisabledButtons() {
if (!prefs.isSkipEnabled) view.skipBtn.visibility = GONE
if (!prefs.areQuestionMarksEnabled) view.unknownBtn.visibility = GONE
}
private fun populate() {
val selectedBtn = when (value) {
YES_MANUAL -> view.yesBtn
YES_AUTO -> view.noBtn
NO -> view.noBtn
UNKNOWN -> if (prefs.areQuestionMarksEnabled) view.unknownBtn else view.noBtn
SKIP -> if (prefs.isSkipEnabled) view.skipBtn else view.noBtn
else -> null
}
view.notes.setText(notes)
}
fun show() {
dialog = Dialog(context, android.R.style.Theme_NoTitleBar)
dialog.setContentView(view.root)
dialog.window?.apply {
setLayout(
view.root.dp(POPUP_WIDTH).toInt(),
view.root.dp(POPUP_HEIGHT).toInt()
)
setBackgroundDrawableResource(android.R.color.transparent)
}
fun onClick(v: Int) {
this.value = v
save()
}
view.yesBtn.setOnClickListener { onClick(YES_MANUAL) }
view.noBtn.setOnClickListener { onClick(NO) }
view.skipBtn.setOnClickListener { onClick(SKIP) }
view.unknownBtn.setOnClickListener { onClick(UNKNOWN) }
dialog.setCanceledOnTouchOutside(true)
dialog.dimBehind()
dialog.show()
}
fun save() {
onToggle(value, view.notes.text.toString().trim())
dialog.dismiss()
}
}

View File

@@ -28,7 +28,7 @@ import org.isoron.uhabits.utils.toPaletteColor
class ColorPickerDialog : ColorPickerDialog() { class ColorPickerDialog : ColorPickerDialog() {
fun setListener(callback: OnColorPickedCallback) { fun setListener(callback: OnColorPickedCallback) {
super.setOnColorSelectedListener { c: Int -> super.setOnColorSelectedListener { c: Int ->
val pc = c.toPaletteColor(context!!) val pc = c.toPaletteColor(requireContext())
callback.onColorPicked(pc) callback.onColorPicked(pc)
} }
} }

View File

@@ -19,20 +19,21 @@
package org.isoron.uhabits.activities.common.dialogs package org.isoron.uhabits.activities.common.dialogs
import android.content.Context import android.content.Context
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.ui.views.Theme
import org.isoron.uhabits.inject.ActivityContext import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.inject.ActivityScope import org.isoron.uhabits.inject.ActivityScope
import org.isoron.uhabits.utils.StyledResources import org.isoron.uhabits.utils.StyledResources
import org.isoron.uhabits.utils.toThemedAndroidColor
import javax.inject.Inject import javax.inject.Inject
@ActivityScope @ActivityScope
class ColorPickerDialogFactory @Inject constructor(@param:ActivityContext private val context: Context) { class ColorPickerDialogFactory @Inject constructor(@param:ActivityContext private val context: Context) {
fun create(color: PaletteColor): ColorPickerDialog { fun create(color: PaletteColor, theme: Theme): ColorPickerDialog {
val dialog = ColorPickerDialog() val dialog = ColorPickerDialog()
val res = StyledResources(context) val res = StyledResources(context)
val androidColor = color.toThemedAndroidColor(context) val androidColor = theme.color(color).toInt()
dialog.initialize( dialog.initialize(
R.string.color_picker_default_title, R.string.color_picker_default_title,
res.getPalette(), res.getPalette(),

View File

@@ -21,7 +21,6 @@ package org.isoron.uhabits.activities.common.dialogs
import android.app.Dialog import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.EditText import android.widget.EditText
@@ -44,7 +43,7 @@ class FrequencyPickerDialog(
constructor() : this(1, 1) constructor() : this(1, 1)
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val inflater = LayoutInflater.from(activity!!) val inflater = LayoutInflater.from(requireActivity())
contentView = inflater.inflate(R.layout.frequency_picker_dialog, null) contentView = inflater.inflate(R.layout.frequency_picker_dialog, null)
addBeforeAfterText( addBeforeAfterText(
@@ -62,15 +61,19 @@ class FrequencyPickerDialog(
contentView.xTimesPerMonthContainer, contentView.xTimesPerMonthContainer,
) )
addBeforeAfterText(
this.getString(R.string.x_times_per_y_days),
contentView.xTimesPerYDaysContainer,
)
contentView.everyDayRadioButton.setOnClickListener { contentView.everyDayRadioButton.setOnClickListener {
check(contentView.everyDayRadioButton) check(contentView.everyDayRadioButton)
unfocusAll()
} }
contentView.everyXDaysRadioButton.setOnClickListener { contentView.everyXDaysRadioButton.setOnClickListener {
check(contentView.everyXDaysRadioButton) check(contentView.everyXDaysRadioButton)
val everyXDaysTextView = contentView.everyXDaysTextView val everyXDaysTextView = contentView.everyXDaysTextView
focus(everyXDaysTextView) selectInputField(everyXDaysTextView)
} }
contentView.everyXDaysTextView.setOnFocusChangeListener { v, hasFocus -> contentView.everyXDaysTextView.setOnFocusChangeListener { v, hasFocus ->
@@ -79,7 +82,7 @@ class FrequencyPickerDialog(
contentView.xTimesPerWeekRadioButton.setOnClickListener { contentView.xTimesPerWeekRadioButton.setOnClickListener {
check(contentView.xTimesPerWeekRadioButton) check(contentView.xTimesPerWeekRadioButton)
focus(contentView.xTimesPerWeekTextView) selectInputField(contentView.xTimesPerWeekTextView)
} }
contentView.xTimesPerWeekTextView.setOnFocusChangeListener { v, hasFocus -> contentView.xTimesPerWeekTextView.setOnFocusChangeListener { v, hasFocus ->
@@ -88,14 +91,27 @@ class FrequencyPickerDialog(
contentView.xTimesPerMonthRadioButton.setOnClickListener { contentView.xTimesPerMonthRadioButton.setOnClickListener {
check(contentView.xTimesPerMonthRadioButton) check(contentView.xTimesPerMonthRadioButton)
focus(contentView.xTimesPerMonthTextView) selectInputField(contentView.xTimesPerMonthTextView)
} }
contentView.xTimesPerMonthTextView.setOnFocusChangeListener { v, hasFocus -> contentView.xTimesPerMonthTextView.setOnFocusChangeListener { v, hasFocus ->
if (hasFocus) check(contentView.xTimesPerMonthRadioButton) if (hasFocus) check(contentView.xTimesPerMonthRadioButton)
} }
return AlertDialog.Builder(activity!!) contentView.xTimesPerYDaysRadioButton.setOnClickListener {
check(contentView.xTimesPerYDaysRadioButton)
selectInputField(contentView.xTimesPerYDaysXTextView)
}
contentView.xTimesPerYDaysXTextView.setOnFocusChangeListener { v, hasFocus ->
if (hasFocus) check(contentView.xTimesPerYDaysRadioButton)
}
contentView.xTimesPerYDaysYTextView.setOnFocusChangeListener { v, hasFocus ->
if (hasFocus) check(contentView.xTimesPerYDaysRadioButton)
}
return AlertDialog.Builder(requireActivity())
.setView(contentView) .setView(contentView)
.setPositiveButton(R.string.save) { _, _ -> onSaveClicked() } .setPositiveButton(R.string.save) { _, _ -> onSaveClicked() }
.create() .create()
@@ -106,12 +122,11 @@ class FrequencyPickerDialog(
container: LinearLayout container: LinearLayout
) { ) {
val parts = str.split("%d") val parts = str.split("%d")
container.addView( for (i in parts.indices) {
TextView(activity).apply { text = parts[0].trim() }, 1, container.addView(
) TextView(activity).apply { text = parts[i].trim() }, 2 * i + 1,
container.addView( )
TextView(activity).apply { text = parts[1].trim() }, 3, }
)
} }
private fun onSaveClicked() { private fun onSaveClicked() {
@@ -132,6 +147,12 @@ class FrequencyPickerDialog(
denominator = 7 denominator = 7
} }
} }
contentView.xTimesPerYDaysRadioButton.isChecked -> {
if (contentView.xTimesPerYDaysXTextView.text.isNotEmpty() && contentView.xTimesPerYDaysYTextView.text.isNotEmpty()) {
numerator = Integer.parseInt(contentView.xTimesPerYDaysXTextView.text.toString())
denominator = Integer.parseInt(contentView.xTimesPerYDaysYTextView.text.toString())
}
}
else -> { else -> {
if (contentView.xTimesPerMonthTextView.text.isNotEmpty()) { if (contentView.xTimesPerMonthTextView.text.isNotEmpty()) {
numerator = Integer.parseInt(contentView.xTimesPerMonthTextView.text.toString()) numerator = Integer.parseInt(contentView.xTimesPerMonthTextView.text.toString())
@@ -147,10 +168,10 @@ class FrequencyPickerDialog(
dismiss() dismiss()
} }
private fun check(view: RadioButton?) { private fun check(view: RadioButton) {
uncheckAll() uncheckAll()
view?.isChecked = true view.isChecked = true
view?.requestFocus() view.requestFocus()
} }
override fun onResume() { override fun onResume() {
@@ -160,32 +181,34 @@ class FrequencyPickerDialog(
private fun populateViews() { private fun populateViews() {
uncheckAll() uncheckAll()
if (freqNumerator == 1) { if (freqDenominator == 30 || freqDenominator == 31) {
if (freqDenominator == 1) { contentView.xTimesPerMonthRadioButton.isChecked = true
contentView.everyDayRadioButton.isChecked = true contentView.xTimesPerMonthTextView.setText(freqNumerator.toString())
} else { selectInputField(contentView.xTimesPerMonthTextView)
contentView.everyXDaysRadioButton.isChecked = true
contentView.everyXDaysTextView.setText(freqDenominator.toString())
focus(contentView.everyXDaysTextView)
}
} else { } else {
if (freqDenominator == 7) { if (freqNumerator == 1) {
contentView.xTimesPerWeekRadioButton.isChecked = true if (freqDenominator == 1) {
contentView.xTimesPerWeekTextView.setText(freqNumerator.toString()) contentView.everyDayRadioButton.isChecked = true
focus(contentView.xTimesPerWeekTextView) } else {
} else if (freqDenominator == 30 || freqDenominator == 31) { contentView.everyXDaysRadioButton.isChecked = true
contentView.xTimesPerMonthRadioButton.isChecked = true contentView.everyXDaysTextView.setText(freqDenominator.toString())
contentView.xTimesPerMonthTextView.setText(freqNumerator.toString()) selectInputField(contentView.everyXDaysTextView)
focus(contentView.xTimesPerMonthTextView) }
} else { } else {
Log.w("FrequencyPickerDialog", "Unknown frequency: $freqNumerator/$freqDenominator") if (freqDenominator == 7) {
contentView.everyDayRadioButton.isChecked = true contentView.xTimesPerWeekRadioButton.isChecked = true
contentView.xTimesPerWeekTextView.setText(freqNumerator.toString())
selectInputField(contentView.xTimesPerWeekTextView)
} else {
contentView.xTimesPerYDaysRadioButton.isChecked = true
contentView.xTimesPerYDaysXTextView.setText(freqNumerator.toString())
contentView.xTimesPerYDaysYTextView.setText(freqDenominator.toString())
}
} }
} }
} }
private fun focus(view: EditText) { private fun selectInputField(view: EditText) {
view.requestFocus()
view.setSelection(view.text.length) view.setSelection(view.text.length)
} }
@@ -194,11 +217,6 @@ class FrequencyPickerDialog(
contentView.everyXDaysRadioButton.isChecked = false contentView.everyXDaysRadioButton.isChecked = false
contentView.xTimesPerWeekRadioButton.isChecked = false contentView.xTimesPerWeekRadioButton.isChecked = false
contentView.xTimesPerMonthRadioButton.isChecked = false contentView.xTimesPerMonthRadioButton.isChecked = false
} contentView.xTimesPerYDaysRadioButton.isChecked = false
private fun unfocusAll() {
contentView.everyXDaysTextView.clearFocus()
contentView.xTimesPerWeekTextView.clearFocus()
contentView.xTimesPerMonthTextView.clearFocus()
} }
} }

View File

@@ -43,18 +43,18 @@ class HistoryEditorDialog : AppCompatDialogFragment(), CommandRunner.Listener {
private lateinit var commandRunner: CommandRunner private lateinit var commandRunner: CommandRunner
private lateinit var habit: Habit private lateinit var habit: Habit
private lateinit var preferences: Preferences private lateinit var preferences: Preferences
private lateinit var dataView: AndroidDataView lateinit var dataView: AndroidDataView
private var chart: HistoryChart? = null private var chart: HistoryChart? = null
private var onDateClickedListener: OnDateClickedListener? = null private var onDateClickedListener: OnDateClickedListener? = null
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val component = (activity!!.application as HabitsApplication).component val component = (requireActivity().application as HabitsApplication).component
commandRunner = component.commandRunner commandRunner = component.commandRunner
habit = component.habitList.getById(arguments!!.getLong("habit"))!! habit = component.habitList.getById(requireArguments().getLong("habit"))!!
preferences = component.preferences preferences = component.preferences
val themeSwitcher = AndroidThemeSwitcher(activity!!, preferences) val themeSwitcher = AndroidThemeSwitcher(requireActivity(), preferences)
themeSwitcher.apply() themeSwitcher.apply()
chart = HistoryChart( chart = HistoryChart(
@@ -62,15 +62,17 @@ class HistoryEditorDialog : AppCompatDialogFragment(), CommandRunner.Listener {
firstWeekday = preferences.firstWeekday, firstWeekday = preferences.firstWeekday,
paletteColor = habit.color, paletteColor = habit.color,
series = emptyList(), series = emptyList(),
defaultSquare = HistoryChart.Square.OFF,
notesIndicators = emptyList(),
theme = themeSwitcher.currentTheme, theme = themeSwitcher.currentTheme,
today = DateUtils.getTodayWithOffset().toLocalDate(), today = DateUtils.getTodayWithOffset().toLocalDate(),
onDateClickedListener = onDateClickedListener ?: OnDateClickedListener { }, onDateClickedListener = onDateClickedListener ?: object : OnDateClickedListener {},
padding = 10.0, padding = 10.0,
) )
dataView = AndroidDataView(context!!, null) dataView = AndroidDataView(requireContext(), null)
dataView.view = chart!! dataView.view = chart!!
return Dialog(context!!).apply { return Dialog(requireContext()).apply {
val metrics = resources.displayMetrics val metrics = resources.displayMetrics
val maxHeight = resources.getDimensionPixelSize(R.dimen.history_editor_max_height) val maxHeight = resources.getDimensionPixelSize(R.dimen.history_editor_max_height)
setContentView(dataView) setContentView(dataView)
@@ -101,6 +103,8 @@ class HistoryEditorDialog : AppCompatDialogFragment(), CommandRunner.Listener {
theme = LightTheme() theme = LightTheme()
) )
chart?.series = model.series chart?.series = model.series
chart?.defaultSquare = model.defaultSquare
chart?.notesIndicators = model.notesIndicators
dataView.postInvalidate() dataView.postInvalidate()
} }

View File

@@ -1,108 +0,0 @@
/*
* Copyright (C) 2016-2021 Álinson Santos Xavier <git@axavier.org>
*
* 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.dialogs
import android.content.Context
import android.content.DialogInterface
import android.text.InputFilter
import android.view.LayoutInflater
import android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import android.widget.NumberPicker
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import org.isoron.uhabits.R
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.utils.InterfaceUtils
import javax.inject.Inject
import kotlin.math.roundToLong
class NumberPickerFactory
@Inject constructor(
@ActivityContext private val context: Context
) {
fun create(
value: Double,
unit: String,
callback: ListHabitsBehavior.NumberPickerCallback
): AlertDialog {
val inflater = LayoutInflater.from(context)
val view = inflater.inflate(R.layout.number_picker_dialog, null)
val picker = view.findViewById<NumberPicker>(R.id.picker)
val picker2 = view.findViewById<NumberPicker>(R.id.picker2)
val tvUnit = view.findViewById<TextView>(R.id.tvUnit)
val intValue = (value * 100).roundToLong().toInt()
picker.minValue = 0
picker.maxValue = Integer.MAX_VALUE / 100
picker.value = intValue / 100
picker.wrapSelectorWheel = false
picker2.minValue = 0
picker2.maxValue = 19
picker2.setFormatter { v -> String.format("%02d", 5 * v) }
picker2.value = intValue % 100 / 5
refreshInitialValue(picker2)
tvUnit.text = unit
val dialog = AlertDialog.Builder(context)
.setView(view)
.setTitle(R.string.change_value)
.setPositiveButton(android.R.string.ok) { _, _ ->
picker.clearFocus()
val v = picker.value + 0.05 * picker2.value
callback.onNumberPicked(v)
}
.setOnDismissListener {
callback.onNumberPickerDismissed()
}
.create()
dialog.setOnShowListener {
picker.getChildAt(0)?.requestFocus()
dialog.window?.setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_VISIBLE)
}
InterfaceUtils.setupEditorAction(
picker
) { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE)
dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick()
false
}
return dialog
}
private fun refreshInitialValue(picker: NumberPicker) {
// Workaround for Android bug:
// https://code.google.com/p/android/issues/detail?id=35482
val f = NumberPicker::class.java.getDeclaredField("mInputText")
f.isAccessible = true
val inputText = f.get(picker) as EditText
inputText.filters = arrayOfNulls<InputFilter>(0)
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (C) 2016-2021 Álinson Santos Xavier <git@axavier.org>
*
* 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.dialogs
import android.app.Dialog
import android.content.Context
import android.view.KeyEvent.KEYCODE_ENTER
import android.view.LayoutInflater
import android.view.MotionEvent.ACTION_DOWN
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.databinding.CheckmarkPopupBinding
import org.isoron.uhabits.utils.dimBehind
import org.isoron.uhabits.utils.dp
import org.isoron.uhabits.utils.requestFocusWithKeyboard
import java.text.DecimalFormat
class NumberPopup(
private val context: Context,
private var notes: String,
private var value: Double,
private val prefs: Preferences,
private val anchor: View,
) {
var onToggle: (Double, String) -> Unit = { _, _ -> }
private val originalValue = value
private lateinit var dialog: Dialog
private val view = CheckmarkPopupBinding.inflate(LayoutInflater.from(context)).apply {
// Required for round corners
container.clipToOutline = true
}
init {
view.numberButtons.visibility = VISIBLE
hideDisabledButtons()
populate()
}
private fun hideDisabledButtons() {
if (!prefs.isSkipEnabled) view.skipBtnNumber.visibility = GONE
}
private fun populate() {
view.notes.setText(notes)
view.value.setText(
when {
value < 0.01 -> "0"
else -> DecimalFormat("#.##").format(value)
}
)
}
fun show() {
dialog = Dialog(context, android.R.style.Theme_NoTitleBar)
dialog.setContentView(view.root)
dialog.window?.apply {
setLayout(
view.root.dp(POPUP_WIDTH).toInt(),
view.root.dp(POPUP_HEIGHT).toInt()
)
setBackgroundDrawableResource(android.R.color.transparent)
}
view.value.setOnKeyListener { _, keyCode, event ->
if (event.action == ACTION_DOWN && keyCode == KEYCODE_ENTER) {
save()
return@setOnKeyListener true
}
return@setOnKeyListener false
}
view.saveBtn.setOnClickListener {
save()
}
view.skipBtnNumber.setOnClickListener {
view.value.setText((Entry.SKIP.toDouble() / 1000).toString())
save()
}
view.value.requestFocusWithKeyboard()
dialog.setCanceledOnTouchOutside(true)
dialog.dimBehind()
dialog.show()
}
fun save() {
val value = view.value.text.toString().toDoubleOrNull() ?: originalValue
val notes = view.notes.text.toString()
onToggle(value, notes)
dialog.dismiss()
}
}

View File

@@ -60,7 +60,7 @@ class WeekdayPickerDialog :
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder( val builder = AlertDialog.Builder(
activity!! requireActivity()
) )
builder builder
.setTitle(R.string.select_weekdays) .setTitle(R.string.select_weekdays)

View File

@@ -41,7 +41,7 @@ class BundleSavedState : AbsSavedState {
} }
companion object { companion object {
val CREATOR: Parcelable.Creator<BundleSavedState> = @JvmField val CREATOR: Parcelable.Creator<BundleSavedState> =
object : ClassLoaderCreator<BundleSavedState> { object : ClassLoaderCreator<BundleSavedState> {
override fun createFromParcel( override fun createFromParcel(
source: Parcel, source: Parcel,

View File

@@ -29,6 +29,7 @@ import org.isoron.uhabits.core.utils.DateUtils.Companion.getShortWeekdayNames
import org.isoron.uhabits.core.utils.DateUtils.Companion.getStartOfTodayCalendar import org.isoron.uhabits.core.utils.DateUtils.Companion.getStartOfTodayCalendar
import org.isoron.uhabits.core.utils.DateUtils.Companion.getStartOfTodayCalendarWithOffset import org.isoron.uhabits.core.utils.DateUtils.Companion.getStartOfTodayCalendarWithOffset
import org.isoron.uhabits.core.utils.DateUtils.Companion.getWeekdaySequence import org.isoron.uhabits.core.utils.DateUtils.Companion.getWeekdaySequence
import org.isoron.uhabits.core.utils.DateUtils.Companion.getWeekdaysInMonth
import org.isoron.uhabits.utils.ColorUtils.mixColors import org.isoron.uhabits.utils.ColorUtils.mixColors
import org.isoron.uhabits.utils.StyledResources import org.isoron.uhabits.utils.StyledResources
import org.isoron.uhabits.utils.toSimpleDataFormat import org.isoron.uhabits.utils.toSimpleDataFormat
@@ -62,7 +63,6 @@ class FrequencyChart : ScrollableChart {
private var primaryColor = 0 private var primaryColor = 0
private var isBackgroundTransparent = false private var isBackgroundTransparent = false
private lateinit var frequency: HashMap<Timestamp, Array<Int>> private lateinit var frequency: HashMap<Timestamp, Array<Int>>
private var maxFreq = 0
private var firstWeekday = Calendar.SUNDAY private var firstWeekday = Calendar.SUNDAY
constructor(context: Context?) : super(context) { constructor(context: Context?) : super(context) {
@@ -82,7 +82,6 @@ class FrequencyChart : ScrollableChart {
fun setFrequency(frequency: java.util.HashMap<Timestamp, Array<Int>>) { fun setFrequency(frequency: java.util.HashMap<Timestamp, Array<Int>>) {
this.frequency = frequency this.frequency = frequency
maxFreq = getMaxFreq(frequency)
postInvalidate() postInvalidate()
} }
@@ -91,15 +90,6 @@ class FrequencyChart : ScrollableChart {
postInvalidate() postInvalidate()
} }
private fun getMaxFreq(frequency: HashMap<Timestamp, Array<Int>>): Int {
var maxValue = 1
for (values in frequency.values) for (value in values) maxValue = max(
value,
maxValue
)
return maxValue
}
fun setIsBackgroundTransparent(isBackgroundTransparent: Boolean) { fun setIsBackgroundTransparent(isBackgroundTransparent: Boolean) {
this.isBackgroundTransparent = isBackgroundTransparent this.isBackgroundTransparent = isBackgroundTransparent
initColors() initColors()
@@ -166,6 +156,7 @@ class FrequencyChart : ScrollableChart {
private fun drawColumn(canvas: Canvas, rect: RectF?, date: GregorianCalendar) { private fun drawColumn(canvas: Canvas, rect: RectF?, date: GregorianCalendar) {
val values = frequency[Timestamp(date)] val values = frequency[Timestamp(date)]
val weekDaysInMonth = getWeekdaysInMonth(Timestamp(date))
val rowHeight = rect!!.height() / 8.0f val rowHeight = rect!!.height() / 8.0f
prevRect!!.set(rect) prevRect!!.set(rect)
val localeWeekdayList: Array<Int> = getWeekdaySequence(firstWeekday) val localeWeekdayList: Array<Int> = getWeekdaySequence(firstWeekday)
@@ -173,7 +164,8 @@ class FrequencyChart : ScrollableChart {
rect[0f, 0f, baseSize.toFloat()] = baseSize.toFloat() rect[0f, 0f, baseSize.toFloat()] = baseSize.toFloat()
rect.offset(prevRect!!.left, prevRect!!.top + baseSize * j) rect.offset(prevRect!!.left, prevRect!!.top + baseSize * j)
val i = localeWeekdayList[j] % 7 val i = localeWeekdayList[j] % 7
if (values != null) drawMarker(canvas, rect, values[i]) if (values != null)
drawMarker(canvas, rect, values[i], weekDaysInMonth[i])
rect.offset(0f, rowHeight) rect.offset(0f, rowHeight)
} }
drawFooter(canvas, rect, date) drawFooter(canvas, rect, date)
@@ -221,12 +213,16 @@ class FrequencyChart : ScrollableChart {
canvas.drawLine(rGrid.left, rGrid.top, rGrid.right, rGrid.top, pGrid!!) canvas.drawLine(rGrid.left, rGrid.top, rGrid.right, rGrid.top, pGrid!!)
} }
private fun drawMarker(canvas: Canvas, rect: RectF?, value: Int?) { private fun drawMarker(canvas: Canvas, rect: RectF?, value: Int?, frequency: Int) {
// value can be negative when the entry is skipped
val valueCopy = value?.let { max(0, it) }
val padding = rect!!.height() * 0.2f val padding = rect!!.height() * 0.2f
// maximal allowed mark radius // maximal allowed mark radius
val maxRadius = (rect.height() - 2 * padding) / 2.0f val maxRadius = (rect.height() - 2 * padding) / 2.0f
// the real mark radius is scaled down by a factor depending on the maximal frequency // the real mark radius is scaled down by a factor depending on the maximal frequency
val scale = 1.0f / maxFreq * value!!
val scale = 1.0f / frequency * valueCopy!!
val radius = maxRadius * scale val radius = maxRadius * scale
val colorIndex = min((colors.size - 1), ((colors.size - 1) * scale).roundToInt()) val colorIndex = min((colors.size - 1), ((colors.size - 1) * scale).roundToInt())
pGraph!!.color = colors[colorIndex] pGraph!!.color = colors[colorIndex]
@@ -289,6 +285,5 @@ class FrequencyChart : ScrollableChart {
frequency[Timestamp(date)] = values frequency[Timestamp(date)] = values
date.add(Calendar.MONTH, -1) date.add(Calendar.MONTH, -1)
} }
maxFreq = getMaxFreq(frequency)
} }
} }

View File

@@ -41,6 +41,7 @@ import org.isoron.uhabits.utils.InterfaceUtils.getFontAwesome
import org.isoron.uhabits.utils.InterfaceUtils.spToPixels import org.isoron.uhabits.utils.InterfaceUtils.spToPixels
import org.isoron.uhabits.utils.PaletteUtils.getAndroidTestColor import org.isoron.uhabits.utils.PaletteUtils.getAndroidTestColor
import org.isoron.uhabits.utils.StyledResources import org.isoron.uhabits.utils.StyledResources
import kotlin.math.max
import kotlin.math.min import kotlin.math.min
import kotlin.math.roundToLong import kotlin.math.roundToLong
@@ -48,7 +49,7 @@ class RingView : View {
private var color: Int private var color: Int
private var precision: Float private var precision: Float
private var percentage: Float private var percentage: Float
private var diameter = 0 private var diameter = 1
private var thickness: Float private var thickness: Float
private var rect: RectF? = null private var rect: RectF? = null
private var pRing: TextPaint? = null private var pRing: TextPaint? = null
@@ -169,7 +170,7 @@ class RingView : View {
super.onMeasure(widthMeasureSpec, heightMeasureSpec) super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val width = MeasureSpec.getSize(widthMeasureSpec) val width = MeasureSpec.getSize(widthMeasureSpec)
val height = MeasureSpec.getSize(heightMeasureSpec) val height = MeasureSpec.getSize(heightMeasureSpec)
diameter = min(height, width) diameter = max(1, min(height, width))
pRing!!.textSize = textSize pRing!!.textSize = textSize
em = pRing!!.measureText("M") em = pRing!!.measureText("M")
setMeasuredDimension(diameter, diameter) setMeasuredDimension(diameter, diameter)

View File

@@ -117,7 +117,11 @@ class TargetChart : View {
barRect[rect.left + stop + padding, rect.top + baseSize * 0.05f, rect.right - padding] = barRect[rect.left + stop + padding, rect.top + baseSize * 0.05f, rect.right - padding] =
rect.bottom - baseSize * 0.05f rect.bottom - baseSize * 0.05f
canvas.drawRoundRect(barRect, round, round, paint!!) canvas.drawRoundRect(barRect, round, round, paint!!)
var percentage = (values[row] / targets[row]).toFloat() var percentage = if (targets[row] > 0) {
(values[row] / targets[row]).toFloat()
} else {
1.0f
}
percentage = min(1.0f, percentage) percentage = min(1.0f, percentage)
// Draw completed box // Draw completed box

View File

@@ -29,10 +29,10 @@ class TaskProgressBar(
context: Context, context: Context,
private val runner: TaskRunner private val runner: TaskRunner
) : ProgressBar( ) : ProgressBar(
context, context,
null, null,
android.R.attr.progressBarStyleHorizontal android.R.attr.progressBarStyleHorizontal
), ),
TaskRunner.Listener { TaskRunner.Listener {
init { init {

View File

@@ -21,6 +21,7 @@ package org.isoron.uhabits.activities.habits.edit
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.content.res.Resources
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.text.Html import android.text.Html
@@ -39,6 +40,7 @@ import kotlinx.android.synthetic.main.activity_edit_habit.notesInput
import kotlinx.android.synthetic.main.activity_edit_habit.questionInput import kotlinx.android.synthetic.main.activity_edit_habit.questionInput
import kotlinx.android.synthetic.main.activity_edit_habit.targetInput import kotlinx.android.synthetic.main.activity_edit_habit.targetInput
import kotlinx.android.synthetic.main.activity_edit_habit.unitInput import kotlinx.android.synthetic.main.activity_edit_habit.unitInput
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.HabitsApplication import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher import org.isoron.uhabits.activities.AndroidThemeSwitcher
@@ -50,6 +52,8 @@ import org.isoron.uhabits.core.commands.CreateHabitCommand
import org.isoron.uhabits.core.commands.EditHabitCommand import org.isoron.uhabits.core.commands.EditHabitCommand
import org.isoron.uhabits.core.models.Frequency import org.isoron.uhabits.core.models.Frequency
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.HabitType
import org.isoron.uhabits.core.models.NumericalHabitType
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.models.Reminder import org.isoron.uhabits.core.models.Reminder
import org.isoron.uhabits.core.models.WeekdayList import org.isoron.uhabits.core.models.WeekdayList
@@ -57,7 +61,16 @@ import org.isoron.uhabits.databinding.ActivityEditHabitBinding
import org.isoron.uhabits.utils.ColorUtils import org.isoron.uhabits.utils.ColorUtils
import org.isoron.uhabits.utils.formatTime import org.isoron.uhabits.utils.formatTime
import org.isoron.uhabits.utils.toFormattedString import org.isoron.uhabits.utils.toFormattedString
import org.isoron.uhabits.utils.toThemedAndroidColor
fun formatFrequency(freqNum: Int, freqDen: Int, resources: Resources) = when {
freqNum == 1 && (freqDen == 30 || freqDen == 31) -> resources.getString(R.string.every_month)
freqDen == 30 || freqDen == 31 -> resources.getString(R.string.x_times_per_month, freqNum)
freqNum == 1 && freqDen == 1 -> resources.getString(R.string.every_day)
freqNum == 1 && freqDen == 7 -> resources.getString(R.string.every_week)
freqNum == 1 && freqDen > 1 -> resources.getString(R.string.every_x_days, freqDen)
freqDen == 7 -> resources.getString(R.string.x_times_per_week, freqNum)
else -> resources.getString(R.string.x_times_per_y_days, freqNum, freqDen)
}
class EditHabitActivity : AppCompatActivity() { class EditHabitActivity : AppCompatActivity() {
@@ -66,7 +79,7 @@ class EditHabitActivity : AppCompatActivity() {
private lateinit var commandRunner: CommandRunner private lateinit var commandRunner: CommandRunner
var habitId = -1L var habitId = -1L
var habitType = -1 lateinit var habitType: HabitType
var unit = "" var unit = ""
var color = PaletteColor(11) var color = PaletteColor(11)
var androidColor = 0 var androidColor = 0
@@ -75,6 +88,7 @@ class EditHabitActivity : AppCompatActivity() {
var reminderHour = -1 var reminderHour = -1
var reminderMin = -1 var reminderMin = -1
var reminderDays: WeekdayList = WeekdayList.EVERY_DAY var reminderDays: WeekdayList = WeekdayList.EVERY_DAY
var targetType = NumericalHabitType.AT_LEAST
override fun onCreate(state: Bundle?) { override fun onCreate(state: Bundle?) {
super.onCreate(state) super.onCreate(state)
@@ -94,6 +108,7 @@ class EditHabitActivity : AppCompatActivity() {
color = habit.color color = habit.color
freqNum = habit.frequency.numerator freqNum = habit.frequency.numerator
freqDen = habit.frequency.denominator freqDen = habit.frequency.denominator
targetType = habit.targetType
habit.reminder?.let { habit.reminder?.let {
reminderHour = it.hour reminderHour = it.hour
reminderMin = it.minute reminderMin = it.minute
@@ -105,12 +120,12 @@ class EditHabitActivity : AppCompatActivity() {
binding.unitInput.setText(habit.unit) binding.unitInput.setText(habit.unit)
binding.targetInput.setText(habit.targetValue.toString()) binding.targetInput.setText(habit.targetValue.toString())
} else { } else {
habitType = intent.getIntExtra("habitType", Habit.YES_NO_HABIT) habitType = HabitType.fromInt(intent.getIntExtra("habitType", HabitType.YES_NO.value))
} }
if (state != null) { if (state != null) {
habitId = state.getLong("habitId") habitId = state.getLong("habitId")
habitType = state.getInt("habitType") habitType = HabitType.fromInt(state.getInt("habitType"))
color = PaletteColor(state.getInt("paletteColor")) color = PaletteColor(state.getInt("paletteColor"))
freqNum = state.getInt("freqNum") freqNum = state.getInt("freqNum")
freqDen = state.getInt("freqDen") freqDen = state.getInt("freqDen")
@@ -121,13 +136,17 @@ class EditHabitActivity : AppCompatActivity() {
updateColors() updateColors()
if (habitType == Habit.YES_NO_HABIT) { when (habitType) {
binding.unitOuterBox.visibility = View.GONE HabitType.YES_NO -> {
binding.targetOuterBox.visibility = View.GONE binding.unitOuterBox.visibility = View.GONE
} else { binding.targetOuterBox.visibility = View.GONE
binding.nameInput.hint = getString(R.string.measurable_short_example) binding.targetTypeOuterBox.visibility = View.GONE
binding.questionInput.hint = getString(R.string.measurable_question_example) }
binding.frequencyOuterBox.visibility = View.GONE HabitType.NUMERICAL -> {
binding.nameInput.hint = getString(R.string.measurable_short_example)
binding.questionInput.hint = getString(R.string.measurable_question_example)
binding.frequencyOuterBox.visibility = View.GONE
}
} }
setSupportActionBar(binding.toolbar) setSupportActionBar(binding.toolbar)
@@ -137,7 +156,7 @@ class EditHabitActivity : AppCompatActivity() {
val colorPickerDialogFactory = ColorPickerDialogFactory(this) val colorPickerDialogFactory = ColorPickerDialogFactory(this)
binding.colorButton.setOnClickListener { binding.colorButton.setOnClickListener {
val dialog = colorPickerDialogFactory.create(color) val dialog = colorPickerDialogFactory.create(color, themeSwitcher.currentTheme)
dialog.setListener { paletteColor -> dialog.setListener { paletteColor ->
this.color = paletteColor this.color = paletteColor
updateColors() updateColors()
@@ -156,6 +175,23 @@ class EditHabitActivity : AppCompatActivity() {
dialog.show(supportFragmentManager, "frequencyPicker") dialog.show(supportFragmentManager, "frequencyPicker")
} }
populateTargetType()
binding.targetTypePicker.setOnClickListener {
val builder = AlertDialog.Builder(this)
val arrayAdapter = ArrayAdapter<String>(this, android.R.layout.select_dialog_item)
arrayAdapter.add(getString(R.string.target_type_at_least))
arrayAdapter.add(getString(R.string.target_type_at_most))
builder.setAdapter(arrayAdapter) { dialog, which ->
targetType = when (which) {
0 -> NumericalHabitType.AT_LEAST
else -> NumericalHabitType.AT_MOST
}
populateTargetType()
dialog.dismiss()
}
builder.show()
}
binding.numericalFrequencyPicker.setOnClickListener { binding.numericalFrequencyPicker.setOnClickListener {
val builder = AlertDialog.Builder(this) val builder = AlertDialog.Builder(this)
val arrayAdapter = ArrayAdapter<String>(this, android.R.layout.select_dialog_item) val arrayAdapter = ArrayAdapter<String>(this, android.R.layout.select_dialog_item)
@@ -244,9 +280,9 @@ class EditHabitActivity : AppCompatActivity() {
} }
habit.frequency = Frequency(freqNum, freqDen) habit.frequency = Frequency(freqNum, freqDen)
if (habitType == Habit.NUMBER_HABIT) { if (habitType == HabitType.NUMERICAL) {
habit.targetValue = targetInput.text.toString().toDouble() habit.targetValue = targetInput.text.toString().toDouble()
habit.targetType = Habit.AT_LEAST habit.targetType = targetType
habit.unit = unitInput.text.trim().toString() habit.unit = unitInput.text.trim().toString()
} }
habit.type = habitType habit.type = habitType
@@ -274,7 +310,7 @@ class EditHabitActivity : AppCompatActivity() {
nameInput.error = getFormattedValidationError(R.string.validation_cannot_be_blank) nameInput.error = getFormattedValidationError(R.string.validation_cannot_be_blank)
isValid = false isValid = false
} }
if (habitType == Habit.NUMBER_HABIT) { if (habitType == HabitType.NUMERICAL) {
if (targetInput.text.isEmpty()) { if (targetInput.text.isEmpty()) {
targetInput.error = getString(R.string.validation_cannot_be_blank) targetInput.error = getString(R.string.validation_cannot_be_blank)
isValid = false isValid = false
@@ -299,14 +335,7 @@ class EditHabitActivity : AppCompatActivity() {
@SuppressLint("StringFormatMatches") @SuppressLint("StringFormatMatches")
private fun populateFrequency() { private fun populateFrequency() {
binding.booleanFrequencyPicker.text = when { binding.booleanFrequencyPicker.text = formatFrequency(freqNum, freqDen, resources)
freqNum == 1 && freqDen == 1 -> getString(R.string.every_day)
freqNum == 1 && freqDen == 7 -> getString(R.string.every_week)
freqNum == 1 && freqDen > 1 -> getString(R.string.every_x_days, freqDen)
freqDen == 7 -> getString(R.string.x_times_per_week, freqNum)
freqDen == 30 || freqDen == 31 -> getString(R.string.x_times_per_month, freqNum)
else -> "$freqNum/$freqDen"
}
binding.numericalFrequencyPicker.text = when (freqDen) { binding.numericalFrequencyPicker.text = when (freqDen) {
1 -> getString(R.string.every_day) 1 -> getString(R.string.every_day)
7 -> getString(R.string.every_week) 7 -> getString(R.string.every_week)
@@ -315,8 +344,15 @@ class EditHabitActivity : AppCompatActivity() {
} }
} }
private fun populateTargetType() {
binding.targetTypePicker.text = when (targetType) {
NumericalHabitType.AT_MOST -> getString(R.string.target_type_at_most)
else -> getString(R.string.target_type_at_least)
}
}
private fun updateColors() { private fun updateColors() {
androidColor = color.toThemedAndroidColor(this) androidColor = themeSwitcher.currentTheme.color(color).toInt()
binding.colorButton.backgroundTintList = ColorStateList.valueOf(androidColor) binding.colorButton.backgroundTintList = ColorStateList.valueOf(androidColor)
if (!themeSwitcher.isNightMode) { if (!themeSwitcher.isNightMode) {
val darkerAndroidColor = ColorUtils.mixColors(Color.BLACK, androidColor, 0.15f) val darkerAndroidColor = ColorUtils.mixColors(Color.BLACK, androidColor, 0.15f)
@@ -334,7 +370,7 @@ class EditHabitActivity : AppCompatActivity() {
super.onSaveInstanceState(state) super.onSaveInstanceState(state)
with(state) { with(state) {
putLong("habitId", habitId) putLong("habitId", habitId)
putInt("habitType", habitType) putInt("habitType", habitType.value)
putInt("paletteColor", color.paletteIndex) putInt("paletteColor", color.paletteIndex)
putInt("androidColor", androidColor) putInt("androidColor", androidColor)
putInt("freqNum", freqNum) putInt("freqNum", freqNum)

View File

@@ -25,7 +25,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AppCompatDialogFragment import androidx.appcompat.app.AppCompatDialogFragment
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.HabitType
import org.isoron.uhabits.databinding.SelectHabitTypeBinding import org.isoron.uhabits.databinding.SelectHabitTypeBinding
import org.isoron.uhabits.intents.IntentFactory import org.isoron.uhabits.intents.IntentFactory
@@ -40,13 +40,13 @@ class HabitTypeDialog : AppCompatDialogFragment() {
val binding = SelectHabitTypeBinding.inflate(inflater, container, false) val binding = SelectHabitTypeBinding.inflate(inflater, container, false)
binding.buttonYesNo.setOnClickListener { binding.buttonYesNo.setOnClickListener {
val intent = IntentFactory().startEditActivity(activity!!, Habit.YES_NO_HABIT) val intent = IntentFactory().startEditActivity(requireActivity(), HabitType.YES_NO.value)
startActivity(intent) startActivity(intent)
dismiss() dismiss()
} }
binding.buttonMeasurable.setOnClickListener { binding.buttonMeasurable.setOnClickListener {
val intent = IntentFactory().startEditActivity(activity!!, Habit.NUMBER_HABIT) val intent = IntentFactory().startEditActivity(requireActivity(), HabitType.NUMERICAL.value)
startActivity(intent) startActivity(intent)
dismiss() dismiss()
} }

View File

@@ -38,7 +38,7 @@ import org.isoron.uhabits.inject.ActivityContextModule
import org.isoron.uhabits.inject.DaggerHabitsActivityComponent import org.isoron.uhabits.inject.DaggerHabitsActivityComponent
import org.isoron.uhabits.utils.restartWithFade import org.isoron.uhabits.utils.restartWithFade
class ListHabitsActivity : AppCompatActivity() { class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
var pureBlack: Boolean = false var pureBlack: Boolean = false
lateinit var taskRunner: TaskRunner lateinit var taskRunner: TaskRunner
@@ -51,6 +51,11 @@ class ListHabitsActivity : AppCompatActivity() {
private lateinit var menu: ListHabitsMenu private lateinit var menu: ListHabitsMenu
override fun onQuestionMarksChanged() {
invalidateOptionsMenu()
menu.behavior.onPreferencesChanged()
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -63,6 +68,7 @@ class ListHabitsActivity : AppCompatActivity() {
component.themeSwitcher.apply() component.themeSwitcher.apply()
prefs = appComponent.preferences prefs = appComponent.preferences
prefs.addListener(this)
pureBlack = prefs.isPureBlackEnabled pureBlack = prefs.isPureBlackEnabled
midnightTimer = appComponent.midnightTimer midnightTimer = appComponent.midnightTimer
rootView = component.listHabitsRootView rootView = component.listHabitsRootView
@@ -77,7 +83,7 @@ class ListHabitsActivity : AppCompatActivity() {
override fun onPause() { override fun onPause() {
midnightTimer.onPause() midnightTimer.onPause()
screen.onDettached() screen.onDetached()
adapter.cancelRefresh() adapter.cancelRefresh()
super.onPause() super.onPause()
} }

View File

@@ -39,7 +39,7 @@ class ListHabitsMenu @Inject constructor(
@ActivityContext context: Context, @ActivityContext context: Context,
private val preferences: Preferences, private val preferences: Preferences,
private val themeSwitcher: ThemeSwitcher, private val themeSwitcher: ThemeSwitcher,
private val behavior: ListHabitsMenuBehavior val behavior: ListHabitsMenuBehavior
) { ) {
val activity = (context as AppCompatActivity) val activity = (context as AppCompatActivity)
@@ -52,6 +52,11 @@ class ListHabitsMenu @Inject constructor(
nightModeItem.isChecked = themeSwitcher.isNightMode nightModeItem.isChecked = themeSwitcher.isNightMode
hideArchivedItem.isChecked = !preferences.showArchived hideArchivedItem.isChecked = !preferences.showArchived
hideCompletedItem.isChecked = !preferences.showCompleted hideCompletedItem.isChecked = !preferences.showCompleted
if (preferences.areQuestionMarksEnabled || preferences.isSkipEnabled) {
hideCompletedItem.title = activity.resources.getString(R.string.hide_entered)
} else {
hideCompletedItem.title = activity.resources.getString(R.string.hide_completed)
}
updateArrows(menu) updateArrows(menu)
} }

View File

@@ -44,6 +44,7 @@ import org.isoron.uhabits.utils.addAtBottom
import org.isoron.uhabits.utils.addAtTop import org.isoron.uhabits.utils.addAtTop
import org.isoron.uhabits.utils.addBelow import org.isoron.uhabits.utils.addBelow
import org.isoron.uhabits.utils.buildToolbar import org.isoron.uhabits.utils.buildToolbar
import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.dim import org.isoron.uhabits.utils.dim
import org.isoron.uhabits.utils.dp import org.isoron.uhabits.utils.dp
import org.isoron.uhabits.utils.setupToolbar import org.isoron.uhabits.utils.setupToolbar
@@ -93,6 +94,7 @@ class ListHabitsRootView @Inject constructor(
title = resources.getString(R.string.main_activity_title), title = resources.getString(R.string.main_activity_title),
color = PaletteColor(17), color = PaletteColor(17),
displayHomeAsUpEnabled = false, displayHomeAsUpEnabled = false,
theme = currentTheme(),
) )
addView(rootView, MATCH_PARENT, MATCH_PARENT) addView(rootView, MATCH_PARENT, MATCH_PARENT)
listAdapter.setListView(listView) listAdapter.setListView(listView)

View File

@@ -24,10 +24,12 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import dagger.Lazy import dagger.Lazy
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.activities.common.dialogs.CheckmarkPopup
import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialogFactory import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialogFactory
import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog
import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory import org.isoron.uhabits.activities.common.dialogs.NumberPopup
import org.isoron.uhabits.activities.habits.edit.HabitTypeDialog import org.isoron.uhabits.activities.habits.edit.HabitTypeDialog
import org.isoron.uhabits.activities.habits.list.views.HabitCardListAdapter import org.isoron.uhabits.activities.habits.list.views.HabitCardListAdapter
import org.isoron.uhabits.core.commands.ArchiveHabitsCommand import org.isoron.uhabits.core.commands.ArchiveHabitsCommand
@@ -40,6 +42,7 @@ import org.isoron.uhabits.core.commands.EditHabitCommand
import org.isoron.uhabits.core.commands.UnarchiveHabitsCommand import org.isoron.uhabits.core.commands.UnarchiveHabitsCommand
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.tasks.TaskRunner import org.isoron.uhabits.core.tasks.TaskRunner
import org.isoron.uhabits.core.ui.ThemeSwitcher import org.isoron.uhabits.core.ui.ThemeSwitcher
import org.isoron.uhabits.core.ui.callbacks.OnColorPickedCallback import org.isoron.uhabits.core.ui.callbacks.OnColorPickedCallback
@@ -60,6 +63,7 @@ import org.isoron.uhabits.tasks.ExportDBTaskFactory
import org.isoron.uhabits.tasks.ImportDataTask import org.isoron.uhabits.tasks.ImportDataTask
import org.isoron.uhabits.tasks.ImportDataTaskFactory import org.isoron.uhabits.tasks.ImportDataTaskFactory
import org.isoron.uhabits.utils.copyTo import org.isoron.uhabits.utils.copyTo
import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.restartWithFade import org.isoron.uhabits.utils.restartWithFade
import org.isoron.uhabits.utils.showMessage import org.isoron.uhabits.utils.showMessage
import org.isoron.uhabits.utils.showSendEmailScreen import org.isoron.uhabits.utils.showSendEmailScreen
@@ -88,8 +92,9 @@ class ListHabitsScreen
private val exportDBFactory: ExportDBTaskFactory, private val exportDBFactory: ExportDBTaskFactory,
private val importTaskFactory: ImportDataTaskFactory, private val importTaskFactory: ImportDataTaskFactory,
private val colorPickerFactory: ColorPickerDialogFactory, private val colorPickerFactory: ColorPickerDialogFactory,
private val numberPickerFactory: NumberPickerFactory, private val behavior: Lazy<ListHabitsBehavior>,
private val behavior: Lazy<ListHabitsBehavior> private val preferences: Preferences,
private val rootView: Lazy<ListHabitsRootView>,
) : CommandRunner.Listener, ) : CommandRunner.Listener,
ListHabitsBehavior.Screen, ListHabitsBehavior.Screen,
ListHabitsMenuBehavior.Screen, ListHabitsMenuBehavior.Screen,
@@ -101,7 +106,7 @@ class ListHabitsScreen
commandRunner.addListener(this) commandRunner.addListener(this)
} }
fun onDettached() { fun onDetached() {
commandRunner.removeListener(this) commandRunner.removeListener(this)
} }
@@ -217,17 +222,47 @@ class ListHabitsScreen
} }
override fun showColorPicker(defaultColor: PaletteColor, callback: OnColorPickedCallback) { override fun showColorPicker(defaultColor: PaletteColor, callback: OnColorPickedCallback) {
val picker = colorPickerFactory.create(defaultColor) val picker = colorPickerFactory.create(defaultColor, themeSwitcher.currentTheme!!)
picker.setListener(callback) picker.setListener(callback)
picker.show(activity.supportFragmentManager, "picker") picker.show(activity.supportFragmentManager, "picker")
} }
override fun showNumberPicker( override fun showNumberPopup(
value: Double, value: Double,
unit: String, notes: String,
callback: ListHabitsBehavior.NumberPickerCallback callback: ListHabitsBehavior.NumberPickerCallback
) { ) {
numberPickerFactory.create(value, unit, callback).show() val view = rootView.get()
NumberPopup(
context = context,
prefs = preferences,
anchor = view,
notes = notes,
value = value,
).apply {
onToggle = { value, notes -> callback.onNumberPicked(value, notes) }
show()
}
}
override fun showCheckmarkPopup(
selectedValue: Int,
notes: String,
color: PaletteColor,
callback: ListHabitsBehavior.CheckMarkDialogCallback
) {
val view = rootView.get()
CheckmarkPopup(
context = context,
prefs = preferences,
anchor = view,
color = view.currentTheme().color(color).toInt(),
notes = notes,
value = selectedValue,
).apply {
onToggle = { value, notes -> callback.onNotesSaved(value, notes) }
show()
}
} }
private fun getExecuteString(command: Command): String? { private fun getExecuteString(command: Command): String? {

View File

@@ -37,13 +37,15 @@ import org.isoron.uhabits.core.models.Entry.Companion.YES_AUTO
import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL
import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.inject.ActivityContext import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.utils.dim import org.isoron.uhabits.utils.drawNotesIndicator
import org.isoron.uhabits.utils.getFontAwesome import org.isoron.uhabits.utils.getFontAwesome
import org.isoron.uhabits.utils.showMessage import org.isoron.uhabits.utils.sp
import org.isoron.uhabits.utils.sres import org.isoron.uhabits.utils.sres
import org.isoron.uhabits.utils.toMeasureSpec import org.isoron.uhabits.utils.toMeasureSpec
import javax.inject.Inject import javax.inject.Inject
const val TOGGLE_DELAY_MILLIS = 2000L
class CheckmarkButtonViewFactory class CheckmarkButtonViewFactory
@Inject constructor( @Inject constructor(
@ActivityContext val context: Context, @ActivityContext val context: Context,
@@ -71,33 +73,42 @@ class CheckmarkButtonView(
invalidate() invalidate()
} }
var onToggle: (Int) -> Unit = {} var notes = ""
set(value) {
field = value
invalidate()
}
var onToggle: (Int, String, Long) -> Unit = { _, _, _ -> }
var onEdit: () -> Unit = { }
private var drawer = Drawer() private var drawer = Drawer()
init { init {
isFocusable = false
setOnClickListener(this) setOnClickListener(this)
setOnLongClickListener(this) setOnLongClickListener(this)
} }
fun performToggle() { fun performToggle(delay: Long) {
value = if (preferences.isSkipEnabled) { value = Entry.nextToggleValue(
Entry.nextToggleValueWithSkip(value) value = value,
} else { isSkipEnabled = preferences.isSkipEnabled,
Entry.nextToggleValueWithoutSkip(value) areQuestionMarksEnabled = preferences.areQuestionMarksEnabled
} )
onToggle(value) onToggle(value, notes, delay)
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
invalidate() invalidate()
} }
override fun onClick(v: View) { override fun onClick(v: View) {
if (preferences.isShortToggleEnabled) performToggle() if (preferences.isShortToggleEnabled) performToggle(TOGGLE_DELAY_MILLIS)
else showMessage(resources.getString(R.string.long_press_to_toggle)) else onEdit()
} }
override fun onLongClick(v: View): Boolean { override fun onLongClick(v: View): Boolean {
performToggle() if (preferences.isShortToggleEnabled) onEdit()
else performToggle(TOGGLE_DELAY_MILLIS)
return true return true
} }
@@ -131,7 +142,7 @@ class CheckmarkButtonView(
paint.color = when (value) { paint.color = when (value) {
YES_MANUAL, YES_AUTO, SKIP -> color YES_MANUAL, YES_AUTO, SKIP -> color
NO -> { NO -> {
if (preferences.areQuestionMarksEnabled()) mediumContrastColor if (preferences.areQuestionMarksEnabled) mediumContrastColor
else lowContrastColor else lowContrastColor
} }
else -> lowContrastColor else -> lowContrastColor
@@ -140,11 +151,16 @@ class CheckmarkButtonView(
SKIP -> R.string.fa_skipped SKIP -> R.string.fa_skipped
NO -> R.string.fa_times NO -> R.string.fa_times
UNKNOWN -> { UNKNOWN -> {
if (preferences.areQuestionMarksEnabled()) R.string.fa_question if (preferences.areQuestionMarksEnabled) R.string.fa_question
else R.string.fa_times else R.string.fa_times
} }
else -> R.string.fa_check else -> R.string.fa_check
} }
paint.textSize = when {
id == R.string.fa_question -> sp(12.0f)
value == YES_AUTO -> sp(13.0f)
else -> sp(14.0f)
}
if (value == YES_AUTO) { if (value == YES_AUTO) {
paint.strokeWidth = 5f paint.strokeWidth = 5f
paint.style = Paint.Style.STROKE paint.style = Paint.Style.STROKE
@@ -153,11 +169,6 @@ class CheckmarkButtonView(
paint.style = Paint.Style.FILL paint.style = Paint.Style.FILL
} }
paint.textSize = when (value) {
UNKNOWN -> dim(R.dimen.smallerTextSize)
else -> dim(R.dimen.smallTextSize)
}
val label = resources.getString(id) val label = resources.getString(id)
val em = paint.measureText("m") val em = paint.measureText("m")
@@ -170,6 +181,8 @@ class CheckmarkButtonView(
paint.style = Paint.Style.FILL paint.style = Paint.Style.FILL
canvas.drawText(label, rect.centerX(), rect.centerY(), paint) canvas.drawText(label, rect.centerX(), rect.centerY(), paint)
} }
drawNotesIndicator(canvas, color, em, notes)
} }
} }
} }

View File

@@ -54,7 +54,19 @@ class CheckmarkPanelView(
setupButtons() setupButtons()
} }
var onToggle: (Timestamp, Int) -> Unit = { _, _ -> } var notes = arrayOf<String>()
set(values) {
field = values
setupButtons()
}
var onToggle: (Timestamp, Int, String, Long) -> Unit = { _, _, _, _ -> }
set(value) {
field = value
setupButtons()
}
var onEdit: (Timestamp) -> Unit = { _ -> }
set(value) { set(value) {
field = value field = value
setupButtons() setupButtons()
@@ -72,8 +84,13 @@ class CheckmarkPanelView(
index + dataOffset < values.size -> values[index + dataOffset] index + dataOffset < values.size -> values[index + dataOffset]
else -> UNKNOWN else -> UNKNOWN
} }
button.notes = when {
index + dataOffset < notes.size -> notes[index + dataOffset]
else -> ""
}
button.color = color button.color = color
button.onToggle = { value -> onToggle(timestamp, value) } button.onToggle = { value, notes, delay -> onToggle(timestamp, value, notes, delay) }
button.onEdit = { onEdit(timestamp) }
} }
} }
} }

View File

@@ -124,8 +124,9 @@ class HabitCardListAdapter @Inject constructor(
val habit = cache.getHabitByPosition(position) val habit = cache.getHabitByPosition(position)
val score = cache.getScore(habit!!.id!!) val score = cache.getScore(habit!!.id!!)
val checkmarks = cache.getCheckmarks(habit.id!!) val checkmarks = cache.getCheckmarks(habit.id!!)
val notes = cache.getNotes(habit.id!!)
val selected = selected.contains(habit) val selected = selected.contains(habit)
listView!!.bindCardView(holder, habit, score, checkmarks, selected) listView!!.bindCardView(holder, habit, score, checkmarks, notes, selected)
} }
override fun onViewAttachedToWindow(holder: HabitCardViewHolder) { override fun onViewAttachedToWindow(holder: HabitCardViewHolder) {

View File

@@ -87,6 +87,7 @@ class HabitCardListView(
habit: Habit, habit: Habit,
score: Double, score: Double,
checkmarks: IntArray, checkmarks: IntArray,
notes: Array<String>,
selected: Boolean selected: Boolean
): View { ): View {
val cardView = holder.itemView as HabitCardView val cardView = holder.itemView as HabitCardView
@@ -98,6 +99,7 @@ class HabitCardListView(
cardView.score = score cardView.score = score
cardView.unit = habit.unit cardView.unit = habit.unit
cardView.threshold = habit.targetValue / habit.frequency.denominator cardView.threshold = habit.targetValue / habit.frequency.denominator
cardView.notes = notes
val detector = GestureDetector(context, CardViewGestureDetector(holder)) val detector = GestureDetector(context, CardViewGestureDetector(holder))
cardView.setOnTouchListener { _, ev -> cardView.setOnTouchListener { _, ev ->

View File

@@ -21,8 +21,8 @@ package org.isoron.uhabits.activities.habits.list.views
import android.content.Context import android.content.Context
import android.graphics.text.LineBreaker.BREAK_STRATEGY_BALANCED import android.graphics.text.LineBreaker.BREAK_STRATEGY_BALANCED
import android.os.Build
import android.os.Build.VERSION.SDK_INT import android.os.Build.VERSION.SDK_INT
import android.os.Build.VERSION_CODES.M
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.text.TextUtils import android.text.TextUtils
@@ -33,6 +33,7 @@ import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.activities.common.views.RingView import org.isoron.uhabits.activities.common.views.RingView
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
@@ -41,9 +42,9 @@ import org.isoron.uhabits.core.models.Timestamp
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
import org.isoron.uhabits.core.utils.DateUtils import org.isoron.uhabits.core.utils.DateUtils
import org.isoron.uhabits.inject.ActivityContext import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.dp import org.isoron.uhabits.utils.dp
import org.isoron.uhabits.utils.sres import org.isoron.uhabits.utils.sres
import org.isoron.uhabits.utils.toThemedAndroidColor
import javax.inject.Inject import javax.inject.Inject
class HabitCardViewFactory class HabitCardViewFactory
@@ -56,6 +57,13 @@ class HabitCardViewFactory
fun create() = HabitCardView(context, checkmarkPanelFactory, numberPanelFactory, behavior) fun create() = HabitCardView(context, checkmarkPanelFactory, numberPanelFactory, behavior)
} }
data class DelayedToggle(
var habit: Habit,
var timestamp: Timestamp,
var value: Int,
var notes: String
)
class HabitCardView( class HabitCardView(
@ActivityContext context: Context, @ActivityContext context: Context,
checkmarkPanelFactory: CheckmarkPanelViewFactory, checkmarkPanelFactory: CheckmarkPanelViewFactory,
@@ -114,12 +122,22 @@ class HabitCardView(
numberPanel.threshold = value numberPanel.threshold = value
} }
var notes
get() = checkmarkPanel.notes
set(values) {
checkmarkPanel.notes = values
numberPanel.notes = values
}
var checkmarkPanel: CheckmarkPanelView var checkmarkPanel: CheckmarkPanelView
private var numberPanel: NumberPanelView private var numberPanel: NumberPanelView
private var innerFrame: LinearLayout private var innerFrame: LinearLayout
private var label: TextView private var label: TextView
private var scoreRing: RingView private var scoreRing: RingView
private var currentToggleTaskId = 0
private var queuedToggles = mutableListOf<DelayedToggle>()
init { init {
scoreRing = RingView(context).apply { scoreRing = RingView(context).apply {
val thickness = dp(3f) val thickness = dp(3f)
@@ -136,13 +154,22 @@ class HabitCardView(
maxLines = 2 maxLines = 2
ellipsize = TextUtils.TruncateAt.END ellipsize = TextUtils.TruncateAt.END
layoutParams = LinearLayout.LayoutParams(0, WRAP_CONTENT, 1f) layoutParams = LinearLayout.LayoutParams(0, WRAP_CONTENT, 1f)
if (SDK_INT >= M) breakStrategy = BREAK_STRATEGY_BALANCED if (SDK_INT >= Build.VERSION_CODES.Q) {
breakStrategy = BREAK_STRATEGY_BALANCED
}
} }
checkmarkPanel = checkmarkPanelFactory.create().apply { checkmarkPanel = checkmarkPanelFactory.create().apply {
onToggle = { timestamp, value -> onToggle = { timestamp, value, notes, delay ->
if (delay > 0) triggerRipple(timestamp)
habit?.let {
val taskId = queueToggle(it, timestamp, value, notes);
{ runPendingToggles(taskId) }.delay(delay)
}
}
onEdit = { timestamp ->
triggerRipple(timestamp) triggerRipple(timestamp)
habit?.let { behavior.onToggle(it, timestamp, value) } habit?.let { behavior.onEdit(it, timestamp) }
} }
} }
@@ -178,6 +205,25 @@ class HabitCardView(
addView(innerFrame) addView(innerFrame)
} }
@Synchronized
private fun runPendingToggles(id: Int) {
if (currentToggleTaskId != id) return
for ((h, t, v, n) in queuedToggles) behavior.onToggle(h, t, v, n)
queuedToggles.clear()
}
@Synchronized
private fun queueToggle(
it: Habit,
timestamp: Timestamp,
value: Int,
notes: String,
): Int {
currentToggleTaskId += 1
queuedToggles.add(DelayedToggle(it, timestamp, value, notes))
return currentToggleTaskId
}
override fun onModelChange() { override fun onModelChange() {
Handler(Looper.getMainLooper()).post { Handler(Looper.getMainLooper()).post {
habit?.let { copyAttributesFrom(it) } habit?.let { copyAttributesFrom(it) }
@@ -213,7 +259,7 @@ class HabitCardView(
fun getActiveColor(habit: Habit): Int { fun getActiveColor(habit: Habit): Int {
return when (habit.isArchived) { return when (habit.isArchived) {
true -> sres.getColor(R.attr.contrast60) true -> sres.getColor(R.attr.contrast60)
false -> habit.color.toThemedAndroidColor(context) false -> currentTheme().color(habit.color).toInt()
} }
} }
@@ -235,6 +281,7 @@ class HabitCardView(
numberPanel.apply { numberPanel.apply {
color = c color = c
units = h.unit units = h.unit
targetType = h.targetType
threshold = h.targetValue threshold = h.targetValue
visibility = when (h.isNumerical) { visibility = when (h.isNumerical) {
true -> View.VISIBLE true -> View.VISIBLE
@@ -261,4 +308,10 @@ class HabitCardView(
} }
innerFrame.setBackgroundResource(background) innerFrame.setBackgroundResource(background)
} }
companion object {
fun (() -> Unit).delay(delayInMillis: Long) {
Handler(Looper.getMainLooper()).postDelayed(this, delayInMillis)
}
}
} }

View File

@@ -29,13 +29,16 @@ import android.view.View
import android.view.View.OnClickListener import android.view.View.OnClickListener
import android.view.View.OnLongClickListener import android.view.View.OnLongClickListener
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.models.NumericalHabitType.AT_LEAST
import org.isoron.uhabits.core.models.NumericalHabitType.AT_MOST
import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.inject.ActivityContext import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.utils.InterfaceUtils.getDimension import org.isoron.uhabits.utils.InterfaceUtils.getDimension
import org.isoron.uhabits.utils.StyledResources
import org.isoron.uhabits.utils.dim import org.isoron.uhabits.utils.dim
import org.isoron.uhabits.utils.drawNotesIndicator
import org.isoron.uhabits.utils.getFontAwesome import org.isoron.uhabits.utils.getFontAwesome
import org.isoron.uhabits.utils.showMessage import org.isoron.uhabits.utils.sres
import java.text.DecimalFormat import java.text.DecimalFormat
import javax.inject.Inject import javax.inject.Inject
@@ -88,13 +91,25 @@ class NumberButtonView(
invalidate() invalidate()
} }
var units = "" var targetType = AT_LEAST
set(value) { set(value) {
field = value field = value
invalidate() invalidate()
} }
var onEdit: () -> Unit = {} var units = ""
set(value) {
field = value
invalidate()
}
var notes = ""
set(value) {
field = value
invalidate()
}
var onEdit: () -> Unit = { }
private var drawer: Drawer = Drawer(context) private var drawer: Drawer = Drawer(context)
init { init {
@@ -103,8 +118,7 @@ class NumberButtonView(
} }
override fun onClick(v: View) { override fun onClick(v: View) {
if (preferences.isShortToggleEnabled) onEdit() onEdit()
else showMessage(resources.getString(R.string.long_press_to_edit))
} }
override fun onLongClick(v: View): Boolean { override fun onLongClick(v: View): Boolean {
@@ -127,11 +141,16 @@ class NumberButtonView(
private val em: Float private val em: Float
private val rect: RectF = RectF() private val rect: RectF = RectF()
private val sr = StyledResources(context)
private val lowContrast: Int private val lowContrast: Int
private val mediumContrast: Int private val mediumContrast: Int
private val paint = TextPaint().apply {
typeface = getFontAwesome()
isAntiAlias = true
textAlign = Paint.Align.CENTER
}
private val pUnit: TextPaint = TextPaint().apply { private val pUnit: TextPaint = TextPaint().apply {
textSize = getDimension(context, R.dimen.smallerTextSize) textSize = getDimension(context, R.dimen.smallerTextSize)
typeface = NORMAL_TYPEFACE typeface = NORMAL_TYPEFACE
@@ -148,15 +167,16 @@ class NumberButtonView(
init { init {
em = pNumber.measureText("m") em = pNumber.measureText("m")
lowContrast = sr.getColor(R.attr.contrast40) lowContrast = sres.getColor(R.attr.contrast40)
mediumContrast = sr.getColor(R.attr.contrast60) mediumContrast = sres.getColor(R.attr.contrast60)
} }
fun draw(canvas: Canvas) { fun draw(canvas: Canvas) {
val activeColor = when { val activeColor = when {
value <= 0.0 -> lowContrast value < 0.0 -> lowContrast
value < threshold -> mediumContrast (targetType == AT_LEAST) && (value >= threshold) -> color
else -> color (targetType == AT_MOST) && (value <= threshold) -> color
else -> mediumContrast
} }
val label: String val label: String
@@ -164,12 +184,17 @@ class NumberButtonView(
val textSize: Float val textSize: Float
when { when {
value == Entry.SKIP.toDouble() / 1000 -> {
label = resources.getString(R.string.fa_skipped)
textSize = dim(R.dimen.smallTextSize)
typeface = getFontAwesome()
}
value >= 0 -> { value >= 0 -> {
label = value.toShortString() label = value.toShortString()
typeface = BOLD_TYPEFACE typeface = BOLD_TYPEFACE
textSize = dim(R.dimen.smallTextSize) textSize = dim(R.dimen.smallTextSize)
} }
preferences.areQuestionMarksEnabled() -> { preferences.areQuestionMarksEnabled -> {
label = resources.getString(R.string.fa_question) label = resources.getString(R.string.fa_question)
typeface = getFontAwesome() typeface = getFontAwesome()
textSize = dim(R.dimen.smallerTextSize) textSize = dim(R.dimen.smallerTextSize)
@@ -196,6 +221,8 @@ class NumberButtonView(
rect.offset(0f, 1.3f * em) rect.offset(0f, 1.3f * em)
canvas.drawText(units, rect.centerX(), rect.centerY(), pUnit) canvas.drawText(units, rect.centerX(), rect.centerY(), pUnit)
} }
drawNotesIndicator(canvas, color, em, notes)
} }
} }
} }

View File

@@ -20,6 +20,7 @@
package org.isoron.uhabits.activities.habits.list.views package org.isoron.uhabits.activities.habits.list.views
import android.content.Context import android.content.Context
import org.isoron.uhabits.core.models.NumericalHabitType
import org.isoron.uhabits.core.models.Timestamp import org.isoron.uhabits.core.models.Timestamp
import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.utils.DateUtils import org.isoron.uhabits.core.utils.DateUtils
@@ -47,6 +48,12 @@ class NumberPanelView(
setupButtons() setupButtons()
} }
var targetType = NumericalHabitType.AT_LEAST
set(value) {
field = value
setupButtons()
}
var threshold = 0.0 var threshold = 0.0
set(value) { set(value) {
field = value field = value
@@ -65,7 +72,13 @@ class NumberPanelView(
setupButtons() setupButtons()
} }
var onEdit: (Timestamp) -> Unit = {} var notes = arrayOf<String>()
set(values) {
field = values
setupButtons()
}
var onEdit: (Timestamp) -> Unit = { _ -> }
set(value) { set(value) {
field = value field = value
setupButtons() setupButtons()
@@ -83,7 +96,12 @@ class NumberPanelView(
index + dataOffset < values.size -> values[index + dataOffset] index + dataOffset < values.size -> values[index + dataOffset]
else -> 0.0 else -> 0.0
} }
button.notes = when {
index + dataOffset < notes.size -> notes[index + dataOffset]
else -> ""
}
button.color = color button.color = color
button.targetType = targetType
button.threshold = threshold button.threshold = threshold
button.units = units button.units = units
button.onEdit = { onEdit(timestamp) } button.onEdit = { onEdit(timestamp) }

View File

@@ -23,21 +23,25 @@ import android.os.Bundle
import android.view.HapticFeedbackConstants import android.view.HapticFeedbackConstants
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.AndroidDirFinder import org.isoron.uhabits.AndroidDirFinder
import org.isoron.uhabits.HabitsApplication import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher import org.isoron.uhabits.activities.AndroidThemeSwitcher
import org.isoron.uhabits.activities.HabitsDirFinder import org.isoron.uhabits.activities.HabitsDirFinder
import org.isoron.uhabits.activities.common.dialogs.CheckmarkPopup
import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog
import org.isoron.uhabits.activities.common.dialogs.HistoryEditorDialog import org.isoron.uhabits.activities.common.dialogs.HistoryEditorDialog
import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory import org.isoron.uhabits.activities.common.dialogs.NumberPopup
import org.isoron.uhabits.core.commands.Command import org.isoron.uhabits.core.commands.Command
import org.isoron.uhabits.core.commands.CommandRunner import org.isoron.uhabits.core.commands.CommandRunner
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.ui.callbacks.OnConfirmedCallback import org.isoron.uhabits.core.ui.callbacks.OnConfirmedCallback
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
@@ -45,6 +49,7 @@ import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitMenuPresenter
import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitPresenter import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitPresenter
import org.isoron.uhabits.core.ui.views.OnDateClickedListener import org.isoron.uhabits.core.ui.views.OnDateClickedListener
import org.isoron.uhabits.intents.IntentFactory import org.isoron.uhabits.intents.IntentFactory
import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.showMessage import org.isoron.uhabits.utils.showMessage
import org.isoron.uhabits.utils.showSendFileScreen import org.isoron.uhabits.utils.showSendFileScreen
import org.isoron.uhabits.widgets.WidgetUpdater import org.isoron.uhabits.widgets.WidgetUpdater
@@ -161,12 +166,49 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
window.decorView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY) window.decorView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
} }
override fun showNumberPicker( override fun showNumberPopup(
value: Double, value: Double,
unit: String, notes: String,
callback: ListHabitsBehavior.NumberPickerCallback, preferences: Preferences,
callback: ListHabitsBehavior.NumberPickerCallback
) { ) {
NumberPickerFactory(this@ShowHabitActivity).create(value, unit, callback).show() val anchor = getPopupAnchor() ?: return
NumberPopup(
context = this@ShowHabitActivity,
prefs = preferences,
notes = notes,
anchor = anchor,
value = value,
).apply {
onToggle = { v, n -> callback.onNumberPicked(v, n) }
show()
}
}
override fun showCheckmarkPopup(
selectedValue: Int,
notes: String,
preferences: Preferences,
color: PaletteColor,
callback: ListHabitsBehavior.CheckMarkDialogCallback
) {
val anchor = getPopupAnchor() ?: return
CheckmarkPopup(
context = this@ShowHabitActivity,
prefs = preferences,
notes = notes,
color = view.currentTheme().color(color).toInt(),
anchor = anchor,
value = selectedValue,
).apply {
onToggle = { v, n -> callback.onNotesSaved(v, n) }
show()
}
}
private fun getPopupAnchor(): View? {
val dialog = supportFragmentManager.findFragmentByTag("historyEditor") as HistoryEditorDialog?
return dialog?.dataView
} }
override fun showEditHabitScreen(habit: Habit) { override fun showEditHabitScreen(habit: Habit) {

View File

@@ -35,7 +35,12 @@ class ShowHabitView(context: Context) : FrameLayout(context) {
} }
fun setState(data: ShowHabitState) { fun setState(data: ShowHabitState) {
setupToolbar(binding.toolbar, title = data.title, color = data.color) setupToolbar(
binding.toolbar,
title = data.title,
color = data.color,
theme = data.theme,
)
binding.subtitleCard.setState(data.subtitle) binding.subtitleCard.setState(data.subtitle)
binding.overviewCard.setState(data.overview) binding.overviewCard.setState(data.overview)
binding.notesCard.setState(data.notes) binding.notesCard.setState(data.notes)

View File

@@ -24,12 +24,12 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.platform.time.JavaLocalDateFormatter import org.isoron.platform.time.JavaLocalDateFormatter
import org.isoron.uhabits.core.ui.screens.habits.show.views.BarCardPresenter import org.isoron.uhabits.core.ui.screens.habits.show.views.BarCardPresenter
import org.isoron.uhabits.core.ui.screens.habits.show.views.BarCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.BarCardState
import org.isoron.uhabits.core.ui.views.BarChart import org.isoron.uhabits.core.ui.views.BarChart
import org.isoron.uhabits.databinding.ShowHabitBarBinding import org.isoron.uhabits.databinding.ShowHabitBarBinding
import org.isoron.uhabits.utils.toThemedAndroidColor
import java.util.Locale import java.util.Locale
class BarCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class BarCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
@@ -37,7 +37,7 @@ class BarCardView(context: Context, attrs: AttributeSet) : LinearLayout(context,
private var binding = ShowHabitBarBinding.inflate(LayoutInflater.from(context), this) private var binding = ShowHabitBarBinding.inflate(LayoutInflater.from(context), this)
fun setState(state: BarCardState) { fun setState(state: BarCardState) {
val androidColor = state.color.toThemedAndroidColor(context) val androidColor = state.theme.color(state.color).toInt()
binding.chart.view = BarChart(state.theme, JavaLocalDateFormatter(Locale.US)).apply { binding.chart.view = BarChart(state.theme, JavaLocalDateFormatter(Locale.US)).apply {
series = mutableListOf(state.entries.map { it.value / 1000.0 }) series = mutableListOf(state.entries.map { it.value / 1000.0 })
colors = mutableListOf(theme.color(state.color.paletteIndex)) colors = mutableListOf(theme.color(state.color.paletteIndex))

View File

@@ -22,16 +22,16 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.core.ui.screens.habits.show.views.FrequencyCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.FrequencyCardState
import org.isoron.uhabits.databinding.ShowHabitFrequencyBinding import org.isoron.uhabits.databinding.ShowHabitFrequencyBinding
import org.isoron.uhabits.utils.toThemedAndroidColor
class FrequencyCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class FrequencyCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
private var binding = ShowHabitFrequencyBinding.inflate(LayoutInflater.from(context), this) private var binding = ShowHabitFrequencyBinding.inflate(LayoutInflater.from(context), this)
fun setState(state: FrequencyCardState) { fun setState(state: FrequencyCardState) {
val androidColor = state.color.toThemedAndroidColor(context) val androidColor = state.theme.color(state.color).toInt()
binding.frequencyChart.setFrequency(state.frequency) binding.frequencyChart.setFrequency(state.frequency)
binding.frequencyChart.setFirstWeekday(state.firstWeekday) binding.frequencyChart.setFirstWeekday(state.firstWeekday)
binding.title.setTextColor(androidColor) binding.title.setTextColor(androidColor)

View File

@@ -22,12 +22,12 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.platform.time.JavaLocalDateFormatter import org.isoron.platform.time.JavaLocalDateFormatter
import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardPresenter import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardPresenter
import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardState
import org.isoron.uhabits.core.ui.views.HistoryChart import org.isoron.uhabits.core.ui.views.HistoryChart
import org.isoron.uhabits.databinding.ShowHabitHistoryBinding import org.isoron.uhabits.databinding.ShowHabitHistoryBinding
import org.isoron.uhabits.utils.toThemedAndroidColor
import java.util.Locale import java.util.Locale
class HistoryCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class HistoryCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
@@ -35,7 +35,7 @@ class HistoryCardView(context: Context, attrs: AttributeSet) : LinearLayout(cont
private var binding = ShowHabitHistoryBinding.inflate(LayoutInflater.from(context), this) private var binding = ShowHabitHistoryBinding.inflate(LayoutInflater.from(context), this)
fun setState(state: HistoryCardState) { fun setState(state: HistoryCardState) {
val androidColor = state.color.toThemedAndroidColor(context) val androidColor = state.theme.color(state.color).toInt()
binding.title.setTextColor(androidColor) binding.title.setTextColor(androidColor)
binding.chart.view = HistoryChart( binding.chart.view = HistoryChart(
today = state.today, today = state.today,
@@ -43,6 +43,8 @@ class HistoryCardView(context: Context, attrs: AttributeSet) : LinearLayout(cont
theme = state.theme, theme = state.theme,
dateFormatter = JavaLocalDateFormatter(Locale.getDefault()), dateFormatter = JavaLocalDateFormatter(Locale.getDefault()),
series = state.series, series = state.series,
defaultSquare = state.defaultSquare,
notesIndicators = state.notesIndicators,
firstWeekday = state.firstWeekday, firstWeekday = state.firstWeekday,
) )
binding.chart.postInvalidate() binding.chart.postInvalidate()

View File

@@ -22,11 +22,11 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardState
import org.isoron.uhabits.databinding.ShowHabitOverviewBinding import org.isoron.uhabits.databinding.ShowHabitOverviewBinding
import org.isoron.uhabits.utils.StyledResources import org.isoron.uhabits.utils.StyledResources
import org.isoron.uhabits.utils.toThemedAndroidColor
import kotlin.math.abs import kotlin.math.abs
class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
@@ -42,7 +42,7 @@ class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
} }
fun setState(state: OverviewCardState) { fun setState(state: OverviewCardState) {
val androidColor = state.color.toThemedAndroidColor(context) val androidColor = state.theme.color(state.color).toInt()
val res = StyledResources(context) val res = StyledResources(context)
val inactiveColor = res.getColor(R.attr.contrast60) val inactiveColor = res.getColor(R.attr.contrast60)
binding.monthDiffLabel.setTextColor(if (state.scoreMonthDiff >= 0) androidColor else inactiveColor) binding.monthDiffLabel.setTextColor(if (state.scoreMonthDiff >= 0) androidColor else inactiveColor)

View File

@@ -24,16 +24,16 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardState
import org.isoron.uhabits.databinding.ShowHabitScoreBinding import org.isoron.uhabits.databinding.ShowHabitScoreBinding
import org.isoron.uhabits.utils.toThemedAndroidColor
class ScoreCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class ScoreCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
private var binding = ShowHabitScoreBinding.inflate(LayoutInflater.from(context), this) private var binding = ShowHabitScoreBinding.inflate(LayoutInflater.from(context), this)
fun setState(state: ScoreCardState) { fun setState(state: ScoreCardState) {
val androidColor = state.color.toThemedAndroidColor(context) val androidColor = state.theme.color(state.color).toInt()
binding.title.setTextColor(androidColor) binding.title.setTextColor(androidColor)
binding.spinner.setSelection(state.spinnerPosition) binding.spinner.setSelection(state.spinnerPosition)
binding.scoreView.setScores(state.scores) binding.scoreView.setScores(state.scores)

View File

@@ -22,16 +22,16 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCardState
import org.isoron.uhabits.databinding.ShowHabitStreakBinding import org.isoron.uhabits.databinding.ShowHabitStreakBinding
import org.isoron.uhabits.utils.toThemedAndroidColor
class StreakCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class StreakCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
private val binding = ShowHabitStreakBinding.inflate(LayoutInflater.from(context), this) private val binding = ShowHabitStreakBinding.inflate(LayoutInflater.from(context), this)
fun setState(state: StreakCardState) { fun setState(state: StreakCardState) {
val color = state.color.toThemedAndroidColor(context) val androidColor = state.theme.color(state.color).toInt()
binding.title.setTextColor(color) binding.title.setTextColor(androidColor)
binding.streakChart.setColor(color) binding.streakChart.setColor(androidColor)
binding.streakChart.setStreaks(state.bestStreaks) binding.streakChart.setStreaks(state.bestStreaks)
postInvalidate() postInvalidate()
} }

View File

@@ -20,19 +20,19 @@ package org.isoron.uhabits.activities.habits.show.views
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.res.Resources
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.activities.habits.edit.formatFrequency
import org.isoron.uhabits.activities.habits.list.views.toShortString import org.isoron.uhabits.activities.habits.list.views.toShortString
import org.isoron.uhabits.core.models.Frequency import org.isoron.uhabits.core.models.NumericalHabitType
import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardState
import org.isoron.uhabits.databinding.ShowHabitSubtitleBinding import org.isoron.uhabits.databinding.ShowHabitSubtitleBinding
import org.isoron.uhabits.utils.InterfaceUtils import org.isoron.uhabits.utils.InterfaceUtils
import org.isoron.uhabits.utils.formatTime import org.isoron.uhabits.utils.formatTime
import org.isoron.uhabits.utils.toThemedAndroidColor
class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
@@ -47,9 +47,13 @@ class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
fun setState(state: SubtitleCardState) { fun setState(state: SubtitleCardState) {
val color = state.color.toThemedAndroidColor(context) val color = state.theme.color(state.color).toInt()
val reminder = state.reminder val reminder = state.reminder
binding.frequencyLabel.text = state.frequency.format(resources) binding.frequencyLabel.text = formatFrequency(
state.frequency.numerator,
state.frequency.denominator,
resources,
)
binding.questionLabel.setTextColor(color) binding.questionLabel.setTextColor(color)
binding.questionLabel.text = state.question binding.questionLabel.text = state.question
binding.reminderLabel.text = if (reminder != null) { binding.reminderLabel.text = if (reminder != null) {
@@ -62,7 +66,12 @@ class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
binding.questionLabel.visibility = View.VISIBLE binding.questionLabel.visibility = View.VISIBLE
binding.targetIcon.visibility = View.VISIBLE binding.targetIcon.visibility = View.VISIBLE
binding.targetText.visibility = View.VISIBLE binding.targetText.visibility = View.VISIBLE
if (!state.isNumerical) { if (state.isNumerical) {
binding.targetIcon.text = when (state.targetType) {
NumericalHabitType.AT_LEAST -> resources.getString(R.string.fa_arrow_circle_up)
else -> resources.getString(R.string.fa_arrow_circle_down)
}
} else {
binding.targetIcon.visibility = View.GONE binding.targetIcon.visibility = View.GONE
binding.targetText.visibility = View.GONE binding.targetText.visibility = View.GONE
} }
@@ -72,32 +81,4 @@ class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
postInvalidate() postInvalidate()
} }
@SuppressLint("StringFormatMatches")
private fun Frequency.format(resources: Resources): String {
val num = this.numerator
val den = this.denominator
if (num == den) {
return resources.getString(R.string.every_day)
}
if (den == 7) {
return resources.getString(R.string.x_times_per_week, num)
}
if (den == 30 || den == 31) {
return resources.getString(R.string.x_times_per_month, num)
}
if (num == 1) {
if (den == 7) {
return resources.getString(R.string.every_week)
}
if (den % 7 == 0) {
return resources.getString(R.string.every_x_weeks, den / 7)
}
if (den == 30 || den == 31) {
return resources.getString(R.string.every_month)
}
return resources.getString(R.string.every_x_days, den)
}
return "$num/$den"
}
} }

View File

@@ -23,15 +23,15 @@ import android.content.res.Resources
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.ui.screens.habits.show.views.TargetCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.TargetCardState
import org.isoron.uhabits.databinding.ShowHabitTargetBinding import org.isoron.uhabits.databinding.ShowHabitTargetBinding
import org.isoron.uhabits.utils.toThemedAndroidColor
class TargetCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class TargetCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
private val binding = ShowHabitTargetBinding.inflate(LayoutInflater.from(context), this) private val binding = ShowHabitTargetBinding.inflate(LayoutInflater.from(context), this)
fun setState(state: TargetCardState) { fun setState(state: TargetCardState) {
val androidColor = state.color.toThemedAndroidColor(context) val androidColor = state.theme.color(state.color).toInt()
binding.targetChart.setValues(state.values) binding.targetChart.setValues(state.values)
binding.targetChart.setTargets(state.targets) binding.targetChart.setTargets(state.targets)
binding.targetChart.setLabels(state.intervals.map { intervalToLabel(resources, it) }) binding.targetChart.setLabels(state.intervals.map { intervalToLabel(resources, it) })

View File

@@ -21,8 +21,9 @@ package org.isoron.uhabits.activities.intro
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import com.github.paolorotolo.appintro.AppIntro2 import androidx.fragment.app.Fragment
import com.github.paolorotolo.appintro.AppIntroFragment import com.github.appintro.AppIntro2
import com.github.appintro.AppIntroFragment
import org.isoron.uhabits.R import org.isoron.uhabits.R
/** /**
@@ -30,7 +31,9 @@ import org.isoron.uhabits.R
* launched for the first time. * launched for the first time.
*/ */
class IntroActivity : AppIntro2() { class IntroActivity : AppIntro2() {
override fun init(savedInstanceState: Bundle?) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
showStatusBar(false) showStatusBar(false)
addSlide( addSlide(
@@ -61,11 +64,13 @@ class IntroActivity : AppIntro2() {
) )
} }
override fun onNextPressed() {} override fun onDonePressed(currentFragment: Fragment?) {
super.onDonePressed(currentFragment)
override fun onDonePressed() {
finish() finish()
} }
override fun onSlideChanged() {} override fun onSkipPressed(currentFragment: Fragment?) {
super.onSkipPressed(currentFragment)
finish()
}
} }

View File

@@ -32,13 +32,15 @@ class SettingsActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val component = (application as HabitsApplication).component val component = (application as HabitsApplication).component
AndroidThemeSwitcher(this, component.preferences).apply() val themeSwitcher = AndroidThemeSwitcher(this, component.preferences)
themeSwitcher.apply()
val binding = SettingsActivityBinding.inflate(LayoutInflater.from(this)) val binding = SettingsActivityBinding.inflate(LayoutInflater.from(this))
binding.root.setupToolbar( binding.root.setupToolbar(
toolbar = binding.toolbar, toolbar = binding.toolbar,
title = resources.getString(R.string.settings), title = resources.getString(R.string.settings),
color = PaletteColor(11), color = PaletteColor(11),
theme = themeSwitcher.currentTheme,
) )
setContentView(binding.root) setContentView(binding.root)
} }

View File

@@ -23,7 +23,7 @@ import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.os.Build import android.os.Build
import android.os.Build.VERSION import android.os.Build.VERSION.SDK_INT
import android.os.Bundle import android.os.Bundle
import android.provider.Settings import android.provider.Settings
import android.util.Log import android.util.Log
@@ -63,7 +63,7 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
addPreferencesFromResource(R.xml.preferences) addPreferencesFromResource(R.xml.preferences)
val appContext = context!!.applicationContext val appContext = requireContext().applicationContext
if (appContext is HabitsApplication) { if (appContext is HabitsApplication) {
prefs = appContext.component.preferences prefs = appContext.component.preferences
widgetUpdater = appContext.component.widgetUpdater widgetUpdater = appContext.component.widgetUpdater
@@ -90,10 +90,10 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
showRingtonePicker() showRingtonePicker()
return true return true
} else if (key == "reminderCustomize") { } else if (key == "reminderCustomize") {
if (VERSION.SDK_INT < Build.VERSION_CODES.O) return true if (SDK_INT < Build.VERSION_CODES.O) return true
createAndroidNotificationChannel(context!!) createAndroidNotificationChannel(requireContext())
val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS) val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context!!.packageName) intent.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
intent.putExtra(Settings.EXTRA_CHANNEL_ID, NotificationTray.REMINDERS_CHANNEL_ID) intent.putExtra(Settings.EXTRA_CHANNEL_ID, NotificationTray.REMINDERS_CHANNEL_ID)
startActivity(intent) startActivity(intent)
return true return true
@@ -103,7 +103,7 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
ringtoneManager = RingtoneManager(activity!!) ringtoneManager = RingtoneManager(requireActivity())
sharedPrefs = preferenceManager.sharedPreferences sharedPrefs = preferenceManager.sharedPreferences
sharedPrefs!!.registerOnSharedPreferenceChangeListener(this) sharedPrefs!!.registerOnSharedPreferenceChangeListener(this)
if (!prefs.isDeveloper) { if (!prefs.isDeveloper) {
@@ -112,7 +112,7 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
} }
updateWeekdayPreference() updateWeekdayPreference()
if (VERSION.SDK_INT < Build.VERSION_CODES.O) if (SDK_INT < Build.VERSION_CODES.O)
findPreference("reminderCustomize").isVisible = false findPreference("reminderCustomize").isVisible = false
else { else {
findPreference("reminderSound").isVisible = false findPreference("reminderSound").isVisible = false
@@ -146,8 +146,8 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
val pref = findPreference(key) val pref = findPreference(key)
pref.onPreferenceClickListener = pref.onPreferenceClickListener =
Preference.OnPreferenceClickListener { Preference.OnPreferenceClickListener {
activity!!.setResult(result) requireActivity().setResult(result)
activity!!.finish() requireActivity().finish()
true true
} }
} }

View File

@@ -23,17 +23,17 @@ import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import org.isoron.uhabits.HabitsApplication import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.activities.AndroidThemeSwitcher import org.isoron.uhabits.activities.AndroidThemeSwitcher
import org.isoron.uhabits.core.models.HabitMatcherBuilder import org.isoron.uhabits.core.models.HabitMatcher
class EditSettingActivity : AppCompatActivity() { class EditSettingActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val app = applicationContext as HabitsApplication val app = applicationContext as HabitsApplication
val habits = app.component.habitList.getFiltered( val habits = app.component.habitList.getFiltered(
HabitMatcherBuilder() HabitMatcher(
.setArchivedAllowed(false) isArchivedAllowed = false,
.setCompletedAllowed(true) isCompletedAllowed = true,
.build() )
) )
AndroidThemeSwitcher(this, app.component.preferences).apply() AndroidThemeSwitcher(this, app.component.preferences).apply()

View File

@@ -33,6 +33,7 @@ import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.HabitList import org.isoron.uhabits.core.models.HabitList
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.databinding.AutomationBinding import org.isoron.uhabits.databinding.AutomationBinding
import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.setupToolbar import org.isoron.uhabits.utils.setupToolbar
import java.util.LinkedList import java.util.LinkedList
@@ -53,6 +54,7 @@ class EditSettingRootView(
title = resources.getString(R.string.app_name), title = resources.getString(R.string.app_name),
color = PaletteColor(11), color = PaletteColor(11),
displayHomeAsUpEnabled = false, displayHomeAsUpEnabled = false,
theme = currentTheme(),
) )
populateHabitSpinner() populateHabitSpinner()
binding.habitSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { binding.habitSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {

View File

@@ -25,8 +25,6 @@ import android.app.AlarmManager.RTC_WAKEUP
import android.app.PendingIntent import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.content.Context.ALARM_SERVICE import android.content.Context.ALARM_SERVICE
import android.os.Build.VERSION.SDK_INT
import android.os.Build.VERSION_CODES.M
import android.util.Log import android.util.Log
import org.isoron.uhabits.core.AppScope import org.isoron.uhabits.core.AppScope
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
@@ -58,10 +56,7 @@ class IntentScheduler
) )
return SchedulerResult.IGNORED return SchedulerResult.IGNORED
} }
if (SDK_INT >= M) manager.setExactAndAllowWhileIdle(alarmType, timestamp, intent)
manager.setExactAndAllowWhileIdle(alarmType, timestamp, intent)
else
manager.setExact(alarmType, timestamp, intent)
return SchedulerResult.OK return SchedulerResult.OK
} }

View File

@@ -20,6 +20,7 @@
package org.isoron.uhabits.intents package org.isoron.uhabits.intents
import android.app.PendingIntent import android.app.PendingIntent
import android.app.PendingIntent.FLAG_IMMUTABLE
import android.app.PendingIntent.FLAG_UPDATE_CURRENT import android.app.PendingIntent.FLAG_UPDATE_CURRENT
import android.app.PendingIntent.getBroadcast import android.app.PendingIntent.getBroadcast
import android.content.Context import android.content.Context
@@ -49,7 +50,7 @@ class PendingIntentFactory
action = WidgetReceiver.ACTION_ADD_REPETITION action = WidgetReceiver.ACTION_ADD_REPETITION
if (timestamp != null) putExtra("timestamp", timestamp.unixTime) if (timestamp != null) putExtra("timestamp", timestamp.unixTime)
}, },
FLAG_UPDATE_CURRENT FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
) )
fun dismissNotification(habit: Habit): PendingIntent = fun dismissNotification(habit: Habit): PendingIntent =
@@ -60,18 +61,19 @@ class PendingIntentFactory
action = WidgetReceiver.ACTION_DISMISS_REMINDER action = WidgetReceiver.ACTION_DISMISS_REMINDER
data = Uri.parse(habit.uriString) data = Uri.parse(habit.uriString)
}, },
FLAG_UPDATE_CURRENT FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
) )
fun removeRepetition(habit: Habit): PendingIntent = fun removeRepetition(habit: Habit, timestamp: Timestamp?): PendingIntent =
getBroadcast( getBroadcast(
context, context,
3, 3,
Intent(context, WidgetReceiver::class.java).apply { Intent(context, WidgetReceiver::class.java).apply {
action = WidgetReceiver.ACTION_REMOVE_REPETITION action = WidgetReceiver.ACTION_REMOVE_REPETITION
data = Uri.parse(habit.uriString) data = Uri.parse(habit.uriString)
if (timestamp != null) putExtra("timestamp", timestamp.unixTime)
}, },
FLAG_UPDATE_CURRENT FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
) )
fun showHabit(habit: Habit): PendingIntent = fun showHabit(habit: Habit): PendingIntent =
@@ -83,7 +85,7 @@ class PendingIntentFactory
habit habit
) )
) )
.getPendingIntent(0, FLAG_UPDATE_CURRENT)!! .getPendingIntent(0, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT)!!
fun showReminder( fun showReminder(
habit: Habit, habit: Habit,
@@ -99,7 +101,7 @@ class PendingIntentFactory
putExtra("timestamp", timestamp) putExtra("timestamp", timestamp)
putExtra("reminderTime", reminderTime) putExtra("reminderTime", reminderTime)
}, },
FLAG_UPDATE_CURRENT FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
) )
fun snoozeNotification(habit: Habit): PendingIntent = fun snoozeNotification(habit: Habit): PendingIntent =
@@ -110,7 +112,7 @@ class PendingIntentFactory
data = Uri.parse(habit.uriString) data = Uri.parse(habit.uriString)
action = ReminderReceiver.ACTION_SNOOZE_REMINDER action = ReminderReceiver.ACTION_SNOOZE_REMINDER
}, },
FLAG_UPDATE_CURRENT FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
) )
fun toggleCheckmark(habit: Habit, timestamp: Long?): PendingIntent = fun toggleCheckmark(habit: Habit, timestamp: Long?): PendingIntent =
@@ -122,7 +124,7 @@ class PendingIntentFactory
action = WidgetReceiver.ACTION_TOGGLE_REPETITION action = WidgetReceiver.ACTION_TOGGLE_REPETITION
if (timestamp != null) putExtra("timestamp", timestamp) if (timestamp != null) putExtra("timestamp", timestamp)
}, },
FLAG_UPDATE_CURRENT FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
) )
fun setNumericalValue( fun setNumericalValue(
@@ -132,17 +134,17 @@ class PendingIntentFactory
timestamp: Long? timestamp: Long?
): ):
PendingIntent = PendingIntent =
getBroadcast( getBroadcast(
widgetContext, widgetContext,
2, 2,
Intent(widgetContext, WidgetReceiver::class.java).apply { Intent(widgetContext, WidgetReceiver::class.java).apply {
data = Uri.parse(habit.uriString) data = Uri.parse(habit.uriString)
action = WidgetReceiver.ACTION_SET_NUMERICAL_VALUE action = WidgetReceiver.ACTION_SET_NUMERICAL_VALUE
putExtra("numericalValue", numericalValue) putExtra("numericalValue", numericalValue)
if (timestamp != null) putExtra("timestamp", timestamp) if (timestamp != null) putExtra("timestamp", timestamp)
}, },
FLAG_UPDATE_CURRENT FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
) )
fun updateWidgets(): PendingIntent = fun updateWidgets(): PendingIntent =
getBroadcast( getBroadcast(
@@ -151,6 +153,6 @@ class PendingIntentFactory
Intent(context, WidgetReceiver::class.java).apply { Intent(context, WidgetReceiver::class.java).apply {
action = WidgetReceiver.ACTION_UPDATE_WIDGETS_VALUE action = WidgetReceiver.ACTION_UPDATE_WIDGETS_VALUE
}, },
FLAG_UPDATE_CURRENT FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
) )
} }

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