Compare commits

...

79 Commits

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Updates `espresso-contrib` from 3.3.0 to 3.4.0

Updates `espresso-core` from 3.3.0 to 3.4.0

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-23 18:01:18 -05:00
12c76245e6 Merge branch 'master' into dev 2021-05-23 17:47:14 -05:00
7f1a1add8c Revert "Temporarily remove device sync"
This reverts commit da018fc64d.
2021-05-09 18:22:15 -05:00
59a4d7552c Update translations; reorganize play/listings 2021-05-09 18:03:04 -05:00
9d7840bdd1 Merge branch 'master' into dev 2021-05-09 17:24:50 -05:00
Quentin Hibon
32db4e363b Add missing dependency to github workflow (#894) 2021-05-02 18:41:34 -05:00
dependabot[bot]
004bb8d71c Bump daggerVersion from 2.34.1 to 2.35.1
Bumps `daggerVersion` from 2.34.1 to 2.35.1.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-30 17:08:54 +02:00
235 changed files with 3068 additions and 1353 deletions

View File

@@ -6,11 +6,16 @@ labels: ''
assignees: ''
---
<!--
Please use the template below for your bug report. Issues that do not follow this
template, or that do not contain all necessary information (namely, description of
the problem, steps to reproduce, phone, phone operating system, and app version)
will be closed without further consideration.
-->
## Pre-submission checklist
- [ ] I am submitting a bug report, not a feature request.
- [ ] I am running the latest version of Loop Habit Tracker.
- [ ] I have have searched for similar issues, but did not find any matches.
- [ ] I have searched for similar issues, but did not find any matches.
## Description
A clear and concise description of what the problem is.
@@ -21,10 +26,11 @@ A clear and concise description of what the problem is.
3. Scroll down to ....
4. See error
## Screenshots
If applicable, add screenshots to help explain your problem.
## System information
- Phone: [e.g. Google Pixel 4]
- Phone Operating System: [e.g. Android 10]
- App version: [e.g. 1.8.9]
- App version: [e.g. 2.0.2]
## Screenshots
If applicable, add screenshots to help explain your problem.

View File

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

View File

@@ -55,6 +55,11 @@ jobs:
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 }}

View File

