Compare commits

...

307 Commits

Author SHA1 Message Date
b2cb54e32b Merge branch 'dev' into feature/sync2 2022-09-11 06:09:27 -05:00
e42d41ef30 Bump minSdk to 28
This change is mostly to reduce the number of APIs we need to run tests
for (from 11 APIs to 6). API 27 was released 5 years ago. Also, as of
2022-09-01, 95.1% of our monthly active users are on API 28 or higher.
2022-09-10 19:57:57 -05:00
5498ff8a87 Switch emulator to google_apis; test APIs 28 to 33 2022-09-10 19:25:40 -05:00
20dcc7929b Remove unused folders 2022-09-10 17:04:43 -05:00
1283cf979d Update CHANGELOG 2022-09-10 16:51:20 -05:00
0a493ff065 Merge branch 'master' into dev 2022-09-10 16:50:48 -05:00
16cd249bae Update CHANGELOG 2022-09-10 16:50:16 -05:00
d136572960 Minor fix to BarChart 2022-09-10 16:50:16 -05:00
318aa3c821 Fix ListHabitsScreen.showColorPicker 2022-09-10 16:50:16 -05:00
73712e0d10 Always update widgets on launch
Helps mitigate situations where the widgets mysteriously fail to render.
The user can always force a refresh by opening the app.
2022-09-10 16:50:16 -05:00
bf504641c6 Merge pull request #1488 from iSoron/fix/stackwidget-api33
Widget fixes
2022-09-10 16:11:55 -05:00
ec1f0c5356 StackWidget: Remove unused remoteViews; fix invalid check 2022-09-09 06:02:57 -05:00
2154d8c192 StackWidget: Remove unused remoteViews; fix invalid check 2022-09-09 05:57:13 -05:00
961fb7618f splitLongs: Handle NumberFormatException 2022-09-09 05:39:15 -05:00
11f726064a StackWidget: Avoid storing RemoteViews reference 2022-09-09 05:39:15 -05:00
4c5a722dc5 splitLongs: Handle NumberFormatException 2022-09-09 05:17:54 -05:00
ee39ff0eda StackWidget: Avoid storing RemoteViews reference 2022-09-08 20:35:59 -05:00
abced92a07 Update CHANGELOG 2022-09-08 20:09:47 -05:00
cheer
eeacc5eef8 Support for Android 13 Themed Icons (#1497) 2022-09-08 20:08:12 -05:00
Eduardo Esparza
16c65f19fd fix marker scaling for numerical habits in frequency display (#1489) 2022-09-08 20:08:05 -05:00
cheer
6a9c3a36eb Support for Android 13 Themed Icons (#1497) 2022-09-08 20:06:57 -05:00
Eduardo Esparza
99ccb44ad3 fix marker scaling for numerical habits in frequency display (#1489) 2022-09-08 20:01:12 -05:00
fc402fd81b Minor fix to BarChart 2022-09-03 20:26:21 -05:00
f7c6bc716c Fix ListHabitsScreen.showColorPicker 2022-09-03 19:52:13 -05:00
2535347d5a Always update widgets on launch
Helps mitigate situations where the widgets mysteriously fail to render.
The user can always force a refresh by opening the app.
2022-09-03 19:45:31 -05:00
dependabot[bot]
8c0655c352 Bump sqlite-jdbc from 3.39.2.0 to 3.39.2.1 (#1483)
Bumps [sqlite-jdbc](https://github.com/xerial/sqlite-jdbc) from 3.39.2.0 to 3.39.2.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.39.2.0...3.39.2.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-03 18:51:50 -05:00
dependabot[bot]
335f8c32fd Bump desugar_jdk_libs from 1.1.5 to 1.2.2 (#1482)
Bumps [desugar_jdk_libs](https://github.com/google/desugar_jdk_libs) from 1.1.5 to 1.2.2.
- [Release notes](https://github.com/google/desugar_jdk_libs/releases)
- [Changelog](https://github.com/google/desugar_jdk_libs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/desugar_jdk_libs/commits)

---
updated-dependencies:
- dependency-name: com.android.tools:desugar_jdk_libs
  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-09-03 18:51:40 -05:00
dependabot[bot]
f77c064722 Bump logback-classic from 1.2.11 to 1.4.0 (#1481)
Bumps [logback-classic](https://github.com/qos-ch/logback) from 1.2.11 to 1.4.0.
- [Release notes](https://github.com/qos-ch/logback/releases)
- [Commits](https://github.com/qos-ch/logback/compare/v_1.2.11...v_1.4.0)

---
updated-dependencies:
- dependency-name: ch.qos.logback:logback-classic
  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-09-03 18:51:31 -05:00
dependabot[bot]
8b0b757f04 Bump org.jlleitschuh.gradle.ktlint from 10.3.0 to 11.0.0 (#1480)
Bumps org.jlleitschuh.gradle.ktlint from 10.3.0 to 11.0.0.

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

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-09-03 18:51:20 -05:00
13af054214 Use different request codes for showNumberPicker pendingIntent
Fixes #1468
2022-09-03 18:46:52 -05:00
fcbb586e80 Use pending intent templates on StackWidget
Fixes #1463
2022-09-03 17:51:55 -05:00
458c9f3b15 Merge branch 'release/2.1.0' into dev 2022-08-17 05:53:48 -05:00
dfa74960b3 Merge branch 'release/2.1.0' into dev 2022-08-17 05:51:36 -05:00
f082842fbe Update Gradle, AGP & Kotlin 2022-08-17 05:36:37 -05:00
d4d818a085 Upgrade dependencies 2022-08-16 05:42:29 -05:00
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
Jakub Kalinowski
428bf42e79 Reimplementing the multiple popups handling in the new popup solution. (#1454)
Co-authored-by: Jakub Kalinowski <kalj@netcompany.com>
2022-08-14 13:25:01 -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
838e13f30c Prevent crashes in AutoBackup from blocking app launch 2022-08-13 07:25:12 -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
0eae43fe55 Fix "enter" notification action on API 31 2022-08-11 05:17:41 -05:00
c0fcd4e763 Update CHANGELOG 2022-08-11 04:08:22 -05:00
79e2402c9d Merge pull request #1425 from eduebernal/freq-display-normal
fix marker scaling in frequency display
2022-08-11 04:04:29 -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
53c270ee12 Merge branch 'number-popup' into release/2.1.0 2022-07-30 16:41:05 -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
0a95b6d2a0 GitHub Actions: Use self-hosted runner 2022-05-16 22:53:35 -05:00
e6bcbb39ff GitHub Actions: Enable AVD cache 2022-05-16 15:26:57 -05:00
90de1f3723 GitHub Actions: Implement emulator boot timeout 2022-05-15 10:42:07 -05:00
68740b4043 SettingsFragment: Minor changes to theme 2022-05-15 09:23:47 -05:00
b66a6ff717 Write release notes 2022-05-15 00:33:36 -05:00
7c1a91e35a Update list of translators 2022-05-15 00:23:27 -05:00
366e9af167 Update translations 2022-05-15 00:15:56 -05:00
03b02aaa06 Merge branch 'number-popup' into release/2.1.0 2022-05-14 23:22:28 -05:00
Quentin Hibon
180cf25ad3 Fix tests in APIs 30, 31 2022-05-14 17:19:53 -05:00
3490cd183a GitHub Actions: Re-run only failed tests; warn about slow tests 2022-05-14 08:45:24 -05:00
Quentin Hibon
0c292d1eaa Make some rendering tests more tolerant 2022-05-13 11:57:54 -05:00
0b256cb2c0 GitHub Actions: Enable API 30, 31; drop some older ones 2022-05-13 11:19:05 -05:00
cc03c48648 TargetCard: Make target more accurate for non-daily habits 2022-05-13 09:53:27 -05:00
53e7ef2918 LoopDBImporter: Improve performance; silence snackbar messages 2022-05-13 08:33:00 -05:00
9609bee0f7 Update CHANGELOG and list of developers 2022-05-13 08:33:00 -05:00
5b23a3f960 Bump version to 2.1.0 2022-05-13 08:33:00 -05: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
b7232b12cd server: Update paths 2022-01-12 08:34:59 -06:00
8cd5b93b47 server: Make registration implicit 2022-01-12 08:15:40 -06:00
1b07efe291 server: Move some classes to uhabits-core; reorganize 2022-01-12 08:00:57 -06:00
232b25bed4 server: Delete links 2022-01-12 07:28:51 -06:00
2ea6fe0570 Apply ktlint to uhabits-server 2022-01-12 07:24:28 -06:00
bb8b742dc4 server: Delete links 2022-01-12 07:21:34 -06:00
85b52a9840 Start implementation of SyncActivity 2022-01-10 16:51:18 -06: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
774412492f Restore x_times_per_y_days translations 2021-12-29 09:59:56 -06:00
370ddfb8db Merge branch 'dev' into feature/sync2 2021-12-29 08:59:55 -06:00
1567e2c0ad Implement basic cryptography functions 2021-12-29 08:59:50 -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
415 changed files with 26381 additions and 2638 deletions

View File

@@ -7,59 +7,24 @@ on:
paths-ignore:
- '**.md'
jobs:
Build:
runs-on: ubuntu-latest
Test:
runs-on: self-hosted
steps:
- name: Check out source code
uses: actions/checkout@v1
- name: Install Java Development Kit 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build Project
- name: Build project
run: ./build.sh build
- name: Upload Build Artifacts
- name: Run Android tests
run: ./build.sh android-tests-parallel 28 29 30 31 32 33
- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v2
with:
name: uhabits-android
path: uhabits-android/build/outputs/
AndroidTest:
needs: Build
runs-on: macOS-10.15
timeout-minutes: 60
strategy:
matrix:
api: [
23,
24,
25,
26,
27,
28,
# 29, # Crashes constantly, see: https://issuetracker.google.com/issues/159732638
# 30, # Not available yet
# 31, # Not available yet
]
steps:
- name: Check out source code
uses: actions/checkout@v1
- name: Download Previously Built APK
uses: actions/download-artifact@v2
with:
name: uhabits-android
path: uhabits-android/build/outputs/
- name: Install flock
run: |
brew install util-linux
echo "/usr/local/opt/util-linux/bin" >> $GITHUB_PATH
- name: Run Android Tests
run: ./build.sh android-tests ${{ matrix.api }}
name: build
path: |
build/*log
uhabits-android/build/outputs

5
.gitignore vendored
View File

@@ -12,13 +12,8 @@
.idea
.secret
build
build/
captures
local.properties
node_modules
*xcuserdata*
*.sketch
/design
/releases
/screenshots
crowdin.yml

View File

@@ -1,16 +0,0 @@
#!/bin/sh
cd "$(dirname "$0")"
if [ -z "$GPG_PASSWORD" ]; then
echo Env variable GPG_PASSWORD must be defined
exit 1
fi
gpg \
--quiet \
--batch \
--yes \
--decrypt \
--passphrase="$GPG_PASSWORD" \
--output secret.tar.gz \
secret
tar -xzf secret.tar.gz
rm secret.tar.gz

Binary file not shown.

View File

@@ -1,5 +1,42 @@
# Changelog
## [2.1.0] -- 2022-09-10
### Added
- Allow user to add notes to specific dates (@vbh, #1103)
- Allow user to track "at most" numerical habits (@KristianTashkov, #1101)
- Allow user to add skips to measurable habits (@kalina559, #1319)
- Bring back custom frequencies (x times in y days) (@hiqua, #1079)
- Improve number picker (@hiqua, @iSoron, #1082, #1370)
- Add new checkmark and number picker (@iSoron, #1370)
- Allow user to import numerical habits from HabitBull (@hiqua, #1278)
- Add support for Android 13 themed icons (@cheeeeer, #1497)
### Removed
- Hide snooze button Android 12 notifications (@hiqua, #1226)
- Remove preference to set LED lights (@iSoron)
### Changed
- Hide failed habits along with completed ones (@hiqua, #1052)
- Cycle through all checkmark states when toggling (@iSoron)
- Add delay after toggling a habit (@hiqua, @kalina559, #1147)
- Small theme improvements (@KristianTashkov, #1113)
- Left-align habit notes (@iSoron)
- Increase target SDK to 31 (@hiqua)
### Fixed
- Fix small dialog buttons (@kalina559, #1096)
- Fix invalid CSV files (@hiqua, #1177)
- Fix small issues in calendar chart (@kalina559, #1314)
- Resort habit list after edit (@hiqua, #1350)
- Fix marker scaling in frequency display (@eduebernal, #1425)
- Fix widgets not working correctly on API 33 (@iSoron, #1488)
### Refactoring & Testing
- Replace raster icons by vector assets (@kalina559)
- Remove JVM dependencies from uhabits-core module (@sgallese)
- Add various missing tests (@sgallese)
- Upgrade project dependencies (@hiqua, @sgallese)
## [2.0.3] - 2021-08-21
### Fixed
- Improve automatic checkmarks for monthly habits (@iSoron, #947)

View File

@@ -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.
* **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

View File

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

128
build.sh
View File

@@ -26,6 +26,7 @@ GRADLE="./gradlew --stacktrace --quiet"
PACKAGE_NAME=org.isoron.uhabits
SDKMANAGER="${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager"
VERSION=$(grep versionName uhabits-android/build.gradle.kts | sed -e 's/.*"\([^"]*\)".*/\1/g')
BOOT_TIMEOUT=360
if [ -z $VERSION ]; then
echo "Could not parse app version from: uhabits-android/build.gradle.kts"
@@ -69,8 +70,7 @@ core_build() {
# Android
# -----------------------------------------------------------------------------
# shellcheck disable=SC2016
android_test() {
android_setup() {
API=$1
AVDNAME=${AVD_PREFIX}${API}
@@ -85,25 +85,63 @@ android_test() {
$AVDMANAGER delete avd --name $AVDNAME
log_info "Creating new Android virtual device (API $API)..."
(echo "y" | $SDKMANAGER --install "system-images;android-$API;default;x86_64") || return 1
(echo "y" | $SDKMANAGER --install "system-images;android-$API;google_apis;x86_64") || return 1
$AVDMANAGER create avd \
--name $AVDNAME \
--package "system-images;android-$API;default;x86_64" \
--package "system-images;android-$API;google_apis;x86_64" \
--device "Nexus 4" || return 1
flock -u 10
) 10>/tmp/uhabitsTest.lock
log_info "Launching emulator..."
$EMULATOR -avd $AVDNAME -port 6${API}0 1>/dev/null 2>&1 &
$EMULATOR \
-avd $AVDNAME \
-port 6${API}0 \
1>/dev/null 2>&1 &
log_info "Waiting for emulator to boot..."
export ADB="$ADB -s emulator-6${API}0"
timeout $BOOT_TIMEOUT $ADB wait-for-device shell 'while [[ -z "$(getprop sys.boot_completed)" ]]; do echo Waiting...; sleep 1; done; input keyevent 82'
if [ $? -ne 0 ]; then
log_error "Emulator failed to boot after $BOOT_TIMEOUT seconds."
return 1
fi
log_info "Saving snapshot..."
$ADB emu avd snapshot save fresh-install
}
android_boot_attempt() {
API=$1
AVDNAME=${AVD_PREFIX}${API}
log_info "Stopping Android emulator..."
while [[ -n $(pgrep -f ${AVDNAME}) ]]; do
pkill -9 -f ${AVDNAME}
done
log_info "Launching emulator..."
$EMULATOR \
-avd $AVDNAME \
-port 6${API}0 \
-snapshot fresh-install \
-no-snapshot-save \
-wipe-data \
1>/dev/null 2>&1 &
log_info "Waiting for emulator to boot..."
export ADB="$ADB -s emulator-6${API}0"
$ADB wait-for-device shell 'while [[ -z "$(getprop sys.boot_completed)" ]]; do echo Waiting...; sleep 1; done; input keyevent 82' || return 1
$ADB root || return 1
sleep 5
timeout $BOOT_TIMEOUT $ADB wait-for-device shell 'while [[ -z "$(getprop sys.boot_completed)" ]]; do echo Waiting...; sleep 1; done; input keyevent 82'
if [ $? -ne 0 ]; then
log_error "Emulator failed to boot after $BOOT_TIMEOUT seconds."
return 1
fi
log_info "Disabling animations..."
$ADB root || return 1
sleep 5
$ADB shell settings put global window_animation_scale 0 || return 1
$ADB shell settings put global transition_animation_scale 0 || return 1
$ADB shell settings put global animator_duration_scale 0 || return 1
@@ -111,6 +149,24 @@ android_test() {
log_info "Acquiring wake lock..."
$ADB shell 'echo android-test > /sys/power/wake_lock' || return 1
}
android_boot() {
for attempt in {1..5}; do
android_boot_attempt $1 && return 0
sleep 5
done
log_error "Too many failed attempts. Aborting."
return 1
}
# shellcheck disable=SC2016
android_test() {
API=$1
AVDNAME=${AVD_PREFIX}${API}
android_boot $API || return 1
if [ -n "$RELEASE" ]; then
log_info "Installing release APK..."
$ADB install -r ${ANDROID_OUTPUTS_DIR}/apk/release/uhabits-android-release.apk || return 1
@@ -122,14 +178,25 @@ android_test() {
$ADB install -r ${ANDROID_OUTPUTS_DIR}/apk/androidTest/debug/uhabits-android-debug-androidTest.apk || return 1
for size in medium large; do
log_info "Running $size instrumented tests..."
OUT_INSTRUMENT=${ANDROID_OUTPUTS_DIR}/instrument-${API}.txt
OUT_LOGCAT=${ANDROID_OUTPUTS_DIR}/logcat-${API}.txt
$ADB shell am instrument \
-r -e coverage true -e size $size \
-w ${PACKAGE_NAME}.test/androidx.test.runner.AndroidJUnitRunner \
| tee $OUT_INSTRUMENT
if grep "\(INSTRUMENTATION_STATUS_CODE.*-1\|FAILURES\|ABORTED\|onError\|Error type\|crashed\)" $OUT_INSTRUMENT; then
FAILED_TESTS=""
for i in {1..5}; do
log_info "Running $size instrumented tests (attempt $i)..."
$ADB shell am instrument \
-r -e coverage true -e size "$size" $FAILED_TESTS \
-w ${PACKAGE_NAME}.test/androidx.test.runner.AndroidJUnitRunner \
| ts "%.s" | tee "$OUT_INSTRUMENT"
FAILED_TESTS=$(tools/parseInstrument.py "$OUT_INSTRUMENT")
SUCCESS=$?
if [ $SUCCESS -eq 0 ]; then
log_info "$size tests passed."
break
fi
done
if [ $SUCCESS -ne 0 ]; then
log_error "Some $size instrumented tests failed."
log_error "Saving logcat: $OUT_LOGCAT..."
$ADB logcat -d > $OUT_LOGCAT
@@ -138,13 +205,14 @@ android_test() {
$ADB shell rm -r /sdcard/Android/data/${PACKAGE_NAME}/files/test-screenshots/
return 1
fi
log_info "$size tests passed."
done
return 0
}
android_test_parallel() {
# Launch background processes
PIDS=""
for API in $*; do
(
LOG=build/android-test-$API.log
@@ -152,12 +220,27 @@ android_test_parallel() {
if android_test $API 1>$LOG 2>&1; then
log_info "API $API: Passed"
else
log_error "API $API: Failed. See $LOG for more details."
log_error "API $API: Failed"
fi
pkill -9 -f ${AVD_PREFIX}${API}
)&
PIDS+=" $!"
done
wait
# Check exit codes
RET_CODE=0
for pid in $PIDS; do
wait $pid || RET_CODE=1
done
# Print all logs
for API in $*; do
echo "::group::Android Tests (API $API)"
cat build/android-test-$API.log
echo "::endgroup::"
done
return $RET_CODE
}
android_build() {
@@ -229,12 +312,14 @@ CI/CD script for Loop Habit Tracker.
Usage:
build.sh build [options]
build.sh android-setup <API>
build.sh android-tests <API> [options]
build.sh android-tests-parallel <API> <API>... [options]
build.sh android-accept-images [options]
Commands:
build Build the app and run small tests
android-setup Create Android virtual machine
android-tests Run medium and large Android tests on an emulator
android-tests-parallel Tests multiple API levels simultaneously
android-accept-images Copy fetched images to corresponding assets folder
@@ -270,18 +355,17 @@ main() {
core_build
android_build
;;
android-setup)
shift; _parse_opts "$@"
android_setup $1
;;
android-tests)
shift; _parse_opts "$@"
if [ -z $1 ]; then
_print_usage
exit 1
fi
for attempt in {1..5}; do
log_info "Running Android tests (attempt $attempt)..."
android_test $1 && return 0
done
log_error "Maximum number of attempts reached. Failing."
return 1
android_test $1
;;
android-tests-parallel)
shift; _parse_opts "$@"

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".
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.
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.

View File

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

View File

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

2
landing/.gitignore vendored
View File

@@ -1,2 +0,0 @@
out/
.sass-cache

View File

@@ -1,27 +0,0 @@
haml := src/*.haml
sass := src/*.sass
html := $(patsubst src/%, out/%, $(patsubst %.haml,%.html,$(wildcard $(haml))))
css := $(patsubst src/%, out/%, $(patsubst %.sass,%.css,$(wildcard $(sass))))
src := $(wildcard src/**)
compile: $(html) $(css)
@rsync -rupE assets/ out/
out/%.css: src/%.sass $(src)
@echo ' sass $<'
@mkdir -p `dirname $@`
@sass $< $@
out/%.html: src/%.haml $(src)
@echo ' haml $<'
@mkdir -p `dirname $@`
@haml -E UTF-8 $< $@
push:
rsync -avP out/ axavier.org:/www/loophabits.org/
clean:
@rm -rfv out
@rm -rfv tmp

View File

@@ -1,27 +0,0 @@
Loop Habit Tracker Landing Page
===============================
This folder contains the source code that generates the project landing page, currently hosted at https://loophabits.org/
Pull requests with ideas for improving it are very welcome.
Build instructions
------------------
1. Install `haml`:
```bash
sudo apt install ruby-haml
```
2. Install `pandoc-ruby`:
```bash
gem install pandoc-ruby
```
3. Run `Makefile`
```bash
make
```
4. View the results (using, for example, [npm serve](https://www.npmjs.com/package/serve))
```bash
npm serve out/
```

View File

@@ -1 +0,0 @@
<meta http-equiv="Refresh" content="0; url='https://github.com/iSoron/uhabits/discussions/689'" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 458 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -1,106 +0,0 @@
!!! 5
%html
%head
%meta(charset="UTF-8")
%link(href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css")
%meta(name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no")
%title Loop Habit Tracker
%link(rel="stylesheet" type="text/css" href="lib/css/bootstrap.min.css")
%link(rel="stylesheet" type="text/css" href="index.css")
%body
.navbar.navbar-expand-md.navbar-light.bg-light
%a.navbar-brand(href="/")
%b Loop
Habit Tracker
%button.navbar-toggler(type="button" data-toggle="collapse" data-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation")
%span.navbar-toggler-icon
#navbar.collapse.navbar-collapse
%ul.navbar-nav.mr-auto.mt-2.mt-lg-0
%li.nav-item
%a.nav-link(href="faq.html") FAQ
%li.nav-item
%a.nav-link(href="privacy.html") Privacy
%li.nav-item
%a.nav-link(href="https://source.loophabits.org") Source Code
%li.nav-item
%a.nav-link(href="https://translate.loophabits.org") Translate
.jumbotron.jumbotron-fluid
.site-wrapper
.container
.row.vertical-align
.col-md
%h1.display-4
Get your life on track
%p.lead
With daily reminders, beautiful charts and insightful statistics,
Loop Habit Tracker&trade; helps you create and maintain great habits. Completely free and open-source.
.store-badges
%a(href="https://play.google.com/store/apps/details?id=org.isoron.uhabits")
%img(src="images/google-play.png")
%a(href="https://f-droid.org/en/packages/org.isoron.uhabits/")
%img(src="images/f-droid.png")
.col-md
.s2
%img.screenshot(src="screenshots/uhabits1.png")
.s1
%img.screenshot(src="screenshots/uhabits4.png")
.section.screenshots
%span
%a(href="screenshots/uhabits1.png")
%img(src="screenshots/uhabits1_th.png")
%a(href="screenshots/uhabits2.png")
%img(src="screenshots/uhabits2_th.png")
%a(href="screenshots/uhabits3.png")
%img(src="screenshots/uhabits3_th.png")
%span
%a(href="screenshots/uhabits4.png")
%img(src="screenshots/uhabits4_th.png")
%a(href="screenshots/uhabits5.png")
%img(src="screenshots/uhabits5_th.png")
.section
.feature-header
%h1
Features
.container
.row
.col-md
%ul
%li
%h3 Habit score
Loop has an advanced formula for calculating the strength of your habits. Every repetition makes your habit stronger and every missed day makes it weaker. A few missed days after a long streak, however, will not completely destroy your progress, unlike many other don't-break-the-chain apps.
%li
%h3 Flexible schedules
In addition to daily habits, Loop supports habits with more complex schedules, such as 3 times per week or every other day.
%li
%h3 Reminders
Schedule notifications to remind you of your habits. Each habit can have its own reminder, at a chosen time of the day. Easily check or dismiss your habit directly from the notification.
%li
%h3 Widgets
Be reminded of your habits whenever you unlock your phone. Colorful widgets allow you to track your habits directly from your home screen, without even opening the app.
.col-md
%ul
%li
%h3 Take control of your data
If you want to further analyze your data, or move it to another service, Loop allows you to export it to spreadsheets (CSV) or to a database file (SQLite). For power users, check marks can be added through task automation apps such as Tasker.
%li
%h3 No limitations
Track as many habits as you wish. Loop imposes no artificial limits on how many habits you can have. All features are available to all users, and there are no in-app purchases.
%li
%h3 Completely ad-free and open source
There are no advertisements, annoying notifications or intrusive permissions in this app, and there will never be. The app is completely open-source (GPLv3).
%li
%h3 Works offline and respects your privacy
Loop doesn't require an Internet connection or online account registration. Your confidential data is never sent to anyone. Neither the developers nor any third-parties have access to it.
.section.footer
Copyright © 2016&ndash;2020, Alinson Santos Xavier. All Rights Reserved.
%script(type="text/javascript" src="lib/js/jquery.min.js")
%script(type="text/javascript" src="lib/js/bootstrap.bundle.min.js")

View File

@@ -1,104 +0,0 @@
html, body
max-width: 100%
overflow-x: hidden
body
font-family: 'Open Sans', sans-serif
padding-bottom: 0
a, a:hover
text-decoration: none
.navbar
box-shadow: rgba(0,0,0,0.4) 0px 0px 20px
background-color: white !important
.nav-link
margin: 0px 18px
.section
background-color: transparent
padding: 18px 0px
.container
ul
list-style-type: none
h3
font-size: 16px
font-weight: bold
margin: 18px 0px 0px 0px
.screenshots
text-align: center
background-color: #222
img
margin: 0.5%
border-radius: 10px
border: 3px solid #fff2
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.5)
max-width: 17%
.footer
color: #888
background-color: #222
text-align: center
font-size: 12px
.jumbotron
background: linear-gradient(rgba(0,30,200,0.8),rgba(90,30,150,0.5)), url("images/hero-background-filter.jpg")
box-shadow: rgba(0,0,0,0.5) 0px 0px 20px
margin: 0
h1
max-width: 25rem
font-weight: bold
color: white
p
max-width: 40rem
color: white
.screenshot
box-shadow: rgba(0, 0, 0, 0.5) 5px 5px 20px
padding: 0px 0px 0px 0px
border-radius: 10px
border: 2px solid rgba(255, 255, 255, 0.2)
background-color: transparent
max-width: 300px
.store-badges
margin: 2rem 1rem
img
opacity: 0.8
height: 75px
img:hover
opacity: 1.0
.s1
padding-bottom: 50px
padding-left: 50px
.s2
position: absolute
top: 50px
left: 175px
.feature-header
text-align: center
font-weight: bold
padding: 18px
.align-right
text-align: right
.vertical-align
display: flex
align-items: center
.content
max-width: 800px
margin: 18px auto
padding: 0px 18px
//padding-left: 120px
h2, h3, h4
margin: 27px 0px 9px 0px
h2, h3
//margin-left: -120px
h4
//margin-left: -60px
font-size: 16px
font-weight: bold

View File

@@ -1,32 +0,0 @@
!!! 5
%html
%head
%meta(charset="UTF-8")
%link(href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css")
%meta(name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no")
%title Privacy | Loop Habit Tracker
%link(rel="stylesheet" type="text/css" href="lib/css/bootstrap.min.css")
%link(rel="stylesheet" type="text/css" href="index.css")
%body
.navbar.navbar-expand-md.navbar-light.bg-light
%a.navbar-brand(href="/")
%b Loop
Habit Tracker
%button.navbar-toggler(type="button" data-toggle="collapse" data-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation")
%span.navbar-toggler-icon
#navbar.collapse.navbar-collapse
%ul.navbar-nav.mr-auto.mt-2.mt-lg-0
%li.nav-item
%a.nav-link(href="faq.html") FAQ
%li.nav-item
%a.nav-link(href="privacy.html") Privacy
%li.nav-item
%a.nav-link(href="https://source.loophabits.org") Source Code
%li.nav-item
%a.nav-link(href="https://translate.loophabits.org") Translate
%body
.content
:markdown
#{File.open("src/privacy.md").read}

View File

@@ -1,14 +0,0 @@
## Privacy Policy
- All data provided to Loop Habit Tracker is only stored locally in your
device. Loop Habit Tracker does not upload your data anywhere. The
developers of Loop Habit Tracker do not have access to your data.
- Your data is not shared with any 3rd parties. Loop Habit Tracker does not
include any advertisement libraries or any 3rd party tracking (analytics)
code, such as Google Analytics or Facebook SDK.
- If you have activated "backup & reset" in your phone settings (Settings /
Backup & Reset / Back up my data), you should be aware that Android itself
will periodically save a copy of your phone's data in Google's servers. The
developers of Loop Habit Tracker do not have access to this data.

View File

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

67
tools/parseInstrument.py Executable file
View File

@@ -0,0 +1,67 @@
#!/usr/bin/env python3
"""
Android Instrumentation Test Parser
Given a raw Android Instrumentation log (produced by "adb shell am instrument -r ...") this script
return zero if all tests pass and non-zero if some tests fail. In case of failure, this script
also prints arguments that, if passed to "am instrument", will cause it to re-run just the tests
that failed. This script additionally prints warnings about the tests on the STDERR; e.g. slow tests.
"""
import sys
import re
STATUS_START = 1
STATUS_DISABLED = -3
SLOW_TEST_THRESHOLD = 5.0
COLOR_RED = '\033[91m'
COLOR_YELLOW = '\033[93m'
COLOR_END = '\033[0m'
def error(msg):
sys.stderr.write("%s%s%s\n" % (COLOR_RED, msg, COLOR_END))
def warning(msg):
sys.stderr.write("%s%s%s\n" % (COLOR_YELLOW, msg, COLOR_END))
log_filename = sys.argv[1]
current_class, current_method = None, None
failed_tests = []
am_args = "-e class "
exit_code = 1
for line in open(log_filename).readlines():
matches = re.findall('^([0-9.]*)', line)
current_time = float(matches[0])
matches = re.findall('INSTRUMENTATION_STATUS: class=(.*)', line)
if len(matches) > 0:
current_class = matches[0]
matches = re.findall('INSTRUMENTATION_STATUS: test=(.*)', line)
if len(matches) > 0:
current_method = matches[0]
matches = re.findall('OK \([0-9]* tests?\)', line)
if len(matches) > 0:
exit_code = 0
matches = re.findall('INSTRUMENTATION_STATUS_CODE: ([-0-9]*)', line)
if len(matches) > 0:
status_code = int(matches[0])
if (status_code < 0) and (status_code != STATUS_DISABLED):
am_args += f"{current_class}#{current_method},"
failed_tests.append(f"{current_class}#{current_method}")
if status_code == STATUS_START:
initial_time = current_time
else:
elapsed_time = current_time - initial_time
if(elapsed_time > SLOW_TEST_THRESHOLD):
warning("SLOW %s#%s (%.2f seconds)" % (current_class, current_method, elapsed_time))
if len(failed_tests) > 0:
for test in failed_tests:
error("FAIL %s" % test)
print(am_args[:-1])
sys.exit(exit_code)

View File

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

View File

@@ -1,5 +1,3 @@
/*
* Copyright (C) 2016-2021 Álinson Santos Xavier <git@axavier.org>
*
@@ -20,7 +18,7 @@
*/
plugins {
id("com.github.triplet.play") version "3.5.0"
id("com.github.triplet.play") version "3.7.0"
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.kapt")
@@ -34,15 +32,15 @@ tasks.compileLint {
android {
compileSdkVersion(30)
compileSdk = 32
defaultConfig {
versionCode(20003)
versionName("2.0.3")
minSdkVersion(23)
targetSdkVersion(30)
applicationId("org.isoron.uhabits")
testInstrumentationRunner("androidx.test.runner.AndroidJUnitRunner")
versionCode = 20100
versionName = "2.1.0"
minSdk = 28
targetSdk = 31
applicationId = "org.isoron.uhabits"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
signingConfigs {
@@ -58,7 +56,7 @@ android {
buildTypes {
getByName("release") {
minifyEnabled(true)
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.txt")
if (signingConfigs.findByName("release") != null) {
signingConfig = signingConfigs.getByName("release")
@@ -70,12 +68,6 @@ android {
}
}
lintOptions {
isCheckReleaseBuilds = false
isAbortOnError = false
disable("GoogleAppIndexingWarning")
}
compileOptions {
isCoreLibraryDesugaringEnabled = true
targetCompatibility(JavaVersion.VERSION_1_8)
@@ -88,29 +80,29 @@ android {
}
dependencies {
val daggerVersion = "2.38.1"
val kotlinVersion = "1.5.21"
val kxCoroutinesVersion = "1.5.1"
val ktorVersion = "1.6.2"
val daggerVersion = "2.43.2"
val kotlinVersion = "1.7.10"
val kxCoroutinesVersion = "1.6.4"
val ktorVersion = "1.6.8"
val espressoVersion = "3.4.0"
androidTestImplementation("androidx.test.espresso:espresso-contrib:$espressoVersion")
androidTestImplementation("androidx.test.espresso:espresso-core:$espressoVersion")
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-jackson:$ktorVersion")
androidTestImplementation("androidx.annotation:annotation:1.2.0")
androidTestImplementation("androidx.annotation:annotation:1.4.0")
androidTestImplementation("androidx.test.ext:junit:1.1.3")
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.2.0")
androidTestImplementation("androidx.test:rules:1.4.0")
androidTestImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
compileOnly("javax.annotation:jsr250-api:1.0")
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5")
implementation("com.github.paolorotolo:appintro:4.1.0")
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.2")
implementation("com.github.AppIntro:AppIntro:6.2.0")
implementation("com.google.code.findbugs:jsr305:3.0.2")
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-core:$ktorVersion")
implementation("io.ktor:ktor-client-jackson:$ktorVersion")
@@ -118,11 +110,11 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$kxCoroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kxCoroutinesVersion")
implementation("androidx.appcompat:appcompat:1.3.1")
implementation("androidx.appcompat:appcompat:1.5.0")
implementation("androidx.legacy:legacy-preference-v14:1.0.0")
implementation("androidx.legacy:legacy-support-v4:1.0.0")
implementation("com.google.android.material:material:1.4.0")
implementation("com.opencsv:opencsv:5.5.1")
implementation("com.google.android.material:material:1.6.1")
implementation("com.opencsv:opencsv:5.6")
implementation(project(":uhabits-core"))
kapt("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: 20 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

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

View File

@@ -20,6 +20,7 @@
package org.isoron.uhabits.acceptance.steps
import android.os.Build.VERSION.SDK_INT
import android.os.SystemClock.sleep
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiSelector
import org.isoron.uhabits.BaseUserInterfaceTest.Companion.device
@@ -39,7 +40,7 @@ fun exportFullBackup() {
}
fun clearDownloadFolder() {
device.executeShellCommand("rm -rf /sdcard/Download/")
device.executeShellCommand("rm -rf /sdcard/Download")
}
fun clearBackupFolder() {
@@ -86,6 +87,7 @@ fun importBackupFromDownloadFolder() {
device.findObject(UiSelector().textContains("Loop")).click()
} else {
device.click(50, 90) // Click menu button
Thread.sleep(1000)
device.findObject(UiSelector().textContains("Download")).click()
device.findObject(UiSelector().textContains("Loop")).click()
}

View File

@@ -18,7 +18,9 @@
*/
package org.isoron.uhabits.acceptance.steps
import android.os.Build.VERSION
import android.os.Build
import android.os.Build.VERSION.SDK_INT
import android.os.Build.VERSION_CODES
import androidx.annotation.StringRes
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso
@@ -72,7 +74,7 @@ object CommonSteps : BaseUserInterfaceTest() {
}
fun offsetHeaders() {
device.swipe(750, 160, 600, 160, 20)
device.swipe(500, 160, 350, 160, 20)
}
fun scrollToText(text: String?) {
@@ -133,7 +135,7 @@ object CommonSteps : BaseUserInterfaceTest() {
@Throws(Exception::class)
fun verifyOpensWebsite(url: String?) {
var browserPkg = "org.chromium.webview_shell"
if (VERSION.SDK_INT <= 23) {
if (SDK_INT <= Build.VERSION_CODES.M) {
browserPkg = "com.android.browser"
}
assertTrue(device.wait(Until.hasObject(By.pkg(browserPkg)), 5000))
@@ -178,6 +180,22 @@ object CommonSteps : BaseUserInterfaceTest() {
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 {
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())
}
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) {
Espresso.onView(ViewMatchers.withId(R.id.colorButton)).perform(ViewActions.click())
BaseUserInterfaceTest.device.findObject(By.descStartsWith(String.format("Color %d", color)))

View File

@@ -53,6 +53,7 @@ object ListHabitsSteps {
clickViewWithId(R.id.action_filter)
CommonSteps.clickText(R.string.hide_completed)
}
else -> throw RuntimeException()
}
device.waitForIdle()
}
@@ -120,6 +121,12 @@ object ListHabitsSteps {
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 {
ABOUT, HELP, SETTINGS, EDIT, DELETE, ARCHIVE, TOGGLE_ARCHIVED, UNARCHIVE, TOGGLE_COMPLETED, ADD
}

View File

@@ -18,7 +18,7 @@
*/
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.UiSelector
import junit.framework.Assert.assertFalse
@@ -50,29 +50,21 @@ object WidgetSteps {
private fun openWidgetScreen() {
val h = BaseUserInterfaceTest.device.displayHeight
val w = BaseUserInterfaceTest.device.displayWidth
if (VERSION.SDK_INT <= 21) {
BaseUserInterfaceTest.device.pressHome()
BaseUserInterfaceTest.device.waitForIdle()
BaseUserInterfaceTest.device.findObject(UiSelector().description("Apps")).click()
BaseUserInterfaceTest.device.findObject(UiSelector().description("Apps")).click()
BaseUserInterfaceTest.device.findObject(UiSelector().description("Widgets")).click()
} else {
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"))
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 (SDK_INT >= 28) {
UiScrollable(UiSelector().resourceId(listId))
.scrollForward()
}
UiScrollable(UiSelector().resourceId(listId))
.scrollIntoView(UiSelector().text("Checkmark"))
}
@Throws(Exception::class)

View File

@@ -29,6 +29,10 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@MediumTest
class EmptyListViewTest : BaseViewTest() {
init {
// TODO: fix rendering differences across APIs
similarityCutoff = 0.00035
}
private val path = "habits/list/EmptyListView"
private val view: EmptyListView = EmptyListView(targetContext)

View File

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

View File

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

View File

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

View File

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

View File

@@ -53,8 +53,6 @@ class SubtitleCardViewTest : BaseViewTest() {
isNumerical = false,
question = "Did you meditate this morning?",
reminder = Reminder(8, 30, EVERY_DAY),
unit = "",
targetValue = 0.0,
theme = LightTheme(),
)
)

View File

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

View File

@@ -21,9 +21,12 @@ package org.isoron.uhabits.regression
import androidx.test.filters.LargeTest
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.LIST_HABITS
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.createHabit
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.ListHabitsSteps.MenuItem.ADD
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.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.YES_AUTO
import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL
import org.junit.Test
@@ -83,4 +89,37 @@ class ListHabitsRegressionTest : BaseUserInterfaceTest() {
offsetHeaders()
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,14 +24,15 @@ import android.widget.FrameLayout
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import org.hamcrest.CoreMatchers
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.isoron.uhabits.BaseViewTest
import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.models.EntryList
import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.Timestamp
import org.isoron.uhabits.core.utils.DateUtils.Companion.getTodayWithOffset
import org.junit.Test
import org.junit.runner.RunWith
@@ -42,10 +43,12 @@ class CheckmarkWidgetTest : BaseViewTest() {
private lateinit var habit: Habit
private lateinit var entries: EntryList
private lateinit var view: FrameLayout
private val today = getTodayWithOffset()
private lateinit var today: Timestamp
override fun setUp() {
super.setUp()
setTheme(R.style.WidgetTheme)
today = getTodayWithOffset()
prefs.widgetOpacity = 255
prefs.isSkipEnabled = true
habit = fixtures.createVeryLongHabit()

View File

@@ -32,6 +32,10 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@MediumTest
class TargetWidgetTest : BaseViewTest() {
init {
// TODO: fix rendering differences across APIs
similarityCutoff = 0.00025
}
private lateinit var habit: Habit
private lateinit var view: FrameLayout
override fun setUp() {

View File

@@ -17,9 +17,10 @@
~ with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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.RECEIVE_BOOT_COMPLETED" />
@@ -48,11 +49,11 @@
android:name=".activities.habits.list.ListHabitsActivity"
android:exported="true"
android:label="@string/main_activity_title"
android:launchMode="singleTop">
</activity>
android:launchMode="singleTop" />
<activity-alias
android:name=".MainActivity"
android:exported="true"
android:label="@string/main_activity_title"
android:launchMode="singleTop"
android:targetActivity=".activities.habits.list.ListHabitsActivity">
@@ -78,6 +79,14 @@
android:value=".activities.habits.list.ListHabitsActivity" />
</activity>
<activity
android:name=".activities.sync.SyncActivity"
android:label="@string/device_sync">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.sync.SyncActivity" />
</activity>
<activity
android:name=".activities.intro.IntroActivity"
android:label=""
@@ -85,6 +94,7 @@
<activity
android:name=".widgets.activities.HabitPickerDialog"
android:exported="true"
android:theme="@style/Theme.AppCompat.Light.Dialog">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
@@ -93,6 +103,7 @@
<activity
android:name=".widgets.activities.BooleanHabitPickerDialog"
android:exported="true"
android:theme="@style/Theme.AppCompat.Light.Dialog">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
@@ -101,6 +112,7 @@
<activity
android:name=".widgets.activities.NumericalHabitPickerDialog"
android:exported="true"
android:theme="@style/Theme.AppCompat.Light.Dialog">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
@@ -115,26 +127,16 @@
android:value=".activities.habits.list.ListHabitsActivity" />
</activity>
<activity
android:name=".widgets.activities.NumericalCheckmarkWidgetActivity"
android:label="NumericalCheckmarkWidget"
android:noHistory="true"
android:excludeFromRecents="true"
android:theme="@style/Theme.AppCompat.Light.Dialog">
<intent-filter>
<action android:name="org.isoron.uhabits.ACTION_SHOW_NUMERICAL_VALUE_ACTIVITY" />
</intent-filter>
</activity>
<activity
android:name=".notifications.SnoozeDelayPickerActivity"
android:taskAffinity=""
android:excludeFromRecents="true"
android:launchMode="singleInstance"
android:taskAffinity=""
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<receiver
android:name=".widgets.CheckmarkWidgetProvider"
android:exported="true"
android:label="@string/checkmark">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -152,6 +154,7 @@
<receiver
android:name=".widgets.HistoryWidgetProvider"
android:exported="true"
android:label="@string/history">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -164,6 +167,7 @@
<receiver
android:name=".widgets.ScoreWidgetProvider"
android:exported="true"
android:label="@string/score">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -176,6 +180,7 @@
<receiver
android:name=".widgets.StreakWidgetProvider"
android:exported="true"
android:label="@string/streaks">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -188,6 +193,7 @@
<receiver
android:name=".widgets.FrequencyWidgetProvider"
android:exported="true"
android:label="@string/frequency">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -200,6 +206,7 @@
<receiver
android:name=".widgets.TargetWidgetProvider"
android:exported="true"
android:label="@string/target">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -210,13 +217,17 @@
android:resource="@xml/widget_target_info" />
</receiver>
<receiver android:name=".receivers.ReminderReceiver">
<receiver
android:name=".receivers.ReminderReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".receivers.WidgetReceiver">
<receiver android:name=".receivers.WidgetReceiver"
android:exported="true"
android:permission="false">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="org.isoron.uhabits.ACTION_SET_NUMERICAL_VALUE" />
@@ -267,7 +278,7 @@
<!-- Locale/Tasker -->
<receiver
android:name=".automation.FireSettingReceiver"
android:exported="true">
android:exported="false">
<intent-filter>
<action android:name="com.twofortyfouram.locale.intent.action.FIRE_SETTING" />
</intent-filter>

View File

@@ -22,7 +22,6 @@ import android.animation.Keyframe;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.annotation.SuppressLint;
import android.os.Build;
import android.text.format.Time;
import android.view.View;
@@ -43,17 +42,13 @@ public class Utils {
static final String SHARED_PREFS_NAME = "com.android.calendar_preferences";
public static boolean isJellybeanOrLater() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
}
/**
* Try to speak the specified text, for accessibility. Only available on JB or later.
* @param text Text to announce.
*/
@SuppressLint("NewApi")
public static void tryAccessibilityAnnounce(View view, CharSequence text) {
if (isJellybeanOrLater() && view != null && text != null) {
if (view != null && text != null) {
view.announceForAccessibility(text);
}
}

View File

@@ -383,10 +383,6 @@ public abstract class DayPickerView extends ListView implements OnScrollListener
if (child instanceof MonthView) {
final CalendarDay focus = ((MonthView) child).getAccessibilityFocus();
if (focus != null) {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR1) {
// Clear focus to avoid ListView bug in Jelly Bean MR1.
((MonthView) child).clearAccessibilityFocus();
}
return focus;
}
}

View File

@@ -49,23 +49,12 @@ class AndroidDataView(
override fun onShowPress(e: MotionEvent?) = Unit
override fun onSingleTapUp(e: MotionEvent?): 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
}
view?.onClick(x / canvas.innerDensity, y / canvas.innerDensity)
return true
return handleClick(e, true)
}
override fun onLongPress(e: MotionEvent?) = Unit
override fun onLongPress(e: MotionEvent?) {
handleClick(e)
}
override fun onScroll(
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

@@ -0,0 +1,128 @@
/*
* 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.dismissCurrentAndShow
import org.isoron.uhabits.utils.dp
import org.isoron.uhabits.utils.sres
const val POPUP_WIDTH = 4 * 48f + 16f
const val POPUP_HEIGHT = 48f * 2.5f + 8f
class CheckmarkPopup(
private val context: Context,
private val color: Int,
private var notes: String,
private var value: Int,
private val prefs: Preferences,
private val anchor: View,
) {
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.dismissCurrentAndShow()
}
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() {
fun setListener(callback: OnColorPickedCallback) {
super.setOnColorSelectedListener { c: Int ->
val pc = c.toPaletteColor(context!!)
val pc = c.toPaletteColor(requireContext())
callback.onColorPicked(pc)
}
}

View File

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

View File

@@ -19,6 +19,7 @@
package org.isoron.uhabits.activities.common.dialogs
import android.app.Dialog
import android.content.DialogInterface
import android.os.Bundle
import androidx.appcompat.app.AppCompatDialogFragment
import org.isoron.platform.gui.AndroidDataView
@@ -43,18 +44,19 @@ class HistoryEditorDialog : AppCompatDialogFragment(), CommandRunner.Listener {
private lateinit var commandRunner: CommandRunner
private lateinit var habit: Habit
private lateinit var preferences: Preferences
private lateinit var dataView: AndroidDataView
lateinit var dataView: AndroidDataView
private var chart: HistoryChart? = null
private var onDateClickedListener: OnDateClickedListener? = null
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val component = (activity!!.application as HabitsApplication).component
clearCurrentDialog()
val component = (requireActivity().application as HabitsApplication).component
commandRunner = component.commandRunner
habit = component.habitList.getById(arguments!!.getLong("habit"))!!
habit = component.habitList.getById(requireArguments().getLong("habit"))!!
preferences = component.preferences
val themeSwitcher = AndroidThemeSwitcher(activity!!, preferences)
val themeSwitcher = AndroidThemeSwitcher(requireActivity(), preferences)
themeSwitcher.apply()
chart = HistoryChart(
@@ -62,20 +64,30 @@ class HistoryEditorDialog : AppCompatDialogFragment(), CommandRunner.Listener {
firstWeekday = preferences.firstWeekday,
paletteColor = habit.color,
series = emptyList(),
defaultSquare = HistoryChart.Square.OFF,
notesIndicators = emptyList(),
theme = themeSwitcher.currentTheme,
today = DateUtils.getTodayWithOffset().toLocalDate(),
onDateClickedListener = onDateClickedListener ?: OnDateClickedListener { },
onDateClickedListener = onDateClickedListener ?: object : OnDateClickedListener {},
padding = 10.0,
)
dataView = AndroidDataView(context!!, null)
dataView = AndroidDataView(requireContext(), null)
dataView.view = chart!!
return Dialog(context!!).apply {
val dialog = Dialog(requireContext()).apply {
val metrics = resources.displayMetrics
val maxHeight = resources.getDimensionPixelSize(R.dimen.history_editor_max_height)
setContentView(dataView)
window!!.setLayout(metrics.widthPixels, min(metrics.heightPixels, maxHeight))
}
currentDialog = dialog
return dialog
}
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
currentDialog = null
}
override fun onResume() {
@@ -101,10 +113,22 @@ class HistoryEditorDialog : AppCompatDialogFragment(), CommandRunner.Listener {
theme = LightTheme()
)
chart?.series = model.series
chart?.defaultSquare = model.defaultSquare
chart?.notesIndicators = model.notesIndicators
dataView.postInvalidate()
}
override fun onCommandFinished(command: Command) {
refreshData()
}
companion object {
// HistoryEditorDialog handles multiple dialogs on its own,
// because sometimes we want it to be shown under another dialog (e.g. NumberPopup)
var currentDialog: Dialog? = null
fun clearCurrentDialog() {
currentDialog?.dismiss()
currentDialog = null
}
}
}

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

View File

@@ -60,7 +60,7 @@ class WeekdayPickerDialog :
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(
activity!!
requireActivity()
)
builder
.setTitle(R.string.select_weekdays)
@@ -73,6 +73,7 @@ class WeekdayPickerDialog :
.setNegativeButton(
android.R.string.cancel
) { _: DialogInterface?, _: Int -> dismiss() }
return builder.create()
}

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.getStartOfTodayCalendarWithOffset
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.StyledResources
import org.isoron.uhabits.utils.toSimpleDataFormat
@@ -64,6 +65,7 @@ class FrequencyChart : ScrollableChart {
private lateinit var frequency: HashMap<Timestamp, Array<Int>>
private var maxFreq = 0
private var firstWeekday = Calendar.SUNDAY
private var isNumerical: Boolean = false
constructor(context: Context?) : super(context) {
init()
@@ -80,6 +82,11 @@ class FrequencyChart : ScrollableChart {
postInvalidate()
}
fun setIsNumerical(type: Boolean) {
isNumerical = type
postInvalidate()
}
fun setFrequency(frequency: java.util.HashMap<Timestamp, Array<Int>>) {
this.frequency = frequency
maxFreq = getMaxFreq(frequency)
@@ -166,6 +173,7 @@ class FrequencyChart : ScrollableChart {
private fun drawColumn(canvas: Canvas, rect: RectF?, date: GregorianCalendar) {
val values = frequency[Timestamp(date)]
val weekDaysInMonth = getWeekdaysInMonth(Timestamp(date))
val rowHeight = rect!!.height() / 8.0f
prevRect!!.set(rect)
val localeWeekdayList: Array<Int> = getWeekdaySequence(firstWeekday)
@@ -173,7 +181,8 @@ class FrequencyChart : ScrollableChart {
rect[0f, 0f, baseSize.toFloat()] = baseSize.toFloat()
rect.offset(prevRect!!.left, prevRect!!.top + baseSize * j)
val i = localeWeekdayList[j] % 7
if (values != null) drawMarker(canvas, rect, values[i])
if (values != null)
drawMarker(canvas, rect, values[i], weekDaysInMonth[i])
rect.offset(0f, rowHeight)
}
drawFooter(canvas, rect, date)
@@ -221,12 +230,16 @@ class FrequencyChart : ScrollableChart {
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?, weekdayFrequency: Int) {
// value can be negative when the entry is skipped
val valueCopy = value?.let { max(0, it) }
val padding = rect!!.height() * 0.2f
// maximal allowed mark radius
val maxRadius = (rect.height() - 2 * padding) / 2.0f
// the real mark radius is scaled down by a factor depending on the maximal frequency
val scale = 1.0f / maxFreq * value!!
val scalingFactor = if (isNumerical) maxFreq else weekdayFrequency
val scale = 1.0f / scalingFactor * valueCopy!!
val radius = maxRadius * scale
val colorIndex = min((colors.size - 1), ((colors.size - 1) * scale).roundToInt())
pGraph!!.color = colors[colorIndex]

View File

@@ -59,6 +59,7 @@ import org.isoron.uhabits.core.models.Reminder
import org.isoron.uhabits.core.models.WeekdayList
import org.isoron.uhabits.databinding.ActivityEditHabitBinding
import org.isoron.uhabits.utils.ColorUtils
import org.isoron.uhabits.utils.dismissCurrentAndShow
import org.isoron.uhabits.utils.formatTime
import org.isoron.uhabits.utils.toFormattedString
@@ -69,7 +70,7 @@ fun formatFrequency(freqNum: Int, freqDen: Int, resources: Resources) = when {
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 -> "$freqNum/$freqDen"
else -> resources.getString(R.string.x_times_per_y_days, freqNum, freqDen)
}
class EditHabitActivity : AppCompatActivity() {
@@ -88,6 +89,7 @@ class EditHabitActivity : AppCompatActivity() {
var reminderHour = -1
var reminderMin = -1
var reminderDays: WeekdayList = WeekdayList.EVERY_DAY
var targetType = NumericalHabitType.AT_LEAST
override fun onCreate(state: Bundle?) {
super.onCreate(state)
@@ -107,6 +109,7 @@ class EditHabitActivity : AppCompatActivity() {
color = habit.color
freqNum = habit.frequency.numerator
freqDen = habit.frequency.denominator
targetType = habit.targetType
habit.reminder?.let {
reminderHour = it.hour
reminderMin = it.minute
@@ -138,6 +141,7 @@ class EditHabitActivity : AppCompatActivity() {
HabitType.YES_NO -> {
binding.unitOuterBox.visibility = View.GONE
binding.targetOuterBox.visibility = View.GONE
binding.targetTypeOuterBox.visibility = View.GONE
}
HabitType.NUMERICAL -> {
binding.nameInput.hint = getString(R.string.measurable_short_example)
@@ -153,23 +157,41 @@ class EditHabitActivity : AppCompatActivity() {
val colorPickerDialogFactory = ColorPickerDialogFactory(this)
binding.colorButton.setOnClickListener {
val dialog = colorPickerDialogFactory.create(color, themeSwitcher.currentTheme)
dialog.setListener { paletteColor ->
val picker = colorPickerDialogFactory.create(color, themeSwitcher.currentTheme)
picker.setListener { paletteColor ->
this.color = paletteColor
updateColors()
}
dialog.show(supportFragmentManager, "colorPicker")
picker.dismissCurrentAndShow(supportFragmentManager, "colorPicker")
}
populateFrequency()
binding.booleanFrequencyPicker.setOnClickListener {
val dialog = FrequencyPickerDialog(freqNum, freqDen)
dialog.onFrequencyPicked = { num, den ->
val picker = FrequencyPickerDialog(freqNum, freqDen)
picker.onFrequencyPicked = { num, den ->
freqNum = num
freqDen = den
populateFrequency()
}
dialog.show(supportFragmentManager, "frequencyPicker")
picker.dismissCurrentAndShow(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()
}
val dialog = builder.create()
dialog.dismissCurrentAndShow()
}
binding.numericalFrequencyPicker.setOnClickListener {
@@ -215,7 +237,7 @@ class EditHabitActivity : AppCompatActivity() {
is24HourMode,
androidColor
)
dialog.show(supportFragmentManager, "timePicker")
dialog.dismissCurrentAndShow(supportFragmentManager, "timePicker")
}
binding.reminderDatePicker.setOnClickListener {
@@ -227,7 +249,7 @@ class EditHabitActivity : AppCompatActivity() {
populateReminder()
}
dialog.setSelectedDays(reminderDays)
dialog.show(supportFragmentManager, "dayPicker")
dialog.dismissCurrentAndShow(supportFragmentManager, "dayPicker")
}
binding.buttonSave.setOnClickListener {
@@ -262,7 +284,7 @@ class EditHabitActivity : AppCompatActivity() {
habit.frequency = Frequency(freqNum, freqDen)
if (habitType == HabitType.NUMERICAL) {
habit.targetValue = targetInput.text.toString().toDouble()
habit.targetType = NumericalHabitType.AT_LEAST
habit.targetType = targetType
habit.unit = unitInput.text.trim().toString()
}
habit.type = habitType
@@ -324,6 +346,13 @@ 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() {
androidColor = themeSwitcher.currentTheme.color(color).toInt()
binding.colorButton.backgroundTintList = ColorStateList.valueOf(androidColor)

View File

@@ -40,13 +40,13 @@ class HabitTypeDialog : AppCompatDialogFragment() {
val binding = SelectHabitTypeBinding.inflate(inflater, container, false)
binding.buttonYesNo.setOnClickListener {
val intent = IntentFactory().startEditActivity(activity!!, HabitType.YES_NO.value)
val intent = IntentFactory().startEditActivity(requireActivity(), HabitType.YES_NO.value)
startActivity(intent)
dismiss()
}
binding.buttonMeasurable.setOnClickListener {
val intent = IntentFactory().startEditActivity(activity!!, HabitType.NUMERICAL.value)
val intent = IntentFactory().startEditActivity(requireActivity(), HabitType.NUMERICAL.value)
startActivity(intent)
dismiss()
}

View File

@@ -21,6 +21,7 @@ package org.isoron.uhabits.activities.habits.list
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
@@ -29,6 +30,7 @@ import kotlinx.coroutines.Dispatchers
import org.isoron.uhabits.BaseExceptionHandler
import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.activities.habits.list.views.HabitCardListAdapter
import org.isoron.uhabits.core.models.Timestamp
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.tasks.TaskRunner
import org.isoron.uhabits.core.ui.ThemeSwitcher.Companion.THEME_DARK
@@ -36,11 +38,15 @@ import org.isoron.uhabits.core.utils.MidnightTimer
import org.isoron.uhabits.database.AutoBackup
import org.isoron.uhabits.inject.ActivityContextModule
import org.isoron.uhabits.inject.DaggerHabitsActivityComponent
import org.isoron.uhabits.inject.HabitsActivityComponent
import org.isoron.uhabits.inject.HabitsApplicationComponent
import org.isoron.uhabits.utils.restartWithFade
class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
var pureBlack: Boolean = false
lateinit var appComponent: HabitsApplicationComponent
lateinit var component: HabitsActivityComponent
lateinit var taskRunner: TaskRunner
lateinit var adapter: HabitCardListAdapter
lateinit var rootView: ListHabitsRootView
@@ -53,13 +59,14 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
override fun onQuestionMarksChanged() {
invalidateOptionsMenu()
menu.behavior.onPreferencesChanged()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val appComponent = (applicationContext as HabitsApplication).component
val component = DaggerHabitsActivityComponent
appComponent = (applicationContext as HabitsApplication).component
component = DaggerHabitsActivityComponent
.builder()
.activityContextModule(ActivityContextModule(this))
.habitsApplicationComponent(appComponent)
@@ -82,7 +89,7 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
override fun onPause() {
midnightTimer.onPause()
screen.onDettached()
screen.onDetached()
adapter.cancelRefresh()
super.onPause()
}
@@ -93,11 +100,17 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
rootView.postInvalidate()
midnightTimer.onResume()
taskRunner.run {
AutoBackup(this@ListHabitsActivity).run()
try {
AutoBackup(this@ListHabitsActivity).run()
appComponent.widgetUpdater.updateWidgets()
} catch (e: Exception) {
Log.e("ListHabitActivity", "TaskRunner failed", e)
}
}
if (prefs.theme == THEME_DARK && prefs.isPureBlackEnabled != pureBlack) {
restartWithFade(ListHabitsActivity::class.java)
}
parseIntents()
super.onResume()
}
@@ -115,4 +128,26 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
super.onActivityResult(request, result, data)
screen.onResult(request, result, data)
}
private fun parseIntents() {
if (intent == null) return
if (intent.action == ACTION_EDIT) {
val habitId = intent.extras?.getLong("habit")
val timestamp = intent.extras?.getLong("timestamp")
if (habitId != null && timestamp != null) {
val habit = appComponent.habitList.getById(habitId)!!
component.listHabitsBehavior.onEdit(habit, Timestamp(timestamp))
}
}
intent = null
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
setIntent(intent)
}
companion object {
const val ACTION_EDIT = "org.isoron.uhabits.ACTION_EDIT"
}
}

View File

@@ -39,7 +39,7 @@ class ListHabitsMenu @Inject constructor(
@ActivityContext context: Context,
private val preferences: Preferences,
private val themeSwitcher: ThemeSwitcher,
private val behavior: ListHabitsMenuBehavior
val behavior: ListHabitsMenuBehavior
) {
val activity = (context as AppCompatActivity)

View File

@@ -24,10 +24,12 @@ import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import dagger.Lazy
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.R
import org.isoron.uhabits.activities.common.dialogs.CheckmarkPopup
import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialogFactory
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.list.views.HabitCardListAdapter
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.models.Habit
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.ui.ThemeSwitcher
import org.isoron.uhabits.core.ui.callbacks.OnColorPickedCallback
@@ -60,6 +63,8 @@ import org.isoron.uhabits.tasks.ExportDBTaskFactory
import org.isoron.uhabits.tasks.ImportDataTask
import org.isoron.uhabits.tasks.ImportDataTaskFactory
import org.isoron.uhabits.utils.copyTo
import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.dismissCurrentAndShow
import org.isoron.uhabits.utils.restartWithFade
import org.isoron.uhabits.utils.showMessage
import org.isoron.uhabits.utils.showSendEmailScreen
@@ -88,8 +93,9 @@ class ListHabitsScreen
private val exportDBFactory: ExportDBTaskFactory,
private val importTaskFactory: ImportDataTaskFactory,
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,
ListHabitsBehavior.Screen,
ListHabitsMenuBehavior.Screen,
@@ -101,7 +107,7 @@ class ListHabitsScreen
commandRunner.addListener(this)
}
fun onDettached() {
fun onDetached() {
commandRunner.removeListener(this)
}
@@ -158,7 +164,7 @@ class ListHabitsScreen
}
override fun showDeleteConfirmationScreen(callback: OnConfirmedCallback, quantity: Int) {
ConfirmDeleteDialog(activity, callback, quantity).show()
ConfirmDeleteDialog(activity, callback, quantity).dismissCurrentAndShow()
}
override fun showEditHabitsScreen(selected: List<Habit>) {
@@ -219,15 +225,45 @@ class ListHabitsScreen
override fun showColorPicker(defaultColor: PaletteColor, callback: OnColorPickedCallback) {
val picker = colorPickerFactory.create(defaultColor, themeSwitcher.currentTheme!!)
picker.setListener(callback)
picker.show(activity.supportFragmentManager, "picker")
picker.dismissCurrentAndShow(activity.supportFragmentManager, "picker")
}
override fun showNumberPicker(
override fun showNumberPopup(
value: Double,
unit: String,
notes: String,
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? {

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.preferences.Preferences
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.showMessage
import org.isoron.uhabits.utils.sp
import org.isoron.uhabits.utils.sres
import org.isoron.uhabits.utils.toMeasureSpec
import javax.inject.Inject
const val TOGGLE_DELAY_MILLIS = 2000L
class CheckmarkButtonViewFactory
@Inject constructor(
@ActivityContext val context: Context,
@@ -71,33 +73,42 @@ class CheckmarkButtonView(
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()
init {
isFocusable = false
setOnClickListener(this)
setOnLongClickListener(this)
}
fun performToggle() {
value = if (preferences.isSkipEnabled) {
Entry.nextToggleValueWithSkip(value)
} else {
Entry.nextToggleValueWithoutSkip(value)
}
onToggle(value)
fun performToggle(delay: Long) {
value = Entry.nextToggleValue(
value = value,
isSkipEnabled = preferences.isSkipEnabled,
areQuestionMarksEnabled = preferences.areQuestionMarksEnabled
)
onToggle(value, notes, delay)
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
invalidate()
}
override fun onClick(v: View) {
if (preferences.isShortToggleEnabled) performToggle()
else showMessage(resources.getString(R.string.long_press_to_toggle))
if (preferences.isShortToggleEnabled) performToggle(TOGGLE_DELAY_MILLIS)
else onEdit()
}
override fun onLongClick(v: View): Boolean {
performToggle()
if (preferences.isShortToggleEnabled) onEdit()
else performToggle(TOGGLE_DELAY_MILLIS)
return true
}
@@ -145,6 +156,11 @@ class CheckmarkButtonView(
}
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) {
paint.strokeWidth = 5f
paint.style = Paint.Style.STROKE
@@ -153,11 +169,6 @@ class CheckmarkButtonView(
paint.style = Paint.Style.FILL
}
paint.textSize = when (id) {
UNKNOWN -> dim(R.dimen.smallerTextSize)
else -> dim(R.dimen.smallTextSize)
}
val label = resources.getString(id)
val em = paint.measureText("m")
@@ -170,6 +181,8 @@ class CheckmarkButtonView(
paint.style = Paint.Style.FILL
canvas.drawText(label, rect.centerX(), rect.centerY(), paint)
}
drawNotesIndicator(canvas, color, em, notes)
}
}
}

View File

@@ -54,7 +54,19 @@ class CheckmarkPanelView(
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) {
field = value
setupButtons()
@@ -72,8 +84,13 @@ class CheckmarkPanelView(
index + dataOffset < values.size -> values[index + dataOffset]
else -> UNKNOWN
}
button.notes = when {
index + dataOffset < notes.size -> notes[index + dataOffset]
else -> ""
}
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 score = cache.getScore(habit!!.id!!)
val checkmarks = cache.getCheckmarks(habit.id!!)
val notes = cache.getNotes(habit.id!!)
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) {

View File

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

View File

@@ -21,8 +21,8 @@ package org.isoron.uhabits.activities.habits.list.views
import android.content.Context
import android.graphics.text.LineBreaker.BREAK_STRATEGY_BALANCED
import android.os.Build
import android.os.Build.VERSION.SDK_INT
import android.os.Build.VERSION_CODES.M
import android.os.Handler
import android.os.Looper
import android.text.TextUtils
@@ -57,6 +57,13 @@ class HabitCardViewFactory
fun create() = HabitCardView(context, checkmarkPanelFactory, numberPanelFactory, behavior)
}
data class DelayedToggle(
var habit: Habit,
var timestamp: Timestamp,
var value: Int,
var notes: String
)
class HabitCardView(
@ActivityContext context: Context,
checkmarkPanelFactory: CheckmarkPanelViewFactory,
@@ -115,12 +122,22 @@ class HabitCardView(
numberPanel.threshold = value
}
var notes
get() = checkmarkPanel.notes
set(values) {
checkmarkPanel.notes = values
numberPanel.notes = values
}
var checkmarkPanel: CheckmarkPanelView
private var numberPanel: NumberPanelView
private var innerFrame: LinearLayout
private var label: TextView
private var scoreRing: RingView
private var currentToggleTaskId = 0
private var queuedToggles = mutableListOf<DelayedToggle>()
init {
scoreRing = RingView(context).apply {
val thickness = dp(3f)
@@ -137,13 +154,22 @@ class HabitCardView(
maxLines = 2
ellipsize = TextUtils.TruncateAt.END
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 {
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)
habit?.let { behavior.onToggle(it, timestamp, value) }
habit?.let { behavior.onEdit(it, timestamp) }
}
}
@@ -179,6 +205,25 @@ class HabitCardView(
addView(innerFrame)
}
@Synchronized
private fun runPendingToggles(id: Int) {
if (currentToggleTaskId != id) return
for ((h, t, v, n) in queuedToggles) behavior.onToggle(h, t, v, n)
queuedToggles.clear()
}
@Synchronized
private fun queueToggle(
it: Habit,
timestamp: Timestamp,
value: Int,
notes: String,
): Int {
currentToggleTaskId += 1
queuedToggles.add(DelayedToggle(it, timestamp, value, notes))
return currentToggleTaskId
}
override fun onModelChange() {
Handler(Looper.getMainLooper()).post {
habit?.let { copyAttributesFrom(it) }
@@ -236,6 +281,7 @@ class HabitCardView(
numberPanel.apply {
color = c
units = h.unit
targetType = h.targetType
threshold = h.targetValue
visibility = when (h.isNumerical) {
true -> View.VISIBLE
@@ -262,4 +308,10 @@ class HabitCardView(
}
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.OnLongClickListener
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.inject.ActivityContext
import org.isoron.uhabits.utils.InterfaceUtils.getDimension
import org.isoron.uhabits.utils.StyledResources
import org.isoron.uhabits.utils.dim
import org.isoron.uhabits.utils.drawNotesIndicator
import org.isoron.uhabits.utils.getFontAwesome
import org.isoron.uhabits.utils.showMessage
import org.isoron.uhabits.utils.sres
import java.text.DecimalFormat
import javax.inject.Inject
@@ -88,13 +91,25 @@ class NumberButtonView(
invalidate()
}
var units = ""
var targetType = AT_LEAST
set(value) {
field = value
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)
init {
@@ -103,8 +118,7 @@ class NumberButtonView(
}
override fun onClick(v: View) {
if (preferences.isShortToggleEnabled) onEdit()
else showMessage(resources.getString(R.string.long_press_to_edit))
onEdit()
}
override fun onLongClick(v: View): Boolean {
@@ -127,11 +141,16 @@ class NumberButtonView(
private val em: Float
private val rect: RectF = RectF()
private val sr = StyledResources(context)
private val lowContrast: Int
private val mediumContrast: Int
private val paint = TextPaint().apply {
typeface = getFontAwesome()
isAntiAlias = true
textAlign = Paint.Align.CENTER
}
private val pUnit: TextPaint = TextPaint().apply {
textSize = getDimension(context, R.dimen.smallerTextSize)
typeface = NORMAL_TYPEFACE
@@ -148,15 +167,16 @@ class NumberButtonView(
init {
em = pNumber.measureText("m")
lowContrast = sr.getColor(R.attr.contrast40)
mediumContrast = sr.getColor(R.attr.contrast60)
lowContrast = sres.getColor(R.attr.contrast40)
mediumContrast = sres.getColor(R.attr.contrast60)
}
fun draw(canvas: Canvas) {
val activeColor = when {
value <= 0.0 -> lowContrast
value < threshold -> mediumContrast
else -> color
value < 0.0 -> lowContrast
(targetType == AT_LEAST) && (value >= threshold) -> color
(targetType == AT_MOST) && (value <= threshold) -> color
else -> mediumContrast
}
val label: String
@@ -164,6 +184,11 @@ class NumberButtonView(
val textSize: Float
when {
value == Entry.SKIP.toDouble() / 1000 -> {
label = resources.getString(R.string.fa_skipped)
textSize = dim(R.dimen.smallTextSize)
typeface = getFontAwesome()
}
value >= 0 -> {
label = value.toShortString()
typeface = BOLD_TYPEFACE
@@ -196,6 +221,8 @@ class NumberButtonView(
rect.offset(0f, 1.3f * em)
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
import android.content.Context
import org.isoron.uhabits.core.models.NumericalHabitType
import org.isoron.uhabits.core.models.Timestamp
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.utils.DateUtils
@@ -47,6 +48,12 @@ class NumberPanelView(
setupButtons()
}
var targetType = NumericalHabitType.AT_LEAST
set(value) {
field = value
setupButtons()
}
var threshold = 0.0
set(value) {
field = value
@@ -65,7 +72,13 @@ class NumberPanelView(
setupButtons()
}
var onEdit: (Timestamp) -> Unit = {}
var notes = arrayOf<String>()
set(values) {
field = values
setupButtons()
}
var onEdit: (Timestamp) -> Unit = { _ -> }
set(value) {
field = value
setupButtons()
@@ -83,7 +96,12 @@ class NumberPanelView(
index + dataOffset < values.size -> values[index + dataOffset]
else -> 0.0
}
button.notes = when {
index + dataOffset < notes.size -> notes[index + dataOffset]
else -> ""
}
button.color = color
button.targetType = targetType
button.threshold = threshold
button.units = units
button.onEdit = { onEdit(timestamp) }

View File

@@ -23,21 +23,25 @@ import android.os.Bundle
import android.view.HapticFeedbackConstants
import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.AndroidDirFinder
import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher
import org.isoron.uhabits.activities.HabitsDirFinder
import org.isoron.uhabits.activities.common.dialogs.CheckmarkPopup
import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog
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.CommandRunner
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.ui.callbacks.OnConfirmedCallback
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
@@ -45,6 +49,8 @@ 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.views.OnDateClickedListener
import org.isoron.uhabits.intents.IntentFactory
import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.dismissCurrentAndShow
import org.isoron.uhabits.utils.showMessage
import org.isoron.uhabits.utils.showSendFileScreen
import org.isoron.uhabits.widgets.WidgetUpdater
@@ -161,12 +167,49 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
window.decorView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
}
override fun showNumberPicker(
override fun showNumberPopup(
value: Double,
unit: String,
callback: ListHabitsBehavior.NumberPickerCallback,
notes: String,
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) {
@@ -178,6 +221,7 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
ShowHabitMenuPresenter.Message.COULD_NOT_EXPORT -> {
showMessage(resources.getString(R.string.could_not_export))
}
else -> {}
}
}
@@ -186,7 +230,7 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
}
override fun showDeleteConfirmationScreen(callback: OnConfirmedCallback) {
ConfirmDeleteDialog(this@ShowHabitActivity, callback, 1).show()
ConfirmDeleteDialog(this@ShowHabitActivity, callback, 1).dismissCurrentAndShow()
}
override fun close() {

View File

@@ -33,6 +33,7 @@ class FrequencyCardView(context: Context, attrs: AttributeSet) : LinearLayout(co
fun setState(state: FrequencyCardState) {
val androidColor = state.theme.color(state.color).toInt()
binding.frequencyChart.setFrequency(state.frequency)
binding.frequencyChart.setIsNumerical(state.isNumerical)
binding.frequencyChart.setFirstWeekday(state.firstWeekday)
binding.title.setTextColor(androidColor)
binding.frequencyChart.setColor(androidColor)

View File

@@ -43,6 +43,8 @@ class HistoryCardView(context: Context, attrs: AttributeSet) : LinearLayout(cont
theme = state.theme,
dateFormatter = JavaLocalDateFormatter(Locale.getDefault()),
series = state.series,
defaultSquare = state.defaultSquare,
notesIndicators = state.notesIndicators,
firstWeekday = state.firstWeekday,
)
binding.chart.postInvalidate()

View File

@@ -28,6 +28,7 @@ import org.isoron.platform.gui.toInt
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.core.models.NumericalHabitType
import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardState
import org.isoron.uhabits.databinding.ShowHabitSubtitleBinding
import org.isoron.uhabits.utils.InterfaceUtils
@@ -65,7 +66,12 @@ class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
binding.questionLabel.visibility = View.VISIBLE
binding.targetIcon.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.targetText.visibility = View.GONE
}

View File

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

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