@@ -1,5 +1,15 @@
# Changelog
## [2.0.3] - 2021-08-21
### Fixed
- Improve automatic checkmarks for monthly habits (@iSoron, #947)
- Fix small theme issues (@iSoron)
- Fix ANR on some Samsung phones (@iSoron, #962)
- Fix dates before the year 2000 (@iSoron, #967)
- Fix notification adding checkmarks to the wrong day (@hiqua, #969)
- Fix crashes in widgets (@hiqua, @iSoron, #907, #966, #965)
- Fix crash when moving habits (@hiqua, #968)
## [2.0.2] - 2021-05-23
### Changed

View File

@@ -18,7 +18,7 @@ source.
<p align="center">
<a href="https://play.google.com/store/apps/details?id=org.isoron.uhabits&utm_source=global_co&utm_medium=prtnr&utm_content=Mar2515&utm_campaign=PartBadge&pcampaignid=MKT-AC-global-none-all-co-pr-py-PartBadges-Oct1515-1"><img alt="Get it on Google Play" src="https://play.google.com/intl/en_us/badges/images/apps/en-play-badge-border.png" height="75px"/></a>
<a href="http://f-droid.org/app/org.isoron.uhabits"><img alt="Get it on F-Droid" src="http://i.imgur.com/baSPE7X.png" height="75px"/></a>
<a href="https://f-droid.org/app/org.isoron.uhabits"><img alt="Get it on F-Droid" src="https://i.imgur.com/baSPE7X.png" height="75px"/></a>
</p>
## Screenshots
@@ -109,7 +109,7 @@ contribute, even if you are not a software developer.
more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
with this program. If not, see <https://www.gnu.org/licenses/>.
[screen1]: screenshots/1.png
[screen2]: screenshots/2.png
@@ -123,9 +123,9 @@ contribute, even if you are not a software developer.
[screen4th]: screenshots/4.thumb.png
[screen5th]: screenshots/5.thumb.png
[screen6th]: screenshots/6.thumb.png
[poedit]: http://translate.loophabits.org
[poedit]: https://translate.loophabits.org
[playstore]: https://play.google.com/store/apps/details?id=org.isoron.uhabits
[releases]: https://github.com/iSoron/uhabits/releases
[fdroid]: http://f-droid.org/app/org.isoron.uhabits
[fdroid]: https://f-droid.org/app/org.isoron.uhabits
[build]: https://github.com/iSoron/uhabits/blob/dev/docs/BUILD.md
[beta]: https://play.google.com/apps/testing/org.isoron.uhabits

View File

@@ -1,11 +1,11 @@
plugins {
val kotlinVersion = "1.4.21"
id("com.android.application") version ("4.1.0") apply (false)
val kotlinVersion = "1.5.0"
id("com.android.application") version ("4.2.0") 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.0.0"
id("org.jlleitschuh.gradle.ktlint") version "10.1.0"
}
apply {

Binary file not shown.

View File

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

2
gradlew vendored
View File

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

25
gradlew.bat vendored
View File

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

View File

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

View File

@@ -20,7 +20,7 @@
*/
plugins {
id("com.github.triplet.play") version "3.2.0"
id("com.github.triplet.play") version "3.5.0"
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.kapt")
@@ -37,8 +37,8 @@ android {
compileSdkVersion(30)
defaultConfig {
versionCode(20002)
versionName("2.0.2")
versionCode(20003)
versionName("2.0.3")
minSdkVersion(23)
targetSdkVersion(30)
applicationId("org.isoron.uhabits")
@@ -88,11 +88,11 @@ android {
}
dependencies {
val daggerVersion = "2.34.1"
val kotlinVersion = "1.4.32"
val kxCoroutinesVersion = "1.4.2"
val ktorVersion = "1.5.3"
val espressoVersion = "3.3.0"
val daggerVersion = "2.38.1"
val kotlinVersion = "1.5.21"
val kxCoroutinesVersion = "1.5.1"
val ktorVersion = "1.6.2"
val espressoVersion = "3.4.0"
androidTestImplementation("androidx.test.espresso:espresso-contrib:$espressoVersion")
androidTestImplementation("androidx.test.espresso:espresso-core:$espressoVersion")
@@ -101,13 +101,13 @@ dependencies {
androidTestImplementation("io.ktor:ktor-client-mock:$ktorVersion")
androidTestImplementation("io.ktor:ktor-jackson:$ktorVersion")
androidTestImplementation("androidx.annotation:annotation:1.2.0")
androidTestImplementation("androidx.test.ext:junit:1.1.2")
androidTestImplementation("androidx.test.ext:junit:1.1.3")
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.2.0")
androidTestImplementation("androidx.test:rules:1.3.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:3.4.0")
implementation("com.github.paolorotolo:appintro:4.1.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")
@@ -118,11 +118,12 @@ 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.2.0")
implementation("androidx.appcompat:appcompat:1.3.1")
implementation("androidx.legacy:legacy-preference-v14:1.0.0")
implementation("androidx.legacy:legacy-support-v4:1.0.0")
implementation("com.google.android.material:material:1.3.0")
implementation("com.opencsv:opencsv:5.4")
implementation("com.google.android.material:material:1.4.0")
implementation("com.google.zxing:core:3.4.1")
implementation("com.opencsv:opencsv:5.5.1")
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: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,154 @@
/*
* 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.sync
import androidx.test.filters.MediumTest
import com.fasterxml.jackson.databind.ObjectMapper
import io.ktor.client.HttpClient
import io.ktor.client.engine.mock.MockEngine
import io.ktor.client.engine.mock.MockRequestHandleScope
import io.ktor.client.engine.mock.respond
import io.ktor.client.engine.mock.respondError
import io.ktor.client.engine.mock.respondOk
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.request.HttpRequestData
import io.ktor.client.request.HttpResponseData
import io.ktor.http.HttpStatusCode
import io.ktor.http.fullPath
import io.ktor.http.headersOf
import kotlinx.coroutines.runBlocking
import org.isoron.uhabits.BaseAndroidTest
import org.isoron.uhabits.core.sync.AbstractSyncServer
import org.isoron.uhabits.core.sync.GetDataVersionResponse
import org.isoron.uhabits.core.sync.KeyNotFoundException
import org.isoron.uhabits.core.sync.RegisterReponse
import org.isoron.uhabits.core.sync.ServiceUnavailable
import org.isoron.uhabits.core.sync.SyncData
import org.junit.Test
@MediumTest
class RemoteSyncServerTest : BaseAndroidTest() {
private val mapper = ObjectMapper()
val data = SyncData(1, "Hello world")
@Test
fun when_register_succeeds_should_return_key() = runBlocking {
val server = server("/register") {
respondWithJson(RegisterReponse("ABCDEF"))
}
assertEquals("ABCDEF", server.register())
}
@Test(expected = ServiceUnavailable::class)
fun when_register_fails_should_raise_correct_exception() = runBlocking {
val server = server("/register") {
respondError(HttpStatusCode.ServiceUnavailable)
}
server.register()
return@runBlocking
}
@Test
fun when_get_data_version_succeeds_should_return_version() = runBlocking {
server("/db/ABC/version") {
respondWithJson(GetDataVersionResponse(5))
}.apply {
assertEquals(5, getDataVersion("ABC"))
}
return@runBlocking
}
@Test(expected = ServiceUnavailable::class)
fun when_get_data_version_with_server_error_should_raise_exception() = runBlocking {
server("/db/ABC/version") {
respondError(HttpStatusCode.InternalServerError)
}.apply {
getDataVersion("ABC")
}
return@runBlocking
}
@Test(expected = KeyNotFoundException::class)
fun when_get_data_version_with_invalid_key_should_raise_exception() = runBlocking {
server("/db/ABC/version") {
respondError(HttpStatusCode.NotFound)
}.apply {
getDataVersion("ABC")
}
return@runBlocking
}
@Test
fun when_get_data_succeeds_should_return_data() = runBlocking {
server("/db/ABC") {
respondWithJson(data)
}.apply {
assertEquals(data, getData("ABC"))
}
return@runBlocking
}
@Test(expected = KeyNotFoundException::class)
fun when_get_data_with_invalid_key_should_raise_exception() = runBlocking {
server("/db/ABC") {
respondError(HttpStatusCode.NotFound)
}.apply {
getData("ABC")
}
return@runBlocking
}
@Test
fun when_put_succeeds_should_not_raise_exceptions() = runBlocking {
server("/db/ABC") {
respondOk()
}.apply {
put("ABC", data)
}
return@runBlocking
}
private fun server(
expectedPath: String,
action: MockRequestHandleScope.(HttpRequestData) -> HttpResponseData
): AbstractSyncServer {
return RemoteSyncServer(
httpClient = HttpClient(MockEngine) {
install(JsonFeature)
engine {
addHandler { request ->
when (request.url.fullPath) {
expectedPath -> action(request)
else -> error("unexpected call: ${request.url.fullPath}")
}
}
}
},
preferences = prefs
)
}
private fun MockRequestHandleScope.respondWithJson(content: Any) =
respond(
mapper.writeValueAsBytes(content),
headers = headersOf("Content-Type" to listOf("application/json"))
)
}

View File

@@ -22,6 +22,8 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".HabitsApplication"
@@ -40,6 +42,14 @@
android:value=".activities.habits.list.ListHabitsActivity" />
</activity>
<activity
android:name=".activities.sync.SyncActivity"
android:exported="true">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.settings.SettingsActivity" />
</activity>
<meta-data
android:name="com.google.android.backup.api_key"
android:value="AEdPqrEAAAAI6aeWncbnMNo8E5GWeZ44dlc5cQ7tCROwFhOtiw" />
@@ -49,6 +59,16 @@
android:exported="true"
android:label="@string/main_activity_title"
android:launchMode="singleTop">
<tools:validation testUrl="https://loophabits.org/sync/123" />
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="loophabits.org"
android:pathPrefix="/sync" />
</intent-filter>
</activity>
<activity-alias

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,45 @@
/*
* 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 androidx.appcompat.app.AlertDialog
import org.isoron.uhabits.R
import org.isoron.uhabits.core.ui.callbacks.OnConfirmedCallback
import org.isoron.uhabits.inject.ActivityContext
class ConfirmSyncKeyDialog(
@ActivityContext context: Context,
callback: OnConfirmedCallback
) : AlertDialog(context) {
init {
setTitle(R.string.device_sync)
val res = context.resources
setMessage(res.getString(R.string.sync_confirm))
setButton(
BUTTON_POSITIVE,
res.getString(R.string.yes)
) { dialog: DialogInterface?, which: Int -> callback.onConfirmed() }
setButton(
BUTTON_NEGATIVE,
res.getString(R.string.no)
) { dialog: DialogInterface?, which: Int -> }
}
}

View File

@@ -160,6 +160,11 @@ class FrequencyPickerDialog(
private fun populateViews() {
uncheckAll()
if (freqDenominator == 30 || freqDenominator == 31) {
contentView.xTimesPerMonthRadioButton.isChecked = true
contentView.xTimesPerMonthTextView.setText(freqNumerator.toString())
focus(contentView.xTimesPerMonthTextView)
} else {
if (freqNumerator == 1) {
if (freqDenominator == 1) {
contentView.everyDayRadioButton.isChecked = true
@@ -173,16 +178,13 @@ class FrequencyPickerDialog(
contentView.xTimesPerWeekRadioButton.isChecked = true
contentView.xTimesPerWeekTextView.setText(freqNumerator.toString())
focus(contentView.xTimesPerWeekTextView)
} else if (freqDenominator == 30 || freqDenominator == 31) {
contentView.xTimesPerMonthRadioButton.isChecked = true
contentView.xTimesPerMonthTextView.setText(freqNumerator.toString())
focus(contentView.xTimesPerMonthTextView)
} else {
Log.w("FrequencyPickerDialog", "Unknown frequency: $freqNumerator/$freqDenominator")
contentView.everyDayRadioButton.isChecked = true
}
}
}
}
private fun focus(view: EditText) {
view.requestFocus()

View File

@@ -32,7 +32,7 @@ class TaskProgressBar(
context,
null,
android.R.attr.progressBarStyleHorizontal
),
),
TaskRunner.Listener {
init {

View File

@@ -21,6 +21,7 @@ package org.isoron.uhabits.activities.habits.edit
import android.annotation.SuppressLint
import android.content.res.ColorStateList
import android.content.res.Resources
import android.graphics.Color
import android.os.Bundle
import android.text.Html
@@ -39,6 +40,7 @@ import kotlinx.android.synthetic.main.activity_edit_habit.notesInput
import kotlinx.android.synthetic.main.activity_edit_habit.questionInput
import kotlinx.android.synthetic.main.activity_edit_habit.targetInput
import kotlinx.android.synthetic.main.activity_edit_habit.unitInput
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher
@@ -50,6 +52,8 @@ import org.isoron.uhabits.core.commands.CreateHabitCommand
import org.isoron.uhabits.core.commands.EditHabitCommand
import org.isoron.uhabits.core.models.Frequency
import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.HabitType
import org.isoron.uhabits.core.models.NumericalHabitType
import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.models.Reminder
import org.isoron.uhabits.core.models.WeekdayList
@@ -57,7 +61,16 @@ import org.isoron.uhabits.databinding.ActivityEditHabitBinding
import org.isoron.uhabits.utils.ColorUtils
import org.isoron.uhabits.utils.formatTime
import org.isoron.uhabits.utils.toFormattedString
import org.isoron.uhabits.utils.toThemedAndroidColor
fun formatFrequency(freqNum: Int, freqDen: Int, resources: Resources) = when {
freqNum == 1 && (freqDen == 30 || freqDen == 31) -> resources.getString(R.string.every_month)
freqDen == 30 || freqDen == 31 -> resources.getString(R.string.x_times_per_month, freqNum)
freqNum == 1 && freqDen == 1 -> resources.getString(R.string.every_day)
freqNum == 1 && freqDen == 7 -> resources.getString(R.string.every_week)
freqNum == 1 && freqDen > 1 -> resources.getString(R.string.every_x_days, freqDen)
freqDen == 7 -> resources.getString(R.string.x_times_per_week, freqNum)
else -> "$freqNum/$freqDen"
}
class EditHabitActivity : AppCompatActivity() {
@@ -66,7 +79,7 @@ class EditHabitActivity : AppCompatActivity() {
private lateinit var commandRunner: CommandRunner
var habitId = -1L
var habitType = -1
lateinit var habitType: HabitType
var unit = ""
var color = PaletteColor(11)
var androidColor = 0
@@ -105,12 +118,12 @@ class EditHabitActivity : AppCompatActivity() {
binding.unitInput.setText(habit.unit)
binding.targetInput.setText(habit.targetValue.toString())
} else {
habitType = intent.getIntExtra("habitType", Habit.YES_NO_HABIT)
habitType = HabitType.fromInt(intent.getIntExtra("habitType", HabitType.YES_NO.value))
}
if (state != null) {
habitId = state.getLong("habitId")
habitType = state.getInt("habitType")
habitType = HabitType.fromInt(state.getInt("habitType"))
color = PaletteColor(state.getInt("paletteColor"))
freqNum = state.getInt("freqNum")
freqDen = state.getInt("freqDen")
@@ -121,14 +134,17 @@ class EditHabitActivity : AppCompatActivity() {
updateColors()
if (habitType == Habit.YES_NO_HABIT) {
when (habitType) {
HabitType.YES_NO -> {
binding.unitOuterBox.visibility = View.GONE
binding.targetOuterBox.visibility = View.GONE
} else {
}
HabitType.NUMERICAL -> {
binding.nameInput.hint = getString(R.string.measurable_short_example)
binding.questionInput.hint = getString(R.string.measurable_question_example)
binding.frequencyOuterBox.visibility = View.GONE
}
}
setSupportActionBar(binding.toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
@@ -137,7 +153,7 @@ class EditHabitActivity : AppCompatActivity() {
val colorPickerDialogFactory = ColorPickerDialogFactory(this)
binding.colorButton.setOnClickListener {
val dialog = colorPickerDialogFactory.create(color)
val dialog = colorPickerDialogFactory.create(color, themeSwitcher.currentTheme)
dialog.setListener { paletteColor ->
this.color = paletteColor
updateColors()
@@ -244,9 +260,9 @@ class EditHabitActivity : AppCompatActivity() {
}
habit.frequency = Frequency(freqNum, freqDen)
if (habitType == Habit.NUMBER_HABIT) {
if (habitType == HabitType.NUMERICAL) {
habit.targetValue = targetInput.text.toString().toDouble()
habit.targetType = Habit.AT_LEAST
habit.targetType = NumericalHabitType.AT_LEAST
habit.unit = unitInput.text.trim().toString()
}
habit.type = habitType
@@ -274,7 +290,7 @@ class EditHabitActivity : AppCompatActivity() {
nameInput.error = getFormattedValidationError(R.string.validation_cannot_be_blank)
isValid = false
}
if (habitType == Habit.NUMBER_HABIT) {
if (habitType == HabitType.NUMERICAL) {
if (targetInput.text.isEmpty()) {
targetInput.error = getString(R.string.validation_cannot_be_blank)
isValid = false
@@ -299,14 +315,7 @@ class EditHabitActivity : AppCompatActivity() {
@SuppressLint("StringFormatMatches")
private fun populateFrequency() {
binding.booleanFrequencyPicker.text = when {
freqNum == 1 && freqDen == 1 -> getString(R.string.every_day)
freqNum == 1 && freqDen == 7 -> getString(R.string.every_week)
freqNum == 1 && freqDen > 1 -> getString(R.string.every_x_days, freqDen)
freqDen == 7 -> getString(R.string.x_times_per_week, freqNum)
freqDen == 30 || freqDen == 31 -> getString(R.string.x_times_per_month, freqNum)
else -> "$freqNum/$freqDen"
}
binding.booleanFrequencyPicker.text = formatFrequency(freqNum, freqDen, resources)
binding.numericalFrequencyPicker.text = when (freqDen) {
1 -> getString(R.string.every_day)
7 -> getString(R.string.every_week)
@@ -316,7 +325,7 @@ class EditHabitActivity : AppCompatActivity() {
}
private fun updateColors() {
androidColor = color.toThemedAndroidColor(this)
androidColor = themeSwitcher.currentTheme.color(color).toInt()
binding.colorButton.backgroundTintList = ColorStateList.valueOf(androidColor)
if (!themeSwitcher.isNightMode) {
val darkerAndroidColor = ColorUtils.mixColors(Color.BLACK, androidColor, 0.15f)
@@ -334,7 +343,7 @@ class EditHabitActivity : AppCompatActivity() {
super.onSaveInstanceState(state)
with(state) {
putLong("habitId", habitId)
putInt("habitType", habitType)
putInt("habitType", habitType.value)
putInt("paletteColor", color.paletteIndex)
putInt("androidColor", androidColor)
putInt("freqNum", freqNum)

View File

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

View File

@@ -26,10 +26,12 @@ import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.isoron.uhabits.BaseExceptionHandler
import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.activities.habits.list.views.HabitCardListAdapter
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.sync.SyncManager
import org.isoron.uhabits.core.tasks.TaskRunner
import org.isoron.uhabits.core.ui.ThemeSwitcher.Companion.THEME_DARK
import org.isoron.uhabits.core.utils.MidnightTimer
@@ -38,7 +40,7 @@ import org.isoron.uhabits.inject.ActivityContextModule
import org.isoron.uhabits.inject.DaggerHabitsActivityComponent
import org.isoron.uhabits.utils.restartWithFade
class ListHabitsActivity : AppCompatActivity() {
class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
var pureBlack: Boolean = false
lateinit var taskRunner: TaskRunner
@@ -47,10 +49,15 @@ class ListHabitsActivity : AppCompatActivity() {
lateinit var screen: ListHabitsScreen
lateinit var prefs: Preferences
lateinit var midnightTimer: MidnightTimer
lateinit var syncManager: SyncManager
private val scope = CoroutineScope(Dispatchers.Main)
private lateinit var menu: ListHabitsMenu
override fun onQuestionMarksChanged() {
invalidateOptionsMenu()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -63,6 +70,8 @@ class ListHabitsActivity : AppCompatActivity() {
component.themeSwitcher.apply()
prefs = appComponent.preferences
prefs.addListener(this)
syncManager = appComponent.syncManager
pureBlack = prefs.isPureBlackEnabled
midnightTimer = appComponent.midnightTimer
rootView = component.listHabitsRootView
@@ -79,6 +88,9 @@ class ListHabitsActivity : AppCompatActivity() {
midnightTimer.onPause()
screen.onDettached()
adapter.cancelRefresh()
scope.launch {
syncManager.onPause()
}
super.onPause()
}
@@ -87,6 +99,9 @@ class ListHabitsActivity : AppCompatActivity() {
screen.onAttached()
rootView.postInvalidate()
midnightTimer.onResume()
scope.launch {
syncManager.onResume()
}
taskRunner.run {
AutoBackup(this@ListHabitsActivity).run()
}

View File

@@ -52,6 +52,11 @@ class ListHabitsMenu @Inject constructor(
nightModeItem.isChecked = themeSwitcher.isNightMode
hideArchivedItem.isChecked = !preferences.showArchived
hideCompletedItem.isChecked = !preferences.showCompleted
if (preferences.areQuestionMarksEnabled || preferences.isSkipEnabled) {
hideCompletedItem.title = activity.resources.getString(R.string.hide_entered)
} else {
hideCompletedItem.title = activity.resources.getString(R.string.hide_completed)
}
updateArrows(menu)
}

View File

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

View File

@@ -22,11 +22,13 @@ package org.isoron.uhabits.activities.habits.list
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import dagger.Lazy
import org.isoron.uhabits.R
import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialogFactory
import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog
import org.isoron.uhabits.activities.common.dialogs.ConfirmSyncKeyDialog
import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory
import org.isoron.uhabits.activities.habits.edit.HabitTypeDialog
import org.isoron.uhabits.activities.habits.list.views.HabitCardListAdapter
@@ -51,6 +53,8 @@ import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior.Message
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior.Message.FILE_NOT_RECOGNIZED
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior.Message.IMPORT_FAILED
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior.Message.IMPORT_SUCCESSFUL
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior.Message.SYNC_ENABLED
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior.Message.SYNC_KEY_ALREADY_INSTALLED
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsMenuBehavior
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsSelectionMenuBehavior
import org.isoron.uhabits.inject.ActivityContext
@@ -99,6 +103,14 @@ class ListHabitsScreen
fun onAttached() {
commandRunner.addListener(this)
if (activity.intent.action == "android.intent.action.VIEW") {
val uri = activity.intent.data!!.toString()
val parts = uri.replace(Regex("^.*sync/"), "").split("#")
val syncKey = parts[0]
val encKey = parts[1]
Log.i("ListHabitsScreen", "sync: $syncKey enc: $encKey")
behavior.get().onSyncKeyOffer(syncKey, encKey)
}
}
fun onDettached() {
@@ -196,6 +208,8 @@ class ListHabitsScreen
DATABASE_REPAIRED -> R.string.database_repaired
COULD_NOT_GENERATE_BUG_REPORT -> R.string.bug_report_failed
FILE_NOT_RECOGNIZED -> R.string.file_not_recognized
SYNC_ENABLED -> R.string.sync_enabled
SYNC_KEY_ALREADY_INSTALLED -> R.string.sync_key_already_installed
}
)
)
@@ -217,7 +231,7 @@ class ListHabitsScreen
}
override fun showColorPicker(defaultColor: PaletteColor, callback: OnColorPickedCallback) {
val picker = colorPickerFactory.create(defaultColor)
val picker = colorPickerFactory.create(defaultColor, themeSwitcher.currentTheme!!)
picker.setListener(callback)
picker.show(activity.supportFragmentManager, "picker")
}
@@ -230,6 +244,10 @@ class ListHabitsScreen
numberPickerFactory.create(value, unit, callback).show()
}
override fun showConfirmInstallSyncKey(callback: OnConfirmedCallback) {
ConfirmSyncKeyDialog(activity, callback).show()
}
private fun getExecuteString(command: Command): String? {
when (command) {
is ArchiveHabitsCommand -> {

View File

@@ -131,7 +131,7 @@ class CheckmarkButtonView(
paint.color = when (value) {
YES_MANUAL, YES_AUTO, SKIP -> color
NO -> {
if (preferences.areQuestionMarksEnabled()) mediumContrastColor
if (preferences.areQuestionMarksEnabled) mediumContrastColor
else lowContrastColor
}
else -> lowContrastColor
@@ -140,7 +140,7 @@ class CheckmarkButtonView(
SKIP -> R.string.fa_skipped
NO -> R.string.fa_times
UNKNOWN -> {
if (preferences.areQuestionMarksEnabled()) R.string.fa_question
if (preferences.areQuestionMarksEnabled) R.string.fa_question
else R.string.fa_times
}
else -> R.string.fa_check

View File

@@ -33,6 +33,7 @@ import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.TextView
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.R
import org.isoron.uhabits.activities.common.views.RingView
import org.isoron.uhabits.core.models.Habit
@@ -41,9 +42,9 @@ import org.isoron.uhabits.core.models.Timestamp
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
import org.isoron.uhabits.core.utils.DateUtils
import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.dp
import org.isoron.uhabits.utils.sres
import org.isoron.uhabits.utils.toThemedAndroidColor
import javax.inject.Inject
class HabitCardViewFactory
@@ -213,7 +214,7 @@ class HabitCardView(
fun getActiveColor(habit: Habit): Int {
return when (habit.isArchived) {
true -> sres.getColor(R.attr.contrast60)
false -> habit.color.toThemedAndroidColor(context)
false -> currentTheme().color(habit.color).toInt()
}
}

View File

@@ -169,7 +169,7 @@ class NumberButtonView(
typeface = BOLD_TYPEFACE
textSize = dim(R.dimen.smallTextSize)
}
preferences.areQuestionMarksEnabled() -> {
preferences.areQuestionMarksEnabled -> {
label = resources.getString(R.string.fa_question)
typeface = getFontAwesome()
textSize = dim(R.dimen.smallerTextSize)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -20,19 +20,18 @@ package org.isoron.uhabits.activities.habits.show.views
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Resources
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
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.Frequency
import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardState
import org.isoron.uhabits.databinding.ShowHabitSubtitleBinding
import org.isoron.uhabits.utils.InterfaceUtils
import org.isoron.uhabits.utils.formatTime
import org.isoron.uhabits.utils.toThemedAndroidColor
class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
@@ -47,9 +46,13 @@ class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
@SuppressLint("SetTextI18n")
fun setState(state: SubtitleCardState) {
val color = state.color.toThemedAndroidColor(context)
val color = state.theme.color(state.color).toInt()
val reminder = state.reminder
binding.frequencyLabel.text = state.frequency.format(resources)
binding.frequencyLabel.text = formatFrequency(
state.frequency.numerator,
state.frequency.denominator,
resources,
)
binding.questionLabel.setTextColor(color)
binding.questionLabel.text = state.question
binding.reminderLabel.text = if (reminder != null) {
@@ -72,32 +75,4 @@ class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
postInvalidate()
}
@SuppressLint("StringFormatMatches")
private fun Frequency.format(resources: Resources): String {
val num = this.numerator
val den = this.denominator
if (num == den) {
return resources.getString(R.string.every_day)
}
if (den == 7) {
return resources.getString(R.string.x_times_per_week, num)
}
if (den == 30 || den == 31) {
return resources.getString(R.string.x_times_per_month, num)
}
if (num == 1) {
if (den == 7) {
return resources.getString(R.string.every_week)
}
if (den % 7 == 0) {
return resources.getString(R.string.every_x_weeks, den / 7)
}
if (den == 30 || den == 31) {
return resources.getString(R.string.every_month)
}
return resources.getString(R.string.every_x_days, den)
}
return "$num/$den"
}
}

View File

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

View File

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

View File

@@ -19,6 +19,7 @@
package org.isoron.uhabits.activities.settings
import android.app.backup.BackupManager
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
@@ -27,6 +28,7 @@ import android.os.Build.VERSION
import android.os.Bundle
import android.provider.Settings
import android.util.Log
import androidx.preference.CheckBoxPreference
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
@@ -41,6 +43,7 @@ import org.isoron.uhabits.activities.habits.list.RESULT_REPAIR_DB
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.ui.NotificationTray
import org.isoron.uhabits.core.utils.DateUtils.Companion.getLongWeekdayNames
import org.isoron.uhabits.intents.IntentFactory
import org.isoron.uhabits.notifications.AndroidNotificationTray.Companion.createAndroidNotificationChannel
import org.isoron.uhabits.notifications.RingtoneManager
import org.isoron.uhabits.widgets.WidgetUpdater
@@ -97,6 +100,13 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
intent.putExtra(Settings.EXTRA_CHANNEL_ID, NotificationTray.REMINDERS_CHANNEL_ID)
startActivity(intent)
return true
} else if (key == "pref_sync_enabled_dummy") {
if (prefs.isSyncEnabled) {
prefs.disableSync()
} else {
val context: Context? = activity
context!!.startActivity(IntentFactory().startSyncActivity(context))
}
}
return super.onPreferenceTreeClick(preference)
}
@@ -111,6 +121,7 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
devCategory.isVisible = false
}
updateWeekdayPreference()
updateSyncPreferences()
if (VERSION.SDK_INT < Build.VERSION_CODES.O)
findPreference("reminderCustomize").isVisible = false
@@ -119,6 +130,12 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
}
}
private fun updateSyncPreferences() {
findPreference("pref_sync_display").isVisible = prefs.isSyncEnabled
(findPreference("pref_sync_enabled_dummy") as CheckBoxPreference).isChecked =
prefs.isSyncEnabled
}
private fun updateWeekdayPreference() {
val weekdayPref = findPreference("pref_first_weekday") as ListPreference
val currentFirstWeekday = prefs.firstWeekday.daysSinceSunday + 1
@@ -140,6 +157,7 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
}
BackupManager.dataChanged("org.isoron.uhabits")
updateWeekdayPreference()
updateSyncPreferences()
}
private fun setResultOnPreferenceClick(key: String, result: Int) {

View File

@@ -0,0 +1,132 @@
/*
* 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.sync
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color
import android.os.Bundle
import android.text.Html
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.google.zxing.BarcodeFormat
import com.google.zxing.qrcode.QRCodeWriter
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.invoke
import kotlinx.coroutines.launch
import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher
import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.ui.screens.sync.SyncBehavior
import org.isoron.uhabits.databinding.ActivitySyncBinding
import org.isoron.uhabits.sync.RemoteSyncServer
import org.isoron.uhabits.utils.InterfaceUtils.getFontAwesome
import org.isoron.uhabits.utils.setupToolbar
import org.isoron.uhabits.utils.showMessage
class SyncActivity : AppCompatActivity(), SyncBehavior.Screen {
private lateinit var binding: ActivitySyncBinding
private lateinit var behavior: SyncBehavior
private val scope = CoroutineScope(Dispatchers.Main)
override fun onCreate(savedInstance: Bundle?) {
super.onCreate(savedInstance)
val component = (application as HabitsApplication).component
val preferences = component.preferences
val server = RemoteSyncServer(preferences = preferences)
val themeSwitcher = AndroidThemeSwitcher(this, component.preferences)
themeSwitcher.apply()
behavior = SyncBehavior(this, preferences, server, component.logging)
binding = ActivitySyncBinding.inflate(layoutInflater)
binding.errorIcon.typeface = getFontAwesome(this)
binding.root.setupToolbar(
toolbar = binding.toolbar,
color = PaletteColor(11),
title = resources.getString(R.string.device_sync),
theme = themeSwitcher.currentTheme,
)
binding.syncLink.setOnClickListener { copyToClipboard() }
binding.instructions.text = Html.fromHtml(resources.getString(R.string.sync_instructions))
setContentView(binding.root)
}
override fun onResume() {
super.onResume()
scope.launch {
behavior.onResume()
}
}
private fun copyToClipboard() {
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clipboard.setPrimaryClip(ClipData.newPlainText("Loop Sync Link", binding.syncLink.text))
showMessage(resources.getString(R.string.copied_to_the_clipboard))
}
suspend fun generateQR(msg: String): Bitmap = Dispatchers.IO {
val writer = QRCodeWriter()
val matrix = writer.encode(msg, BarcodeFormat.QR_CODE, 1024, 1024)
val height = matrix.height
val width = matrix.width
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565)
val bgColor = Color.WHITE
val fgColor = Color.BLACK
for (x in 0 until width) {
for (y in 0 until height) {
val color = if (matrix.get(x, y)) fgColor else bgColor
bitmap.setPixel(x, y, color)
}
}
return@IO bitmap
}
suspend fun showQR(msg: String) {
binding.progress.visibility = View.GONE
binding.qrCode.visibility = View.VISIBLE
binding.qrCode.setImageBitmap(generateQR(msg))
}
override suspend fun showLoadingScreen() {
binding.qrCode.visibility = View.GONE
binding.progress.visibility = View.VISIBLE
binding.errorPanel.visibility = View.GONE
}
override suspend fun showErrorScreen() {
binding.qrCode.visibility = View.GONE
binding.progress.visibility = View.GONE
binding.errorPanel.visibility = View.VISIBLE
}
override suspend fun showLink(link: String) {
binding.qrCode.visibility = View.GONE
binding.progress.visibility = View.VISIBLE
binding.errorPanel.visibility = View.GONE
binding.syncLink.text = link
showQR(link)
}
}

View File

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

View File

@@ -29,6 +29,7 @@ import org.isoron.uhabits.core.models.ModelFactory
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.preferences.WidgetPreferences
import org.isoron.uhabits.core.reminders.ReminderScheduler
import org.isoron.uhabits.core.sync.SyncManager
import org.isoron.uhabits.core.tasks.TaskRunner
import org.isoron.uhabits.core.ui.NotificationTray
import org.isoron.uhabits.core.ui.screens.habits.list.HabitCardListCache
@@ -63,4 +64,5 @@ interface HabitsApplicationComponent {
val taskRunner: TaskRunner
val widgetPreferences: WidgetPreferences
val widgetUpdater: WidgetUpdater
val syncManager: SyncManager
}

View File

@@ -19,6 +19,7 @@
package org.isoron.uhabits.inject
import android.content.Context
import dagger.Module
import dagger.Provides
import org.isoron.uhabits.core.AppScope
@@ -33,6 +34,8 @@ import org.isoron.uhabits.core.models.sqlite.SQLiteHabitList
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.preferences.WidgetPreferences
import org.isoron.uhabits.core.reminders.ReminderScheduler
import org.isoron.uhabits.core.sync.AbstractSyncServer
import org.isoron.uhabits.core.sync.NetworkManager
import org.isoron.uhabits.core.tasks.TaskRunner
import org.isoron.uhabits.core.ui.NotificationTray
import org.isoron.uhabits.database.AndroidDatabase
@@ -41,6 +44,8 @@ import org.isoron.uhabits.intents.IntentScheduler
import org.isoron.uhabits.io.AndroidLogging
import org.isoron.uhabits.notifications.AndroidNotificationTray
import org.isoron.uhabits.preferences.SharedPreferencesStorage
import org.isoron.uhabits.sync.AndroidNetworkManager
import org.isoron.uhabits.sync.RemoteSyncServer
import org.isoron.uhabits.utils.DatabaseUtils
import java.io.File
@@ -109,6 +114,18 @@ class HabitsModule(dbFile: File) {
return AndroidLogging()
}
@Provides
@AppScope
fun getNetworkManager(@AppContext context: Context): NetworkManager {
return AndroidNetworkManager(context)
}
@Provides
@AppScope
fun getSyncServer(preferences: Preferences): AbstractSyncServer {
return RemoteSyncServer(preferences)
}
@Provides
@AppScope
fun getDatabase(): Database {

View File

@@ -28,6 +28,7 @@ import org.isoron.uhabits.activities.habits.edit.EditHabitActivity
import org.isoron.uhabits.activities.habits.show.ShowHabitActivity
import org.isoron.uhabits.activities.intro.IntroActivity
import org.isoron.uhabits.activities.settings.SettingsActivity
import org.isoron.uhabits.activities.sync.SyncActivity
import org.isoron.uhabits.core.models.Habit
import javax.inject.Inject
@@ -100,4 +101,8 @@ class IntentFactory
intent.putExtra("habitType", habitType)
return intent
}
fun startSyncActivity(context: Context): Intent {
return Intent(context, SyncActivity::class.java)
}
}

View File

@@ -63,13 +63,14 @@ class PendingIntentFactory
FLAG_UPDATE_CURRENT
)
fun removeRepetition(habit: Habit): PendingIntent =
fun removeRepetition(habit: Habit, timestamp: Timestamp?): PendingIntent =
getBroadcast(
context,
3,
Intent(context, WidgetReceiver::class.java).apply {
action = WidgetReceiver.ACTION_REMOVE_REPETITION
data = Uri.parse(habit.uriString)
if (timestamp != null) putExtra("timestamp", timestamp.unixTime)
},
FLAG_UPDATE_CURRENT
)

View File

@@ -107,7 +107,7 @@ class AndroidNotificationTray
val removeRepetitionAction = Action(
R.drawable.ic_action_cancel,
context.getString(R.string.no),
pendingIntents.removeRepetition(habit)
pendingIntents.removeRepetition(habit, timestamp)
)
val enterAction = Action(

View File

@@ -28,6 +28,7 @@ import android.widget.AdapterView.OnItemClickListener
import androidx.fragment.app.FragmentActivity
import com.android.datetimepicker.time.RadialPickerLayout
import com.android.datetimepicker.time.TimePickerDialog
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher
@@ -35,14 +36,13 @@ import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.ui.ThemeSwitcher.Companion.THEME_LIGHT
import org.isoron.uhabits.receivers.ReminderController
import org.isoron.uhabits.utils.SystemUtils
import org.isoron.uhabits.utils.toThemedAndroidColor
import java.util.Calendar
class SnoozeDelayPickerActivity : FragmentActivity(), OnItemClickListener {
private var habit: Habit? = null
private var reminderController: ReminderController? = null
private var dialog: AlertDialog? = null
private var color: Int = 0
private var androidColor: Int = 0
override fun onCreate(bundle: Bundle?) {
super.onCreate(bundle)
@@ -63,7 +63,7 @@ class SnoozeDelayPickerActivity : FragmentActivity(), OnItemClickListener {
habit = appComponent.habitList.getById(ContentUris.parseId(data))
}
if (habit == null) finish()
color = habit!!.color.toThemedAndroidColor(this)
androidColor = themeSwitcher.currentTheme.color(habit!!.color).toInt()
reminderController = appComponent.reminderController
dialog = AlertDialog.Builder(this)
.setTitle(R.string.select_snooze_delay)
@@ -85,7 +85,7 @@ class SnoozeDelayPickerActivity : FragmentActivity(), OnItemClickListener {
calendar[Calendar.HOUR_OF_DAY],
calendar[Calendar.MINUTE],
DateFormat.is24HourFormat(this),
color
androidColor
)
dialog.show(supportFragmentManager, "timePicker")
}

View File

@@ -92,6 +92,9 @@ class SharedPreferencesStorage
preferences.setNotificationsSticky(getBoolean(key, false))
"pref_led_notifications" ->
preferences.setNotificationsLed(getBoolean(key, false))
"pref_unknown_enabled" -> {
preferences.areQuestionMarksEnabled = getBoolean(key, false)
}
}
sharedPreferences.registerOnSharedPreferenceChangeListener(this)
}

View File

@@ -0,0 +1,59 @@
/*
* 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.sync
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkRequest
import org.isoron.uhabits.core.sync.NetworkManager
class AndroidNetworkManager(
val context: Context,
) : NetworkManager, ConnectivityManager.NetworkCallback() {
val listeners = mutableListOf<NetworkManager.Listener>()
var connected = false
init {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
cm.registerNetworkCallback(NetworkRequest.Builder().build(), this)
}
override fun addListener(listener: NetworkManager.Listener) {
if (connected) listener.onNetworkAvailable()
else listener.onNetworkLost()
listeners.add(listener)
}
override fun remoteListener(listener: NetworkManager.Listener) {
listeners.remove(listener)
}
override fun onAvailable(network: Network) {
connected = true
for (l in listeners) l.onNetworkAvailable()
}
override fun onLost(network: Network) {
connected = false
for (l in listeners) l.onNetworkLost()
}
}

View File

@@ -0,0 +1,105 @@
/*
* 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.sync
import android.util.Log
import io.ktor.client.HttpClient
import io.ktor.client.engine.android.Android
import io.ktor.client.features.ClientRequestException
import io.ktor.client.features.ServerResponseException
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.request.get
import io.ktor.client.request.header
import io.ktor.client.request.post
import io.ktor.client.request.put
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.invoke
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.sync.AbstractSyncServer
import org.isoron.uhabits.core.sync.EditConflictException
import org.isoron.uhabits.core.sync.GetDataVersionResponse
import org.isoron.uhabits.core.sync.KeyNotFoundException
import org.isoron.uhabits.core.sync.RegisterReponse
import org.isoron.uhabits.core.sync.ServiceUnavailable
import org.isoron.uhabits.core.sync.SyncData
class RemoteSyncServer(
private val preferences: Preferences,
private val httpClient: HttpClient = HttpClient(Android) {
install(JsonFeature)
}
) : AbstractSyncServer {
override suspend fun register(): String = Dispatchers.IO {
try {
val url = "${preferences.syncBaseURL}/register"
Log.i("RemoteSyncServer", "POST $url")
val response: RegisterReponse = httpClient.post(url)
return@IO response.key
} catch (e: ServerResponseException) {
throw ServiceUnavailable()
}
}
override suspend fun put(key: String, newData: SyncData) = Dispatchers.IO {
try {
val url = "${preferences.syncBaseURL}/db/$key"
Log.i("RemoteSyncServer", "PUT $url")
val response: String = httpClient.put(url) {
header("Content-Type", "application/json")
body = newData
}
} catch (e: ServerResponseException) {
throw ServiceUnavailable()
} catch (e: ClientRequestException) {
Log.w("RemoteSyncServer", "ClientRequestException", e)
if (e.message!!.contains("409")) throw EditConflictException()
if (e.message!!.contains("404")) throw KeyNotFoundException()
throw e
}
}
override suspend fun getData(key: String): SyncData = Dispatchers.IO {
try {
val url = "${preferences.syncBaseURL}/db/$key"
Log.i("RemoteSyncServer", "GET $url")
return@IO httpClient.get<SyncData>(url)
} catch (e: ServerResponseException) {
throw ServiceUnavailable()
} catch (e: ClientRequestException) {
Log.w("RemoteSyncServer", "ClientRequestException", e)
throw KeyNotFoundException()
}
}
override suspend fun getDataVersion(key: String): Long = Dispatchers.IO {
try {
val url = "${preferences.syncBaseURL}/db/$key/version"
Log.i("RemoteSyncServer", "GET $url")
val response: GetDataVersionResponse = httpClient.get(url)
return@IO response.version
} catch (e: ServerResponseException) {
throw ServiceUnavailable()
} catch (e: ClientRequestException) {
Log.w("RemoteSyncServer", "ClientRequestException", e)
throw KeyNotFoundException()
}
}
}

View File

@@ -21,7 +21,6 @@ package org.isoron.uhabits.utils
import android.content.Context
import android.graphics.Color
import android.util.Log
import org.isoron.uhabits.core.models.PaletteColor
object PaletteUtils {
@@ -29,16 +28,6 @@ object PaletteUtils {
fun getAndroidTestColor(index: Int) = PaletteColor(index).toFixedAndroidColor()
}
fun PaletteColor.toThemedAndroidColor(context: Context): Int {
val palette = StyledResources(context).getPalette()
return if (paletteIndex in palette.indices) {
palette[paletteIndex]
} else {
Log.w("ColorHelper", "Invalid color: $paletteIndex. Returning default.")
palette[0]
}
}
fun PaletteColor.toFixedAndroidColor(): Int {
return intArrayOf(
Color.parseColor("#D32F2F"), // 0 red

View File

@@ -40,8 +40,12 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.core.content.FileProvider
import com.google.android.material.snackbar.Snackbar
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher
import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.ui.views.Theme
import java.io.File
fun RelativeLayout.addBelow(
@@ -157,6 +161,7 @@ fun View.setupToolbar(
toolbar: Toolbar,
title: String,
color: PaletteColor,
theme: Theme,
displayHomeAsUpEnabled: Boolean = true,
) {
toolbar.elevation = InterfaceUtils.dpToPixels(context, 2f)
@@ -165,7 +170,7 @@ fun View.setupToolbar(
val toolbarColor = if (!res.getBoolean(R.attr.useHabitColorAsPrimary)) {
StyledResources(context).getColor(R.attr.colorPrimary)
} else {
color.toThemedAndroidColor(context)
theme.color(color).toInt()
}
val darkerColor = ColorUtils.mixColors(toolbarColor, Color.BLACK, 0.75f)
toolbar.background = ColorDrawable(toolbarColor)
@@ -175,6 +180,13 @@ fun View.setupToolbar(
activity.supportActionBar?.setDisplayHomeAsUpEnabled(displayHomeAsUpEnabled)
}
fun View.currentTheme(): Theme {
val component = (context.applicationContext as HabitsApplication).component
val themeSwitcher = AndroidThemeSwitcher(context, component.preferences)
themeSwitcher.apply()
return themeSwitcher.currentTheme
}
fun Int.toMeasureSpec(mode: Int) =
View.MeasureSpec.makeMeasureSpec(this, mode)

View File

@@ -32,6 +32,7 @@ import org.isoron.uhabits.core.commands.CommandRunner
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.preferences.WidgetPreferences
import org.isoron.uhabits.intents.PendingIntentFactory
import kotlin.math.max
abstract class BaseWidget(val context: Context, val id: Int, val stacked: Boolean) {
private val widgetPrefs: WidgetPreferences
@@ -103,8 +104,8 @@ abstract class BaseWidget(val context: Context, val id: Int, val stacked: Boolea
private fun getBitmapFromView(view: View): Bitmap {
view.invalidate()
val width = view.measuredWidth
val height = view.measuredHeight
val width = max(1, view.measuredWidth)
val height = max(1, view.measuredHeight)
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
view.draw(canvas)

View File

@@ -109,7 +109,7 @@ abstract class BaseWidgetProvider : AppWidgetProvider() {
}
protected fun getHabitsFromWidgetId(widgetId: Int): List<Habit> {
val selectedIds = widgetPrefs.getHabitIdsFromWidgetId(widgetId)!!
val selectedIds = widgetPrefs.getHabitIdsFromWidgetId(widgetId)
val selectedHabits = ArrayList<Habit>(selectedIds.size)
for (id in selectedIds) {
val h = habits.getById(id) ?: throw HabitNotFoundException()

View File

@@ -24,10 +24,11 @@ import android.content.Context
import android.os.Build
import android.view.View
import androidx.annotation.RequiresApi
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.ui.views.WidgetTheme
import org.isoron.uhabits.core.utils.DateUtils
import org.isoron.uhabits.utils.toThemedAndroidColor
import org.isoron.uhabits.widgets.views.CheckmarkWidgetView
open class CheckmarkWidget(
@@ -53,7 +54,7 @@ open class CheckmarkWidget(
(widgetView as CheckmarkWidgetView).apply {
val today = DateUtils.getTodayWithOffset()
setBackgroundAlpha(preferedBackgroundAlpha)
activeColor = habit.color.toThemedAndroidColor(context)
activeColor = WidgetTheme().color(habit.color).toInt()
name = habit.name
entryValue = habit.computedEntries.get(today).value
if (habit.isNumerical) {

View File

@@ -22,9 +22,10 @@ package org.isoron.uhabits.widgets
import android.app.PendingIntent
import android.content.Context
import android.view.View
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.activities.common.views.FrequencyChart
import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.utils.toThemedAndroidColor
import org.isoron.uhabits.core.ui.views.WidgetTheme
import org.isoron.uhabits.widgets.views.GraphWidgetView
class FrequencyWidget(
@@ -47,7 +48,7 @@ class FrequencyWidget(
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
(widgetView.dataView as FrequencyChart).apply {
setFirstWeekday(firstWeekday)
setColor(habit.color.toThemedAndroidColor(context))
setColor(WidgetTheme().color(habit.color).toInt())
setFrequency(habit.originalEntries.computeWeekdayFrequency(habit.isNumerical))
}
}

View File

@@ -22,10 +22,11 @@ package org.isoron.uhabits.widgets
import android.app.PendingIntent
import android.content.Context
import android.view.View
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.activities.common.views.ScoreChart
import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter
import org.isoron.uhabits.utils.toThemedAndroidColor
import org.isoron.uhabits.core.ui.views.WidgetTheme
import org.isoron.uhabits.widgets.views.GraphWidgetView
class ScoreWidget(
@@ -44,7 +45,8 @@ class ScoreWidget(
val viewModel = ScoreCardPresenter.buildState(
habit = habit,
firstWeekday = prefs.firstWeekdayInt,
spinnerPosition = prefs.scoreCardSpinnerPosition
spinnerPosition = prefs.scoreCardSpinnerPosition,
theme = WidgetTheme(),
)
val widgetView = view as GraphWidgetView
widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
@@ -52,7 +54,7 @@ class ScoreWidget(
(widgetView.dataView as ScoreChart).apply {
setIsTransparencyEnabled(true)
setBucketSize(viewModel.bucketSize)
setColor(habit.color.toThemedAndroidColor(context))
setColor(WidgetTheme().color(habit.color).toInt())
setScores(viewModel.scores)
}
}

View File

@@ -53,7 +53,7 @@ internal class StackRemoteViewsFactory(private val context: Context, intent: Int
AppWidgetManager.INVALID_APPWIDGET_ID
)
private val habitIds: LongArray
private val widgetType: StackWidgetType?
private val widgetType: StackWidgetType
private var remoteViews = ArrayList<RemoteViews>()
override fun onCreate() {}
override fun onDestroy() {}
@@ -86,27 +86,27 @@ internal class StackRemoteViewsFactory(private val context: Context, intent: Int
override fun getViewAt(position: Int): RemoteViews? {
Log.i("StackRemoteViewsFactory", "getViewAt $position")
return if (position < 0 || position > remoteViews.size) null else remoteViews[position]
return if (0 <= position && position < remoteViews.size) remoteViews[position] else null
}
private fun constructWidget(
habit: Habit,
prefs: Preferences
): BaseWidget {
when (widgetType) {
StackWidgetType.CHECKMARK -> return CheckmarkWidget(context, widgetId, habit, true)
StackWidgetType.FREQUENCY -> return FrequencyWidget(
return when (widgetType) {
StackWidgetType.CHECKMARK -> CheckmarkWidget(context, widgetId, habit, true)
StackWidgetType.FREQUENCY -> FrequencyWidget(
context,
widgetId,
habit,
prefs.firstWeekdayInt,
true
)
StackWidgetType.SCORE -> return ScoreWidget(context, widgetId, habit, true)
StackWidgetType.HISTORY -> return HistoryWidget(context, widgetId, habit, true)
StackWidgetType.STREAKS -> return StreakWidget(context, widgetId, habit, true)
StackWidgetType.SCORE -> ScoreWidget(context, widgetId, habit, true)
StackWidgetType.HISTORY -> HistoryWidget(context, widgetId, habit, true)
StackWidgetType.STREAKS -> StreakWidget(context, widgetId, habit, true)
StackWidgetType.TARGET -> TargetWidget(context, widgetId, habit, true)
}
throw IllegalStateException()
}
override fun getLoadingView(): RemoteViews {
@@ -157,6 +157,7 @@ internal class StackRemoteViewsFactory(private val context: Context, intent: Int
if (widgetTypeValue < 0) throw RuntimeException("invalid widget type")
if (habitIdsStr == null) throw RuntimeException("habitIdsStr is null")
widgetType = StackWidgetType.getWidgetTypeFromValue(widgetTypeValue)
?: throw RuntimeException("unknown widget type value: $widgetTypeValue")
habitIds = splitLongs(habitIdsStr)
}
}

View File

@@ -19,61 +19,59 @@
package org.isoron.uhabits.widgets
import org.isoron.uhabits.R
import java.lang.IllegalStateException
/**
* Created by victoryu on 11/3/17.
*/
enum class StackWidgetType(val value: Int) {
CHECKMARK(0), FREQUENCY(1), SCORE(2), // habit strength widget
HISTORY(3), STREAKS(4), TARGET(5);
companion object {
fun getWidgetTypeFromValue(value: Int): StackWidgetType? {
return when {
CHECKMARK.value == value -> CHECKMARK
FREQUENCY.value == value -> FREQUENCY
SCORE.value == value -> SCORE
HISTORY.value == value -> HISTORY
STREAKS.value == value -> STREAKS
TARGET.value == value -> TARGET
return when (value) {
CHECKMARK.value -> CHECKMARK
FREQUENCY.value -> FREQUENCY
SCORE.value -> SCORE
HISTORY.value -> HISTORY
STREAKS.value -> STREAKS
TARGET.value -> TARGET
else -> null
}
}
fun getStackWidgetLayoutId(type: StackWidgetType?): Int {
when (type) {
CHECKMARK -> return R.layout.checkmark_stackview_widget
FREQUENCY -> return R.layout.frequency_stackview_widget
SCORE -> return R.layout.score_stackview_widget
HISTORY -> return R.layout.history_stackview_widget
STREAKS -> return R.layout.streak_stackview_widget
TARGET -> return R.layout.target_stackview_widget
return when (type) {
CHECKMARK -> R.layout.checkmark_stackview_widget
FREQUENCY -> R.layout.frequency_stackview_widget
SCORE -> R.layout.score_stackview_widget
HISTORY -> R.layout.history_stackview_widget
STREAKS -> R.layout.streak_stackview_widget
TARGET -> R.layout.target_stackview_widget
else -> throw IllegalStateException()
}
return 0
}
fun getStackWidgetAdapterViewId(type: StackWidgetType?): Int {
when (type) {
CHECKMARK -> return R.id.checkmarkStackWidgetView
FREQUENCY -> return R.id.frequencyStackWidgetView
SCORE -> return R.id.scoreStackWidgetView
HISTORY -> return R.id.historyStackWidgetView
STREAKS -> return R.id.streakStackWidgetView
TARGET -> return R.id.targetStackWidgetView
return when (type) {
CHECKMARK -> R.id.checkmarkStackWidgetView
FREQUENCY -> R.id.frequencyStackWidgetView
SCORE -> R.id.scoreStackWidgetView
HISTORY -> R.id.historyStackWidgetView
STREAKS -> R.id.streakStackWidgetView
TARGET -> R.id.targetStackWidgetView
else -> throw IllegalStateException()
}
return 0
}
fun getStackWidgetEmptyViewId(type: StackWidgetType?): Int {
when (type) {
CHECKMARK -> return R.id.checkmarkStackWidgetEmptyView
FREQUENCY -> return R.id.frequencyStackWidgetEmptyView
SCORE -> return R.id.scoreStackWidgetEmptyView
HISTORY -> return R.id.historyStackWidgetEmptyView
STREAKS -> return R.id.streakStackWidgetEmptyView
TARGET -> return R.id.targetStackWidgetEmptyView
return when (type) {
CHECKMARK -> R.id.checkmarkStackWidgetEmptyView
FREQUENCY -> R.id.frequencyStackWidgetEmptyView
SCORE -> R.id.scoreStackWidgetEmptyView
HISTORY -> R.id.historyStackWidgetEmptyView
STREAKS -> R.id.streakStackWidgetEmptyView
TARGET -> R.id.targetStackWidgetEmptyView
else -> throw IllegalStateException()
}
return 0
}
}
}

View File

@@ -24,9 +24,10 @@ import android.content.Context
import android.view.View
import android.view.ViewGroup.LayoutParams
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.activities.common.views.StreakChart
import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.utils.toThemedAndroidColor
import org.isoron.uhabits.core.ui.views.WidgetTheme
import org.isoron.uhabits.widgets.views.GraphWidgetView
class StreakWidget(
@@ -46,7 +47,7 @@ class StreakWidget(
widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
(widgetView.dataView as StreakChart).apply {
setColor(habit.color.toThemedAndroidColor(context))
setColor(WidgetTheme().color(habit.color).toInt())
setStreaks(habit.streaks.getBest(maxStreakCount))
}
}

View File

@@ -25,11 +25,12 @@ import android.view.View
import android.view.ViewGroup.LayoutParams
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import kotlinx.coroutines.runBlocking
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.activities.common.views.TargetChart
import org.isoron.uhabits.activities.habits.show.views.TargetCardView.Companion.intervalToLabel
import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.ui.screens.habits.show.views.TargetCardPresenter
import org.isoron.uhabits.utils.toThemedAndroidColor
import org.isoron.uhabits.core.ui.views.WidgetTheme
import org.isoron.uhabits.widgets.views.GraphWidgetView
class TargetWidget(
@@ -49,8 +50,12 @@ class TargetWidget(
widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
val chart = (widgetView.dataView as TargetChart)
val data = TargetCardPresenter.buildState(habit, prefs.firstWeekdayInt)
chart.setColor(data.color.toThemedAndroidColor(context))
val data = TargetCardPresenter.buildState(
habit = habit,
firstWeekday = prefs.firstWeekdayInt,
theme = WidgetTheme(),
)
chart.setColor(WidgetTheme().color(habit.color).toInt())
chart.setTargets(data.targets)
chart.setLabels(data.intervals.map { intervalToLabel(context.resources, it) })
chart.setValues(data.values)

View File

@@ -95,7 +95,7 @@ class WidgetUpdater
val modifiedWidgetIds = when (modifiedHabitId) {
null -> widgetIds.toList()
else -> widgetIds.filter { w ->
widgetPrefs.getHabitIdsFromWidgetId(w)!!.contains(modifiedHabitId)
widgetPrefs.getHabitIdsFromWidgetId(w).contains(modifiedHabitId)
}
}

View File

@@ -31,6 +31,7 @@ import android.widget.ListView
import android.widget.TextView
import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher
import org.isoron.uhabits.core.preferences.WidgetPreferences
import org.isoron.uhabits.widgets.WidgetUpdater
import java.util.ArrayList
@@ -58,6 +59,7 @@ open class HabitPickerDialog : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val component = (applicationContext as HabitsApplication).component
AndroidThemeSwitcher(this, component.preferences).apply()
val habitList = component.habitList
widgetPreferences = component.widgetPreferences
widgetUpdater = component.widgetUpdater

View File

@@ -39,6 +39,7 @@ import org.isoron.uhabits.utils.PaletteUtils.getAndroidTestColor
import org.isoron.uhabits.utils.StyledResources
import kotlin.math.max
import kotlin.math.min
import kotlin.math.roundToInt
class CheckmarkWidgetView : HabitWidgetView {
var activeColor: Int = 0
@@ -102,7 +103,7 @@ class CheckmarkWidgetView : HabitWidgetView {
SKIP -> resources.getString(R.string.fa_skipped)
UNKNOWN -> {
run {
if (preferences!!.areQuestionMarksEnabled()) {
if (preferences!!.areQuestionMarksEnabled) {
return resources.getString(R.string.fa_question)
} else {
resources.getString(R.string.fa_times)
@@ -118,19 +119,25 @@ class CheckmarkWidgetView : HabitWidgetView {
get() = R.layout.widget_checkmark
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val width = MeasureSpec.getSize(widthMeasureSpec)
val height = MeasureSpec.getSize(heightMeasureSpec)
var textSize = 0.15f * height
val maxTextSize = getDimension(context, R.dimen.smallerTextSize)
textSize = min(textSize, maxTextSize)
var width = MeasureSpec.getSize(widthMeasureSpec)
var height = MeasureSpec.getSize(heightMeasureSpec)
if (height >= width) {
height = min(height, (width * 1.5).roundToInt())
} else {
width = min(width, height)
}
val textSize = min(0.2f * width, getDimension(context, R.dimen.smallerTextSize))
label.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
if (isNumerical) {
ring.setTextSize(textSize * 0.75f)
ring.setTextSize(textSize * 0.9f)
} else {
ring.setTextSize(textSize)
}
ring.setThickness(0.15f * textSize)
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
ring.setThickness(0.03f * width)
super.onMeasure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
)
}
private fun init() {

View File

@@ -0,0 +1 @@
Loop - Gewoonte Boekhouer

View File

@@ -1,22 +0,0 @@
لب يساعدك على خلق والحفاظ على العادات الجيدة، مما يسمح لك لتحقيق أهدافكة. الرسوم البيانية والإحصاءات التفصيلية تبين لكم كيف تحسن عاداتك مع مرور الوقت. هو تماما خالية من الاعلانات ومفتوحة المصدر.
<b>واجهة بسيطة، جميلة وحديثة </b>
لوب يحتوي على واجهة بسيطة وهي سهلة الاستخدام و تتابع نظام تصميم الماتريل دسيجن.
<b>نتيجة العادات</b>
بالإضافة إلى عرض التقدم الحالي، لوب ديه خوارزمية متقدمة لحساب قوة عاداتك. كل التكرار يجعل هذه العادة أقوى، وفي كل يوم غاب يجعلها أضعف. مع ذلك غيب أيام قليلة بعد تقدم طويلة ، لن تدمر تماما تقدمك .
<b>الرسوم البيانية والإحصاءات المفصلة</b>
نرى بوضوح كيف كنت قد تحسنت عاداتك بمرور الوقت مع الرسوم البيانية الجميله ومفصلة. انتقل إلى الوراء لنرى التاريخ الكامل لعاداتك.
<b>جداول مرنة</b>
تؤيد كل من العادات اليومية والعادات مع جداول أكثر تعقيدا، مثل 3 مرات كل أسبوع، مرة واحدة كل أسبوعين، أو مرة كل يومين.
<b>تذكير</b>
إنشاء تذكير لكل فرد من عاداتك، في ساعة اختيار من اليوم. تحقق بسهولة، رفض أو غفوة عادتك مباشرة من الإخطار، دون الحاجة إلى فتح التطبيق.
<b>خالية تماما من الإعلانات و المصدر المفتوح</b>
لا توجد على الاطلاق الإعلانات والشعارات المزعجة أو أذونات إضافية في هذا التطبيق، و سوف يكون هناك أبدا.
<b>الأمثل للساعات الذكية</b>
يمكن التحقق من رسائل التذكير، رفض أو غفوة عادتك مباشرة من ساعتك الاندرويد وير.

View File

@@ -1 +0,0 @@
خلق عادات جيدة وتتبع تقدمك على مر الزمن

View File

@@ -1 +0,0 @@
لوب ملاحق العادة

View File

@@ -0,0 +1 @@
Loop Следене на навици

View File

@@ -1,4 +1,4 @@
Loop Seguiment d'hàbits t'ajuda a crear i mantenir en la teva vida hàbits positius de llarg termini. Estadístiques i gràfiques detallades et donen una imatge clara de com els teus hàbits han millorat en el temps. L'app és completament sense anuncis, de codi obert i respecta la teva privadesa.
Loop Seguiment d'hàbits t'ajuda a crear i mantenir en la teva vida hàbits positius de llarg termini. Gràfics i estadístiques detallades us proporcionen una imatge clara de com els vostres hàbits han millorat amb el pas del temps. L'aplicació Blokada és totalment lliure de publicitat, de codi obert i respecta la vostra privadesa.
<b>Interfície minimalista, lleugera i bonica</b>
Loop té una interfície elegant i minimalista que es molt fàcil d'usar, inclús per als usuaris primerencs. Altament optimitzada per a que sigui ràpida, l'app funciona bé inclús en telèfons antics.

View File

@@ -0,0 +1 @@
Loop - Hàbit Rastrejador

View File

@@ -1,22 +0,0 @@
Loop t'ajuda a crear i mantenir bons hàbits, permetent-te aconseguir els teus objectius a llarg termini. Els gràfics i estadístiques detallades et mostren com han millorat els teus hàbits al llarg del temps. És completament de codi obert i lliure de publicitat.
<b>Senzilla, bonica i moderna interfície</b>
Loop té una interfície minimalista que és fàcil d'utilitzar i segueix les guies de "material design".
<b>Puntuació d'hàbit</b>
A més de mostrar la teva ratxa actual, Loop té un algoritme avançat per a calcular la fortalesa dels teus hàbits. Cada repetició fa el teu hàbit més fort, i cada dia que fallis el farà més dèbil. Tot i això uns quants dies que fallis després d'una llarga ratxa no malmetrà completament el teu progrès.
<b>Gràfics i estadístiques detallades</b>
Permet veure de forma clara com han millorat els teus hàbits al llarg del temps amb gràfics bonics i detallats. Pots anar enrera i veure també l'històric complet dels teus hàbits.
<b>Planificació flexible</b>
Suporta tant hàbits diaris com hàbits amb planificacions més complexes, com per exemple 3 vegades per setmana; un cop setmana si setmana no; o un dia si i altre no.
<b>Recordatoris</b>
Crea un recordatori individual per a cada hàbit, a l'hora escollida del dia. Revisa fàcilment, endarrereix o anul·la el teu hàbit directament des de la notificació, sense obrir l'app.
<b>Completament de codi obert i lliure de publicitat</b>
No hi ha cap tipus de publicitat, notificacions molestes o permisos intrusius en aquesta app, i mai n'hi haurà. El codi font complet està disponible sota la llicència GPLv3.
<b>Optimitzat per a rellotges intel·ligents</b>
Els recordatoris poden ser revisats, endarrerits o anul·lats directament des del teu rellotge Android Wear.

View File

@@ -1 +0,0 @@
Crea bons hàbits i segueix el seu progrés al llarg del temps (sense publicitat)

View File

@@ -1,22 +0,0 @@
Aplikace ti pomůže vytvořit a udržovat si prospěšné návyky a dosáhnout tak tvých dlouhodobých cílů. Detailní grafy a statistiky ti ukáží, jak se tvoje zvyky postupem času zlepšují. Vše je kompletně bez reklam a open source.
<b>Jednoduché, krásné a moderní prostředí</b>
Aplikace má minimalistický design s jednoduchým použitím. Dodržuje pravidla material designu.
<b>Síla zvyku</b>
Pro zobrazení aktuální úspěšné serie aplikace využívá pokročilý algoritmus, aby vypočítala sílu tvých zvyků. Každé opakování dělá tvůj zvyk silnějším a každé nedodržení ho oslabuje. Ale pár vynechaných dní po dlouhé řadě kompletně nezničí celý tvůj postup.
<b>Detailní grafy a statistika</b>
Přehledně vidíš na krásných grafech, jak moc se tvoje zvyky zlepšují v průběhu času. Jeď zpět, abys viděl kompletní historii.
<b>Flexibilní časový plán</b>
Podpora jak denních návyků, tak návyků s komplexnějším rozvrhem. Jako jsou 3 krát týdně, jednou za dva týdny, nebo obden.
<b>Upomínky</b>
Vytvoř si individuální upomínku pro každý zvyk ve zvolený čas. Jednoduše potvrď, přeskoč nebo odlož notifikace bez nutnosti otevření aplikace.
<b>Kompletně bez reklam a open source</b>
Nejsou tu naprosto žádné reklamy, otravné notifikace nebo dotěrná povolení aplikace. A nikdy nebudou. Kompletní zdrojový kód je dostupný pod GPLv3.
<b>Optimalizované pro chytré hodinky</b>
Upomínky mohou být potvrzen, odloženy nebo smazány přímo z tvého zařízení s Android Wear.

View File

@@ -1 +0,0 @@
Vytvoř si prospěšné návyky a sleduj jejich vývoj v průběhu času (bez reklam)

View File

@@ -1 +0,0 @@
Loop - Habit Tracker

View File

@@ -0,0 +1 @@
Loop Vane Tracker

View File

@@ -1,22 +0,0 @@
Loop hilft dir gute Gewohnheiten anzunehmen und deine langfristigen Ziele zu erreichen. Detailierte Statistiken zeigen dir, wie du dich entwickelt hast. Es ist ohne Werbung und Open Source.
<b>Einfaches, schönes und modernes Oberfläche</b>
Loop hat eine minimale Oberfläche und ist deshalb einfach zu nutzen. Es folgt dem material Design.
<b>Habit Punkte</b>
Um dir deine Schwächen zu zeigen, hat Loop einen Algorithmus, um deine starken Angewohnheiten zu erkennen. Jede Wiederholung verstärkt diese und jedes Aussetzen schwächt sie. Aber ein paar Verfehlungen nach langem Durchhalten machen natürlich nicht gleich alles zu nichte.
<b>Statistiken</b>
Schau dir an, wie sich deine Angewohnheiten im Laufe der Zeit gemacht haben. Schau auf die schönen Diagramme und gehe zurück im gesamten Verlauf.
<b>Flexible Zeiten</b>
Unterstützt sowohl tägliche Vorgaben, als auch komplexere Pläne, woe etwa 3 mal pro Woche; ein mal in jeder anderen Woche; oder jeden anderen Tag.
<b>Erinnerungen</b>
Erstelle individuelle Erinnerungen und wann diese dich benachrichtigen sollen. Kontrolliere deine Vorhaben ganz einfach und lehne sie bei Bedarf direkt ab, ohne in die App zu wechseln.
<b>Komplett werbefrei und Open Source</b>
Es gibt absolut keine Werbung, nervende Einblendungen oder merkwürdige Berechtigungen in dieser App und das wird auch so bleiben. Der komplette Quellcode steht unter der GPLv3.
<b>Optimiert für Smartwatches</b>
Erinnerungen können direkt von der Android Wear watch kontrolliert, pausiert, oder verschoben werden.

View File

@@ -1 +0,0 @@
Nimm gute Gewohnheiten an und verfolge deinen Fortschritt (ohne Werbung)

View File

@@ -0,0 +1 @@
Loop - Gewohnheiten Tracking

View File

@@ -0,0 +1 @@
Loop - Καταγραφή Συνηθειών

View File

@@ -1,22 +0,0 @@
Loop te ayuda a crear y mantener buenos hábitos, permitiéndote alcanzar tus metas a largo plazo. Detallados gráficos y estadísticas muestran como tus hábitos mejoran con el tiempo. No existe ningún anuncio y es de código abierto.
<b>Una interfaz simple, bella y moderna</b>
Loop tiene una interfaz minimalista que es fácil de usar y sigue los principios del material design.
<b>Puntuación del hábito</b>
Además de mostrar tu racha actual, Loop tiene un algoritmo avanzado para calcular la fuerza de tus hábitos. Cada repetición hace tu hábito más fuerte y cada día fallido lo hace más débil. Sin embargo, unos pocos días después de una larga racha no destruirán completamente todo tu progreso.
<b>Detallados gráficos y estadísticas</b>
Observa claramente como tus hábitos han mejorado con el tiempo con bellos y detallados gráficos. Ve hacia atrás para ver el historial completo del hábito.
<b>Horarios flexibles</b>
Soporta hábitos diarios y hábitos con repeticiones más complejas, como 3 veces por semana; una vez cada varias semanas; o cada día.
<b>Recordatorios</b>
Crea recordatorios individuales para cada hábito a una hora determinada del día. Fácilmente marcables, descartables o posponibles directamente desde la notificación, sin abrir la app.
<b>Completamente sin anuncios y de código abierto</b>
No existe ningún tipo de publicidad, notificaciones molestas o permisos intrusivos, y nunca los habrá. Todo el código está disponible bajo GPLv3.
<b>Optimizado para smartwatches</b>
Los recordatorios se pueden marcar, posponer o descartar directamente desde tu reloj Android Wear.

View File

@@ -1 +0,0 @@
Crea buenos hábitos y haz un seguimiento de su progreso a lo largo del tiempo

View File

@@ -1 +0,0 @@
Loop - Analizador de Hábitos

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