Compare commits

...

308 Commits

Author SHA1 Message Date
Sylvia van Os
cd5ef267e8 WIP 2024-05-21 18:49:52 +02:00
Sylvia van Os
4b1d1f4541 Merge pull request #1896 from CatimaLoyalty/dependabot/gradle/com.android.application-8.4.1
Bump com.android.application from 8.4.0 to 8.4.1
2024-05-21 08:25:15 +02:00
dependabot[bot]
801d3fa8cd ---
updated-dependencies:
- dependency-name: com.android.application
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-21 02:19:26 +00:00
Sylvia van Os
d15a46fc6f Fix typo 2024-05-20 20:04:01 +02:00
Sylvia van Os
7f46a267b6 Merge pull request #1895 from CatimaLoyalty/create-pull-request/patch-1716220734
Update Fastlane changelogs
2024-05-20 18:12:04 +02:00
TheLastProject
195cb8d5ee Update Fastlane changelogs 2024-05-20 15:58:53 +00:00
Sylvia van Os
7454a965bc Update CHANGELOG 2024-05-20 17:58:40 +02:00
Sylvia van Os
9ef988c259 Merge pull request #1894 from CatimaLoyalty/feature/showImageTypeInCardIdVield
Show image type on view screen when not viewing barcode
2024-05-20 17:54:09 +02:00
Sylvia van Os
7a2ff0995f Show image type on view screen when not viewing barcode 2024-05-20 17:47:19 +02:00
Sylvia van Os
9b65d3926b Merge pull request #1893 from CatimaLoyalty/create-pull-request/patch-1716210906
Update Fastlane changelogs
2024-05-20 15:20:35 +02:00
TheLastProject
06b3536079 Update Fastlane changelogs 2024-05-20 13:15:06 +00:00
Sylvia van Os
315396fd42 Merge pull request #1892 from CatimaLoyalty/feature/1860
Support for creating a card from shared text
2024-05-20 15:14:53 +02:00
Sylvia van Os
b90c43f667 Support for creating a card from shared text 2024-05-20 14:53:10 +02:00
Aglag257
6d97a29e9c Fix describeContents() in LoyaltyCard Class (#1887) 2024-05-20 13:19:13 +02:00
Sylvia van Os
7f0e2acab9 Merge pull request #1891 from CatimaLoyalty/dependabot/gradle/org.robolectric-robolectric-4.12.2
Bump org.robolectric:robolectric from 4.12.1 to 4.12.2
2024-05-20 11:52:00 +02:00
Sylvia van Os
be35886c92 Merge pull request #1890 from CatimaLoyalty/dependabot/github_actions/actions/checkout-4.1.6
Bump actions/checkout from 4.1.5 to 4.1.6
2024-05-20 11:51:23 +02:00
dependabot[bot]
73ad9c5365 Bump org.robolectric:robolectric from 4.12.1 to 4.12.2
Bumps [org.robolectric:robolectric](https://github.com/robolectric/robolectric) from 4.12.1 to 4.12.2.
- [Release notes](https://github.com/robolectric/robolectric/releases)
- [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.12.1...robolectric-4.12.2)

---
updated-dependencies:
- dependency-name: org.robolectric:robolectric
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-20 02:34:37 +00:00
dependabot[bot]
818751ffad Bump actions/checkout from 4.1.5 to 4.1.6
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.5 to 4.1.6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4.1.5...v4.1.6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-20 02:12:05 +00:00
Sylvia van Os
d5856e7974 Release Catima 2.29.1 2024-05-19 10:53:43 +02:00
Sylvia van Os
2caf3d42f4 Update fastlane 2024-05-18 10:18:33 +02:00
Sylvia van Os
e766743baa Merge pull request #1885 from CatimaLoyalty/fix/properSeparatorFix
Properly fix decimal separator detection logic
2024-05-14 17:06:20 +02:00
Sylvia van Os
facb23f0a5 Properly fix decimal separator detection logic 2024-05-13 21:17:13 +02:00
Sylvia van Os
a2dff0e6bf Merge pull request #1884 from CatimaLoyalty/dependabot/github_actions/actions/checkout-4.1.5
Bump actions/checkout from 4.1.4 to 4.1.5
2024-05-13 18:42:40 +02:00
dependabot[bot]
60c53ec1d1 Bump actions/checkout from 4.1.4 to 4.1.5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.4 to 4.1.5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4.1.4...v4.1.5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-13 02:55:49 +00:00
Sylvia van Os
e3c903f773 Merge pull request #1883 from CatimaLoyalty/create-pull-request/patch-1715516406
Update Fastlane changelogs
2024-05-12 15:05:00 +02:00
TheLastProject
955764aa18 Update Fastlane changelogs 2024-05-12 12:20:06 +00:00
Sylvia van Os
ed22aa844f Document balance handling improvements 2024-05-12 14:19:36 +02:00
Sylvia van Os
6b8fc50021 Merge pull request #1878 from CatimaLoyalty/feature/acceptBothSeparators
Disable currency grouping and accept thousand separator as decimal separator
2024-05-12 14:17:58 +02:00
Sylvia van Os
1aed5c36b1 Merge pull request #1882 from CatimaLoyalty/create-pull-request/patch-1715487330
Update contributors
2024-05-12 10:33:39 +02:00
TheLastProject
4690f53be7 Update contributors 2024-05-12 04:15:30 +00:00
Sylvia van Os
29a22926aa Merge pull request #1879 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-05-10 23:31:27 +02:00
ΣΤΑΥΡΟΣ ΔΑΛΙΑΚΟΠΟΥΛΟΣ
a4da8144c3 Translated using Weblate (Greek)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/el/
2024-05-10 23:24:06 +02:00
Sylvia van Os
84bfa304c4 Disable currency grouping and accept thousand separator as decimal separator 2024-05-10 20:01:39 +02:00
Sylvia van Os
72749015dd Merge pull request #1877 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-05-09 21:57:52 +02:00
ΣΤΑΥΡΟΣ ΔΑΛΙΑΚΟΠΟΥΛΟΣ
ae5d656a64 Translated using Weblate (Greek)
Currently translated at 100.0% (1 of 1 strings)

Translation: Catima/Android (Debug)
Translate-URL: https://hosted.weblate.org/projects/catima/android-debug/el/
2024-05-07 16:07:57 +02:00
ΣΤΑΥΡΟΣ ΔΑΛΙΑΚΟΠΟΥΛΟΣ
d8f2cde9de Translated using Weblate (Greek)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/el/
2024-05-07 16:07:57 +02:00
Sylvia van Os
935a4ae46e Merge pull request #1874 from CatimaLoyalty/create-pull-request/patch-1714882546
Update contributors
2024-05-05 10:37:59 +02:00
TheLastProject
ffecec9cba Update contributors 2024-05-05 04:15:45 +00:00
Sylvia van Os
734845eff0 Merge pull request #1871 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-05-03 17:03:36 +02:00
Sébastien Delord
bd6b18eea2 Translated using Weblate (French)
Currently translated at 98.4% (130 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/fr/
2024-05-03 09:43:43 +02:00
Sylvia van Os
6473bfe84e Merge pull request #1868 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-05-03 08:26:25 +02:00
Sylvia van Os
66fff2d3d9 Merge pull request #1870 from CatimaLoyalty/dependabot/gradle/com.google.android.material-material-1.12.0
Bump com.google.android.material:material from 1.11.0 to 1.12.0
2024-05-03 08:20:50 +02:00
dependabot[bot]
ef1b470f0a Bump com.google.android.material:material from 1.11.0 to 1.12.0
Bumps [com.google.android.material:material](https://github.com/material-components/material-components-android) from 1.11.0 to 1.12.0.
- [Release notes](https://github.com/material-components/material-components-android/releases)
- [Commits](https://github.com/material-components/material-components-android/compare/1.11.0...1.12.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>
2024-05-03 02:49:31 +00:00
Milo Ivir
b087d49530 Translated using Weblate (Croatian)
Currently translated at 100.0% (312 of 312 strings)

Co-authored-by: Milo Ivir <mail@milotype.de>
Translate-URL: https://hosted.weblate.org/projects/catima/catima/hr/
Translation: Catima/Android
2024-05-03 02:09:26 +02:00
Sylvia van Os
cd46cd3f8d Merge pull request #1866 from CatimaLoyalty/dependabot/gradle/com.android.application-8.4.0
Bump com.android.application from 8.3.2 to 8.4.0
2024-05-01 18:38:37 +02:00
dependabot[bot]
c44133942a Bump com.android.application from 8.3.2 to 8.4.0
Bumps com.android.application from 8.3.2 to 8.4.0.

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-01 02:24:02 +00:00
Sylvia van Os
24e40f41a5 Merge pull request #1865 from CatimaLoyalty/dependabot/github_actions/actions/checkout-4.1.4
Bump actions/checkout from 4.1.3 to 4.1.4
2024-04-29 19:22:01 +02:00
Sylvia van Os
43b90587a5 Merge pull request #1864 from CatimaLoyalty/dependabot/github_actions/actions/upload-artifact-4.3.3
Bump actions/upload-artifact from 4.3.2 to 4.3.3
2024-04-29 19:02:36 +02:00
Sylvia van Os
f5b2516492 Merge pull request #1863 from CatimaLoyalty/dependabot/github_actions/peter-evans/create-pull-request-6.0.5
Bump peter-evans/create-pull-request from 6.0.4 to 6.0.5
2024-04-29 19:02:11 +02:00
dependabot[bot]
5bec40eb59 Bump actions/checkout from 4.1.3 to 4.1.4
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.3 to 4.1.4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4.1.3...v4.1.4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-29 02:12:58 +00:00
dependabot[bot]
6b1cccfdf8 Bump actions/upload-artifact from 4.3.2 to 4.3.3
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.2 to 4.3.3.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4.3.2...v4.3.3)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-29 02:12:56 +00:00
dependabot[bot]
ddf28d7542 Bump peter-evans/create-pull-request from 6.0.4 to 6.0.5
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6.0.4 to 6.0.5.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v6.0.4...v6.0.5)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-29 02:12:53 +00:00
Sylvia van Os
9cf69a3128 Merge pull request #1862 from CatimaLoyalty/create-pull-request/patch-1714277679
Update contributors
2024-04-28 10:22:11 +02:00
Sylvia van Os
8dc62def08 Merge pull request #1861 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-28 10:21:09 +02:00
TheLastProject
ac8b898ccc Update contributors 2024-04-28 04:14:39 +00:00
Young
97e675e476 Translated using Weblate (Chinese (Traditional))
Currently translated at 98.0% (306 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/zh_Hant/
2024-04-28 04:07:18 +02:00
Sylvia van Os
4b488ce1f7 Merge pull request #1859 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-25 17:37:57 +02:00
solokot
7f5fe8831a Translated using Weblate (Russian)
Currently translated at 100.0% (132 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/ru/
2024-04-25 01:07:38 +02:00
Jesus Aguilar-Andrade
f7ff63301b Translated using Weblate (Spanish)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/es/
2024-04-25 01:07:37 +02:00
simosathan9
9bb1602370 Fix balance unexpected rounding and app crashing issue (#1838)
Co-authored-by:  Colette Kerr <colette.m.y.kerr@gmail.com>
2024-04-24 21:41:22 +02:00
Sylvia van Os
40da1d2e16 Merge pull request #1855 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-24 18:37:33 +02:00
Jesus Aguilar-Andrade
8dd61d026c Translated using Weblate (Spanish)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/es/
2024-04-24 00:15:47 +02:00
Sylvia van Os
4d0464f729 Merge pull request #1852 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-22 21:32:33 +02:00
vesp
e0f1410c8b Translated using Weblate (Czech)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/cs/
2024-04-22 21:07:18 +02:00
Sylvia van Os
2bf7698961 Merge pull request #1847 from CatimaLoyalty/dependabot/github_actions/actions/upload-artifact-4.3.2
Bump actions/upload-artifact from 4.3.1 to 4.3.2
2024-04-22 18:30:47 +02:00
Sylvia van Os
0654a2baef Merge pull request #1846 from CatimaLoyalty/dependabot/github_actions/actions/checkout-4.1.3
Bump actions/checkout from 4.1.1 to 4.1.3
2024-04-22 18:29:56 +02:00
Sylvia van Os
0e785b2ccf Merge pull request #1845 from CatimaLoyalty/dependabot/github_actions/peter-evans/create-pull-request-6.0.4
Bump peter-evans/create-pull-request from 6.0.3 to 6.0.4
2024-04-22 18:28:35 +02:00
dependabot[bot]
46088a48f9 Bump actions/upload-artifact from 4.3.1 to 4.3.2
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.1 to 4.3.2.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4.3.1...v4.3.2)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-22 02:40:35 +00:00
dependabot[bot]
82acaef96f Bump actions/checkout from 4.1.1 to 4.1.3
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 to 4.1.3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4.1.1...v4.1.3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-22 02:40:32 +00:00
dependabot[bot]
8556f4d586 Bump peter-evans/create-pull-request from 6.0.3 to 6.0.4
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6.0.3 to 6.0.4.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v6.0.3...v6.0.4)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-22 02:40:29 +00:00
Sylvia van Os
e8308b1069 Merge branch 'main' of github.com:CatimaLoyalty/Android 2024-04-21 12:31:52 +02:00
Sylvia van Os
6516d18cc2 Remove F-Droid buttons
IzzyOnDroid is the recommended source for Catima updates
2024-04-21 12:30:35 +02:00
Sylvia van Os
6dd0105908 Merge pull request #1843 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-21 09:54:37 +02:00
Sylvia van Os
3e27b931b5 Merge pull request #1844 from CatimaLoyalty/create-pull-request/patch-1713672853
Update contributors
2024-04-21 09:53:27 +02:00
TheLastProject
73046e56e5 Update contributors 2024-04-21 04:14:13 +00:00
Nicoara Alex
84c350af90 Translated using Weblate (Romanian)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ro/
2024-04-21 04:07:20 +02:00
Sylvia van Os
30bd8d810f Update fastlane 2024-04-20 18:40:48 +02:00
Sylvia van Os
d67b17c58a Release Catima 2.29.0 2024-04-19 18:48:09 +02:00
Sylvia van Os
5033fbba50 Merge pull request #1840 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-19 18:46:39 +02:00
Heimen Stoffels
5e752ecfb4 Translated using Weblate (Dutch)
Currently translated at 13.6% (18 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/nl/
2024-04-19 18:39:00 +02:00
Heimen Stoffels
e976bf3ef6 Translated using Weblate (Dutch)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/nl/
2024-04-19 18:38:59 +02:00
Sylvia van Os
24ae8d3c4c Merge pull request #1839 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-18 21:04:05 +02:00
LEGEND OG (LEGEND)
26fb9482aa Translated using Weblate (Arabic)
Currently translated at 100.0% (1 of 1 strings)

Translation: Catima/Android (Debug)
Translate-URL: https://hosted.weblate.org/projects/catima/android-debug/ar/
2024-04-18 20:03:24 +02:00
LEGEND OG (LEGEND)
1a3019b94f Translated using Weblate (Arabic)
Currently translated at 7.5% (10 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/ar/
2024-04-18 20:03:24 +02:00
LEGEND OG (LEGEND)
67136b708f Translated using Weblate (Arabic)
Currently translated at 99.6% (311 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ar/
2024-04-18 20:03:24 +02:00
Eji-san
07990cea6f Translated using Weblate (Indonesian)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/id/
2024-04-18 20:03:24 +02:00
syntheticbonus
a92895f96e Translated using Weblate (Dutch)
Currently translated at 99.6% (311 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/nl/
2024-04-18 20:03:23 +02:00
Aglag257
861df94e69 Translated using Weblate (Greek)
Currently translated at 98.7% (308 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/el/
2024-04-18 20:03:23 +02:00
Sylvia van Os
5efd18dac7 Merge pull request #1836 from CatimaLoyalty/dependabot/gradle/com.github.yalantis-ucrop-2.2.9
Bump com.github.yalantis:ucrop from 2.2.8 to 2.2.9
2024-04-17 19:56:15 +02:00
Sylvia van Os
77fcc8cd7e Merge pull request #1837 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-17 18:09:45 +02:00
tabby
b5e53eb076 Translated using Weblate (Korean)
Currently translated at 100.0% (132 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/ko/
2024-04-17 11:03:50 +02:00
tabby
39fe0a17b8 Translated using Weblate (Korean)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ko/
2024-04-17 11:03:50 +02:00
solokot
524278a94c Translated using Weblate (Russian)
Currently translated at 100.0% (132 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/ru/
2024-04-17 11:03:50 +02:00
dependabot[bot]
8d3f36d62c Bump com.github.yalantis:ucrop from 2.2.8 to 2.2.9
Bumps [com.github.yalantis:ucrop](https://github.com/Yalantis/uCrop) from 2.2.8 to 2.2.9.
- [Release notes](https://github.com/Yalantis/uCrop/releases)
- [Commits](https://github.com/Yalantis/uCrop/compare/2.2.8...2.2.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-17 02:06:36 +00:00
Sylvia van Os
459b318fdf Merge pull request #1835 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-16 17:30:56 +02:00
Andre Costa
68e7930835 Translated using Weblate (Portuguese (Portugal))
Currently translated at 100.0% (132 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/pt_PT/
2024-04-16 10:02:02 +02:00
Scrambled777
947b3f79be Translated using Weblate (Hindi)
Currently translated at 100.0% (132 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/hi/
2024-04-16 10:02:01 +02:00
Rodolphe Veniel
8070e5564b Translated using Weblate (French)
Currently translated at 97.7% (129 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/fr/
2024-04-16 10:02:00 +02:00
simosathan9
443a67581e Translated using Weblate (Greek)
Currently translated at 91.6% (286 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/el/
2024-04-16 10:01:59 +02:00
Sylvia van Os
60aaff9f38 Merge pull request #1834 from CatimaLoyalty/dependabot/github_actions/gradle/wrapper-validation-action-3
Bump gradle/wrapper-validation-action from 2 to 3
2024-04-15 20:27:58 +02:00
Sylvia van Os
0464e3dbfe Migrate to new location 2024-04-15 19:05:55 +02:00
Sylvia van Os
6f892e5174 Merge pull request #1831 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-15 17:10:56 +02:00
大王叫我来巡山
187cbb7d67 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (132 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/zh_Hans/
2024-04-15 09:23:02 +02:00
Hendrik
b114b6da81 Translated using Weblate (German)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/de/
2024-04-15 09:23:02 +02:00
dependabot[bot]
1228d55fcb Bump gradle/wrapper-validation-action from 2 to 3
Bumps [gradle/wrapper-validation-action](https://github.com/gradle/wrapper-validation-action) from 2 to 3.
- [Release notes](https://github.com/gradle/wrapper-validation-action/releases)
- [Commits](https://github.com/gradle/wrapper-validation-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: gradle/wrapper-validation-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-15 05:01:40 +00:00
Sylvia van Os
b5c17c9776 Merge pull request #1833 from CatimaLoyalty/dependabot/github_actions/peter-evans/create-pull-request-6.0.3
Bump peter-evans/create-pull-request from 6.0.2 to 6.0.3
2024-04-15 07:01:04 +02:00
dependabot[bot]
27ee52b5c0 Bump peter-evans/create-pull-request from 6.0.2 to 6.0.3
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6.0.2 to 6.0.3.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v6.0.2...v6.0.3)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-15 02:07:53 +00:00
Sylvia van Os
ccbbd2555a Merge pull request #1830 from CatimaLoyalty/create-pull-request/patch-1713069410
Update contributors
2024-04-14 10:12:59 +02:00
TheLastProject
d78b7b2fee Update contributors 2024-04-14 04:36:49 +00:00
Sylvia van Os
047639a36e Merge pull request #1829 from CatimaLoyalty/screenshotUpdate
Update screenshots
2024-04-13 18:41:09 +02:00
Sylvia van Os
86b5007ba5 Update screenshots 2024-04-13 18:34:40 +02:00
Sylvia van Os
4879aab701 Merge pull request #1828 from CatimaLoyalty/create-pull-request/patch-1712939446
Update Fastlane changelogs
2024-04-12 18:31:58 +02:00
TheLastProject
da49b651b8 Update Fastlane changelogs 2024-04-12 16:30:45 +00:00
Sylvia van Os
c2e9c0eebc Update CHANGELOG 2024-04-12 18:30:30 +02:00
fynngodau
9ed6bc921d Draw app bar under status bar (#1817)
* Draw app bar under status bar

* Add tint-on-scroll effect to more activites

One remaining problem is the `ListView` in
`barcode_selector_activity.xml`. While it would theoretically be
sufficient to set
`app:layout_behavior="@string/appbar_scrolling_view_behavior"` on
`ListView` if `android:nestedScrollingEnabled="true"` is also set, this
leads to odd visual glitches.

* Appropriate color for tab bar

* Fix remaining tab bar coloring

Remove unused tab group from group activity
2024-04-12 17:22:35 +02:00
Sylvia van Os
d78ecf17e2 Merge pull request #1826 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-11 20:52:34 +02:00
gallegonovato
8aeddf1141 Translated using Weblate (Spanish)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/es/
2024-04-11 16:01:52 +02:00
Sylvia van Os
31924276d3 Merge pull request #1819 from fynngodau/about-layout
Improve About layout
2024-04-10 17:18:07 +02:00
Sylvia van Os
3321b11e2a Merge pull request #1821 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-10 08:10:42 +02:00
Sylvia van Os
920379c5af Merge pull request #1822 from CatimaLoyalty/dependabot/gradle/com.android.application-8.3.2
Bump com.android.application from 8.3.1 to 8.3.2
2024-04-10 07:40:23 +02:00
dependabot[bot]
598a4345f0 Bump com.android.application from 8.3.1 to 8.3.2
Bumps com.android.application from 8.3.1 to 8.3.2.

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-10 02:24:46 +00:00
109247019824
ff8013ed44 Translated using Weblate (Bulgarian)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/bg/
2024-04-10 02:02:09 +02:00
Lionel HANNEQUIN
20b69b4286 Translated using Weblate (French)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/fr/
2024-04-10 02:02:09 +02:00
Sylvia van Os
60165bad5c Merge pull request #1820 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-08 23:11:57 +02:00
Balanda Nazarii
149f7ff106 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/uk/
2024-04-08 23:01:56 +02:00
Julia Deoniziak
ac699a1c76 Translated using Weblate (Polish)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/pl/
2024-04-08 23:01:56 +02:00
Fynn Godau
a43c480e0c Improve layout of about screen
* Selectable item ripple background for each row
* Center Donate text in its row
* Don't clip too low when scrolling
2024-04-07 22:48:04 +02:00
Sylvia van Os
6eda7791c6 Merge pull request #1818 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-07 21:16:29 +02:00
Jiri Grönroos
7dc0bf027a Translated using Weblate (Finnish)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/fi/
2024-04-07 21:01:58 +02:00
solokot
c218518805 Translated using Weblate (Russian)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ru/
2024-04-07 21:01:58 +02:00
Sylvia van Os
0505c51ee8 Merge pull request #1816 from CatimaLoyalty/create-pull-request/patch-1712463357
Update contributors
2024-04-07 09:32:59 +02:00
TheLastProject
f29da33bcf Update contributors 2024-04-07 04:15:57 +00:00
Sylvia van Os
5f8e3069b3 Merge pull request #1815 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-07 00:26:16 +02:00
solokot
8d7abddace Translated using Weblate (Russian)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ru/
2024-04-06 20:42:21 +02:00
Evgeniy Khramov
39fe61f57e Translated using Weblate (Russian)
Currently translated at 100.0% (132 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/ru/
2024-04-06 20:42:21 +02:00
Mika
176f7a0cc8 Translated using Weblate (Russian)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ru/
2024-04-06 20:42:21 +02:00
Sylvia van Os
e9ec9889d4 Merge pull request #1814 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-06 09:55:45 +02:00
Andre Costa
0a161bdf55 Translated using Weblate (Portuguese (Portugal))
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/pt_PT/
2024-04-06 07:02:14 +02:00
Andre Costa
e817f190b6 Translated using Weblate (Portuguese (Portugal))
Currently translated at 100.0% (132 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/pt_PT/
2024-04-06 07:02:14 +02:00
phat dang thanh
f88a96cd4f Translated using Weblate (Vietnamese)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/vi/
2024-04-06 07:02:13 +02:00
Scrambled777
7cf47935e0 Translated using Weblate (Hindi)
Currently translated at 100.0% (132 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/hi/
2024-04-06 07:02:13 +02:00
Scrambled777
f2844003e8 Translated using Weblate (Hindi)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/hi/
2024-04-06 07:02:12 +02:00
Oğuz Ersen
9702fd6ce5 Translated using Weblate (Turkish)
Currently translated at 73.4% (97 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/tr/
2024-04-06 07:02:12 +02:00
Oğuz Ersen
577c3f2990 Translated using Weblate (Turkish)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/tr/
2024-04-06 07:02:12 +02:00
大王叫我来巡山
bf9216168b Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (132 of 132 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/zh_Hans/
2024-04-06 07:02:11 +02:00
大王叫我来巡山
95dc2f1235 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/zh_Hans/
2024-04-06 07:02:11 +02:00
Giovanni Donisi
84503253d2 Translated using Weblate (Italian)
Currently translated at 100.0% (312 of 312 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/it/
2024-04-06 07:02:10 +02:00
Sylvia van Os
5fd48c6707 Merge pull request #1813 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-04-05 08:32:56 +02:00
Stefan Racic
335668c03a Translated using Weblate (Bosnian)
Currently translated at 45.9% (141 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/bs/
2024-04-05 05:50:14 +02:00
Sylvia van Os
cba4b6856c Merge pull request #1811 from CatimaLoyalty/dependabot/gradle/org.robolectric-robolectric-4.12.1
Bump org.robolectric:robolectric from 4.12 to 4.12.1
2024-04-03 08:19:08 +02:00
dependabot[bot]
c345c6cdd1 Bump org.robolectric:robolectric from 4.12 to 4.12.1
Bumps [org.robolectric:robolectric](https://github.com/robolectric/robolectric) from 4.12 to 4.12.1.
- [Release notes](https://github.com/robolectric/robolectric/releases)
- [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.12...robolectric-4.12.1)

---
updated-dependencies:
- dependency-name: org.robolectric:robolectric
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-03 02:55:01 +00:00
Sylvia van Os
a1e214e657 Merge pull request #1810 from CatimaLoyalty/dependabot/github_actions/actions/setup-python-5.1.0
Bump actions/setup-python from 5.0.0 to 5.1.0
2024-04-01 07:41:31 +02:00
Sylvia van Os
ff1654b3f7 Merge pull request #1809 from CatimaLoyalty/dependabot/gradle/org.robolectric-robolectric-4.12
Bump org.robolectric:robolectric from 4.11.1 to 4.12
2024-04-01 07:40:06 +02:00
dependabot[bot]
12e24abdd6 Bump actions/setup-python from 5.0.0 to 5.1.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.0.0 to 5.1.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5.0.0...v5.1.0)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-01 02:37:45 +00:00
dependabot[bot]
33a9d7fbcf Bump org.robolectric:robolectric from 4.11.1 to 4.12
Bumps [org.robolectric:robolectric](https://github.com/robolectric/robolectric) from 4.11.1 to 4.12.
- [Release notes](https://github.com/robolectric/robolectric/releases)
- [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.11.1...robolectric-4.12)

---
updated-dependencies:
- dependency-name: org.robolectric:robolectric
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-01 02:16:22 +00:00
Dimitrios Papathanasiou
bdff59e628 Minor cleanups in PDF barcode retrieval (#1807) 2024-03-31 12:08:21 +02:00
Sylvia van Os
c1ef5c346a Merge pull request #1808 from CatimaLoyalty/create-pull-request/patch-1711858517
Update contributors
2024-03-31 10:01:21 +02:00
TheLastProject
a573db1be9 Update contributors 2024-03-31 04:15:16 +00:00
Sylvia van Os
84e3e37a44 Merge pull request #1802 from CatimaLoyalty/create-pull-request/patch-1711486318
Update Fastlane changelogs
2024-03-26 22:38:26 +01:00
TheLastProject
f5724dfca0 Update Fastlane changelogs 2024-03-26 20:51:58 +00:00
Sylvia van Os
f848710afa Merge pull request #1795 from CatimaLoyalty/pdfImport
PDF import + multiple barcode support
2024-03-26 21:51:44 +01:00
Sylvia van Os
1e0dc4f541 Merge pull request #1799 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-03-26 08:45:47 +01:00
Viet Nguyem
470bbf4261 Translated using Weblate (Vietnamese)
Currently translated at 11.4% (15 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/vi/
2024-03-26 07:02:08 +01:00
Sylvia van Os
8519e12aa7 Add page number to barcode selector for PDF scan results 2024-03-24 20:31:03 +01:00
Sylvia van Os
026bfaf7a9 Merge pull request #1798 from CatimaLoyalty/create-pull-request/patch-1711274306
Update locales
2024-03-24 11:30:07 +01:00
TheLastProject
4d4e76960f Update locales 2024-03-24 09:58:25 +00:00
Sylvia van Os
3637c37cca Merge pull request #1797 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-03-24 10:58:14 +01:00
Amir Ghasemi
a5ed6caa5a Added translation using Weblate (Persian) 2024-03-24 10:46:57 +01:00
Sylvia van Os
1429abd94d Update CHANGELOG 2024-03-23 23:55:03 +01:00
Sylvia van Os
0e873b9ea5 Basic selector when multiple barcodes found 2024-03-23 23:54:57 +01:00
Sylvia van Os
cbc8886241 Load barcode from PDF when sharing to Catima 2024-03-23 17:52:07 +01:00
Sylvia van Os
6c7bfb4c50 Initial PDF import through More Options menu 2024-03-23 17:52:07 +01:00
Sylvia van Os
6ed5e52890 Merge pull request #1796 from CatimaLoyalty/create-pull-request/patch-1711174860
Update Gradle to 8.7
2024-03-23 17:51:46 +01:00
TheLastProject
bc1bd88d75 Update Gradle to 8.7 2024-03-23 06:20:59 +00:00
Sylvia van Os
09e1201086 Merge pull request #1794 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-03-22 08:31:46 +01:00
gallegonovato
df829a4956 Translated using Weblate (Spanish)
Currently translated at 46.5% (61 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/es/
2024-03-22 02:02:22 +01:00
Axus Wizix
46dc163e06 Translated using Weblate (Russian)
Currently translated at 100.0% (131 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/ru/
2024-03-22 02:02:22 +01:00
Sylvia van Os
e70b2bdbbd Merge pull request #1792 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-03-19 21:56:57 +01:00
Tim Trek
c1f8e930bb Translated using Weblate (German)
Currently translated at 93.8% (123 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/de/
2024-03-19 21:40:22 +01:00
Sylvia van Os
c8dd1d8509 Merge pull request #1791 from CatimaLoyalty/dependabot/gradle/com.android.application-8.3.1
Bump com.android.application from 8.3.0 to 8.3.1
2024-03-19 07:23:04 +01:00
dependabot[bot]
e50adc39c5 Bump com.android.application from 8.3.0 to 8.3.1
Bumps com.android.application from 8.3.0 to 8.3.1.

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-19 02:11:33 +00:00
Sylvia van Os
09948b6a21 Merge pull request #1790 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-03-18 22:11:52 +01:00
solokot
f50e80d24d Translated using Weblate (Russian)
Currently translated at 100.0% (131 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/ru/
2024-03-18 21:02:09 +01:00
Sylvia van Os
777512aad7 Merge pull request #1789 from CatimaLoyalty/dependabot/github_actions/peter-evans/create-pull-request-6.0.2
Bump peter-evans/create-pull-request from 6.0.1 to 6.0.2
2024-03-18 18:18:03 +01:00
dependabot[bot]
423fd272d4 Bump peter-evans/create-pull-request from 6.0.1 to 6.0.2
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v6.0.1...v6.0.2)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-18 02:08:29 +00:00
Sylvia van Os
969256f130 Merge pull request #1787 from CatimaLoyalty/create-pull-request/patch-1710648875
Update contributors
2024-03-17 09:33:40 +01:00
TheLastProject
702d4af8d9 Update contributors 2024-03-17 04:14:35 +00:00
Sylvia van Os
02696c1328 Merge pull request #1786 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-03-15 17:53:01 +01:00
Tim Trek
dcffdf3329 Translated using Weblate (German)
Currently translated at 92.3% (121 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/de/
2024-03-15 01:53:02 +01:00
richard01000
4110b5ab48 Translated using Weblate (Romanian)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ro/
2024-03-15 01:53:02 +01:00
Sylvia van Os
dea96069b0 Merge pull request #1785 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-03-14 18:16:26 +01:00
Allan Nordhøy
04c5cb08f1 Translated using Weblate (Norwegian Bokmål)
Currently translated at 96.7% (297 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/nb_NO/
2024-03-14 07:01:56 +01:00
Sylvia van Os
b37f8943c7 Merge pull request #1784 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-03-10 14:18:14 +01:00
ngocanhtve
54d4f8b70b Translated using Weblate (Vietnamese)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/vi/
2024-03-10 14:02:02 +01:00
unnerving duck
658cc43f86 Translated using Weblate (Finnish)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/fi/
2024-03-10 14:02:01 +01:00
Sylvia van Os
958abe5ed7 Merge pull request #1780 from CatimaLoyalty/fix/shortcutFixes
Several fixes for shortcut handling
2024-03-10 13:20:45 +01:00
Sylvia van Os
fa99c2ef7c Several fixes for shortcut handling
- Update the card priority in the dynamic shortcut manager also when the
  card isn't opened from the main screen
- Remove from dynamic shortcut manager when the card gets archived
- Fix icons disappearing of other cards when one card gets removed
2024-03-10 13:00:41 +01:00
Sylvia van Os
2b38f474fd Merge pull request #1781 from CatimaLoyalty/fix/rb
Fix RB failure
2024-03-10 09:23:05 +01:00
Sylvia van Os
5643814e65 Merge pull request #1783 from CatimaLoyalty/create-pull-request/patch-1710044020
Update contributors
2024-03-10 08:51:01 +01:00
TheLastProject
59b588b797 Update contributors 2024-03-10 04:13:40 +00:00
Sylvia van Os
757321930d Fix RB failure
AGP 8.3 includes the commit hash in the build metadata, so for the
official build to be reproducible it needs to be on the same commit as
third-party builds. This commit reorders the instructions to ensure I
will create the commit before building and thus fixes an RB failure in
AGP 8.3+.
2024-03-09 11:42:55 +01:00
Sylvia van Os
03a5a382e9 Release Catima v2.28.0 2024-03-08 18:17:49 +01:00
Sylvia van Os
66a91db8f0 Merge pull request #1776 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-03-08 18:10:16 +01:00
Marcel Hecko
013dd020c1 Translated using Weblate (Slovak)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/sk/
2024-03-08 18:05:24 +01:00
Julia Sugawara
948e469c05 Translated using Weblate (German)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/de/
2024-03-08 05:01:58 +01:00
Sylvia van Os
d4aff16da8 Merge pull request #1774 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-03-06 19:36:31 +01:00
Sylvia van Os
efa17689b6 Translated using Weblate (Greek)
Currently translated at 89.2% (274 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/el/
2024-03-06 12:37:38 +01:00
Takahiro Namatame
57ab82b2f0 Translated using Weblate (Japanese)
Currently translated at 77.1% (237 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ja/
2024-03-06 10:02:01 +01:00
Giovanni Donisi
4052cec9ba Translated using Weblate (Italian)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/it/
2024-03-06 10:02:00 +01:00
Yohan Denis
3fc1057999 Translated using Weblate (French)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/fr/
2024-03-06 10:01:59 +01:00
ΚΩΝΣΤΑΝΤΙΝΟΣ ΠΑΠΑΣ
8458beaab0 Translated using Weblate (Greek)
Currently translated at 89.2% (274 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/el/
2024-03-06 10:01:59 +01:00
Sylvia van Os
c04c505368 Merge pull request #1773 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-03-05 20:20:57 +01:00
Andre Costa
2ee913c833 Translated using Weblate (Portuguese (Portugal))
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/pt_PT/
2024-03-05 08:02:17 +01:00
Andre Costa
09074cbc9e Translated using Weblate (Portuguese (Portugal))
Currently translated at 100.0% (131 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/pt_PT/
2024-03-05 08:02:17 +01:00
ngocanhtve
29b79a010b Translated using Weblate (Vietnamese)
Currently translated at 99.6% (306 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/vi/
2024-03-05 08:02:17 +01:00
H Tamás
992f2e2e44 Translated using Weblate (Hungarian)
Currently translated at 35.1% (46 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/hu/
2024-03-05 08:02:17 +01:00
이정희
7cca7154c5 Translated using Weblate (Korean)
Currently translated at 98.3% (302 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ko/
2024-03-05 08:02:17 +01:00
Ranforingus
daa7f7a7e2 Translated using Weblate (Dutch)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/nl/
2024-03-05 08:02:17 +01:00
gallegonovato
21c1580513 Translated using Weblate (Spanish)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/es/
2024-03-05 08:02:17 +01:00
Sylvia van Os
9c700eb8d0 Merge pull request #1771 from CatimaLoyalty/dependabot/github_actions/peter-evans/create-pull-request-6.0.1
Bump peter-evans/create-pull-request from 6.0.0 to 6.0.1
2024-03-04 07:31:39 +01:00
dependabot[bot]
be21ba515a Bump peter-evans/create-pull-request from 6.0.0 to 6.0.1
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v6.0.0...v6.0.1)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-04 02:14:36 +00:00
Sylvia van Os
671b0b1228 Merge pull request #1770 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-03-03 18:13:50 +01:00
Odweta
dd455bfabd Translated using Weblate (Czech)
Currently translated at 100.0% (131 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/cs/
2024-03-03 14:02:03 +01:00
solokot
b3294112aa Translated using Weblate (Russian)
Currently translated at 100.0% (131 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/ru/
2024-03-03 14:02:02 +01:00
Odweta
baae7ab358 Translated using Weblate (Czech)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/cs/
2024-03-03 14:02:02 +01:00
Sylvia van Os
d14d5ef83e Merge pull request #1769 from CatimaLoyalty/create-pull-request/patch-1709439294
Update contributors
2024-03-03 09:24:56 +01:00
TheLastProject
9b92882fc5 Update contributors 2024-03-03 04:14:54 +00:00
Sylvia van Os
ebfe0d0b6c Merge pull request #1768 from CatimaLoyalty/feature/viewPasswordImportExport
Make it possible to view password on export/import dialogs
2024-03-02 13:36:15 +01:00
Sylvia van Os
83a35e02ce Make it possible to view password on export/import dialogs 2024-03-02 13:29:20 +01:00
Sylvia van Os
13ae1f5014 Merge pull request #1767 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-03-02 10:00:22 +01:00
Scrambled777
4327c45cd3 Translated using Weblate (Hindi)
Currently translated at 100.0% (131 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/hi/
2024-03-02 05:01:13 +01:00
Scrambled777
3f4076bc7d Translated using Weblate (Hindi)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/hi/
2024-03-02 05:01:13 +01:00
Roblox Lover
1ae09c3dff Translated using Weblate (Arabic)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ar/
2024-03-02 05:01:12 +01:00
H Tamás
daa8127f47 Translated using Weblate (Hungarian)
Currently translated at 33.5% (44 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/hu/
2024-03-02 05:01:12 +01:00
H Tamás
aadb5334c2 Translated using Weblate (Hungarian)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/hu/
2024-03-02 05:01:11 +01:00
Oğuz Ersen
b5b897f7b9 Translated using Weblate (Turkish)
Currently translated at 73.2% (96 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/tr/
2024-03-02 05:01:11 +01:00
Oğuz Ersen
273035b209 Translated using Weblate (Turkish)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/tr/
2024-03-02 05:01:10 +01:00
109247019824
6867408d14 Translated using Weblate (Bulgarian)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/bg/
2024-03-02 05:01:09 +01:00
大王叫我来巡山
bf17d12b08 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (131 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/zh_Hans/
2024-03-02 05:01:09 +01:00
大王叫我来巡山
523a602442 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/zh_Hans/
2024-03-02 05:01:08 +01:00
solokot
103beef323 Translated using Weblate (Russian)
Currently translated at 100.0% (307 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ru/
2024-03-02 05:01:08 +01:00
Sylvia van Os
e700afac60 Merge pull request #1765 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-03-01 08:18:52 +01:00
Sylvia van Os
4e60bc2029 Merge pull request #1764 from CatimaLoyalty/dependabot/gradle/com.android.application-8.3.0
Bump com.android.application from 8.2.2 to 8.3.0
2024-03-01 08:16:55 +01:00
Anonymous
a233db799d Translated using Weblate (Portuguese (Portugal))
Currently translated at 97.3% (299 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/pt_PT/
2024-03-01 04:12:58 +01:00
Anonymous
c4958ff40d Translated using Weblate (Vietnamese)
Currently translated at 97.3% (299 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/vi/
2024-03-01 04:12:58 +01:00
Anonymous
02329e1176 Translated using Weblate (Hungarian)
Currently translated at 97.7% (300 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/hu/
2024-03-01 04:12:57 +01:00
Anonymous
480bf8489e Translated using Weblate (Latvian)
Currently translated at 82.4% (253 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/lv/
2024-03-01 04:12:57 +01:00
Anonymous
6762c342c9 Translated using Weblate (Croatian)
Currently translated at 97.7% (300 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/hr/
2024-03-01 04:12:57 +01:00
Anonymous
d760e17095 Translated using Weblate (Indonesian)
Currently translated at 97.7% (300 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/id/
2024-03-01 04:12:57 +01:00
Anonymous
3b6d1e1764 Translated using Weblate (Bengali (India))
Currently translated at 88.5% (272 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/bn_IN/
2024-03-01 04:12:57 +01:00
Anonymous
9250b2b3dc Translated using Weblate (Turkish)
Currently translated at 98.6% (303 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/tr/
2024-03-01 04:12:56 +01:00
Anonymous
0c1cdc98e8 Translated using Weblate (Swedish)
Currently translated at 94.7% (291 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/sv/
2024-03-01 04:12:56 +01:00
Anonymous
a90f000d46 Translated using Weblate (Bulgarian)
Currently translated at 98.6% (303 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/bg/
2024-03-01 04:12:56 +01:00
Anonymous
90fe400069 Translated using Weblate (Finnish)
Currently translated at 98.0% (301 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/fi/
2024-03-01 04:12:56 +01:00
Anonymous
de7bc3d7ea Translated using Weblate (Korean)
Currently translated at 97.3% (299 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ko/
2024-03-01 04:12:28 +01:00
Anonymous
46b1040108 Translated using Weblate (Ukrainian)
Currently translated at 98.6% (303 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/uk/
2024-03-01 04:12:25 +01:00
Anonymous
d42908e163 Translated using Weblate (Slovenian)
Currently translated at 85.3% (262 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/sl/
2024-03-01 04:12:25 +01:00
Anonymous
6468491e04 Translated using Weblate (Slovak)
Currently translated at 97.7% (300 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/sk/
2024-03-01 04:12:25 +01:00
Anonymous
1e58cfb5f3 Translated using Weblate (Russian)
Currently translated at 98.6% (303 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ru/
2024-03-01 04:12:25 +01:00
Anonymous
f01c388f0c Translated using Weblate (Polish)
Currently translated at 97.7% (300 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/pl/
2024-03-01 04:12:25 +01:00
Anonymous
0e5c84e8f2 Translated using Weblate (Dutch)
Currently translated at 97.7% (300 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/nl/
2024-03-01 04:12:25 +01:00
Anonymous
ca733a5404 Translated using Weblate (Norwegian Bokmål)
Currently translated at 95.1% (292 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/nb_NO/
2024-03-01 04:12:25 +01:00
Anonymous
59a28ebd62 Translated using Weblate (Lithuanian)
Currently translated at 86.6% (266 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/lt/
2024-03-01 04:12:25 +01:00
Anonymous
d48247f107 Translated using Weblate (Italian)
Currently translated at 98.6% (303 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/it/
2024-03-01 04:12:25 +01:00
Anonymous
d084d5f67b Translated using Weblate (French)
Currently translated at 98.6% (303 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/fr/
2024-03-01 04:12:25 +01:00
Anonymous
d11483dcf2 Translated using Weblate (Spanish)
Currently translated at 98.6% (303 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/es/
2024-03-01 04:12:24 +01:00
Anonymous
2386ee30f7 Translated using Weblate (German)
Currently translated at 97.7% (300 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/de/
2024-03-01 04:12:24 +01:00
Anonymous
9899d80719 Translated using Weblate (Czech)
Currently translated at 98.6% (303 of 307 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/cs/
2024-03-01 04:12:24 +01:00
dependabot[bot]
e809392191 Bump com.android.application from 8.2.2 to 8.3.0
Bumps com.android.application from 8.2.2 to 8.3.0.

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-01 02:56:50 +00:00
Sylvia van Os
94d9010731 Merge pull request #1762 from CatimaLoyalty/fix/iconBackground
Fix background colour not being set for images in card view
2024-02-28 19:08:36 +01:00
Sylvia van Os
b160b1dca8 Fix background colour not being set for images in card view 2024-02-28 18:55:28 +01:00
Sylvia van Os
6e2fa6fd22 Merge pull request #1761 from CatimaLoyalty/create-pull-request/patch-1709140863
Update Fastlane changelogs
2024-02-28 18:21:55 +01:00
TheLastProject
2b0a126d3c Update Fastlane changelogs 2024-02-28 17:21:02 +00:00
Sylvia van Os
d8297db010 Merge pull request #1760 from CatimaLoyalty/feature/balanceUpdate
Update spending screen to also support receiving
2024-02-28 18:20:51 +01:00
Sylvia van Os
fd7b72d6e5 Update spending screen to also support receiving 2024-02-28 18:13:59 +01:00
Sylvia van Os
45471910e6 Merge pull request #1759 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-02-26 10:10:47 +01:00
大王叫我来巡山
bb36804a46 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (131 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/zh_Hans/
2024-02-26 07:02:37 +01:00
大王叫我来巡山
0e2991cb7f Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (304 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/zh_Hans/
2024-02-26 07:02:37 +01:00
solokot
efbcd00b55 Translated using Weblate (Russian)
Currently translated at 100.0% (131 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/ru/
2024-02-26 07:02:37 +01:00
Sylvia van Os
27e252f68a Merge pull request #1758 from CatimaLoyalty/create-pull-request/patch-1708834494
Update contributors
2024-02-25 09:34:05 +01:00
TheLastProject
d2cdced416 Update contributors 2024-02-25 04:14:54 +00:00
Sylvia van Os
b150ace903 Merge pull request #1757 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-02-24 16:33:33 +01:00
迎春心情
7697855e0d Translated using Weblate (Chinese (Simplified))
Currently translated at 99.6% (303 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/zh_Hans/
2024-02-24 16:02:06 +01:00
solokot
08f4cb32a5 Translated using Weblate (Russian)
Currently translated at 100.0% (304 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ru/
2024-02-24 16:02:06 +01:00
Sylvia van Os
eef026ff4f Merge pull request #1756 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-02-23 18:17:46 +01:00
solokot
3fac41e8b1 Translated using Weblate (Russian)
Currently translated at 100.0% (304 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ru/
2024-02-23 14:06:11 +01:00
yue weikai
5c01f638be Translated using Weblate (Chinese (Simplified))
Currently translated at 99.3% (302 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/zh_Hans/
2024-02-23 14:06:10 +01:00
Alexander Ivanov
9e2d41b821 Translated using Weblate (Russian)
Currently translated at 100.0% (304 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ru/
2024-02-23 14:06:09 +01:00
Sylvia van Os
472f837f44 Merge pull request #1755 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-02-21 18:15:09 +01:00
109247019824
f2d1b9b5c9 Translated using Weblate (Bulgarian)
Currently translated at 100.0% (304 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/bg/
2024-02-21 17:52:39 +01:00
Jiri Grönroos
621bfa3f99 Translated using Weblate (Finnish)
Currently translated at 99.3% (302 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/fi/
2024-02-21 17:52:39 +01:00
Giovanni Donisi
f64703d683 Translated using Weblate (Italian)
Currently translated at 100.0% (304 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/it/
2024-02-21 17:52:39 +01:00
Naga
75d1fba8f8 Translated using Weblate (French)
Currently translated at 100.0% (304 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/fr/
2024-02-21 17:52:39 +01:00
Sylvia van Os
308a2bbaf3 Merge pull request #1754 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-02-20 10:09:25 +01:00
Nitin Khalia
4ba752a10e Translated using Weblate (Hindi)
Currently translated at 100.0% (131 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/hi/
2024-02-20 09:02:21 +01:00
ikanakova
df826d76e5 Translated using Weblate (Czech)
Currently translated at 100.0% (131 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/cs/
2024-02-20 09:02:20 +01:00
Mauro
f70138cd28 Translated using Weblate (Italian)
Currently translated at 99.6% (303 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/it/
2024-02-20 09:02:19 +01:00
ikanakova
ea81304dd5 Translated using Weblate (Czech)
Currently translated at 100.0% (304 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/cs/
2024-02-20 09:02:19 +01:00
Sylvia van Os
683ef8cc49 Merge pull request #1752 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2024-02-18 19:18:54 +01:00
Sylvia van Os
f9db51c8d7 Use translated title with default subtext if it exists 2024-02-18 19:13:11 +01:00
Vietto
e5de170887 Translated using Weblate (Vietnamese)
Currently translated at 5.3% (7 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/vi/
2024-02-18 18:09:33 +01:00
Nitin Khalia
c45761f069 Translated using Weblate (Hindi)
Currently translated at 100.0% (304 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/hi/
2024-02-18 18:09:32 +01:00
Oğuz Ersen
65937be5b2 Translated using Weblate (Turkish)
Currently translated at 73.2% (96 of 131 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/tr/
2024-02-18 18:09:32 +01:00
Oğuz Ersen
b249dd141d Translated using Weblate (Turkish)
Currently translated at 100.0% (304 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/tr/
2024-02-18 18:09:31 +01:00
Сергій
f67548d18b Translated using Weblate (Ukrainian)
Currently translated at 100.0% (304 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/uk/
2024-02-18 18:09:31 +01:00
richard01000
a8b8c10f0f Translated using Weblate (Romanian)
Currently translated at 100.0% (304 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ro/
2024-02-18 18:09:30 +01:00
gallegonovato
3cd0aab25e Translated using Weblate (Spanish)
Currently translated at 100.0% (304 of 304 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/es/
2024-02-18 18:09:30 +01:00
Sylvia van Os
4dcafe0abe Merge pull request #1746 from CatimaLoyalty/fix/1744
Fix feature graphic generation
2024-02-18 16:20:24 +01:00
158 changed files with 1788 additions and 862 deletions

View File

@@ -29,10 +29,10 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.1
- uses: actions/checkout@v4.1.6
- name: Fail on bad translations
run: if grep -ri "&lt;xliff" app/src/main/res/values*/strings.xml; then echo "Invalidly escaped translations found"; exit 1; fi
- uses: gradle/wrapper-validation-action@v2
- uses: gradle/actions/wrapper-validation@v3
- name: set up OpenJDK 17
run: |
sudo apt-get update
@@ -48,7 +48,7 @@ jobs:
run: ./gradlew spotbugsRelease
- name: Archive test results
if: always()
uses: actions/upload-artifact@v4.3.1
uses: actions/upload-artifact@v4.3.3
with:
name: test-results
path: app/build/reports

View File

@@ -27,15 +27,15 @@ jobs:
steps:
- name: Checkout repo
id: checkout
uses: actions/checkout@v4.1.1
uses: actions/checkout@v4.1.6
- name: Setup Python
uses: actions/setup-python@v5.0.0
uses: actions/setup-python@v5.1.0
with:
python-version: '3.x'
- name: Run converter script
run: python .scripts/changelog_to_fastlane.py
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6.0.0
uses: peter-evans/create-pull-request@v6.0.5
with:
title: "Update Fastlane changelogs"
commit-message: "Update Fastlane changelogs"

View File

@@ -25,7 +25,7 @@ jobs:
steps:
- name: Checkout repo
id: checkout
uses: actions/checkout@v4.1.1
uses: actions/checkout@v4.1.6
- name: Update contributors
id: update_contributors
uses: TheLastProject/contributors-to-file-action@v3.2.0
@@ -33,7 +33,7 @@ jobs:
file_in_repo: app/src/main/res/raw/contributors.txt
min_commit_count: 5
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6.0.0
uses: peter-evans/create-pull-request@v6.0.5
with:
title: "Update contributors"
commit-message: "Update contributors"

View File

@@ -24,7 +24,7 @@ jobs:
generate-feature-graphic:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.1
- uses: actions/checkout@v4.1.6
- name: Install requirements
run: |
sudo apt-get update
@@ -38,7 +38,7 @@ jobs:
- name: Generate featureGraphic.png for each language
run: .scripts/generate_feature_graphic/generate_feature_graphic.sh
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6.0.0
uses: peter-evans/create-pull-request@v6.0.5
with:
title: "Update feature graphic"
commit-message: "Update feature graphic"

View File

@@ -21,12 +21,12 @@ jobs:
gradle-update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.1
- uses: actions/checkout@v4.1.6
- uses: obfusk/gradle-update-action@v2.0.0
id: gradle-update
- uses: gradle/wrapper-validation-action@v2
- uses: gradle/actions/wrapper-validation@v3
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6.0.0
uses: peter-evans/create-pull-request@v6.0.5
with:
title: "Update Gradle to ${{ steps.gradle-update.outputs.version }}"
commit-message: "Update Gradle to ${{ steps.gradle-update.outputs.version }}"

View File

@@ -25,13 +25,13 @@ jobs:
update-locales:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.1
- uses: actions/checkout@v4.1.6
- name: Add new locales
run: .scripts/new-locales.py
- name: Update locales
run: .scripts/locales.py
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6.0.0
uses: peter-evans/create-pull-request@v6.0.5
with:
title: "Update locales"
commit-message: "Update locales"

View File

@@ -13,14 +13,18 @@ for lang in "$script_location/../../fastlane/metadata/android/"*; do
elif grep -q title.txt; then
# No result, try splitting title.txt on (en dash)
IFS='' read -r appname subtext < title.txt
else
elif grep -q - title.txt; then
# No result, try splitting on - (dash)
IFS='-' read -r appname subtext < title.txt
else
# No result, use the full title as app name and default subtext
appname=$(< title.txt)
subtext="Loyalty Card Wallet"
fi
export appname=${appname%% }
export subtext=${subtext## }
# If there is subtext, change the .svg accordingly
if [ -n "$subtext" ]; then
# If the appname isn't Catima or there is subtext, change the .svg accordingly
if [ "$appname" != "Catima" ] || [ -n "$subtext" ]; then
perl -pi -e 's/Catima/$ENV{appname}/' featureGraphic.svg
perl -pi -e 's/Loyalty Card Wallet/$ENV{subtext}/' featureGraphic.svg
# Set correct font or font size for language if needed

View File

@@ -1,10 +1,26 @@
# Changelog
## Unreleased - 133
## Unreleased - 136
- Support for creating a card when sharing plain text
- Display image type instead of barcode below images
## v2.29.1 - 135 (2024-05-19)
- Various fixes and improvements to balance handling
## v2.29.0 - 134 (2024-04-19)
- Support for scanning PDF files for barcodes
- Support for image files with multiple barcodes
- Minor UI fixes
## v2.28.0 - 133 (2024-03-08)
- Target Android 14
- Open card icon in gallery on touch
- Improve design of Photos tab in edit view
- Update spending screen to also support receiving
## v2.27.0 - 132 (2024-01-30)

View File

@@ -1,29 +1,32 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.6)
CFPropertyList (3.0.7)
base64
nkf
rexml
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
artifactory (3.0.15)
artifactory (3.0.17)
atomos (0.1.3)
aws-eventstream (1.3.0)
aws-partitions (1.884.0)
aws-sdk-core (3.191.0)
aws-partitions (1.931.0)
aws-sdk-core (3.196.1)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.77.0)
aws-sdk-core (~> 3, >= 3.191.0)
aws-sdk-kms (1.81.0)
aws-sdk-core (~> 3, >= 3.193.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.143.0)
aws-sdk-core (~> 3, >= 3.191.0)
aws-sdk-s3 (1.151.0)
aws-sdk-core (~> 3, >= 3.194.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.8)
aws-sigv4 (1.8.0)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
base64 (0.2.0)
claide (1.1.0)
colored (1.2)
colored2 (3.1.2)
@@ -35,7 +38,7 @@ GEM
domain_name (0.6.20240107)
dotenv (2.8.1)
emoji_regex (3.2.3)
excon (0.109.0)
excon (0.110.0)
faraday (1.10.3)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
@@ -64,15 +67,15 @@ GEM
faraday-retry (1.0.3)
faraday_middleware (1.2.0)
faraday (~> 1.0)
fastimage (2.3.0)
fastlane (2.219.0)
fastimage (2.3.1)
fastlane (2.220.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
aws-sdk-s3 (~> 1.0)
babosa (>= 1.0.3, < 2.0.0)
bundler (>= 1.12.0, < 3.0.0)
colored
colored (~> 1.2)
commander (~> 4.6)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 4.0)
@@ -93,10 +96,10 @@ GEM
mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (>= 2.0.0, < 3.0.0)
naturally (~> 2.2)
optparse (>= 0.1.1)
optparse (>= 0.1.1, < 1.0.0)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.3)
security (= 0.1.5)
simctl (~> 1.6.3)
terminal-notifier (>= 2.0.0, < 3.0.0)
terminal-table (~> 3)
@@ -105,7 +108,7 @@ GEM
word_wrap (~> 1.0.0)
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.54.0)
google-apis-core (>= 0.11.0, < 2.a)
@@ -123,12 +126,12 @@ GEM
google-apis-core (>= 0.11.0, < 2.a)
google-apis-storage_v1 (0.31.0)
google-apis-core (>= 0.11.0, < 2.a)
google-cloud-core (1.6.1)
google-cloud-core (1.7.0)
google-cloud-env (>= 1.0, < 3.a)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.3.1)
google-cloud-errors (1.4.0)
google-cloud-storage (1.47.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
@@ -148,30 +151,33 @@ GEM
domain_name (~> 0.5)
httpclient (2.8.3)
jmespath (1.6.2)
json (2.7.1)
jwt (2.7.1)
json (2.7.2)
jwt (2.8.1)
base64
mini_magick (4.12.0)
mini_mime (1.1.5)
multi_json (1.15.0)
multipart-post (2.3.0)
multipart-post (2.4.1)
nanaimo (0.3.0)
naturally (2.2.1)
optparse (0.4.0)
nkf (0.2.0)
optparse (0.5.0)
os (1.1.4)
plist (3.7.1)
public_suffix (5.0.4)
rake (13.1.0)
public_suffix (5.0.5)
rake (13.2.1)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.2.6)
rexml (3.2.8)
strscan (>= 3.0.9)
rouge (2.0.7)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
security (0.1.3)
signet (0.18.0)
security (0.1.5)
signet (0.19.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
@@ -179,6 +185,7 @@ GEM
simctl (1.6.10)
CFPropertyList
naturally
strscan (3.1.0)
terminal-notifier (2.0.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
@@ -209,4 +216,4 @@ DEPENDENCIES
fastlane
BUNDLED WITH
2.3.26
2.5.9

View File

@@ -21,8 +21,8 @@ android {
applicationId = "me.hackerchick.catima"
minSdk = 21
targetSdk = 34
versionCode = 132
versionName = "2.27.0"
versionCode = 135
versionName = "2.29.1"
vectorDrawables.useSupportLibrary = true
multiDexEnabled = true
@@ -92,8 +92,9 @@ dependencies {
implementation("androidx.exifinterface:exifinterface:1.3.7")
implementation("androidx.palette:palette:1.0.0")
implementation("androidx.preference:preference:1.2.1")
implementation("com.google.android.material:material:1.11.0")
implementation("com.github.yalantis:ucrop:2.2.8")
implementation("com.google.android.material:material:1.12.0")
implementation("com.github.yalantis:ucrop:2.2.9")
implementation("androidx.work:work-runtime:2.9.0")
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4")
// Splash Screen
@@ -112,7 +113,7 @@ dependencies {
// Testing
testImplementation("androidx.test:core:1.5.0")
testImplementation("junit:junit:4.13.2")
testImplementation("org.robolectric:robolectric:4.11.1")
testImplementation("org.robolectric:robolectric:4.12.2")
}
tasks.withType<SpotBugsTask>().configureEach {

View File

@@ -1,2 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>
<resources>
<string name="app_name">تصحيح Catima</string>
</resources>

View File

@@ -1,2 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>
<resources>
<string name="app_name">Αποσφαλμάτωση Catima</string>
</resources>

View File

@@ -12,6 +12,8 @@
<uses-sdk tools:overrideLibrary="com.google.zxing.client.android" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="23" />
<uses-feature
@@ -43,7 +45,9 @@
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
<data android:mimeType="image/*" />
<data android:mimeType="application/pdf" />
</intent-filter>
</activity>
<activity
@@ -186,5 +190,6 @@
<action android:name="android.service.controls.ControlsProviderService" />
</intent-filter>
</service>
<service android:name=".importexport.ImportExportWorker"/>
</application>
</manifest>

View File

@@ -3,12 +3,17 @@ package protect.card_locker;
public class BarcodeValues {
private final String mFormat;
private final String mContent;
private String mNote;
public BarcodeValues(String format, String content) {
mFormat = format;
mContent = content;
}
public void setNote(String note) {
mNote = note;
}
public String format() {
return mFormat;
}
@@ -17,7 +22,5 @@ public class BarcodeValues {
return mContent;
}
public boolean isEmpty() {
return mFormat == null && mContent == null;
}
}
public String note() { return mNote; }
}

View File

@@ -0,0 +1,6 @@
package protect.card_locker;
public interface BarcodeValuesListDisambiguatorCallback {
void onUserChoseBarcode(BarcodeValues barcodeValues);
void onUserDismissedSelector();
}

View File

@@ -1,8 +1,9 @@
package protect.card_locker;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.text.InputType;
@@ -12,34 +13,36 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.work.Data;
import androidx.work.ExistingWorkPolicy;
import androidx.work.OneTimeWorkRequest;
import androidx.work.OutOfQuotaPolicy;
import androidx.work.WorkManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputLayout;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import protect.card_locker.async.TaskHandler;
import protect.card_locker.databinding.ImportExportActivityBinding;
import protect.card_locker.importexport.DataFormat;
import protect.card_locker.importexport.ImportExportResult;
import protect.card_locker.importexport.ImportExportResultType;
import protect.card_locker.importexport.ImportExportWorker;
public class ImportExportActivity extends CatimaAppCompatActivity {
private ImportExportActivityBinding binding;
private static final String TAG = "Catima";
private ImportExportTask importExporter;
private String importAlertTitle;
private String importAlertMessage;
private DataFormat importDataFormat;
@@ -49,7 +52,10 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
private ActivityResultLauncher<String> fileOpenLauncher;
private ActivityResultLauncher<Intent> filePickerLauncher;
final private TaskHandler mTasks = new TaskHandler();
private static final int PERMISSION_REQUEST_EXPORT = 100;
private static final int PERMISSION_REQUEST_IMPORT = 101;
private OneTimeWorkRequest mRequestedWorkRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -78,15 +84,20 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
Log.e(TAG, "Activity returned NULL uri");
return;
}
try {
OutputStream writer = getContentResolver().openOutputStream(uri);
Log.e(TAG, "Starting file export with: " + result.toString());
startExport(writer, uri, exportPassword.toCharArray(), true);
} catch (IOException e) {
Log.e(TAG, "Failed to export file: " + result.toString(), e);
onExportComplete(new ImportExportResult(ImportExportResultType.GenericFailure, result.toString()), uri);
}
Data exportRequestData = new Data.Builder()
.putString(ImportExportWorker.INPUT_URI, uri.toString())
.putString(ImportExportWorker.INPUT_ACTION, ImportExportWorker.ACTION_EXPORT)
.putString(ImportExportWorker.INPUT_FORMAT, DataFormat.Catima.name())
.putString(ImportExportWorker.INPUT_PASSWORD, exportPassword)
.build();
mRequestedWorkRequest = new OneTimeWorkRequest.Builder(ImportExportWorker.class)
.setInputData(exportRequestData)
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.build();
PermissionUtils.requestPostNotificationsPermission(this, PERMISSION_REQUEST_EXPORT);
});
fileOpenLauncher = registerForActivityResult(new ActivityResultContracts.GetContent(), result -> {
if (result == null) {
@@ -121,16 +132,19 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
builder.setTitle(R.string.exportPassword);
FrameLayout container = new FrameLayout(ImportExportActivity.this);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.leftMargin = 50;
params.rightMargin = 50;
final TextInputLayout textInputLayout = new TextInputLayout(ImportExportActivity.this);
textInputLayout.setEndIconMode(TextInputLayout.END_ICON_PASSWORD_TOGGLE);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(50, 10, 50, 0);
textInputLayout.setLayoutParams(params);
final EditText input = new EditText(ImportExportActivity.this);
input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
input.setLayoutParams(params);
input.setHint(R.string.exportPasswordHint);
container.addView(input);
textInputLayout.addView(input);
container.addView(textInputLayout);
builder.setView(container);
builder.setPositiveButton(R.string.ok, (dialogInterface, i) -> {
exportPassword = input.getText().toString();
@@ -143,7 +157,6 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
});
builder.setNegativeButton(R.string.cancel, (dialogInterface, i) -> dialogInterface.cancel());
builder.show();
});
// Check that there is a file manager available
@@ -155,15 +168,24 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
importApplication.setOnClickListener(v -> chooseImportType(true, null));
}
public static OneTimeWorkRequest buildImportRequest(DataFormat dataFormat, Uri uri, char[] password) {
Data importRequestData = new Data.Builder()
.putString(ImportExportWorker.INPUT_URI, uri.toString())
.putString(ImportExportWorker.INPUT_ACTION, ImportExportWorker.ACTION_IMPORT)
.putString(ImportExportWorker.INPUT_FORMAT, dataFormat.name())
.putString(ImportExportWorker.INPUT_PASSWORD, Arrays.toString(password))
.build();
return new OneTimeWorkRequest.Builder(ImportExportWorker.class)
.setInputData(importRequestData)
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.build();
}
private void openFileForImport(Uri uri, char[] password) {
try {
InputStream reader = getContentResolver().openInputStream(uri);
Log.e(TAG, "Starting file import with: " + uri.toString());
startImport(reader, uri, importDataFormat, password, true);
} catch (IOException e) {
Log.e(TAG, "Failed to import file: " + uri.toString(), e);
onImportComplete(new ImportExportResult(ImportExportResultType.GenericFailure, e.toString()), uri, importDataFormat);
}
mRequestedWorkRequest = buildImportRequest(importDataFormat, uri, password);
PermissionUtils.requestPostNotificationsPermission(this, PERMISSION_REQUEST_IMPORT);
}
private void chooseImportType(boolean choosePicker,
@@ -228,20 +250,17 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
new MaterialAlertDialogBuilder(this)
.setTitle(importAlertTitle)
.setMessage(importAlertMessage)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
if (choosePicker) {
final Intent intentPickAction = new Intent(Intent.ACTION_PICK);
filePickerLauncher.launch(intentPickAction);
} else {
fileOpenLauncher.launch("*/*");
}
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), R.string.failedOpeningFileManager, Toast.LENGTH_LONG).show();
Log.e(TAG, "No activity found to handle intent", e);
.setPositiveButton(R.string.ok, (dialog1, which1) -> {
try {
if (choosePicker) {
final Intent intentPickAction = new Intent(Intent.ACTION_PICK);
filePickerLauncher.launch(intentPickAction);
} else {
fileOpenLauncher.launch("*/*");
}
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), R.string.failedOpeningFileManager, Toast.LENGTH_LONG).show();
Log.e(TAG, "No activity found to handle intent", e);
}
})
.setNegativeButton(R.string.cancel, null)
@@ -250,60 +269,12 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
builder.show();
}
private void startImport(final InputStream target, final Uri targetUri, final DataFormat dataFormat, final char[] password, final boolean closeWhenDone) {
mTasks.flushTaskList(TaskHandler.TYPE.IMPORT, true, false, false);
ImportExportTask.TaskCompleteListener listener = new ImportExportTask.TaskCompleteListener() {
@Override
public void onTaskComplete(ImportExportResult result, DataFormat dataFormat) {
onImportComplete(result, targetUri, dataFormat);
if (closeWhenDone) {
try {
target.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
};
importExporter = new ImportExportTask(ImportExportActivity.this,
dataFormat, target, password, listener);
mTasks.executeTask(TaskHandler.TYPE.IMPORT, importExporter);
}
private void startExport(final OutputStream target, final Uri targetUri, char[] password, final boolean closeWhenDone) {
mTasks.flushTaskList(TaskHandler.TYPE.EXPORT, true, false, false);
ImportExportTask.TaskCompleteListener listener = new ImportExportTask.TaskCompleteListener() {
@Override
public void onTaskComplete(ImportExportResult result, DataFormat dataFormat) {
onExportComplete(result, targetUri);
if (closeWhenDone) {
try {
target.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
};
importExporter = new ImportExportTask(ImportExportActivity.this,
DataFormat.Catima, target, password, listener);
mTasks.executeTask(TaskHandler.TYPE.EXPORT, importExporter);
}
@Override
protected void onDestroy() {
mTasks.flushTaskList(TaskHandler.TYPE.IMPORT, true, false, false);
mTasks.flushTaskList(TaskHandler.TYPE.EXPORT, true, false, false);
super.onDestroy();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
setResult(RESULT_CANCELED);
finish();
return true;
}
@@ -311,84 +282,76 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
return super.onOptionsItemSelected(item);
}
private void retryWithPassword(DataFormat dataFormat, Uri uri) {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
public static void retryWithPassword(Context context, DataFormat dataFormat, Uri uri) {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
builder.setTitle(R.string.passwordRequired);
final EditText input = new EditText(this);
FrameLayout container = new FrameLayout(context);
final TextInputLayout textInputLayout = new TextInputLayout(context);
textInputLayout.setEndIconMode(TextInputLayout.END_ICON_PASSWORD_TOGGLE);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(50, 10, 50, 0);
textInputLayout.setLayoutParams(params);
final EditText input = new EditText(context);
input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
builder.setView(input);
input.setHint(R.string.exportPasswordHint);
textInputLayout.addView(input);
container.addView(textInputLayout);
builder.setView(container);
builder.setPositiveButton(R.string.ok, (dialogInterface, i) -> {
openFileForImport(uri, input.getText().toString().toCharArray());
OneTimeWorkRequest importRequest = ImportExportActivity.buildImportRequest(dataFormat, uri, input.getText().toString().toCharArray());
WorkManager.getInstance(context).enqueueUniqueWork(ImportExportWorker.ACTION_IMPORT, ExistingWorkPolicy.REPLACE, importRequest);
});
builder.setNegativeButton(R.string.cancel, (dialogInterface, i) -> dialogInterface.cancel());
builder.show();
}
private String buildResultDialogMessage(ImportExportResult result, boolean isImport) {
int messageId;
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (result.resultType() == ImportExportResultType.Success) {
messageId = isImport ? R.string.importSuccessful : R.string.exportSuccessful;
} else {
messageId = isImport ? R.string.importFailed : R.string.exportFailed;
}
StringBuilder messageBuilder = new StringBuilder(getResources().getString(messageId));
if (result.developerDetails() != null) {
messageBuilder.append("\n\n");
messageBuilder.append(getResources().getString(R.string.include_if_asking_support));
messageBuilder.append("\n\n");
messageBuilder.append(result.developerDetails());
}
return messageBuilder.toString();
onMockedRequestPermissionsResult(requestCode, permissions, grantResults);
}
private void onImportComplete(ImportExportResult result, Uri path, DataFormat dataFormat) {
ImportExportResultType resultType = result.resultType();
public void onMockedRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
boolean granted = grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
Integer failureReason = null;
if (resultType == ImportExportResultType.BadPassword) {
retryWithPassword(dataFormat, path);
return;
if (requestCode == PERMISSION_REQUEST_EXPORT) {
if (granted) {
WorkManager.getInstance(this).enqueueUniqueWork(ImportExportWorker.ACTION_EXPORT, ExistingWorkPolicy.REPLACE, mRequestedWorkRequest);
Toast.makeText(this, R.string.exportStartedCheckNotifications, Toast.LENGTH_LONG).show();
// Import/export started
setResult(RESULT_OK);
finish();
return;
}
failureReason = R.string.postNotificationsPermissionRequired;
} else if (requestCode == PERMISSION_REQUEST_IMPORT) {
if (granted) {
WorkManager.getInstance(this).enqueueUniqueWork(ImportExportWorker.ACTION_IMPORT, ExistingWorkPolicy.REPLACE, mRequestedWorkRequest);
// Import/export started
setResult(RESULT_OK);
finish();
return;
}
failureReason = R.string.postNotificationsPermissionRequired;
}
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
builder.setTitle(resultType == ImportExportResultType.Success ? R.string.importSuccessfulTitle : R.string.importFailedTitle);
builder.setMessage(buildResultDialogMessage(result, true));
builder.setNeutralButton(R.string.ok, (dialog, which) -> dialog.dismiss());
builder.create().show();
}
private void onExportComplete(ImportExportResult result, final Uri path) {
ImportExportResultType resultType = result.resultType();
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
builder.setTitle(resultType == ImportExportResultType.Success ? R.string.exportSuccessfulTitle : R.string.exportFailedTitle);
builder.setMessage(buildResultDialogMessage(result, false));
builder.setNeutralButton(R.string.ok, (dialog, which) -> dialog.dismiss());
if (resultType == ImportExportResultType.Success) {
final CharSequence sendLabel = ImportExportActivity.this.getResources().getText(R.string.sendLabel);
builder.setPositiveButton(sendLabel, (dialog, which) -> {
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, path);
sendIntent.setType("text/csv");
// set flag to give temporary permission to external app to use the FileProvider
sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
ImportExportActivity.this.startActivity(Intent.createChooser(sendIntent,
sendLabel));
dialog.dismiss();
});
if (failureReason != null) {
Toast.makeText(this, failureReason, Toast.LENGTH_LONG).show();
}
builder.create().show();
}
}

View File

@@ -1,143 +0,0 @@
package protect.card_locker;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import protect.card_locker.async.CompatCallable;
import protect.card_locker.importexport.DataFormat;
import protect.card_locker.importexport.ImportExportResult;
import protect.card_locker.importexport.ImportExportResultType;
import protect.card_locker.importexport.MultiFormatExporter;
import protect.card_locker.importexport.MultiFormatImporter;
public class ImportExportTask implements CompatCallable<ImportExportResult> {
private static final String TAG = "Catima";
private Activity activity;
private boolean doImport;
private DataFormat format;
private OutputStream outputStream;
private InputStream inputStream;
private char[] password;
private TaskCompleteListener listener;
private ProgressDialog progress;
/**
* Constructor which will setup a task for exporting to the given file
*/
ImportExportTask(Activity activity, DataFormat format, OutputStream output, char[] password,
TaskCompleteListener listener) {
super();
this.activity = activity;
this.doImport = false;
this.format = format;
this.outputStream = output;
this.password = password;
this.listener = listener;
}
/**
* Constructor which will setup a task for importing from the given InputStream.
*/
ImportExportTask(Activity activity, DataFormat format, InputStream input, char[] password,
TaskCompleteListener listener) {
super();
this.activity = activity;
this.doImport = true;
this.format = format;
this.inputStream = input;
this.password = password;
this.listener = listener;
}
private ImportExportResult performImport(Context context, InputStream stream, SQLiteDatabase database, char[] password) {
ImportExportResult importResult = MultiFormatImporter.importData(context, database, stream, format, password);
Log.i(TAG, "Import result: " + importResult);
return importResult;
}
private ImportExportResult performExport(Context context, OutputStream stream, SQLiteDatabase database, char[] password) {
ImportExportResult result;
try {
OutputStreamWriter writer = new OutputStreamWriter(stream, StandardCharsets.UTF_8);
result = MultiFormatExporter.exportData(context, database, stream, format, password);
writer.close();
} catch (IOException e) {
result = new ImportExportResult(ImportExportResultType.GenericFailure, e.toString());
Log.e(TAG, "Unable to export file", e);
}
Log.i(TAG, "Export result: " + result);
return result;
}
public void onPreExecute() {
progress = new ProgressDialog(activity);
progress.setTitle(doImport ? R.string.importing : R.string.exporting);
progress.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
ImportExportTask.this.stop();
}
});
progress.show();
}
protected ImportExportResult doInBackground(Void... nothing) {
final SQLiteDatabase database = new DBHelper(activity).getWritableDatabase();
ImportExportResult result;
if (doImport) {
result = performImport(activity.getApplicationContext(), inputStream, database, password);
} else {
result = performExport(activity.getApplicationContext(), outputStream, database, password);
}
database.close();
return result;
}
public void onPostExecute(Object castResult) {
listener.onTaskComplete((ImportExportResult) castResult, format);
progress.dismiss();
Log.i(TAG, (doImport ? "Import" : "Export") + " Complete");
}
protected void onCancelled() {
progress.dismiss();
Log.i(TAG, (doImport ? "Import" : "Export") + " Cancelled");
}
protected void stop() {
// Whelp
}
@Override
public ImportExportResult call() {
return doInBackground();
}
interface TaskCompleteListener {
void onTaskComplete(ImportExportResult result, DataFormat format);
}
}

View File

@@ -164,7 +164,7 @@ public class LoyaltyCard implements Parcelable {
@Override
public int describeContents() {
return id;
return 0;
}
@NonNull

View File

@@ -123,8 +123,7 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
}
inputHolder.mCardIcon.setContentDescription(loyaltyCard.store);
Utils.setIconOrTextWithBackground(mContext, loyaltyCard, icon, inputHolder.mCardIcon, inputHolder.mCardText);
inputHolder.setIconBackgroundColor(Utils.getHeaderColor(mContext, loyaltyCard));
inputHolder.mIconBackgroundColor = Utils.setIconOrTextWithBackground(mContext, loyaltyCard, icon, inputHolder.mCardIcon, inputHolder.mCardText);
inputHolder.toggleCardStateIcon(loyaltyCard.starStatus != 0, loyaltyCard.archiveStatus != 0, itemSelected(inputCursor.getPosition()));
@@ -339,11 +338,6 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
mArchivedBackground.invalidate();
}
public void setIconBackgroundColor(int color) {
mIconBackgroundColor = color;
mCardIcon.setBackgroundColor(color);
}
}
public int dpToPx(int dp, Context mContext) {

View File

@@ -646,11 +646,22 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
Log.d("barcode card id editor", "barcode and card id editor picker returned without an intent");
return;
}
BarcodeValues barcodeValues = Utils.parseSetBarcodeActivityResult(Utils.BARCODE_SCAN, result.getResultCode(), intent, getApplicationContext());
cardId = barcodeValues.content();
barcodeType = barcodeValues.format();
barcodeId = "";
List<BarcodeValues> barcodeValuesList = Utils.parseSetBarcodeActivityResult(Utils.BARCODE_SCAN, result.getResultCode(), intent, getApplicationContext());
Utils.makeUserChooseBarcodeFromList(this, barcodeValuesList, new BarcodeValuesListDisambiguatorCallback() {
@Override
public void onUserChoseBarcode(BarcodeValues barcodeValues) {
cardId = barcodeValues.content();
barcodeType = barcodeValues.format();
barcodeId = "";
}
@Override
public void onUserDismissedSelector() {
}
});
}
});

View File

@@ -1,7 +1,6 @@
package protect.card_locker;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.ColorStateList;
@@ -60,7 +59,6 @@ import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Currency;
import java.util.Date;
import java.util.List;
import java.util.function.Predicate;
@@ -420,7 +418,11 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
private void showBalanceUpdateDialog() {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
// Header
builder.setTitle(R.string.updateBalanceTitle);
// Layout
FrameLayout container = new FrameLayout(this);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
@@ -438,61 +440,91 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
currentTextview.setText(getString(R.string.currentBalanceSentence, Utils.formatBalance(this, loyaltyCard.balance, loyaltyCard.balanceType)));
layout.addView(currentTextview);
TextView updateTextView = new TextView(this);
updateTextView.setText(getString(R.string.newBalanceSentence, Utils.formatBalance(this, loyaltyCard.balance, loyaltyCard.balanceType)));
layout.addView(updateTextView);
final TextInputEditText input = new TextInputEditText(this);
Context dialogContext = this;
input.setInputType(InputType.TYPE_CLASS_NUMBER);
input.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
input.setKeyListener(DigitsKeyListener.getInstance("0123456789,."));
input.setHint(R.string.updateBalanceHint);
input.addTextChangedListener(new SimpleTextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
BigDecimal newBalance;
try {
newBalance = calculateNewBalance(loyaltyCard.balance, loyaltyCard.balanceType, s.toString());
} catch (ParseException e) {
input.setTag(null);
updateTextView.setText(getString(R.string.newBalanceSentence, Utils.formatBalance(dialogContext, loyaltyCard.balance, loyaltyCard.balanceType)));
return;
}
// Save new balance into this element
input.setTag(newBalance);
updateTextView.setText(getString(R.string.newBalanceSentence, Utils.formatBalance(dialogContext, newBalance, loyaltyCard.balanceType)));
}
});
layout.addView(input);
layout.setLayoutParams(params);
container.addView(layout);
// Set layout
builder.setView(container);
builder.setPositiveButton(R.string.ok, (dialogInterface, i) -> {
// Grab calculated balance from input field
BigDecimal newBalance = (BigDecimal) input.getTag();
if (newBalance == null) {
return;
// Buttons
builder.setPositiveButton(R.string.spend, (dialogInterface, i) -> {
// Calculate and update balance
try {
BigDecimal balanceChange = Utils.parseBalance(input.getText().toString(), loyaltyCard.balanceType);
BigDecimal newBalance = loyaltyCard.balance.subtract(balanceChange).max(new BigDecimal(0));
DBHelper.updateLoyaltyCardBalance(database, loyaltyCardId, newBalance);
} catch (ParseException e) {
Toast.makeText(getApplicationContext(), R.string.amountParsingFailed, Toast.LENGTH_LONG).show();
}
// Actually update balance
DBHelper.updateLoyaltyCardBalance(database, loyaltyCardId, newBalance);
// Reload UI
// Reload state
this.onResume();
// Show new balance
Toast.makeText(getApplicationContext(), getString(R.string.newBalanceSentence, Utils.formatBalance(this, loyaltyCard.balance, loyaltyCard.balanceType)), Toast.LENGTH_LONG).show();
});
builder.setNegativeButton(getString(R.string.cancel), (dialog, which) -> dialog.cancel());
builder.setNegativeButton(R.string.receive, (dialogInterface, i) -> {
// Calculate and update balance
try {
BigDecimal balanceChange = Utils.parseBalance(input.getText().toString(), loyaltyCard.balanceType);
BigDecimal newBalance = loyaltyCard.balance.add(balanceChange);
DBHelper.updateLoyaltyCardBalance(database, loyaltyCardId, newBalance);
} catch (ParseException e) {
Toast.makeText(getApplicationContext(), R.string.amountParsingFailed, Toast.LENGTH_LONG).show();
}
// Reload state
this.onResume();
// Show new balance
Toast.makeText(getApplicationContext(), getString(R.string.newBalanceSentence, Utils.formatBalance(this, loyaltyCard.balance, loyaltyCard.balanceType)), Toast.LENGTH_LONG).show();
});
builder.setNeutralButton(getString(R.string.cancel), (dialog, which) -> dialog.cancel());
AlertDialog dialog = builder.create();
// Now that the dialog exists, we can bind something that affects the buttons
input.addTextChangedListener(new SimpleTextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
BigDecimal balanceChange;
try {
balanceChange = Utils.parseBalance(s.toString(), loyaltyCard.balanceType);
} catch (ParseException e) {
input.setError(getString(R.string.amountParsingFailed));
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(false);
return;
}
input.setError(null);
if (balanceChange.equals(new BigDecimal(0))) {
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(false);
} else {
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(true);
}
}
});
dialog.show();
// Disable buttons (must be done **after** dialog is shown to prevent crash
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(false);
// Set focus on input field
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
input.requestFocus();
}
private BigDecimal calculateNewBalance(BigDecimal currentBalance, Currency currency, String unparsedSubtraction) throws ParseException {
BigDecimal subtraction = Utils.parseBalance(unparsedSubtraction, currency);
return currentBalance.subtract(subtraction).max(new BigDecimal(0));
}
private void setBottomAppBarButtonState() {
if (!loyaltyCard.note.isEmpty() || !loyaltyCardGroups.isEmpty() || hasBalance(loyaltyCard) || loyaltyCard.validFrom != null || loyaltyCard.expiry != null) {
binding.bottomAppBarInfoButton.setVisibility(View.VISIBLE);
@@ -619,10 +651,15 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
cardIdString = loyaltyCard.cardId;
barcodeIdString = loyaltyCard.barcodeId;
binding.cardIdView.setText(loyaltyCard.cardId);
binding.mainImageDescription.setText(loyaltyCard.cardId);
// Display full text on click in case it doesn't fit in a single line
binding.cardIdView.setOnClickListener(v -> {
binding.mainImageDescription.setOnClickListener(v -> {
if (mainImageIndex != 0) {
// Don't show cardId dialog, we're displaying something else
return;
}
TextView cardIdView = new TextView(LoyaltyCardViewActivity.this);
cardIdView.setText(loyaltyCard.cardId);
cardIdView.setTextIsSelectable(true);
@@ -701,6 +738,8 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
DBHelper.updateLoyaltyCardLastUsed(database, loyaltyCard.id);
invalidateOptionsMenu();
ShortcutHelper.updateShortcuts(this, loyaltyCard);
}
private void setStateBasedOnImageTypes() {
@@ -800,6 +839,8 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
DBHelper.updateLoyaltyCardArchiveStatus(database, loyaltyCardId, 1);
Toast.makeText(LoyaltyCardViewActivity.this, R.string.archived, Toast.LENGTH_LONG).show();
ShortcutHelper.removeShortcut(LoyaltyCardViewActivity.this, loyaltyCardId);
// Re-init loyaltyCard with new data from DB
onResume();
invalidateOptionsMenu();
@@ -891,7 +932,9 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
if (imageTypes.isEmpty()) {
barcodeRenderTarget.setVisibility(View.GONE);
binding.mainCardView.setCardBackgroundColor(Color.TRANSPARENT);
binding.cardIdView.setTextColor(MaterialColors.getColor(binding.cardIdView, com.google.android.material.R.attr.colorOnSurfaceVariant));
binding.mainImageDescription.setTextColor(MaterialColors.getColor(binding.mainImageDescription, com.google.android.material.R.attr.colorOnSurfaceVariant));
binding.mainImageDescription.setText(loyaltyCard.cardId);
return;
}
@@ -900,7 +943,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
if (wantedImageType == ImageType.BARCODE) {
barcodeRenderTarget.setBackgroundColor(Color.WHITE);
binding.mainCardView.setCardBackgroundColor(Color.WHITE);
binding.cardIdView.setTextColor(getResources().getColor(R.color.md_theme_light_onSurfaceVariant));
binding.mainImageDescription.setTextColor(getResources().getColor(R.color.md_theme_light_onSurfaceVariant));
if (waitForResize) {
redrawBarcodeAfterResize(!isFullscreen);
@@ -908,18 +951,23 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
drawBarcode(!isFullscreen);
}
binding.mainImageDescription.setText(loyaltyCard.cardId);
barcodeRenderTarget.setContentDescription(getString(R.string.barcodeImageDescriptionWithType, format.prettyName()));
} else if (wantedImageType == ImageType.IMAGE_FRONT) {
barcodeRenderTarget.setImageBitmap(frontImageBitmap);
barcodeRenderTarget.setBackgroundColor(Color.TRANSPARENT);
binding.mainCardView.setCardBackgroundColor(Color.TRANSPARENT);
binding.cardIdView.setTextColor(MaterialColors.getColor(binding.cardIdView, com.google.android.material.R.attr.colorOnSurfaceVariant));
binding.mainImageDescription.setTextColor(MaterialColors.getColor(binding.mainImageDescription, com.google.android.material.R.attr.colorOnSurfaceVariant));
binding.mainImageDescription.setText(getString(R.string.frontImageDescription));
barcodeRenderTarget.setContentDescription(getString(R.string.frontImageDescription));
} else if (wantedImageType == ImageType.IMAGE_BACK) {
barcodeRenderTarget.setImageBitmap(backImageBitmap);
barcodeRenderTarget.setBackgroundColor(Color.TRANSPARENT);
binding.mainCardView.setCardBackgroundColor(Color.TRANSPARENT);
binding.cardIdView.setTextColor(MaterialColors.getColor(binding.cardIdView, com.google.android.material.R.attr.colorOnSurfaceVariant));
binding.mainImageDescription.setTextColor(MaterialColors.getColor(binding.mainImageDescription, com.google.android.material.R.attr.colorOnSurfaceVariant));
binding.mainImageDescription.setText(getString(R.string.backImageDescription));
barcodeRenderTarget.setContentDescription(getString(R.string.backImageDescription));
} else {
throw new IllegalArgumentException("Unknown image type: " + wantedImageType);

View File

@@ -7,8 +7,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.database.CursorIndexOutOfBoundsException;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -28,21 +26,29 @@ import androidx.appcompat.view.ActionMode;
import androidx.appcompat.widget.SearchView;
import androidx.core.splashscreen.SplashScreen;
import androidx.recyclerview.widget.RecyclerView;
import androidx.work.Data;
import androidx.work.WorkInfo;
import androidx.work.WorkManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayout;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import protect.card_locker.databinding.ContentMainBinding;
import protect.card_locker.databinding.MainActivityBinding;
import protect.card_locker.databinding.SortingOptionBinding;
import protect.card_locker.importexport.DataFormat;
import protect.card_locker.importexport.ImportExportWorker;
import protect.card_locker.preferences.SettingsActivity;
public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCardCursorAdapter.CardAdapterListener {
@@ -73,6 +79,7 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
private ActivityResultLauncher<Intent> mBarcodeScannerLauncher;
private ActivityResultLauncher<Intent> mSettingsLauncher;
private ActivityResultLauncher<Intent> mImportExportLauncher;
private ActionMode.Callback mCurrentActionModeCallback = new ActionMode.Callback() {
@Override
@@ -150,6 +157,7 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
for (LoyaltyCard loyaltyCard : mAdapter.getSelectedItems()) {
Log.d(TAG, "Archiving card: " + loyaltyCard.id);
DBHelper.updateLoyaltyCardArchiveStatus(mDatabase, loyaltyCard.id, 1);
ShortcutHelper.removeShortcut(MainActivity.this, loyaltyCard.id);
updateLoyaltyCardList(false);
inputMode.finish();
invalidateOptionsMenu();
@@ -194,10 +202,12 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
@Override
protected void onCreate(Bundle inputSavedInstanceState) {
extractIntentFields(getIntent());
SplashScreen.installSplashScreen(this);
super.onCreate(inputSavedInstanceState);
// We should extract the share intent after we called the super.onCreate as it may need to spawn a dialog window and the app needs to be initialized to not crash
extractIntentFields(getIntent());
binding = MainActivityBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
@@ -287,11 +297,11 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
}
Intent intent = result.getData();
BarcodeValues barcodeValues = Utils.parseSetBarcodeActivityResult(Utils.BARCODE_SCAN, result.getResultCode(), intent, this);
List<BarcodeValues> barcodeValuesList = Utils.parseSetBarcodeActivityResult(Utils.BARCODE_SCAN, result.getResultCode(), intent, this);
Bundle inputBundle = intent.getExtras();
String group = inputBundle != null ? inputBundle.getString(LoyaltyCardEditActivity.BUNDLE_ADDGROUP) : null;
processBarcodeValues(barcodeValues, group);
processBarcodeValuesList(barcodeValuesList, group, false);
});
mSettingsLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
@@ -303,6 +313,69 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
}
});
mImportExportLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
// User didn't ask for import or export
if (result.getResultCode() != RESULT_OK) {
return;
}
// Watch for active imports/exports
new Thread(() -> {
WorkManager workManager = WorkManager.getInstance(MainActivity.this);
Snackbar importRunning = Snackbar.make(binding.getRoot(), R.string.importing, Snackbar.LENGTH_INDEFINITE);
while (true) {
try {
List<WorkInfo> activeImports = workManager.getWorkInfosForUniqueWork(ImportExportWorker.ACTION_IMPORT).get();
// We should only have one import running at a time, so it should be safe to always grab the latest
WorkInfo activeImport = activeImports.get(activeImports.size() - 1);
WorkInfo.State importState = activeImport.getState();
if (importState == WorkInfo.State.RUNNING || importState == WorkInfo.State.ENQUEUED || importState == WorkInfo.State.BLOCKED) {
importRunning.show();
} else if (importState == WorkInfo.State.SUCCEEDED) {
importRunning.dismiss();
runOnUiThread(() -> {
Toast.makeText(getApplicationContext(), getString(R.string.importSuccessful), Toast.LENGTH_LONG).show();
updateLoyaltyCardList(true);
});
break;
} else {
importRunning.dismiss();
Data outputData = activeImport.getOutputData();
// FIXME: This dialog will asynchronously be accepted or declined and we don't know the status of it so we can't show the import state
// We want to get back into this function
// A cheap fix would be to keep looping but if the user dismissed the dialog that could mean we're looping forever...
if (Objects.equals(outputData.getString(ImportExportWorker.OUTPUT_ERROR_REASON), ImportExportWorker.ERROR_PASSWORD_REQUIRED)) {
runOnUiThread(() -> ImportExportActivity.retryWithPassword(
MainActivity.this,
DataFormat.valueOf(outputData.getString(ImportExportWorker.INPUT_FORMAT)),
Uri.parse(outputData.getString(ImportExportWorker.INPUT_URI))
));
} else {
runOnUiThread(() -> {
Toast.makeText(getApplicationContext(), getString(R.string.importFailed), Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), activeImport.getOutputData().getString(ImportExportWorker.OUTPUT_ERROR_REASON), Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), activeImport.getOutputData().getString(ImportExportWorker.OUTPUT_ERROR_DETAILS), Toast.LENGTH_LONG).show();
});
}
break;
}
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}).start();
});
getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
@@ -446,63 +519,59 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
}
}
private void processBarcodeValues(BarcodeValues barcodeValues, String group) {
if (barcodeValues.isEmpty()) {
private void processBarcodeValuesList(List<BarcodeValues> barcodeValuesList, String group, boolean closeAppOnNoBarcode) {
if (barcodeValuesList.isEmpty()) {
throw new IllegalArgumentException("barcodesValues may not be empty");
}
Intent newIntent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
Bundle newBundle = new Bundle();
newBundle.putString(LoyaltyCardEditActivity.BUNDLE_BARCODETYPE, barcodeValues.format());
newBundle.putString(LoyaltyCardEditActivity.BUNDLE_CARDID, barcodeValues.content());
if (group != null) {
newBundle.putString(LoyaltyCardEditActivity.BUNDLE_ADDGROUP, group);
}
newIntent.putExtras(newBundle);
startActivity(newIntent);
Utils.makeUserChooseBarcodeFromList(MainActivity.this, barcodeValuesList, new BarcodeValuesListDisambiguatorCallback() {
@Override
public void onUserChoseBarcode(BarcodeValues barcodeValues) {
Intent newIntent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
Bundle newBundle = new Bundle();
newBundle.putString(LoyaltyCardEditActivity.BUNDLE_BARCODETYPE, barcodeValues.format());
newBundle.putString(LoyaltyCardEditActivity.BUNDLE_CARDID, barcodeValues.content());
if (group != null) {
newBundle.putString(LoyaltyCardEditActivity.BUNDLE_ADDGROUP, group);
}
newIntent.putExtras(newBundle);
startActivity(newIntent);
}
@Override
public void onUserDismissedSelector() {
if (closeAppOnNoBarcode) {
finish();
}
}
});
}
private void onSharedIntent(Intent intent) {
String receivedAction = intent.getAction();
String receivedType = intent.getType();
// Check if an image was shared to us
// Check if an image or file was shared to us
if (Intent.ACTION_SEND.equals(receivedAction)) {
if (!receivedType.startsWith("image/")) {
List<BarcodeValues> barcodeValuesList;
if (receivedType.equals("text/plain")) {
barcodeValuesList = Collections.singletonList(new BarcodeValues(null, intent.getStringExtra(Intent.EXTRA_TEXT)));
} else if (receivedType.startsWith("image/")) {
barcodeValuesList = Utils.retrieveBarcodesFromImage(this, intent.getParcelableExtra(Intent.EXTRA_STREAM));
} else if (receivedType.equals("application/pdf")) {
barcodeValuesList = Utils.retrieveBarcodesFromPdf(this, intent.getParcelableExtra(Intent.EXTRA_STREAM));
} else {
Log.e(TAG, "Wrong mime-type");
return;
}
BarcodeValues barcodeValues;
Bitmap bitmap;
Uri data = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (data == null) {
Toast.makeText(this, R.string.errorReadingImage, Toast.LENGTH_LONG).show();
if (barcodeValuesList.isEmpty()) {
finish();
return;
}
try {
bitmap = Utils.retrieveImageFromUri(this, data);
} catch (IOException e) {
Log.e(TAG, "Error getting data from image file");
e.printStackTrace();
Toast.makeText(this, R.string.errorReadingImage, Toast.LENGTH_LONG).show();
finish();
return;
}
barcodeValues = Utils.getBarcodeFromBitmap(bitmap);
if (barcodeValues.isEmpty()) {
Log.i(TAG, "No barcode found in image file");
Toast.makeText(this, R.string.noBarcodeFound, Toast.LENGTH_LONG).show();
finish();
return;
}
processBarcodeValues(barcodeValues, null);
processBarcodeValuesList(barcodeValuesList, null, true);
}
}
@@ -644,7 +713,7 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
if (id == R.id.action_import_export) {
Intent i = new Intent(getApplicationContext(), ImportExportActivity.class);
startActivity(i);
mImportExportLauncher.launch(i);
return true;
}
@@ -798,8 +867,6 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
b.putIntegerArrayList("cardList", cardList);
intent.putExtras(b);
ShortcutHelper.updateShortcuts(MainActivity.this, loyaltyCard);
startActivity(intent);
}
}

View File

@@ -0,0 +1,63 @@
package protect.card_locker;
import static android.content.Context.NOTIFICATION_SERVICE;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class NotificationHelper {
// Do not change these IDs!
public static final String CHANNEL_IMPORT = "import";
public static final String CHANNEL_EXPORT = "export";
public static final int IMPORT_ID = 100;
public static final int IMPORT_PROGRESS_ID = 101;
public static final int EXPORT_ID = 103;
public static final int EXPORT_PROGRESS_ID = 104;
public static Notification.Builder createNotificationBuilder(@NonNull Context context, @NonNull String channel, @NonNull int icon, @NonNull String title, @Nullable String message) {
Notification.Builder notificationBuilder = new Notification.Builder(context)
.setSmallIcon(icon)
.setTicker(title)
.setContentTitle(title);
if (message != null) {
notificationBuilder.setContentText(message);
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
NotificationChannel notificationChannel = new NotificationChannel(channel, getChannelName(channel), NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(notificationChannel);
notificationBuilder.setChannelId(channel);
}
return notificationBuilder;
}
public static void sendNotification(@NonNull Context context, @NonNull int notificationId, @NonNull Notification notification) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(notificationId, notification);
}
private static String getChannelName(@NonNull String channel) {
switch(channel) {
case CHANNEL_IMPORT:
return "Import";
case CHANNEL_EXPORT:
return "Export";
default:
throw new IllegalArgumentException("Unknown notification channel");
}
}
}

View File

@@ -42,6 +42,16 @@ public class PermissionUtils {
return ContextCompat.checkSelfPermission(activity, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED;
}
/**
* Check if post notifications permission is needed
*
* @param activity
* @return
*/
public static boolean needsPostNotificationsPermission(Activity activity) {
return ContextCompat.checkSelfPermission(activity, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED;
}
/**
* Call onRequestPermissionsResult after storage read permission was granted.
* Mocks a successful grant if a grant is not necessary.
@@ -91,4 +101,37 @@ public class PermissionUtils {
activity.onMockedRequestPermissionsResult(requestCode, permissions, mockedResults);
}
}
/**
* Call onRequestPermissionsResult after notification permission was granted.
* Mocks a successful grant if a grant is not necessary.
*
* @param activity
* @param requestCode
*/
public static void requestPostNotificationsPermission(CatimaAppCompatActivity activity, int requestCode) {
int[] mockedResults = new int[]{ PackageManager.PERMISSION_GRANTED };
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.TIRAMISU) {
String[] permissions = new String[0];
activity.onMockedRequestPermissionsResult(requestCode, permissions, mockedResults);
return;
}
String[] permissions = new String[]{ Manifest.permission.POST_NOTIFICATIONS};
if (needsPostNotificationsPermission(activity)) {
ActivityCompat.requestPermissions(activity, permissions, requestCode);
} else {
// FIXME: This points to onMockedRequestPermissionResult instead of to
// onRequestPermissionResult because onRequestPermissionResult was only introduced in
// Android 6.0 (SDK 23) and we and to support Android 5.0 (SDK 21) too.
//
// When minSdk becomes 23, this should point to onRequestPermissionResult directly and
// the activity input variable should be changed from CatimaAppCompatActivity to
// Activity.
activity.onMockedRequestPermissionsResult(requestCode, permissions, mockedResults);
}
}
}

View File

@@ -62,6 +62,7 @@ public class ScanActivity extends CatimaAppCompatActivity {
private static final int COMPAT_SCALE_FACTOR_DIP = 320;
private static final int PERMISSION_SCAN_ADD_FROM_IMAGE = 100;
private static final int PERMISSION_SCAN_ADD_FROM_PDF = 101;
private CaptureManager capture;
private DecoratedBarcodeView barcodeScannerView;
@@ -73,6 +74,7 @@ public class ScanActivity extends CatimaAppCompatActivity {
private ActivityResultLauncher<Intent> manualAddLauncher;
// can't use the pre-made contract because that launches the file manager for image type instead of gallery
private ActivityResultLauncher<Intent> photoPickerLauncher;
private ActivityResultLauncher<Intent> pdfPickerLauncher;
static final String STATE_SCANNER_ACTIVE = "scannerActive";
private boolean mScannerActive = true;
@@ -99,6 +101,7 @@ public class ScanActivity extends CatimaAppCompatActivity {
manualAddLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> handleActivityResult(Utils.SELECT_BARCODE_REQUEST, result.getResultCode(), result.getData()));
photoPickerLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> handleActivityResult(Utils.BARCODE_IMPORT_FROM_IMAGE_FILE, result.getResultCode(), result.getData()));
pdfPickerLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> handleActivityResult(Utils.BARCODE_IMPORT_FROM_PDF_FILE, result.getResultCode(), result.getData()));
customBarcodeScannerBinding.fabOtherOptions.setOnClickListener(view -> {
setScannerActive(false);
@@ -108,7 +111,8 @@ public class ScanActivity extends CatimaAppCompatActivity {
new CharSequence[]{
getString(R.string.addWithoutBarcode),
getString(R.string.addManually),
getString(R.string.addFromImage)
getString(R.string.addFromImage),
getString(R.string.addFromPdfFile)
},
(dialogInterface, i) -> {
switch (i) {
@@ -121,6 +125,9 @@ public class ScanActivity extends CatimaAppCompatActivity {
case 2:
addFromImage();
break;
case 3:
addFromPdfFile();
break;
default:
throw new IllegalArgumentException("Unknown 'Add a card in a different way' dialog option");
}
@@ -268,14 +275,24 @@ public class ScanActivity extends CatimaAppCompatActivity {
private void handleActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
BarcodeValues barcodeValues = Utils.parseSetBarcodeActivityResult(requestCode, resultCode, intent, this);
List<BarcodeValues> barcodeValuesList = Utils.parseSetBarcodeActivityResult(requestCode, resultCode, intent, this);
if (barcodeValues.isEmpty()) {
if (barcodeValuesList.isEmpty()) {
setScannerActive(true);
return;
}
returnResult(barcodeValues.content(), barcodeValues.format());
Utils.makeUserChooseBarcodeFromList(this, barcodeValuesList, new BarcodeValuesListDisambiguatorCallback() {
@Override
public void onUserChoseBarcode(BarcodeValues barcodeValues) {
returnResult(barcodeValues.content(), barcodeValues.format());
}
@Override
public void onUserDismissedSelector() {
setScannerActive(true);
}
});
}
private void addWithoutBarcode() {
@@ -364,19 +381,23 @@ public class ScanActivity extends CatimaAppCompatActivity {
PermissionUtils.requestStorageReadPermission(this, PERMISSION_SCAN_ADD_FROM_IMAGE);
}
private void addFromImageAfterPermission() {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
Intent contentIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentIntent.setType("image/*");
public void addFromPdfFile() {
PermissionUtils.requestStorageReadPermission(this, PERMISSION_SCAN_ADD_FROM_PDF);
}
Intent chooserIntent = Intent.createChooser(photoPickerIntent, getString(R.string.addFromImage));
private void addFromImageOrFileAfterPermission(String mimeType, ActivityResultLauncher<Intent> launcher, int chooserText, int errorMessage) {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType(mimeType);
Intent contentIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentIntent.setType(mimeType);
Intent chooserIntent = Intent.createChooser(photoPickerIntent, getString(chooserText));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { contentIntent });
try {
photoPickerLauncher.launch(chooserIntent);
launcher.launch(chooserIntent);
} catch (ActivityNotFoundException e) {
setScannerActive(true);
Toast.makeText(getApplicationContext(), R.string.failedLaunchingPhotoPicker, Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), errorMessage, Toast.LENGTH_LONG).show();
Log.e(TAG, "No activity found to handle intent", e);
}
}
@@ -424,9 +445,13 @@ public class ScanActivity extends CatimaAppCompatActivity {
if (requestCode == CaptureManager.getCameraPermissionReqCode()) {
showCameraPermissionMissingText(!granted);
} else if (requestCode == PERMISSION_SCAN_ADD_FROM_IMAGE) {
} else if (requestCode == PERMISSION_SCAN_ADD_FROM_IMAGE || requestCode == PERMISSION_SCAN_ADD_FROM_PDF) {
if (granted) {
addFromImageAfterPermission();
if (requestCode == PERMISSION_SCAN_ADD_FROM_IMAGE) {
addFromImageOrFileAfterPermission("image/*", photoPickerLauncher, R.string.addFromImage, R.string.failedLaunchingPhotoPicker);
} else {
addFromImageOrFileAfterPermission("application/pdf", pdfPickerLauncher, R.string.addFromPdfFile, R.string.failedLaunchingFileManager);
}
} else {
setScannerActive(true);
Toast.makeText(this, R.string.storageReadPermissionRequired, Toast.LENGTH_LONG).show();

View File

@@ -43,6 +43,11 @@ class ShortcutHelper {
* used card shortcut is discarded.
*/
static void updateShortcuts(Context context, LoyaltyCard card) {
if (card.archiveStatus == 1) {
// Don't add archived card to menu
return;
}
LinkedList<ShortcutInfoCompat> list = new LinkedList<>(ShortcutManagerCompat.getDynamicShortcuts(context));
SQLiteDatabase database = new DBHelper(context).getReadableDatabase();
@@ -108,18 +113,7 @@ class ShortcutHelper {
* shortcut exists.
*/
static void removeShortcut(Context context, int cardId) {
List<ShortcutInfoCompat> list = ShortcutManagerCompat.getDynamicShortcuts(context);
String shortcutId = Integer.toString(cardId);
for (int index = 0; index < list.size(); index++) {
if (list.get(index).getId().equals(shortcutId)) {
list.remove(index);
break;
}
}
ShortcutManagerCompat.setDynamicShortcuts(context, list);
ShortcutManagerCompat.removeDynamicShortcuts(context, Collections.singletonList(Integer.toString(cardId)));
}
static @NotNull

View File

@@ -12,8 +12,10 @@ import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.ImageDecoder;
import android.graphics.Matrix;
import android.graphics.pdf.PdfRenderer;
import android.net.Uri;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.text.Layout;
import android.text.Spanned;
@@ -39,6 +41,7 @@ import androidx.exifinterface.media.ExifInterface;
import androidx.palette.graphics.Palette;
import com.google.android.material.color.DynamicColors;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
@@ -46,6 +49,8 @@ import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.multi.GenericMultipleBarcodeReader;
import com.google.zxing.multi.MultipleBarcodeReader;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
@@ -60,10 +65,13 @@ import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Currency;
import java.util.Date;
import java.util.GregorianCalendar;
@@ -83,12 +91,13 @@ public class Utils {
public static final int SELECT_BARCODE_REQUEST = 2;
public static final int BARCODE_SCAN = 3;
public static final int BARCODE_IMPORT_FROM_IMAGE_FILE = 4;
public static final int CARD_IMAGE_FROM_CAMERA_FRONT = 5;
public static final int CARD_IMAGE_FROM_CAMERA_BACK = 6;
public static final int CARD_IMAGE_FROM_CAMERA_ICON = 7;
public static final int CARD_IMAGE_FROM_FILE_FRONT = 8;
public static final int CARD_IMAGE_FROM_FILE_BACK = 9;
public static final int CARD_IMAGE_FROM_FILE_ICON = 10;
public static final int BARCODE_IMPORT_FROM_PDF_FILE = 5;
public static final int CARD_IMAGE_FROM_CAMERA_FRONT = 6;
public static final int CARD_IMAGE_FROM_CAMERA_BACK = 7;
public static final int CARD_IMAGE_FROM_CAMERA_ICON = 8;
public static final int CARD_IMAGE_FROM_FILE_FRONT = 9;
public static final int CARD_IMAGE_FROM_FILE_BACK = 10;
public static final int CARD_IMAGE_FROM_FILE_ICON = 11;
public static final String CARD_IMAGE_FILENAME_REGEX = "^(card_)(\\d+)(_(?:front|back|icon)\\.png)$";
@@ -131,6 +140,91 @@ public class Utils {
return ColorUtils.calculateLuminance(backgroundColor) > LUMINANCE_MIDPOINT;
}
static public List<BarcodeValues> retrieveBarcodesFromImage(Context context, Uri uri) {
Log.i(TAG, "Received image file with possible barcode");
if (uri == null) {
Log.e(TAG, "Uri did not contain any data");
Toast.makeText(context, R.string.errorReadingImage, Toast.LENGTH_LONG).show();
return new ArrayList<>();
}
Bitmap bitmap;
try {
bitmap = retrieveImageFromUri(context, uri);
} catch (IOException e) {
Log.e(TAG, "Error getting data from image file");
e.printStackTrace();
Toast.makeText(context, R.string.errorReadingImage, Toast.LENGTH_LONG).show();
return new ArrayList<>();
}
List<BarcodeValues> barcodesFromBitmap = getBarcodesFromBitmap(bitmap);
if (barcodesFromBitmap.isEmpty()) {
Log.i(TAG, "No barcode found in image file");
Toast.makeText(context, R.string.noBarcodeFound, Toast.LENGTH_LONG).show();
}
return barcodesFromBitmap;
}
static public List<BarcodeValues> retrieveBarcodesFromPdf(Context context, Uri uri) {
Log.i(TAG, "Received PDF file with possible barcode");
if (uri == null) {
Log.e(TAG, "Uri did not contain any data");
Toast.makeText(context, R.string.errorReadingFile, Toast.LENGTH_LONG).show();
return new ArrayList<>();
}
ParcelFileDescriptor parcelFileDescriptor = null;
PdfRenderer renderer = null;
List<BarcodeValues> barcodesFromPdfPages = new ArrayList<>();
try {
parcelFileDescriptor = context.getContentResolver().openFileDescriptor(uri, "r");
if (parcelFileDescriptor != null) {
renderer = new PdfRenderer(parcelFileDescriptor);
// Loop over all pages to find barcodes
Bitmap renderedPage;
for (int i = 0; i < renderer.getPageCount(); i++) {
PdfRenderer.Page page = renderer.openPage(i);
renderedPage = Bitmap.createBitmap(page.getWidth(), page.getHeight(), Bitmap.Config.ARGB_8888);
page.render(renderedPage, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
page.close();
List<BarcodeValues> barcodesFromPage = getBarcodesFromBitmap(renderedPage);
for (BarcodeValues barcodeValues : barcodesFromPage) {
barcodeValues.setNote(String.format(context.getString(R.string.pageWithNumber), i+1));
barcodesFromPdfPages.add(barcodeValues);
}
}
}
} catch (IOException e) {
Log.e(TAG, "Error reading PDF file", e);
Toast.makeText(context, R.string.errorReadingFile, Toast.LENGTH_LONG).show();
} finally {
// Resource handling
if (renderer != null) {
renderer.close();
}
if (parcelFileDescriptor != null) {
try {
parcelFileDescriptor.close();
} catch (IOException e) {
Log.e(TAG, "Error closing ParcelFileDescriptor", e);
}
}
}
if (barcodesFromPdfPages.isEmpty()) {
Log.i(TAG, "No barcode found in pdf file");
Toast.makeText(context, R.string.noBarcodeFound, Toast.LENGTH_LONG).show();
}
return barcodesFromPdfPages;
}
/**
* Returns the Barcode format and content based on the result of an activity.
* It shows toasts to notify the end-user as needed itself and will return an empty
@@ -142,45 +236,20 @@ public class Utils {
* @param context
* @return BarcodeValues
*/
static public BarcodeValues parseSetBarcodeActivityResult(int requestCode, int resultCode, Intent intent, Context context) {
static public List<BarcodeValues> parseSetBarcodeActivityResult(int requestCode, int resultCode, Intent intent, Context context) {
String contents;
String format;
if (resultCode != Activity.RESULT_OK) {
return new BarcodeValues(null, null);
return new ArrayList<>();
}
if (requestCode == Utils.BARCODE_IMPORT_FROM_IMAGE_FILE) {
Log.i(TAG, "Received image file with possible barcode");
return retrieveBarcodesFromImage(context, intent.getData());
}
Uri data = intent.getData();
if (data == null) {
Log.e(TAG, "Intent did not contain any data");
Toast.makeText(context, R.string.errorReadingImage, Toast.LENGTH_LONG).show();
return new BarcodeValues(null, null);
}
Bitmap bitmap;
try {
bitmap = retrieveImageFromUri(context, data);
} catch (IOException e) {
Log.e(TAG, "Error getting data from image file");
e.printStackTrace();
Toast.makeText(context, R.string.errorReadingImage, Toast.LENGTH_LONG).show();
return new BarcodeValues(null, null);
}
BarcodeValues barcodeFromBitmap = getBarcodeFromBitmap(bitmap);
if (barcodeFromBitmap.isEmpty()) {
Log.i(TAG, "No barcode found in image file");
Toast.makeText(context, R.string.noBarcodeFound, Toast.LENGTH_LONG).show();
}
Log.i(TAG, "Read barcode id: " + barcodeFromBitmap.content());
Log.i(TAG, "Read format: " + barcodeFromBitmap.format());
return barcodeFromBitmap;
if (requestCode == Utils.BARCODE_IMPORT_FROM_PDF_FILE) {
return retrieveBarcodesFromPdf(context, intent.getData());
}
if (requestCode == Utils.BARCODE_SCAN || requestCode == Utils.SELECT_BARCODE_REQUEST) {
@@ -196,7 +265,7 @@ public class Utils {
Log.i(TAG, "Read barcode id: " + contents);
Log.i(TAG, "Read format: " + format);
return new BarcodeValues(format, contents);
return Collections.singletonList(new BarcodeValues(format, contents));
}
throw new UnsupportedOperationException("Unknown request code for parseSetBarcodeActivityResult");
@@ -216,22 +285,22 @@ public class Utils {
return MediaStore.Images.Media.getBitmap(context.getContentResolver(), data);
}
static public BarcodeValues getBarcodeFromBitmap(Bitmap bitmap) {
static public List<BarcodeValues> getBarcodesFromBitmap(Bitmap bitmap) {
// This function is vulnerable to OOM, so we try again with a smaller bitmap is we get OOM
for (int i = 0; i < 10; i++) {
try {
return Utils.getBarcodeFromBitmapReal(bitmap);
return Utils.getBarcodesFromBitmapReal(bitmap);
} catch (OutOfMemoryError e) {
Log.w(TAG, "Ran OOM in getBarcodeFromBitmap! Trying again with smaller picture! Retry " + i + " of 10.");
Log.w(TAG, "Ran OOM in getBarcodesFromBitmap! Trying again with smaller picture! Retry " + i + " of 10.");
bitmap = Bitmap.createScaledBitmap(bitmap, (int) Math.round(0.75 * bitmap.getWidth()), (int) Math.round(0.75 * bitmap.getHeight()), false);
}
}
// Give up
return new BarcodeValues(null, null);
return new ArrayList<>();
}
static private BarcodeValues getBarcodeFromBitmapReal(Bitmap bitmap) {
static private List<BarcodeValues> getBarcodesFromBitmapReal(Bitmap bitmap) {
// In order to decode it, the Bitmap must first be converted into a pixel array...
int[] intArray = new int[bitmap.getWidth() * bitmap.getHeight()];
bitmap.getPixels(intArray, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
@@ -240,15 +309,63 @@ public class Utils {
LuminanceSource source = new RGBLuminanceSource(bitmap.getWidth(), bitmap.getHeight(), intArray);
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
List<BarcodeValues> barcodeValuesList = new ArrayList<>();
try {
Result barcodeResult = new MultiFormatReader().decode(binaryBitmap);
MultiFormatReader multiFormatReader = new MultiFormatReader();
MultipleBarcodeReader multipleBarcodeReader = new GenericMultipleBarcodeReader(multiFormatReader);
return new BarcodeValues(barcodeResult.getBarcodeFormat().name(), barcodeResult.getText());
Result[] barcodeResults = multipleBarcodeReader.decodeMultiple(binaryBitmap);
for (Result barcodeResult : barcodeResults) {
Log.i(TAG, "Read barcode id: " + barcodeResult.getText());
Log.i(TAG, "Read format: " + barcodeResult.getBarcodeFormat().name());
barcodeValuesList.add(new BarcodeValues(barcodeResult.getBarcodeFormat().name(), barcodeResult.getText()));
}
return barcodeValuesList;
} catch (NotFoundException e) {
return new BarcodeValues(null, null);
return barcodeValuesList;
}
}
static public void makeUserChooseBarcodeFromList(Context context, List<BarcodeValues> barcodeValuesList, BarcodeValuesListDisambiguatorCallback callback) {
// If there is only one choice, consider it chosen
if (barcodeValuesList.size() == 1) {
callback.onUserChoseBarcode(barcodeValuesList.get(0));
return;
}
// Ask user to choose a barcode
// TODO: This should contain an image of the barcode in question to help users understand the choice they're making
CharSequence[] barcodeDescriptions = new CharSequence[barcodeValuesList.size()];
for (int i = 0; i < barcodeValuesList.size(); i++) {
BarcodeValues barcodeValues = barcodeValuesList.get(i);
CatimaBarcode catimaBarcode = CatimaBarcode.fromName(barcodeValues.format());
String barcodeContent = barcodeValues.content();
// Shorten overly long barcodes
if (barcodeContent.length() > 22) {
barcodeContent = barcodeContent.substring(0, 20) + "";
}
if (barcodeValues.note() != null) {
barcodeDescriptions[i] = String.format("%s: %s (%s)", barcodeValues.note(), catimaBarcode.prettyName(), barcodeContent);
} else {
barcodeDescriptions[i] = String.format("%s (%s)", catimaBarcode.prettyName(), barcodeContent);
}
}
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context);
builder.setTitle(context.getString(R.string.multipleBarcodesFoundPleaseChooseOne));
builder.setItems(
barcodeDescriptions,
(dialogInterface, i) -> callback.onUserChoseBarcode(barcodeValuesList.get(i))
);
builder.setOnCancelListener(dialogInterface -> callback.onUserDismissedSelector());
builder.show();
}
static public Boolean isNotYetValid(Date validFromDate) {
// The note in `hasExpired` does not apply here, since the bug was fixed before this feature was added.
return validFromDate.after(getStartOfToday().getTime());
@@ -276,6 +393,7 @@ public class Utils {
static public String formatBalance(Context context, BigDecimal value, Currency currency) {
NumberFormat numberFormat = NumberFormat.getInstance();
numberFormat.setGroupingUsed(false);
if (currency == null) {
numberFormat.setMaximumFractionDigits(0);
@@ -283,6 +401,7 @@ public class Utils {
}
NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
currencyFormat.setGroupingUsed(false);
currencyFormat.setCurrency(currency);
currencyFormat.setMinimumFractionDigits(currency.getDefaultFractionDigits());
currencyFormat.setMaximumFractionDigits(currency.getDefaultFractionDigits());
@@ -292,6 +411,7 @@ public class Utils {
static public String formatBalanceWithoutCurrencySymbol(BigDecimal value, Currency currency) {
NumberFormat numberFormat = NumberFormat.getInstance();
numberFormat.setGroupingUsed(false);
if (currency == null) {
numberFormat.setMaximumFractionDigits(0);
@@ -304,19 +424,72 @@ public class Utils {
return numberFormat.format(value);
}
private static final double LargestPreciseDouble = (double) (1l << 53);
static{
assert (LargestPreciseDouble + 1.0) == LargestPreciseDouble;
assert (LargestPreciseDouble - 1.0) != LargestPreciseDouble;
}
private static BigDecimal fromParsed(Number parsed){
if(parsed instanceof BigDecimal)
return (BigDecimal) parsed;
final double d = parsed.doubleValue();
if(d >= LargestPreciseDouble)
return new BigDecimal(parsed.longValue());
return new BigDecimal(d);
}
static public BigDecimal parseBalance(String value, Currency currency) throws ParseException {
// This function expects the input string to not have any grouping (thousand separators).
// It will refuse to work otherwise
NumberFormat numberFormat = NumberFormat.getInstance();
numberFormat.setGroupingUsed(false);
if (numberFormat instanceof DecimalFormat) {
((DecimalFormat) numberFormat).setParseBigDecimal(true);
}
if (currency == null) {
numberFormat.setMaximumFractionDigits(0);
} else {
numberFormat.setMinimumFractionDigits(currency.getDefaultFractionDigits());
numberFormat.setMaximumFractionDigits(currency.getDefaultFractionDigits());
int fractionDigits = currency.getDefaultFractionDigits();
numberFormat.setMinimumFractionDigits(fractionDigits);
numberFormat.setMaximumFractionDigits(fractionDigits);
if (numberFormat instanceof DecimalFormat) {
// If the string contains both thousand separators and decimals separators, fail hard
DecimalFormatSymbols decimalFormatSymbols = ((DecimalFormat) numberFormat).getDecimalFormatSymbols();
char decimalSeparator = decimalFormatSymbols.getDecimalSeparator();
// Translate all non-digits to decimal separators, failing if we find more than 1.
// We loop over the codepoints to make sure eastern arabic numerals are not mistakenly
// treated as a separator.
boolean separatorFound = false;
StringBuilder translatedValue = new StringBuilder();
for (int i = 0; i < value.length();) {
int character = value.codePointAt(i);
if (Character.isDigit(character)) {
translatedValue.append(value.charAt(i));
} else {
if (separatorFound) {
throw new ParseException("Contains multiple separators", i);
}
separatorFound = true;
translatedValue.append(decimalSeparator);
}
i += Character.charCount(character);
}
value = translatedValue.toString();
}
}
Log.d(TAG, numberFormat.parse(value).toString());
return new BigDecimal(numberFormat.parse(value).toString());
return fromParsed(numberFormat.parse(value));
}
static public byte[] bitmapToByteArray(Bitmap bitmap) {
@@ -748,23 +921,30 @@ public class Utils {
.replaceAll("(?<!href=\")\\b(https?://[\\w@#%&+=:?/.-]*[\\w@#%&+=:?/-])", "<a href=\"$1\">$1</a>");
}
public static void setIconOrTextWithBackground(Context context, LoyaltyCard loyaltyCard, Bitmap icon, ImageView backgroundOrIcon, TextView textWhenNoImage) {
if (icon != null) {
Log.d("onResume", "setting icon image");
textWhenNoImage.setVisibility(View.GONE);
/**
* Sets an icon or text with background on the given ImageView and/or TextView, including background colour.
*
* @param context Android context
* @param loyaltyCard Loyalty Card
* @param icon Bitmap of the icon to set, or null
* @param backgroundOrIcon ImageView to draw the icon and background on to
* @param textWhenNoImage TextView to write the loyalty card name into if icon is null
* @return background colour
*/
public static int setIconOrTextWithBackground(Context context, LoyaltyCard loyaltyCard, Bitmap icon, ImageView backgroundOrIcon, TextView textWhenNoImage) {
int headerColor = getHeaderColor(context, loyaltyCard);
backgroundOrIcon.setImageBitmap(icon);
backgroundOrIcon.setBackgroundColor(headerColor);
backgroundOrIcon.setImageBitmap(icon);
backgroundOrIcon.setBackgroundColor(Color.TRANSPARENT);
if (icon != null) {
textWhenNoImage.setVisibility(View.GONE);
} else {
textWhenNoImage.setVisibility(View.VISIBLE);
int headerColor = getHeaderColor(context, loyaltyCard);
backgroundOrIcon.setImageBitmap(null);
backgroundOrIcon.setBackgroundColor(headerColor);
textWhenNoImage.setText(loyaltyCard.store);
textWhenNoImage.setTextColor(Utils.needsDarkForeground(headerColor) ? Color.BLACK : Color.WHITE);
}
return headerColor;
}
public static boolean installedFromGooglePlay(Context context) {

View File

@@ -0,0 +1,212 @@
package protect.card_locker.importexport;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.work.Data;
import androidx.work.ForegroundInfo;
import androidx.work.WorkManager;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import protect.card_locker.DBHelper;
import protect.card_locker.NotificationHelper;
import protect.card_locker.R;
public class ImportExportWorker extends Worker {
private final String TAG = "Catima";
public static final String INPUT_URI = "uri";
public static final String INPUT_ACTION = "action";
public static final String INPUT_FORMAT = "format";
public static final String INPUT_PASSWORD = "password";
public static final String ACTION_IMPORT = "import";
public static final String ACTION_EXPORT = "export";
public static final String OUTPUT_ERROR_REASON = "errorReason";
public static final String ERROR_GENERIC = "errorTypeGeneric";
public static final String ERROR_PASSWORD_REQUIRED = "errorTypePasswordRequired";
public static final String OUTPUT_ERROR_DETAILS = "errorDetails";
public ImportExportWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
Log.e("CATIMA", "Started import/export worker");
Context context = getApplicationContext();
Data inputData = getInputData();
String uriString = inputData.getString(INPUT_URI);
String action = inputData.getString(INPUT_ACTION);
String format = inputData.getString(INPUT_FORMAT);
String password = inputData.getString(INPUT_PASSWORD);
if (action.equals(ACTION_IMPORT)) {
Log.e("CATIMA", "Import requested");
setForegroundAsync(createForegroundInfo(NotificationHelper.CHANNEL_IMPORT, NotificationHelper.IMPORT_PROGRESS_ID, R.string.importing));
ImportExportResult result;
InputStream stream;
try {
stream = context.getContentResolver().openInputStream(Uri.parse(uriString));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
final SQLiteDatabase database = new DBHelper(context).getWritableDatabase();
try {
InputStreamReader writer = new InputStreamReader(stream, StandardCharsets.UTF_8);
result = MultiFormatImporter.importData(context, database, stream, DataFormat.valueOf(format), password.toCharArray());
writer.close();
} catch (IOException e) {
Log.e(TAG, "Unable to import file", e);
NotificationHelper.sendNotification(context, NotificationHelper.IMPORT_ID, NotificationHelper.createNotificationBuilder(context, NotificationHelper.CHANNEL_IMPORT, R.drawable.ic_import_export_white_24dp, context.getString(R.string.importFailedTitle), e.getLocalizedMessage()).build());
Data failureData = new Data.Builder()
.putString(OUTPUT_ERROR_REASON, ERROR_GENERIC)
.putString(OUTPUT_ERROR_DETAILS, e.getLocalizedMessage())
.putString(INPUT_URI, uriString)
.putString(INPUT_ACTION, action)
.putString(INPUT_FORMAT, format)
.putString(INPUT_PASSWORD, password)
.build();
return Result.failure(failureData);
}
Log.i(TAG, "Import result: " + result);
if (result.resultType() == ImportExportResultType.Success) {
NotificationHelper.sendNotification(context, NotificationHelper.IMPORT_ID, NotificationHelper.createNotificationBuilder(context, NotificationHelper.CHANNEL_IMPORT, R.drawable.ic_import_export_white_24dp, context.getString(R.string.importSuccessfulTitle), context.getString(R.string.importSuccessful)).build());
return Result.success();
} else if (result.resultType() == ImportExportResultType.BadPassword) {
Log.e(TAG, "Needs password, unhandled for now");
NotificationHelper.sendNotification(context, NotificationHelper.IMPORT_ID, NotificationHelper.createNotificationBuilder(context, NotificationHelper.CHANNEL_IMPORT, R.drawable.ic_import_export_white_24dp, context.getString(R.string.importing), context.getString(R.string.passwordRequired)).build());
Data failureData = new Data.Builder()
.putString(OUTPUT_ERROR_REASON, ERROR_PASSWORD_REQUIRED)
.putString(OUTPUT_ERROR_DETAILS, result.developerDetails())
.putString(INPUT_URI, uriString)
.putString(INPUT_ACTION, action)
.putString(INPUT_FORMAT, format)
.putString(INPUT_PASSWORD, password)
.build();
return Result.failure(failureData);
} else {
NotificationHelper.sendNotification(context, NotificationHelper.IMPORT_ID, NotificationHelper.createNotificationBuilder(context, NotificationHelper.CHANNEL_IMPORT, R.drawable.ic_import_export_white_24dp, context.getString(R.string.importFailedTitle), context.getString(R.string.importFailed)).build());
Data failureData = new Data.Builder()
.putString(OUTPUT_ERROR_REASON, ERROR_GENERIC)
.putString(OUTPUT_ERROR_DETAILS, result.developerDetails())
.putString(INPUT_URI, uriString)
.putString(INPUT_ACTION, action)
.putString(INPUT_FORMAT, format)
.putString(INPUT_PASSWORD, password)
.build();
return Result.failure(failureData);
}
} else {
Log.e("CATIMA", "Export requested");
setForegroundAsync(createForegroundInfo(NotificationHelper.CHANNEL_EXPORT, NotificationHelper.EXPORT_PROGRESS_ID, R.string.exporting));
ImportExportResult result;
OutputStream stream;
try {
stream = context.getContentResolver().openOutputStream(Uri.parse(uriString));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
final SQLiteDatabase database = new DBHelper(context).getReadableDatabase();
try {
OutputStreamWriter writer = new OutputStreamWriter(stream, StandardCharsets.UTF_8);
result = MultiFormatExporter.exportData(context, database, stream, DataFormat.valueOf(format), password.toCharArray());
writer.close();
} catch (IOException e) {
Log.e(TAG, "Unable to export file", e);
NotificationHelper.sendNotification(context, NotificationHelper.EXPORT_ID, NotificationHelper.createNotificationBuilder(context, NotificationHelper.CHANNEL_EXPORT, R.drawable.ic_import_export_white_24dp, context.getString(R.string.exportFailedTitle), e.getLocalizedMessage()).build());
Data failureData = new Data.Builder()
.putString(OUTPUT_ERROR_REASON, ERROR_GENERIC)
.putString(OUTPUT_ERROR_DETAILS, e.getLocalizedMessage())
.putString(INPUT_URI, uriString)
.putString(INPUT_ACTION, action)
.putString(INPUT_FORMAT, format)
.putString(INPUT_PASSWORD, password)
.build();
return Result.failure(failureData);
}
Log.i(TAG, "Export result: " + result);
if (result.resultType() == ImportExportResultType.Success) {
NotificationHelper.sendNotification(context, NotificationHelper.EXPORT_ID, NotificationHelper.createNotificationBuilder(context, NotificationHelper.CHANNEL_EXPORT, R.drawable.ic_import_export_white_24dp, context.getString(R.string.exportSuccessfulTitle), context.getString(R.string.exportSuccessful)).build());
return Result.success();
} else {
NotificationHelper.sendNotification(context, NotificationHelper.EXPORT_ID, NotificationHelper.createNotificationBuilder(context, NotificationHelper.CHANNEL_EXPORT, R.drawable.ic_import_export_white_24dp, context.getString(R.string.exportFailedTitle), context.getString(R.string.exportFailed)).build());
Data failureData = new Data.Builder()
.putString(OUTPUT_ERROR_REASON, ERROR_GENERIC)
.putString(OUTPUT_ERROR_DETAILS, result.developerDetails())
.putString(INPUT_URI, uriString)
.putString(INPUT_ACTION, action)
.putString(INPUT_FORMAT, format)
.putString(INPUT_PASSWORD, password)
.build();
return Result.failure(failureData);
}
}
}
@NonNull
private ForegroundInfo createForegroundInfo(@NonNull String channel, int notificationId, int title) {
Context context = getApplicationContext();
String cancel = context.getString(R.string.cancel);
// This PendingIntent can be used to cancel the worker
PendingIntent intent = WorkManager.getInstance(context)
.createCancelPendingIntent(getId());
Notification.Builder notificationBuilder = NotificationHelper.createNotificationBuilder(context, channel, R.drawable.ic_import_export_white_24dp, context.getString(title), null);
Notification notification = notificationBuilder
.setOngoing(true)
// Add the cancel action to the notification which can
// be used to cancel the worker
.addAction(android.R.drawable.ic_delete, cancel, intent)
.build();
return new ForegroundInfo(notificationId, notification);
}
}

View File

@@ -45,7 +45,7 @@ public class MultiFormatImporter {
break;
}
String error = null;
String error;
if (importer != null) {
File inputFile;
try {

View File

@@ -10,7 +10,8 @@
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
@@ -20,11 +21,12 @@
</com.google.android.material.appbar.AppBarLayout>
<ScrollView
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:padding="10dp">
android:paddingVertical="8dp"
android:clipToPadding="false">
<LinearLayout
android:layout_width="match_parent"
@@ -35,7 +37,9 @@
android:id="@+id/version_history"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/version_history_main"
@@ -74,7 +78,9 @@
android:id="@+id/credits"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/credits_main"
@@ -113,7 +119,9 @@
android:id="@+id/translate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/translate_main"
@@ -153,7 +161,9 @@
android:id="@+id/license"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/license_main"
@@ -193,7 +203,9 @@
android:id="@+id/repo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/repo_main"
@@ -233,7 +245,9 @@
android:id="@+id/privacy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/privacy_main"
@@ -273,7 +287,9 @@
android:id="@+id/donate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/donate_main"
@@ -284,6 +300,7 @@
android:text="@string/donate"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
@@ -303,7 +320,9 @@
android:id="@+id/rate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/rate_main"
@@ -340,10 +359,12 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:padding="8dp"
android:id="@+id/report_error"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/report_error_main"
@@ -379,5 +400,5 @@
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</ScrollView>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -31,13 +31,6 @@
android:layout_height="?attr/actionBarSize"
style="?attr/toolbarStyle" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/groups"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:tabMode="scrollable" />
</com.google.android.material.appbar.AppBarLayout>

View File

@@ -7,7 +7,8 @@
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
@@ -17,11 +18,11 @@
</com.google.android.material.appbar.AppBarLayout>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent"
@@ -127,7 +128,7 @@
android:layout_marginTop="8dp"
android:text="@string/importOptionApplicationButton" />
</LinearLayout>
</ScrollView>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -18,7 +18,8 @@
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
@@ -29,7 +30,8 @@
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:background="@android:color/transparent">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -46,9 +48,10 @@
</com.google.android.material.appbar.AppBarLayout>
<ScrollView android:layout_width="fill_parent"
android:layout_height="wrap_content"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.core.widget.NestedScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -473,6 +476,6 @@
</LinearLayout>
</TableLayout>
</TableLayout>
</ScrollView>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -121,7 +121,7 @@
android:layout_weight="1"/>
<TextView
android:id="@+id/card_id_view"
android:id="@+id/main_image_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/text_size_large"

View File

@@ -19,7 +19,8 @@
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
@@ -31,6 +32,7 @@
android:id="@+id/groups"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
app:tabMode="scrollable"
android:visibility="gone"/>

View File

@@ -19,7 +19,8 @@
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"

View File

@@ -8,7 +8,8 @@
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"

View File

@@ -8,7 +8,8 @@
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"

View File

@@ -1,14 +1,14 @@
Sylvia van Os
Branden Archer
J. Lavoie
Allan Nordhøy
solokot
Allan Nordhøy
Heimen Stoffels
FC (Fay) Stegerman
Oğuz Ersen
FC (Fay) Stegerman
Katharine Chui
SlavekB
StoyanDimitrov
SlavekB
mondstern
IllusiveMan196
Altonss
@@ -23,29 +23,33 @@ pfaffenrodt
Aayush Gupta
HudobniVolk
Nyatsuki
Giovanni Donisi
Jiri Grönroos
大王叫我来巡山
Samantaz Fox
arno-github
Cliff Heraldo
Sergio Paredes
Ankit Tiwari
Milan Šalka
Jiri Grönroos
Balázs Meskó
Giovanni Donisi
Scrambled777
Milo Ivir
Milan Šalka
mdvhimself
Balázs Meskó
Skrripy
huuhaa
waffshappen
ikanakova
Projjal Moitra
Quentin PAGÈS
waffshappen
Eryk Michalak
Ziad OUALHADJ
Robin Liu
mdvhimself
Denis Shilin
Robin Liu
Ziad OUALHADJ
ngocanhtve
Alexander Ivanov
Miha Frangež
Viet Nguyen Hoang
Silvério Santos
ikanakova
Virginie
Michael Gangolf
rudy3
@@ -53,4 +57,4 @@ Kim Seohyun
Govind S Nair
Freddo espresso
arshbeerSingh
Alexander Ivanov
MisterCosta96

View File

@@ -251,7 +251,7 @@
<string name="barcodeLongPressMessage">يمكن فتح صور فقط في تطبيق معرض الصور</string>
<string name="failedToOpenUrl">ثبت متصفح ويب أولاً</string>
<string name="welcome">مرحبا بك في كاتيما</string>
<string name="updateBalanceTitle">كم أنفقت؟</string>
<string name="updateBalanceTitle">كم أنفقت أو استلمت؟</string>
<string name="currentBalanceSentence">الرصيد الحالي: <xliff:g> %s </xliff:g></string>
<plurals name="viewArchivedCardsWithCount">
<item quantity="zero">عرض الأرشيف (<xliff:g>%1$d</xliff:g> بطاقة)</item>
@@ -312,4 +312,15 @@
<string name="field_must_not_be_empty">يجب ألا يكون الحقل فارغا</string>
<string name="app_name">كاتيما</string>
<string name="settings_follow_sensor_orientation">التدوير دائمًا ( تجاهل إعدادات النظام)</string>
<string name="add_manually_warning_title">الفحص موصى به</string>
<string name="continue_">استمر</string>
<string name="spend">انفق</string>
<string name="receive">استلم</string>
<string name="amountParsingFailed">كمية غير صحيحة</string>
<string name="add_manually_warning_message">في بعض المتاجر قيمة الباركود تختلف عن الرقم الموجود على البطاقة. لهذا السبب إدخال الباركود يدوياً لن ينجح دائماً. من المستحسن فحص الباركود بكاميرا بدلا من ذالك. هل انت مُصِر على الاستكمال؟</string>
<string name="addFromPdfFile">تحديد ملف PDF</string>
<string name="errorReadingFile">لا يمكن قراءة الملف</string>
<string name="failedLaunchingFileManager">لم يتم العثور على مدير ملفات مدعوم</string>
<string name="multipleBarcodesFoundPleaseChooseOne">اي من الـbarcodes تريد استخدامه؟</string>
<string name="pageWithNumber">صفحة<xliff:g>%d</xliff:g></string>
</resources>

View File

@@ -233,7 +233,7 @@
<string name="barcodeLongPressMessage">В приложението галерия могат да бъдат отваряни само изображения</string>
<string name="failedToRetrieveImageFile">Не е възможно извличане на изображение</string>
<string name="noCameraPermissionDirectToSystemSetting">За да сканирате щрихкодове с Catima е необходим достъп до камерата. За да промените разрешението докоснете тук.</string>
<string name="updateBalanceTitle">Каква е промяната\?</string>
<string name="updateBalanceTitle">Колко е похарчено или получено?</string>
<string name="updateBalanceHint">Въведете стойност</string>
<string name="newBalanceSentence">Нов баланс: <xliff:g>%s</xliff:g></string>
<string name="cameraPermissionDeniedTitle">Камерата е недостъпна</string>
@@ -284,4 +284,15 @@
<string name="field_must_not_be_empty">Полето не трябва да е празно</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Винаги да се завърта (пренебрегва системната настройка)</string>
<string name="continue_">Продължаване</string>
<string name="add_manually_warning_title">Препоръчително е да сканирате</string>
<string name="add_manually_warning_message">Стойностите от щрихкода и отбелязаните на картата числа в някои случаи се различават. По тази причина е при ръчно въвеждане картата може да не работи. Силно препоръчително е да сканирате щрихкода с камерата. Желаете ли да продължите въпреки това?</string>
<string name="amountParsingFailed">Неприемлива сума</string>
<string name="spend">Похарчено</string>
<string name="receive">Получено</string>
<string name="pageWithNumber">Страница <xliff:g>%d</xliff:g></string>
<string name="addFromPdfFile">Изберете PDF</string>
<string name="errorReadingFile">Файлът не може да бъде прочетен</string>
<string name="failedLaunchingFileManager">Не е намерено приложение за управление на файлове</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Кой от намерените щрихкодове желаете да бъде използван?</string>
</resources>

View File

@@ -243,7 +243,7 @@
<string name="unarchive">সংরক্ষণাগারমুক্ত করুন</string>
<string name="archived">কার্ড সংরক্ষণাগারভুক্ত</string>
<string name="welcome">Catima-তে স্বাগতম</string>
<string name="updateBalanceTitle">আপনি কত খরচ করেছেন\?</string>
<string name="updateBalanceTitle">আপনি কত খরচ করেছেন?</string>
<string name="updateBalanceHint">পরিমান লিখুন</string>
<string name="currentBalanceSentence">বর্তমান ব্যালেন্স: <xliff:g>%s</xliff:g></string>
<string name="show_name_below_image_thumbnail">ছবির থাম্বনেইল এর নিচে নামটি দেখান</string>

View File

@@ -2,13 +2,13 @@
<resources>
<string name="save">Snimi</string>
<string name="cancel">Odustani</string>
<string name="unstar">Ukloni sve omiljene</string>
<string name="star">Omiljene</string>
<string name="barcodeType">Barcode tip</string>
<string name="note">Bilježnica</string>
<string name="unstar">Ukloni iz omiljenih</string>
<string name="star">Dodaj u omiljene</string>
<string name="barcodeType">Tip barkoda</string>
<string name="note">Zabilješka</string>
<string name="storeName">Ime</string>
<string name="noMatchingGiftCards">Nema rezultata. Pokušaj promijeniti pretragu.</string>
<string name="noGiftCards">Kliknite + Plus dugme da dodate kartu ili uvozite nešto iz menija prvo.</string>
<string name="noGiftCards">Kliknite + Plus dugme da dodate kartu ili uvezete nešto iz menija prvo.</string>
<string name="action_add">Dodaj</string>
<string name="all">Sve</string>
<string name="noGroupCards">Ova grupa ne sadrži nikakve karte</string>
@@ -104,4 +104,6 @@
<string name="importOptionApplicationExplanation">Koristi bilo koju aplikaciju ili Vašu omiljenu aplikaciju da bi otvorili file.</string>
<string name="importOptionApplicationButton">Koristi drugu aplikaciju</string>
<string name="about">O</string>
</resources>
<string name="noBarcode">Nema barkoda</string>
<string name="deleteTitle">Obriši karticu</string>
</resources>

View File

@@ -243,7 +243,7 @@
<string name="updateBalance">Aktualizovat zůstatek</string>
<string name="currentBalanceSentence">Současný zůstatek: <xliff:g>%s</xliff:g></string>
<string name="noCameraPermissionDirectToSystemSetting">Pro skenování čárových kódů bude Catima potřebovat přístup k fotoaparátu. Klepněte zde pro změnu nastavení oprávnění.</string>
<string name="updateBalanceTitle">Kolik jste utratil\?</string>
<string name="updateBalanceTitle">Kolik jste utratil/a nebo obdržel/a?</string>
<string name="updateBalanceHint">Zadejte výši</string>
<string name="newBalanceSentence">Nový zůstatek: <xliff:g>%s</xliff:g></string>
<string name="storageReadPermissionRequired">Pro tuto akci je potřeba oprávnění ke čtení úložiště…</string>
@@ -291,4 +291,15 @@
<string name="field_must_not_be_empty">Položka nesmí být prázdná</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Vždy otáčet (ignoruje nastavení systému)</string>
<string name="continue_">Pokračovat</string>
<string name="add_manually_warning_title">Doporučuje se skenování</string>
<string name="add_manually_warning_message">V některých obchodech se hodnota čárového kódu liší od čísla napsaného na kartě. Z tohoto důvodu nemusí ruční zadání čárového kódu vždy fungovat. Důrazně doporučujeme místo toho naskenovat čárový kód pomocí fotoaparátu. Chcete přesto pokračovat?</string>
<string name="spend">Utratit</string>
<string name="receive">Obdržet</string>
<string name="amountParsingFailed">Neplatné množství</string>
<string name="addFromPdfFile">Vybrat soubor PDF</string>
<string name="errorReadingFile">Soubor nelze přečíst</string>
<string name="pageWithNumber">Stránka <xliff:g>%d</xliff:g></string>
<string name="multipleBarcodesFoundPleaseChooseOne">Který z nalezených čárových kódů chcete použít?</string>
<string name="failedLaunchingFileManager">Nelze nalézt podporovaný správce souborů</string>
</resources>

View File

@@ -231,7 +231,7 @@
<string name="welcome">Willkommen bei Catima</string>
<string name="barcodeLongPressMessage">In der Galerie können nur Bilder geöffnet werden</string>
<string name="failedToRetrieveImageFile">Bilddatei konnte nicht abgerufen werden</string>
<string name="updateBalanceTitle">Wie viel haben Sie ausgegeben\?</string>
<string name="updateBalanceTitle">Wie viel hast du ausgegeben oder erhalten?</string>
<string name="cameraPermissionDeniedTitle">Kein Zugriff auf die Kamera möglich</string>
<string name="noCameraPermissionDirectToSystemSetting">Um Strichcodes zu scannen, benötigt Catima Zugriff auf Ihre Kamera. Tippen Sie hier, um Ihre Berechtigungseinstellungen zu ändern.</string>
<string name="updateBalanceHint">Betrag eingeben</string>
@@ -284,4 +284,15 @@
<string name="manually_enter_barcode_instructions">Trage die ID Nummer oder Text deiner Karte ein und drücke auf den Barcode, der wie auf deiner Karte aussieht.</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Immer drehen (ignoriert Systemeinstellungen)</string>
<string name="continue_">Fortfahren</string>
<string name="add_manually_warning_title">Es wird empfohlen, zu scannen</string>
<string name="add_manually_warning_message">In einigen Geschäften weicht der Wert des Barcodes von dem auf der Karte angegebenen Wert ab. Aus diesem Grund funktioniert die manuelle Eingabe des Barcodes in einigen Fällen nicht. Es wird dringend empfohlen, den Barcode mit einer Kamera zu scannen. Möchtest du dennoch fortfahren?</string>
<string name="spend">Zahlen</string>
<string name="receive">Erhalten</string>
<string name="amountParsingFailed">Ungültiger Betrag</string>
<string name="addFromPdfFile">PDF-Datei auswählen</string>
<string name="errorReadingFile">Datei konnte nicht gelesen werden</string>
<string name="failedLaunchingFileManager">Konnte keinen unterstützten Dateimanager finden</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Welchen der gefundenen Barcodes möchten Sie verwenden?</string>
<string name="pageWithNumber">Seite <xliff:g>%d</xliff:g></string>
</resources>

View File

@@ -14,13 +14,13 @@
<string name="sendLabel">Αποστολή…</string>
<string name="editCardTitle">Επεξεργασία Κάρτας</string>
<string name="addCardTitle">Προσθήκη Κάρτας</string>
<string name="scanCardBarcode">Σαρώστε τον γραμμοκώδικα (bardcode)</string>
<string name="scanCardBarcode">Σαρώστε τον γραμμωτό κώδικα</string>
<string name="cardShortcut">Συντόμευση Κάρτας</string>
<string name="noCardsMessage">Προσθέστε μία κάρτα πρώτα</string>
<string name="noCardExistsError">Δεν ήταν δυνατό να εντοπιστεί η κάρτα</string>
<string name="importExport">Εισαγωγή/Εξαγωγή</string>
<string name="exportName">Εξαγωγή</string>
<string name="importExportHelp">Τα αντίγραφα ασφαλείας, σας επιτρέπουν να τα εισάγετε σε άλλη συσκευή.</string>
<string name="importExportHelp">Τα αντίγραφα ασφαλείας σας επιτρέπουν να τα εισάγετε σε άλλη συσκευή.</string>
<string name="importSuccessfulTitle">Εισήχθησαν</string>
<string name="importFailedTitle">Εισαγωγή ανεπιτυχής</string>
<string name="importFailed">Δεν ήταν δυνατή η εισαγωγή</string>
@@ -39,7 +39,7 @@
<string name="app_license">Άδεια χρήσης υπό GPLv3+</string>
<string name="about_title_fmt">Σχετικά με <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Έκδοση: <xliff:g id="version">%s</xliff:g></string>
<string name="selectBarcodeTitle">Επιλέξτε Barcode</string>
<string name="selectBarcodeTitle">Επιλέξτε γραμμωτό κώδικα</string>
<string name="thumbnailDescription">Μικρογραφία</string>
<string name="settings">Ρυθμίσεις</string>
<string name="settings_dark_theme">Σκοτεινό</string>
@@ -54,7 +54,7 @@
<item quantity="other"><xliff:g>%d</xliff:g> επιλέγχθηκαν</item>
</plurals>
<string name="noGiftCardsGroup">Δημιούργησε κάρτες και βάλτες σε αυτή την ομάδα.</string>
<string name="addManually">Χειροκίνητη εισαγωγή κωδικού</string>
<string name="addManually">Εισαγάγετε τον γραμμωτό κώδικα με μη αυτόματο τρόπο</string>
<string name="never">Ποτέ</string>
<string name="share">Κοινοποίηση</string>
<plurals name="balancePoints">
@@ -64,14 +64,14 @@
<string name="exportOptionExplanation">Τα δεδομένα θα μεταφερθούν σε τοποθεσία της επιλογής σας.</string>
<string name="settings_theme">Θέμα</string>
<string name="groupsList">Ομάδες: <xliff:g>%s</xliff:g></string>
<string name="barcodeId">Τιμή γραμμοκώδικα</string>
<string name="barcodeId">Τιμή γραμμωτού κώδικα</string>
<string name="sort">Ταξινόμηση</string>
<string name="deleteConfirmationGroup">Διαγραφή ομάδας;</string>
<string name="moveDown">Προχώρα κάτω</string>
<string name="accept">Αποδοχή</string>
<string name="yes">Ναι</string>
<string name="no">Όχι</string>
<string name="addFromImage">Επιλογή εικόνας από την συλλογή</string>
<string name="addFromImage">Επιλέξτε μια εικόνα από τη συλλογή</string>
<string name="expiryStateSentence">Λήγει: <xliff:g>%s</xliff:g></string>
<string name="expiryDate">Ημερομηνία λήξης</string>
<string name="settings_keep_screen_on">Κράτα την οθόνη ανοιχτή</string>
@@ -91,18 +91,18 @@
<string name="importLoyaltyCardKeychainMessage">Επιλέξτε την <i>LoyaltyCardKeychain.csv</i> εξαγωγή από το Loyalty Card Keychain για εισαγωγή.
\nΔημιουργήστε το από το μενού Εισαγωγής/Εξαγωγής στο Loyalty Card Keychain επιλέγοντας Εξαγωγή.</string>
<string name="importFidme">Εισαγωγή από FidMe</string>
<string name="importFidmeMessage">Επιλέξτε την <i>fidme-export-request-xxxxxx.zip</i> εξαγωγή από το FidMe για εισαγωγή και επιλέξτε χειροκίνητα τους τύπους γραμμοκώδικα μετέπειτα.
<string name="importFidmeMessage">Επιλέξτε την <i>fidme-export-request-xxxxxx.zip</i> εξαγωγή από το FidMe για εισαγωγή και επιλέξτε χειροκίνητα τους τύπους γραμμωτού κώδικα μετέπειτα.
\nΔημιουργήστε το από το FidMe προφίλ επιλέγοντας Προστασία Δεδομένων και διαλέγοντας εξαγωγή δεδομένων.</string>
<string name="setBarcodeId">Επιλέξτε τιμή γραμμοκώδικα</string>
<string name="wrongValueForBarcodeType">Η τιμή δεν είναι έγκυρη για αυτού του τύπου γραμμοκώδικα</string>
<string name="setBarcodeId">Επιλέξτε τιμή γραμμωτού κώδικα</string>
<string name="wrongValueForBarcodeType">Η τιμή δεν είναι έγκυρη για τον επιλεγμένο γραμμωτό κώδικα</string>
<string name="setBackImage">Επιλογή οπίσθιας εικόνας</string>
<string name="removeImage">Αφαίρεση εικόνας</string>
<string name="takePhoto">Τραβήξτε μια φωτογραφία</string>
<string name="updateBarcodeQuestionText">Αλλάξατε τον κωδικό. Θέλετε να ενημερώσετε και τον γραμμοκώδικα στην ίδια τιμή;</string>
<string name="updateBarcodeQuestionText">Αλλάξατε τον κωδικό. Θέλετε να ενημερώσετε και τον γραμμωτό κώδικα στην ίδια τιμή;</string>
<string name="options">Επιλογές</string>
<string name="noGroupCards">Αυτή η ομάδα είναι άδεια</string>
<string name="settings_display_barcode_max_brightness">Επιπλέον φωτισμός γραμμοκώδικα</string>
<string name="group_name_is_empty">Το όνομα ομάδας δεν γίνεται να είναι κενό</string>
<string name="settings_display_barcode_max_brightness">Επιπλέον φωτισμός γραμμωτού κώδικα</string>
<string name="group_name_is_empty">Το όνομα της ομάδας δεν πρέπει να είναι κενό</string>
<string name="group_edit">Επεξεργασία ομάδας</string>
<string name="star">Προσθήκη στα αγαπημένα</string>
<string name="unstar">Αφαίρεση από τα αγαπημένα</string>
@@ -114,7 +114,7 @@
<string name="currency">Νόμισμα</string>
<string name="privacy_policy">Πολιτική απορρήτου</string>
<string name="chooseImportType">Εισαγωγή δεδομένων από</string>
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
<string name="app_loyalty_card_keychain">Lοyalty Card Keychain</string>
<string name="privacy_policy_popup_text">Σημείωμα πολιτικής απορρήτου ( υποχρεωτικό σε κάποια \"μαγαζιά\" εφαρμογών)
\n
\nΜΗΔΕΝΙΚΆ ΔΕΔΟΜΈΝΑ ΣΥΛΛΈΓΟΝΤΑΙ, ο οποιοσδήποτε μπορεί να το επιβεβαιώσει μιας και η εφαρμογή είναι ελεύθερο λογισμικό.</string>
@@ -131,21 +131,21 @@
<string name="setFrontImage">Επιλογή μπροστινής εικόνας</string>
<string name="importVoucherVaultMessage">Επιλέξτε την <i>vouchervault.json</i> εξαγωγή από το Voucher Vault για εισαγωγή.
\nΔημιουργήστε το επιλέγοντας Εξαγωγή στο Voucher Vault.</string>
<string name="unsupportedBarcodeType">Ο τύπος γραμμοκώδικα δεν γίνεται να εμφανιστεί ακόμα. Μπορεί να υποστηρίζεται σε μια μελλοντική έκδοση της εφαρμογής.</string>
<string name="unsupportedBarcodeType">Ο τύπος γραμμωτού κώδικα δεν μπορεί να εμφανιστεί ακόμα. Μπορεί να υποστηρίζεται σε μια μελλοντική έκδοση της εφαρμογής.</string>
<string name="frontImageDescription">Μπροστινή εικόνα</string>
<string name="photos">Φωτογραφίες</string>
<string name="backImageDescription">Οπίσθια εικόνα</string>
<string name="updateBarcodeQuestionTitle">Ενημέρωση τιμής γραμμοκώδικα;</string>
<string name="updateBarcodeQuestionTitle">Ενημέρωση τιμής γραμμωτού κώδικα;</string>
<string name="passwordRequired">Παρακαλώ εισάγετε τον κωδικό</string>
<string name="sort_by_most_recently_used">Χρησιμοποιήθηκαν πρόσφατα</string>
<string name="shortcutSelectCard">Επιλέξτε μία κάρτα</string>
<string name="barcodeImageDescriptionWithType">Εικόνα <xliff:g>%s</xliff:g> γραμμοκώδικα</string>
<string name="barcodeImageDescriptionWithType">Εικόνα <xliff:g>%s</xliff:g> γραμμωτού κώδικα</string>
<string name="app_libraries">Ελεύθερες βιβλιοθήκες τρίτων: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="license">Άδεια</string>
<string name="include_if_asking_support">Αν θέλετε να ζητήσετε υποστήριξη, συμπεριλάβετε τις ακόλουθες πληροφορίες:</string>
<string name="importSuccessful">Δεδομένα εισήχθησαν</string>
<string name="moveUp">Προχώρα πάνω</string>
<string name="barcodeType">Τύπος γραμμοκώδικα</string>
<string name="barcodeType">Τύπος γραμμωτού κώδικα</string>
<string name="app_resources">Ελεύθερες πηγές τρίτων: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="selectColor">Επιλογή χρώματος</string>
<string name="setIcon">Ορισμός εικονιδίου</string>
@@ -162,7 +162,7 @@
<string name="exportSuccessful">Δεδομένα εξήχθησαν</string>
<string name="settings_disable_lockscreen_while_viewing_card">Αποτροπή κλειδώματος οθόνης</string>
<string name="failedLaunchingPhotoPicker">Δεν βρέθηκε υποστηριζόμενη εφαρμογή συλλογής</string>
<string name="noBarcode">Χωρίς barcode</string>
<string name="noBarcode">Χωρίς γραμμωτό κώδικα</string>
<string name="starImage">Αγαπημένο αστέρι</string>
<string name="balanceSentence">Υπόλοιπο: <xliff:g>%s</xliff:g></string>
<string name="failedParsingImportUriError">Δεν ήταν δυνατή η ανάλυση του εισαγόμενου URL</string>
@@ -173,7 +173,7 @@
<string name="app_copyright_old">Βασισμένο στο Loyalty Card Keychain
\nπνευματικά δικαιώματα © 2016-2020 Branden Archer</string>
<string name="settings_follow_system_orientation">Ακολούθηση συστήματος</string>
<string name="settings_card_orientation">Προσανατολισμός γραμμοκώδικα</string>
<string name="settings_card_orientation">Προσανατολισμός γραμμωτού κώδικα</string>
<string name="settings_portrait_orientation">Πορτραίτο</string>
<string name="settings_landscape_orientation">Οριζόντια</string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Πνευματικά δικαιώματα © 2019-<xliff:g>%d</xliff:g> Sylvia van Os</string>
@@ -189,15 +189,15 @@
<string name="leaveWithoutSaveConfirmation">Έξοδος χωρίς αποθήκευση;</string>
<string name="expiryStateSentenceExpired">Έληξε: <xliff:g>%s</xliff:g></string>
<string name="card">Κάρτα</string>
<string name="editBarcode">Επεξεργασία γραμμοκώδικα</string>
<string name="editBarcode">Επεξεργασία γραμμωτού κώδικα</string>
<string name="chooseExpiryDate">Επιλέξτε ημερομηνία λήξης</string>
<string name="moveBarcodeToTopOfScreen">Μετακίνηση του γραμμοκώδικα στο πάνω μέρος της οθόνης</string>
<string name="noBarcodeFound">Δεν βρέθηκε γραμμοκώδικας</string>
<string name="moveBarcodeToTopOfScreen">Μετακίνηση του γραμμωτού κώδικα στο πάνω μέρος της οθόνης</string>
<string name="noBarcodeFound">Δεν βρέθηκε γραμμωτός κώδικα</string>
<string name="balance">Υπόλοιπο</string>
<string name="importCatima">Εισαγωγή από Catima</string>
<string name="importStocard">Εισαγωγή από Stocard</string>
<string name="importVoucherVault">Εισαγωγή από Voucher Vault</string>
<string name="sameAsCardId">Ίδιος κωδικός</string>
<string name="sameAsCardId">Όπως ο κωδικός</string>
<string name="exportPassword">Προσθέστε έναν κωδικό για προστασία της εξαγωγής (προαιρετικά)</string>
<string name="exportPasswordHint">Εισαγωγή κωδικού</string>
<string name="failedGeneratingShareURL">Δεν ήταν δυνατή η δημιουργία κοινοποιούμενου URL. Παρακαλώ αναφέρετε το.</string>
@@ -207,7 +207,7 @@
<string name="settings_oled_dark">Απόλυτο μαύρο φόντο για το μαύρο θέμα</string>
<string name="settings_system_locale">Σύστημα</string>
<string name="settings_theme_color">Χρώμα θέματος</string>
<string name="settings_catima_theme">Catima</string>
<string name="settings_catima_theme">Κάτιμα</string>
<string name="settings_pink_theme">Ροζ</string>
<string name="settings_magenta_theme">Φούξια</string>
<string name="settings_violet_theme">Βιολετί</string>
@@ -222,14 +222,14 @@
<string name="archived">Η κάρτα αρχειοθετήθηκε</string>
<string name="unarchived">Η κάρτα αφαιρέθηκε από το αρχείο</string>
<string name="unarchive">Αφαίρεση από το αρχείο</string>
<string name="updateBalanceTitle">Πόσα ξοδέψατε;</string>
<string name="updateBalanceTitle">Πόσα ξοδέψατε ή λάβατε;</string>
<string name="cameraPermissionDeniedTitle">Αδύνατη η πρόσβαση στην κάμερα</string>
<string name="failedToRetrieveImageFile">Αποτυχία ανάκτησης αρχείου εικόνας</string>
<string name="previousCard">Προηγούμενη</string>
<string name="nextCard">Επόμενη</string>
<string name="updateBalance">Ενημέρωση υπολοίπου</string>
<string name="barcodeLongPressMessage">Μόνο εικόνες μπορούν να ανοιχτούν στην εφαρμογή φωτογραφιών</string>
<string name="noCameraPermissionDirectToSystemSetting">Για να σκανάρετε γραμμοκώδικες, θα χρειαστεί πρόσβαση στην κάμερα από το Catima. Πατήστε εδώ για να δώσετε πρόσβαση.</string>
<string name="noCameraPermissionDirectToSystemSetting">Για να σκανάρετε γραμμωτούς κώδικες, θα χρειαστεί πρόσβαση στην κάμερα από το Catima. Πατήστε εδώ για να δώσετε πρόσβαση.</string>
<plurals name="viewArchivedCardsWithCount">
<item quantity="one">Προβολή αρχείου (<xliff:g>%1$d</xliff:g> κάρτας)</item>
<item quantity="other">Προβολή αρχείου (<xliff:g>%1$d</xliff:g> καρτών)</item>
@@ -240,8 +240,59 @@
<string name="newBalanceSentence">Νέο υπόλοιπο: <xliff:g>%s</xliff:g></string>
<string name="failedToOpenUrl">Εγκαταστήστε έναν περιηγητή πρώτα</string>
<string name="welcome">Καλώς ήρθατε στο Catima</string>
<string name="settings_disable_lockscreen_while_viewing_card_summary">Απενεργοποιεί το κλείδωμα οθόνης ενόσω βλέπετε μια κάρτα</string>
<string name="settings_display_barcode_max_brightness_summary">Απαραίτητο για να δουλέψει σε κάποια σκάνερ</string>
<string name="cameraPermissionRequired">Χρειάζεται άδεια για πρόσβαση στην κάμερα γι\' αυτή την ενέργεια…</string>
<string name="settings_allow_content_provider_read_title">Επιτρέπει σε άλλες εφαρμογές να έχουν πρόσβαση στα δεδομένα μου</string>
<string name="settings_disable_lockscreen_while_viewing_card_summary">Απενεργοποιεί το κλείδωμα οθόνης κατά την προβολή μιας κάρτας</string>
<string name="settings_display_barcode_max_brightness_summary">Απαραίτητο για να δουλέψει σε κάποιους σαρωτές</string>
<string name="cameraPermissionRequired">Δικαίωμα πρόσβασης στην κάμερα απαραίτητο γι\' αυτή την ενέργεια…</string>
<string name="settings_allow_content_provider_read_title">Να επιτρέπεται σε άλλες εφαρμογές να έχουν πρόσβαση στα δεδομένα μου</string>
<string name="app_copyright_short">Πνευματικά δικαιώματα © Sylvia van Os και συνεργάτες</string>
<string name="height">Ύψος:</string>
<string name="switchToFrontImage">Μετάβαση στην μπροστινή εικόνα</string>
<string name="switchToBackImage">Μετάβαση στην οπίσθια εικόνα</string>
<string name="switchToBarcode">Μετάβαση σε γραμμωτό κώδικα</string>
<string name="validFromSentence">Ισχύει από: <xliff:g>%s</xliff:g></string>
<string name="permissionReadCardsLabel">Διαβάστε τις κάρτες Catima</string>
<string name="openBackImageInGalleryApp">Ανοίξτε την οπίσθια εικόνα στην εφαρμογή γκαλερί</string>
<string name="permissionReadCardsDescription">Διάβασε τις Κάρτες σου Catima και όλες τους τις λεπτομέρειες, συμπεριλαμβανομένων των σημειώσεων και των εικόνων</string>
<string name="donate">Δωρεά</string>
<string name="icon_header_click_text">Πατήστε παρατεταμένα για επεξεργασία του εικονιδίου</string>
<string name="openFrontImageInGalleryApp">Ανοίξτε την μπροστινή εικόνα στην εφαρμογή γκαλερί</string>
<string name="storageReadPermissionRequired">Δικαίωμα ανάγνωσης του χώρου αποθήκευσης απαραίτητο για αυτήν την ενέργεια…</string>
<string name="settings_follow_sensor_orientation">Πάντα σε περιστροφή (αγνοεί τις ρυθμίσεις του συστήματος)</string>
<string name="validFromDate">Ισχύει από</string>
<string name="anyDate">Οποιαδήποτε ημερομηνία</string>
<string name="chooseValidFromDate">Επιλέξτε έγκυρη ημερομηνία από</string>
<string name="setBarcodeHeight">Ρυθμίστε το ύψος του γραμμωτού κώδικα</string>
<string name="show_name_below_image_thumbnail">Εμφάνιση ονόματος κάτω από το εικονίδιο</string>
<string name="app_name">Catima</string>
<string name="balanceParsingFailed">Μη έγκυρο υπόλοιπο</string>
<string name="continue_">Συνέχεια</string>
<string name="settings_category_title_privacy">Απόρρητο</string>
<string name="addFromPdfFile">Επιλογή αρχείου PDF</string>
<string name="add_manually_warning_message">Για ορισμένα καταστήματα, ο γραμμωτός κώδικας διαφέρει από τον αριθμό που αναγράφεται πάνω στην κάρτα. Εξαιτίας αυτού, η εισαγωγή γραμμωτού κώδικα χειροκίνητα ενδέχεται να μην λειτουργεί πάντα. Προτείνεται να σκανάρετε τον γραμμωτό κώδικα με χρήση της κάμερας. Επιθυμείτε να συνεχίσετε ;</string>
<string name="amountParsingFailed">Μη έγκυρο ποσό</string>
<string name="show_balance">Προβολή υπολοίπου</string>
<string name="action_display_options">Επιλογές εμφάνισης</string>
<string name="settings_category_title_cards">Κάρτες</string>
<string name="settings_category_title_general">Γενικά</string>
<string name="show_archived_cards">Προβολή αρχειοθετημένων καρτών</string>
<string name="addWithoutBarcode">Προσθήκη κάρτας χωρίς γραμμωτό κώδικα</string>
<string name="view_online">Προβολή διαδικτυακά</string>
<string name="errorReadingFile">Δεν ήταν δυνατή η ανάγνωση του αρχείου</string>
<string name="failedLaunchingFileManager">Δεν ήταν δυνατή η εύρεση υποστηριζόμενου διαχειριστή αρχείων</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Ποιους από τους γραμμωτούς κώδικες που βρέθηκαν θέλετε να χρησιμοποιήσετε;</string>
<string name="pageWithNumber">Σελίδα <xliff:g>%d</xliff:g></string>
<string name="spend">Δαπάνησε</string>
<string name="receive">Λήψη</string>
<string name="settings_keep_screen_on_summary">Απενεργοποιεί το χρονικό όριο της οθόνης κατά την προβολή μιας κάρτας</string>
<string name="settings_oled_dark_summary">Μειώνει τη χρήση της μπαταρίας στις οθόνες OLED</string>
<string name="show_note">Εμφάνιση σημείωσης</string>
<string name="action_more_options">Περισσότερες επιλογές</string>
<string name="enter_card_id">Εισαγάγετε τον κωδικό αριθμό ή το κείμενο στην κάρτα σας</string>
<string name="show_validity">Εμφάνιση εγκυρότητας</string>
<string name="add_a_card_in_a_different_way">Προσθέστε μια κάρτα με διαφορετικό τρόπο</string>
<string name="card_id_must_not_be_empty">Ο κωδικός αριθμός της κάρτας δεν πρέπει να είναι κενός</string>
<string name="settings_allow_content_provider_read_summary">Οι εφαρμογές θα πρέπει ακόμα να ζητήσουν άδεια για να τους δοθεί πρόσβαση</string>
<string name="field_must_not_be_empty">Το πεδίο δεν πρέπει να είναι κενό</string>
<string name="manually_enter_barcode_instructions">Εισαγάγετε τον κωδικό αριθμό ή το κείμενο στην κάρτα σας και πατήστε τον γραμμωτό κώδικα που μοιάζει με αυτόν της κάρτας σας.</string>
<string name="add_manually_warning_title">Συνιστάται η σάρωση</string>
</resources>

View File

@@ -4,7 +4,7 @@
<string name="noGiftCards">Haz clic en el botón + para añadir una tarjeta, o importa desde el menú ⋮.</string>
<string name="storeName">Nombre</string>
<string name="note">Nota</string>
<string name="cardId">ID. de tarjeta</string>
<string name="cardId">ID de tarjeta</string>
<string name="cancel">Cancelar</string>
<string name="save">Guardar</string>
<string name="edit">Editar</string>
@@ -20,7 +20,7 @@
<string name="noCardExistsError">No se ha podido encontrar esa tarjeta</string>
<string name="importExport">Importar/Exportar</string>
<string name="exportName">Exportar</string>
<string name="importExportHelp">Hacer una copia de seguridad de los datos permite trasladarlos a otro dispositivo.</string>
<string name="importExportHelp">Respaldar tus datos permite trasladarlos a otro dispositivo.</string>
<string name="importSuccessfulTitle">Importado</string>
<string name="importFailedTitle">Falló la importación</string>
<string name="importFailed">No se ha podido realizar la importación</string>
@@ -33,9 +33,9 @@
<string name="importOptionFilesystemExplanation">Elegir un archivo concreto del sistema de archivos.</string>
<string name="importOptionFilesystemButton">Desde el sistema de archivos</string>
<string name="importOptionApplicationTitle">Utilizar otra aplicación</string>
<string name="importOptionApplicationExplanation">Use una aplicación o su gestor de archivos favoritos para abrir un archivo.</string>
<string name="importOptionApplicationExplanation">Usa cualquier aplicación o tu administrador de archivos favorito para abrir un archivo.</string>
<string name="importOptionApplicationButton">Utilizar otra aplicación</string>
<string name="about">Acerca de</string>
<string name="about">Información</string>
<string name="app_license">Programa libre con «copyleft», disponible en virtud de la licencia GPLv3+</string>
<string name="about_title_fmt">Acerca de <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Versión: <xliff:g id="version">%s</xliff:g></string>
@@ -56,16 +56,16 @@
<string name="barcodeType">Tipo de código de barras</string>
<string name="noMatchingGiftCards">Sin resultados. Intente cambiar su búsqueda.</string>
<string name="action_search">Buscar</string>
<string name="noGroups">Pulse en el botón «+» para añadir grupos de categorización.</string>
<string name="noGroups">Pulse en el botón + para añadir grupos de categorización.</string>
<string name="starImage">Estrella favorita</string>
<string name="thumbnailDescription">Miniatura</string>
<string name="selectBarcodeTitle">Seleccionar el código de barras</string>
<string name="unstar">Eliminar de favoritos</string>
<string name="noBarcode">Sin código de barras</string>
<string name="enter_group_name">Introducir nombre del grupo</string>
<string name="enter_group_name">Escribe el nombre del grupo</string>
<string name="groups">Grupos</string>
<string name="groupsList">Grupos: <xliff:g>%s</xliff:g></string>
<string name="addManually">Introducir manualmente el código de barras</string>
<string name="addManually">Escribe manualmente el código de barras</string>
<string name="leaveWithoutSaveConfirmation">¿Quiere abandonar sin guardar\?</string>
<string name="leaveWithoutSaveTitle">Salir</string>
<string name="moveDown">Bajar</string>
@@ -115,7 +115,7 @@
<string name="removeImage">Quitar imagen</string>
<string name="setFrontImage">Establecer imagen frontal</string>
<string name="photos">Fotos</string>
<string name="backImageDescription">Imagen del reverso</string>
<string name="backImageDescription">Imagen de atrás</string>
<string name="frontImageDescription">Imagen frontal</string>
<string name="wrongValueForBarcodeType">El valor no es válido para el tipo de código de barras seleccionado</string>
<string name="unsupportedBarcodeType">Este tipo de código de barras todavía no se puede visualizar. Es posible que se admita en una futura versión de la aplicación.</string>
@@ -184,10 +184,10 @@
<string name="settings_portrait_orientation">Formato vertical</string>
<string name="group_edit">Editar grupo</string>
<string name="group_updated">Grupo actualizado</string>
<string name="noGiftCardsGroup">Cree algunas tarjetas y luego asígnelas al grupo aquí.</string>
<string name="settings_follow_system_orientation">Seguir el sistema</string>
<string name="noGiftCardsGroup">Crea algunas tarjetas y luego asígnelas al grupo aquí.</string>
<string name="settings_follow_system_orientation">Segue el sistema</string>
<string name="settings_lock_on_opening_orientation">Bloqueo a la orientación utilizada al abrir la tarjeta</string>
<string name="sort_by_most_recently_used">Lo más reciente que se ha utilizado</string>
<string name="sort_by_most_recently_used">Lo más usado recientemente</string>
<string name="sort_by_expiry">Caducidad</string>
<string name="version_history">Historial de versiones</string>
<string name="help_translate_this_app">Ayuda a traducir esta aplicación</string>
@@ -199,7 +199,7 @@
<string name="sort_by_name">Nombre</string>
<string name="license">Licencia</string>
<string name="source_repository">Repositorio de fuente</string>
<string name="on_github">En GitHub</string>
<string name="on_github">en GitHub</string>
<string name="on_google_play">en Google Play</string>
<string name="report_error">Informar de un error</string>
<string name="translate_platform">en Weblate</string>
@@ -230,7 +230,7 @@
<string name="archived">Tarjeta archivada</string>
<string name="unarchived">Tarjeta desarchivada</string>
<string name="exportPassword">Establezca una contraseña para proteger su exportación (opcional)</string>
<string name="failedLaunchingPhotoPicker">No se ha podido encontrar una aplicación de galería compatible</string>
<string name="failedLaunchingPhotoPicker">No se ha encontró una aplicación de galería compatible</string>
<plurals name="groupCardCountWithArchived">
<item quantity="one"><xliff:g>%1$d</xliff:g> tarjeta (archivada)<xliff:g id="archivedCount">%2$d</xliff:g></item>
<item quantity="many"><xliff:g>%1$d</xliff:g> tarjetas (archivadas)<xliff:g id="archivedCount">%2$d</xliff:g></item>
@@ -239,7 +239,7 @@
<string name="starred">Estrellado</string>
<string name="failedToRetrieveImageFile">No se pudo recuperar el archivo de imagen</string>
<string name="barcodeLongPressMessage">Solo se pueden abrir imágenes en la aplicación de galería</string>
<string name="updateBalanceTitle">¿Cuánto has gastado\?</string>
<string name="updateBalanceTitle">¿Cuánto has gastado o recibido?</string>
<string name="currentBalanceSentence">Saldo actual: <xliff:g>%s</xliff:g></string>
<string name="noCameraPermissionDirectToSystemSetting">Para escanear códigos de barras, Catima necesitará acceso a su cámara. Toque aquí para cambiar la configuración de sus permisos.</string>
<string name="updateBalanceHint">Introduzca el importe</string>
@@ -291,4 +291,15 @@
<string name="field_must_not_be_empty">Este campo no debe estar vacío</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Girar siempre (ignora la configuración del sistema)</string>
<string name="continue_">Continuar</string>
<string name="add_manually_warning_title">Se recomienda escanear</string>
<string name="add_manually_warning_message">En algunas tiendas, el valor del código de barras difiere del número escrito en la tarjeta. Por este motivo, es posible que la introducción manual del código de barras no siempre funcione. Se recomienda encarecidamente escanear el código de barras con la cámara. ¿Aún desea continuar?</string>
<string name="spend">Gastar</string>
<string name="receive">Recibió</string>
<string name="amountParsingFailed">Importe incorrecto</string>
<string name="addFromPdfFile">Seleccionar un archivo PDF</string>
<string name="errorReadingFile">No se ha podido leer el archivo</string>
<string name="failedLaunchingFileManager">No se ha podido encontrar un gestor de archivos compatible</string>
<string name="multipleBarcodesFoundPleaseChooseOne">¿Cuál de los códigos de barras encontrados desea utilizar?</string>
<string name="pageWithNumber">Página <xliff:g>%d</xliff:g></string>
</resources>

View File

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

View File

@@ -228,7 +228,7 @@
<item quantity="one">Näytä arkisto (<xliff:g>%1$d</xliff:g> kortti)</item>
<item quantity="other">Näytä arkisto (<xliff:g>%1$d</xliff:g> korttia)</item>
</plurals>
<string name="updateBalanceTitle">Kuinka paljon kulutit\?</string>
<string name="updateBalanceTitle">Kuinka paljon kulutit tai tienasit?</string>
<string name="updateBalanceHint">Syötä summa</string>
<string name="barcodeLongPressMessage">Vain kuvia on mahdollista avata galleriasovelluksessa</string>
<string name="archive">Arkistoi</string>
@@ -284,4 +284,15 @@
<string name="balanceParsingFailed">Virheellinen saldo</string>
<string name="view_online">Näytä verkossa</string>
<string name="settings_follow_sensor_orientation">Kierrä aina (ohittaa järjestelmän asetukset)</string>
<string name="continue_">Jatka</string>
<string name="add_manually_warning_title">Skannausta suositellaan</string>
<string name="spend">Kuluta</string>
<string name="receive">Vastaanota</string>
<string name="amountParsingFailed">Virheellinen määrä</string>
<string name="add_manually_warning_message">Joidenkin kauppojen kohdalla viivakoodin arvo eroaa kortilla olevasta numerosta. Tämän takia viivakoodin syöttäminen käsin ei aina toimi. On vahvasti suositeltua skannata viivakoodi kameralla. Haluatko silti jatkaa?</string>
<string name="addFromPdfFile">Valitse PDF-tiedosto</string>
<string name="errorReadingFile">Tiedostoa ei voitu lukea</string>
<string name="failedLaunchingFileManager">Tuettua tiedostonhallintasovellusta ei löytynyt</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Mitä löytyneistä viivakoodeista haluat käyttää?</string>
<string name="pageWithNumber">Sivu <xliff:g>%d</xliff:g></string>
</resources>

View File

@@ -243,7 +243,7 @@
<string name="cameraPermissionDeniedTitle">Impossible daccéder à la caméra</string>
<string name="noCameraPermissionDirectToSystemSetting">Pour scanner les codes-barres, Catima doit avoir accès à votre caméra. Tapez ici pour modifier vos paramètres d\'autorisation.</string>
<string name="updateBalance">Mettre à jour le solde</string>
<string name="updateBalanceTitle">Combien avez-vous dépensé \?</string>
<string name="updateBalanceTitle">Combien avez-vous dépensé ou reçu?</string>
<string name="newBalanceSentence">Nouveau solde : <xliff:g>%s</xliff:g></string>
<string name="importCards">Importer des cartes</string>
<string name="storageReadPermissionRequired">Lautorisation de lire le stockage est nécessaire pour cette action…</string>
@@ -291,4 +291,15 @@
<string name="field_must_not_be_empty">Le champ ne peut pas être vide</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Toujours pivoter (ignore les paramètres du système)</string>
<string name="add_manually_warning_title">Scan recommandé</string>
<string name="continue_">Continuer</string>
<string name="add_manually_warning_message">Pour certains magasins, la valeur du code-barres diffère du numéro inscrit sur la carte. Pour cette raison, la saisie manuelle dun code-barres peut ne pas toujours fonctionner. Il est fortement recommandé de scanner le code-barres avec votre appareil photo. Voulez-vous toujours continuer?</string>
<string name="spend">Dépenser</string>
<string name="receive">Reçevoir</string>
<string name="amountParsingFailed">Montant Invalide</string>
<string name="addFromPdfFile">Sélectionner un fichier PDF</string>
<string name="errorReadingFile">Lecture du fichier impossible</string>
<string name="failedLaunchingFileManager">Impossible de trouver un gestionnaire de fichiers supporté</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Quel code-barre, parmi ceux trouvés, voulez-vous utiliser?</string>
<string name="pageWithNumber">Page <xliff:g>%d</xliff:g></string>
</resources>

View File

@@ -255,7 +255,7 @@
<item quantity="one">संग्रह देखें (<xliff:g>%1$d</xliff:g> कार्ड)</item>
<item quantity="other">संग्रह देखें (<xliff:g>%1$d</xliff:g> कार्ड)</item>
</plurals>
<string name="updateBalanceTitle">आपने कितना खर्च किया?</string>
<string name="updateBalanceTitle">आपने कितना खर्च या प्राप्त किया?</string>
<string name="chooseValidFromDate">दिनांक से वैध चुनें</string>
<string name="show_name_below_image_thumbnail">छवि थंबनेल के नीचे नाम दिखाएँ</string>
<string name="show_archived_cards">संग्रहीत कार्ड दिखाएँ</string>
@@ -284,4 +284,15 @@
<string name="setBarcodeHeight">बारकोड ऊंचाई सेट करें</string>
<string name="icon_header_click_text">थंबनेल संपादित करने के लिए देर तक दबाएँ</string>
<string name="enter_card_id">अपने कार्ड पर आईडी नंबर या पाठ दर्ज करें</string>
<string name="continue_">जारी रखें</string>
<string name="add_manually_warning_message">कुछ दुकानों के लिए, बारकोड का मान कार्ड पर लिखे नंबर से भिन्न होता है। इस वजह से, बारकोड को मैन्युअल रूप से दर्ज करना हमेशा काम नहीं कर सकता है। इसके बजाय बारकोड को अपने कैमरे से स्कैन करने की पुरजोर अनुशंसा की जाती है। क्या आप अब भी जारी रखना चाहते हैं?</string>
<string name="add_manually_warning_title">स्कैनिंग की अनुशंसा की जाती है</string>
<string name="spend">खर्च किया</string>
<string name="receive">प्राप्त किया</string>
<string name="amountParsingFailed">अमान्य राशि</string>
<string name="multipleBarcodesFoundPleaseChooseOne">आप पाए गए बारकोड में से कौन सा उपयोग करना चाहते हैं?</string>
<string name="pageWithNumber">पृष्ठ <xliff:g>%d</xliff:g></string>
<string name="addFromPdfFile">एक PDF फाइल चुनें</string>
<string name="errorReadingFile">फाइल को पढ़ा नहीं जा सका</string>
<string name="failedLaunchingFileManager">समर्थित फाइल प्रबंधक नहीं मिल सका</string>
</resources>

View File

@@ -252,7 +252,7 @@
<string name="shortcutSelectCard">Odaberi karticu</string>
<string name="previousCard">Prethodna</string>
<string name="nextCard">Sljedeća</string>
<string name="updateBalanceTitle">Koliko si potrošio/la\?</string>
<string name="updateBalanceTitle">Koliko si potrošio/la ili primio/la?</string>
<string name="updateBalanceHint">Upiši iznos</string>
<string name="about_title_fmt">Informaije o <xliff:g id="app_name">%s</xliff:g></string>
<string name="failedToOpenUrl">Najprije instaliraj web preglednik</string>
@@ -291,4 +291,15 @@
<string name="settings_keep_screen_on_summary">Deaktivira isključivanje ekrana tijekom prikaza kartice</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Uvijek rotiraj (ignorira sistemske postavke)</string>
<string name="continue_">Nastavi</string>
<string name="add_manually_warning_message">Za neke trgovine se vrijednost barkoda razlikuje od broja napisanog na kartici. Zbog toga ručni unos barkoda možda neće uvijek funkcionirati. Preporučuje se snimanje barkoda pomoću kamere. Želiš li svejedno nastaviti?</string>
<string name="add_manually_warning_title">Preporučuje se snimanje</string>
<string name="addFromPdfFile">Odaberi PDF datoteku</string>
<string name="errorReadingFile">Neuspjelo čitanje datoteke</string>
<string name="failedLaunchingFileManager">Nije pronađen podržani upravljač datoteka</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Koji pronađeni barkod želiš koristiti?</string>
<string name="pageWithNumber">Stranica <xliff:g>%d</xliff:g></string>
<string name="spend">Potroši</string>
<string name="receive">Primi</string>
<string name="amountParsingFailed">Neispravan iznos</string>
</resources>

View File

@@ -226,7 +226,7 @@
<string name="currentBalanceSentence">Jelenlegi egyenleg: <xliff:g>%s</xliff:g></string>
<string name="updateBalanceHint">Adja meg az összeget</string>
<string name="importCards">Kártyák importálása</string>
<string name="updateBalanceTitle">Mennyit költött\?</string>
<string name="updateBalanceTitle">Mennyit költött és kapott?</string>
<string name="newBalanceSentence">Új egyenleg: <xliff:g>%s</xliff:g></string>
<string name="cameraPermissionDeniedTitle">Nem sikerült hozzáférni a kamerához</string>
<string name="failedToRetrieveImageFile">Nem sikerült lekérni a képfájlt</string>
@@ -284,4 +284,10 @@
<string name="show_archived_cards">Archivált kártyák megjelenítése</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Mindig forgassa (figyelmen kívül hagyja a rendszerbeállításokat)</string>
<string name="amountParsingFailed">Hibás érték</string>
<string name="add_manually_warning_title">Szkennelés ajánlott</string>
<string name="add_manually_warning_message">Egyes boltoknál a kártyán levő számsor különbözik a vonalkódtól. Emiatt a manuális szám beírás nem minden esetben fog működni. Erősen ajánlott inkább a vonalkód szkennelése kamerával. Biztosan folytatja?</string>
<string name="continue_">Tovább</string>
<string name="spend">Költött</string>
<string name="receive">Megkapott</string>
</resources>

View File

@@ -231,7 +231,7 @@
<string name="updateBalance">Perbarui saldo</string>
<string name="updateBalanceHint">Masukkan jumlah</string>
<string name="currentBalanceSentence">Saldo saat ini: <xliff:g>%s</xliff:g></string>
<string name="updateBalanceTitle">Berapa banyak yang telah kamu habiskan \?</string>
<string name="updateBalanceTitle">Berapa banyak yang kamu belanjakan atau terima?</string>
<string name="noCameraPermissionDirectToSystemSetting">Untuk memindai barcode, Catima membutuhkan akses ke kamera mu. Tap disini untuk mengganti pengaturan perizinan mu.</string>
<string name="cameraPermissionRequired">Berikan izin untuk mengakses kamera anda…</string>
<string name="storageReadPermissionRequired">Berikan izin untuk membaca penyimpanan anda…</string>
@@ -277,4 +277,15 @@
<string name="field_must_not_be_empty">Isian tidak boleh kosong</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Selalu rotasi (abaikan pengaturan sistem)</string>
<string name="add_manually_warning_title">Pemindaian sangat dianjurkan</string>
<string name="continue_">Lanjut</string>
<string name="failedLaunchingFileManager">Tidak dapat menemukan pengelola file yang didukung</string>
<string name="errorReadingFile">Tidak dapat membaca file</string>
<string name="addFromPdfFile">Pilih file PDF</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Barcode mana yang ingin Anda gunakan?</string>
<string name="pageWithNumber">Halaman <xliff:g>%d</xliff:g></string>
<string name="spend">Dibelanjakan</string>
<string name="receive">Terima</string>
<string name="amountParsingFailed">Jumlah tidak valid</string>
<string name="add_manually_warning_message">Untuk beberapa toko, nilai barcode berbeda dengan nomor yang tertulis di kartu. Oleh karena itu, memasukkan barcode secara manual mungkin tidak selalu berhasil. Sangat disarankan untuk memindai barcode dengan kamera anda. Apakah anda masih ingin melanjutkan?</string>
</resources>

View File

@@ -241,7 +241,7 @@
<string name="cameraPermissionDeniedTitle">È impossibile accedere alla fotocamera</string>
<string name="noCameraPermissionDirectToSystemSetting">Per poter scansionare i codici a barre, Catima ha bisogno di accedere alla tua fotocamera. Premi qui per poter cambiare le impostazioni dei permessi.</string>
<string name="updateBalance">Aggiorna bilancio</string>
<string name="updateBalanceTitle">Quanto hai speso\?</string>
<string name="updateBalanceTitle">Quanto hai speso o ricevuto?</string>
<string name="updateBalanceHint">Inserisci l\'importo</string>
<string name="currentBalanceSentence">Bilancio attuale: <xliff:g>%s</xliff:g></string>
<string name="newBalanceSentence">Nuovo bilancio: <xliff:g>%s</xliff:g></string>
@@ -291,4 +291,15 @@
<string name="field_must_not_be_empty">Il campo non deve essere vuoto</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Ruota sempre (ignora le impostazioni di sistema)</string>
<string name="add_manually_warning_title">Consigliata scansione</string>
<string name="continue_">Successivo</string>
<string name="add_manually_warning_message">In alcuni negozi, il valore del codice a barre differisce dal numero scritto sulla carta. Per questo motivo, l\'inserimento manuale del codice a barre potrebbe non funzionare sempre. Si consiglia di scansionare il codice a barre con la fotocamera. Vuoi continuare lo stesso?</string>
<string name="amountParsingFailed">Importo non valido</string>
<string name="spend">Spendi</string>
<string name="receive">Ricevi</string>
<string name="errorReadingFile">Impossibile leggere il file</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Quale dei codici a barre trovati vuoi utilizzare?</string>
<string name="addFromPdfFile">Seleziona un file PDF</string>
<string name="failedLaunchingFileManager">Impossibile trovare un file manager supportato</string>
<string name="pageWithNumber">Pagina <xliff:g>%d</xliff:g></string>
</resources>

View File

@@ -206,4 +206,5 @@
<string name="settings_landscape_orientation"></string>
<string name="settings_portrait_orientation"></string>
<string name="noGiftCardsGroup">いくつかのカードを作って、それらをこのグループにアサインします。</string>
<string name="noCameraPermissionDirectToSystemSetting">バーコードをスキャンするためには、Catimaはカメラへのアクセスを必要とします。ここをタップして権限設定の変更をお願いします。</string>
</resources>

View File

@@ -214,7 +214,7 @@
<string name="backImageDescription">후면 사진</string>
<string name="currentBalanceSentence">현재 잔액: <xliff:g>%s</xliff:g></string>
<string name="importCards">카드 가져오기</string>
<string name="updateBalanceTitle">얼마를 썼습니까\?</string>
<string name="updateBalanceTitle">지출하거나 수령한 금액은 얼마입니까?</string>
<string name="newBalanceSentence">새 잔액: <xliff:g>%s</xliff:g></string>
<string name="settings_card_orientation">바코드 방향</string>
<string name="settings_follow_system_orientation">기기 설정 따르기</string>
@@ -276,4 +276,16 @@
<string name="enter_card_id">카드에 있는 ID 숫자 또는 텍스트 입력</string>
<string name="addWithoutBarcode">바코드가 없는 카드 추가</string>
<string name="app_name">Catima</string>
<string name="add_manually_warning_title">스캔을 권장합니다</string>
<string name="settings_follow_sensor_orientation">항상 회전 (시스템 설정 무시)</string>
<string name="continue_">계속</string>
<string name="addFromPdfFile">PDF 파일 선택</string>
<string name="errorReadingFile">파일을 읽을 수 없습니다</string>
<string name="failedLaunchingFileManager">지원되는 파일 관리자를 찾을 수 없습니다</string>
<string name="multipleBarcodesFoundPleaseChooseOne">검색된 바코드 중 어떤 바코드를 사용하시겠습니까?</string>
<string name="pageWithNumber">페이지 <xliff:g>%d</xliff:g></string>
<string name="spend">보내기</string>
<string name="receive">받기</string>
<string name="amountParsingFailed">잘못된 금액</string>
<string name="add_manually_warning_message">일부 매장의 경우 바코드 값이 카드에 적힌 숫자와 다릅니다. 이 때문에 수동으로 바코드를 입력하는 것이 항상 작동하지 않을 수 있습니다. 대신 카메라로 바코드를 스캔하는 것이 좋습니다. 계속하시겠습니까?</string>
</resources>

View File

@@ -227,7 +227,7 @@
<string name="unarchive">Išarchyvuoti</string>
<string name="archived">Kortelė archyvuota</string>
<string name="unarchived">Kortelė išarchyvuota</string>
<string name="updateBalanceTitle">Kiek išleidote\?</string>
<string name="updateBalanceTitle">Kiek išleidote?</string>
<string name="updateBalanceHint">Įveskite sumą</string>
<string name="currentBalanceSentence">Dabartinis likutis: <xliff:g>%s</xliff:g></string>
<string name="newBalanceSentence">Naujas balansas: <xliff:g>%s</xliff:g></string>
@@ -261,4 +261,4 @@
<string name="switchToFrontImage">Perjungti į priekinį vaizdą</string>
<string name="openFrontImageInGalleryApp">Atidarykite priekinį vaizdą galerijos programėlėje</string>
<string name="donate">Aukoti</string>
</resources>
</resources>

View File

@@ -238,10 +238,10 @@
<string name="noCameraPermissionDirectToSystemSetting">Lai skanētu svītrkods, Catima ir nepieciešama pieeja jūsu kamerai. Nospied šeit lai nomainītu atļaujas iestatījumus.</string>
<string name="cameraPermissionDeniedTitle">Nevar pievienieties kamerai</string>
<string name="updateBalance">Atjaunināta bilance</string>
<string name="updateBalanceTitle">Cik daudz Tu iztērēji\?</string>
<string name="updateBalanceTitle">Cik daudz Tu iztērēji?</string>
<string name="updateBalanceHint">Ievadi summu</string>
<string name="currentBalanceSentence">Šābrīža bilance: <xliff:g>%s</xliff:g></string>
<string name="newBalanceSentence">Jauna bilance: <xliff:g>%s</xliff:g></string>
<string name="storageReadPermissionRequired">Atļauja lasīt noliktavu ir nepieciešama šai darbībai…</string>
<string name="importCards">Importēt kartes</string>
</resources>
</resources>

View File

@@ -236,7 +236,7 @@
<string name="noCameraPermissionDirectToSystemSetting">Catima trenger kameratilgang for å skanne strekkoder. Trykk her for å endre tilgangsinnstillingene.</string>
<string name="importCards">Importer kort</string>
<string name="currentBalanceSentence">Nåværende saldo: <xliff:g>%s</xliff:g></string>
<string name="updateBalanceTitle">Hvor mye brukte du\?</string>
<string name="updateBalanceTitle">Hvor mye brukte du?</string>
<string name="updateBalanceHint">Skriv inn beløp</string>
<string name="newBalanceSentence">Ny saldo: <xliff:g>%s</xliff:g></string>
<string name="updateBalance">Oppdater saldo</string>
@@ -283,4 +283,11 @@
<string name="manually_enter_barcode_instructions">Skriv inn ID-nummer eller tekst fra kortet og trykk på strekkoden som ser ut til å ligne.</string>
<string name="enter_card_id">Skriv inn ID-nummeret eller teksten på kortet</string>
<string name="field_must_not_be_empty">Feltet må fylles ut</string>
<string name="add_manually_warning_title">Skanning anbefales</string>
<string name="continue_">Fortsett</string>
<string name="amountParsingFailed">Ugyldig beløp</string>
<string name="spend">Utgifter</string>
<string name="receive">Inntekt</string>
<string name="settings_follow_sensor_orientation">Alltid roter (ignorerer systeminnstilling)</string>
<string name="add_manually_warning_message">I noen butikker er strekkoden forskjellig fra nummeret på kortet. Som følge av dette kan det hende at å skrive inn strekkoden ikke virker. Det anbefales å skanne strekkoden med kameraet istedenfor. Fortsett?</string>
</resources>

View File

@@ -233,7 +233,7 @@
<string name="failedToRetrieveImageFile">De afbeelding kan niet worden opgehaald</string>
<string name="barcodeLongPressMessage">Alleen afbeeldingen kunnen worden geopend in de galerij-app</string>
<string name="cameraPermissionDeniedTitle">Geen cameratoegang</string>
<string name="updateBalanceTitle">Hoeveel heb je uitgegeven\?</string>
<string name="updateBalanceTitle">Hoeveel heb je uitgegeven of ontvangen?</string>
<string name="noCameraPermissionDirectToSystemSetting">Catima heeft toegang tot je camera nodig om barcodes te kunnen scannen. Druk hier om toegang te verlenen.</string>
<string name="currentBalanceSentence">Huidig saldo: <xliff:g>%s</xliff:g></string>
<string name="updateBalance">Saldo bijwerken</string>
@@ -284,4 +284,15 @@
<string name="field_must_not_be_empty">Dit veld is vereist</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Altijd draaien (negeert systeeminstellingen)</string>
<string name="add_manually_warning_title">Scannen wordt aangeraden</string>
<string name="add_manually_warning_message">Bij sommige winkels wijkt de barcodewaarde af van het nummer op de kaart. Hierdoor werkt het handmatig invoeren van een barcode niet altijd. Het wordt sterk aangeraden om in plaats daarvan de barcode met je camera te scannen. Wilt u nog steeds doorgaan?</string>
<string name="continue_">Ga door</string>
<string name="spend">Geef uit</string>
<string name="receive">Ontvang</string>
<string name="amountParsingFailed">Ongeldig bedrag</string>
<string name="addFromPdfFile">Kies een pdf-bestand</string>
<string name="errorReadingFile">Lezen bestand mislukt</string>
<string name="failedLaunchingFileManager">Geen ondersteunde bestandsbeheerder aangetroffen</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Welke van de gevonden barcodes wil je gebruiken?</string>
<string name="pageWithNumber">Pagina <xliff:g>%d</xliff:g></string>
</resources>

View File

@@ -248,7 +248,7 @@
</plurals>
<string name="currentBalanceSentence">Bieżące saldo: <xliff:g>%s</xliff:g></string>
<string name="noCameraPermissionDirectToSystemSetting">By zeskanować kody kreskowe, Catima musi mieć dostęp do twojej kamery. Dotknij tutaj by zmienić swoje ustawienia dostępu.</string>
<string name="updateBalanceTitle">Ile wydałeś\?</string>
<string name="updateBalanceTitle">Ile wydałeś lub otrzymałeś?</string>
<string name="updateBalanceHint">Wpisz sumę</string>
<string name="updateBalance">Zaktualizuj balans</string>
<string name="cameraPermissionDeniedTitle">Odmówiono dostępu do kamery</string>
@@ -298,4 +298,15 @@
<string name="field_must_not_be_empty">Pole nie może być puste</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Zawsze obracaj (ignoruje ustawienia systemowe)</string>
<string name="continue_">Kontynuuj</string>
<string name="addFromPdfFile">Wybierz plik PDF</string>
<string name="errorReadingFile">Nie można odczytać pliku</string>
<string name="pageWithNumber">Strona <xliff:g>%d</xliff:g></string>
<string name="spend">Wydaj</string>
<string name="receive">Otrzymaj</string>
<string name="amountParsingFailed">Nieprawidłowa ilość</string>
<string name="add_manually_warning_title">Skanowanie jest zalecane</string>
<string name="failedLaunchingFileManager">Nie można znaleźć obsługiwanego menedżera plików</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Którego ze znalezionych kodów kreskowych chciałbyś użyć?</string>
<string name="add_manually_warning_message">W przypadku niektórych sklepów wartość kodu kreskowego różni się od liczby zapisanej na karcie. Z tego powodu ręczne wprowadzanie kodu kreskowego może nie zawsze działać. Zdecydowanie zaleca się zeskanowanie kodu kreskowego za pomocą aparatu. Czy nadal chcesz kontynuować?</string>
</resources>

View File

@@ -245,7 +245,7 @@
<string name="currentBalanceSentence">Saldo atual: <xliff:g>%s</xliff:g></string>
<string name="newBalanceSentence">Novo saldo: <xliff:g>%s</xliff:g></string>
<string name="updateBalance">Atualizar saldo</string>
<string name="updateBalanceTitle">Quanto gastou\?</string>
<string name="updateBalanceTitle">Quanto gastou ou recebeu?</string>
<string name="updateBalanceHint">Introduza o valor</string>
<string name="storageReadPermissionRequired">É necessária a permissão para ler o armazenamento para esta ação…</string>
<string name="cameraPermissionRequired">É necessária a permissão para aceder à câmara para esta ação…</string>
@@ -290,4 +290,16 @@
<string name="field_must_not_be_empty">O campo não pode estar vazio</string>
<string name="show_archived_cards">Exibir cartões arquivados</string>
<string name="app_name">Catima</string>
<string name="continue_">Continuar</string>
<string name="add_manually_warning_title">Recomenda-se a digitalização</string>
<string name="add_manually_warning_message">Em algumas lojas, o valor do código de barras é diferente do número escrito no cartão. Por este motivo, a introdução manual de um código de barras pode nem sempre funcionar. Recomenda-se vivamente que, em vez disso, digitalize o código de barras com a sua câmara. Ainda quer continuar?</string>
<string name="spend">Gastar</string>
<string name="receive">Receber</string>
<string name="amountParsingFailed">Montante inválida</string>
<string name="settings_follow_sensor_orientation">Rodar sempre (ignora as definições do sistema)</string>
<string name="addFromPdfFile">Selecionar um ficheiro PDF</string>
<string name="errorReadingFile">Não foi possível ler o ficheiro</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Qual dos códigos de barras encontrados pretende utilizar?</string>
<string name="pageWithNumber">Página <xliff:g>%d</xliff:g></string>
<string name="failedLaunchingFileManager">Não foi possível encontrar um gestor de ficheiros suportado</string>
</resources>

View File

@@ -257,7 +257,7 @@
<string name="show_archived_cards">Afișați cardurile arhivate</string>
<string name="settings_card_orientation">Orientarea codului de bare</string>
<string name="app_libraries">Biblioteci terță deschise: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="updateBalanceTitle">Cât de mult ați folosit?</string>
<string name="updateBalanceTitle">Cât de mult ați cheltuit sau primit?</string>
<string name="settings_blue_theme">Albastru</string>
<string name="app_resources">Resurse terță deschise: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="app_name">Catima</string>
@@ -291,4 +291,15 @@
<string name="rate_this_app">Acordați o recenzie acestei aplicații</string>
<string name="credits">Contribuabili</string>
<string name="settings_follow_sensor_orientation">Rotește întotdeauna (ignora setările de sistem)</string>
<string name="continue_">Continua</string>
<string name="add_manually_warning_title">Se recomandă scanarea</string>
<string name="add_manually_warning_message">Pentru unele magazine, valoarea codului de bare diferă de numărul scris pe card. Din acest motiv, este posibil ca introducerea manuală a unui cod de bare să nu funcționeze întotdeauna. În schimb, este recomandat să scanați codul de bare cu camera dvs. Mai vrei să continui?</string>
<string name="spend">Cheltuie</string>
<string name="receive">Primește</string>
<string name="amountParsingFailed">Sumă nevalidă</string>
<string name="addFromPdfFile">Selectați un fișier PDF</string>
<string name="errorReadingFile">Nu am putut citi fișierul</string>
<string name="failedLaunchingFileManager">Nu s-a găsit un manager de fișiere suportat</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Pe care dintre codurile de bare găsite dorești să-l folosești?</string>
<string name="pageWithNumber">Pagina <xliff:g>%d</xliff:g></string>
</resources>

View File

@@ -18,7 +18,7 @@
<string name="sendLabel">Отправить…</string>
<string name="editCardTitle">Изменить карту</string>
<string name="addCardTitle">Добавить карту</string>
<string name="scanCardBarcode">Отсканируйте штрих-код</string>
<string name="scanCardBarcode">Сканировать штрих-код</string>
<string name="cardShortcut">Ярлык карты</string>
<string name="noCardsMessage">Сначала добавьте карту</string>
<string name="noCardExistsError">Карта не найдена</string>
@@ -252,7 +252,7 @@
<string name="currentBalanceSentence">Текущий баланс: <xliff:g>%s</xliff:g></string>
<string name="cameraPermissionDeniedTitle">Камера недоступна</string>
<string name="updateBalanceHint">Введите сумму</string>
<string name="updateBalanceTitle">Какое изменение\?</string>
<string name="updateBalanceTitle">Сколько потрачено или получено?</string>
<string name="importCards">Импорт карт</string>
<string name="storageReadPermissionRequired">Для этого действия необходимо разрешение на чтение хранилища…</string>
<string name="cameraPermissionRequired">Для этого действия необходимо разрешение на доступ к камере…</string>
@@ -298,4 +298,15 @@
<string name="field_must_not_be_empty">Поле не может быть пустым</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Всегда поворачивать (игнорировать системные настройки)</string>
<string name="add_manually_warning_title">Рекомендуется сканирование</string>
<string name="continue_">Продолжить</string>
<string name="add_manually_warning_message">В некоторых магазинах значение штрих-кода отличается от написанного на карте номера, из-за чего введение штрих-кода вручную не всегда работает. Вместо этого настоятельно рекомендуется отсканировать штрих-код камерой. Продолжить?</string>
<string name="spend">Потрачено</string>
<string name="receive">Получено</string>
<string name="amountParsingFailed">Недопустимая сумма</string>
<string name="addFromPdfFile">Выберите PDF-файл</string>
<string name="errorReadingFile">Невозможно прочитать файл</string>
<string name="pageWithNumber">Страница <xliff:g>%d</xliff:g></string>
<string name="failedLaunchingFileManager">Не найден поддерживаемый файловый менеджер</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Какой из найденных штрих-кодов вы хотите использовать?</string>
</resources>

View File

@@ -204,7 +204,7 @@
<string name="unarchived">Karta vrátená z archívu</string>
<string name="previousCard">Predošlá</string>
<string name="nextCard">Nasledujúca</string>
<string name="updateBalanceTitle">Koľko ste minuli\?</string>
<string name="updateBalanceTitle">Koľko ste minuli alebo prjali?</string>
<string name="updateBalanceHint">Zadajte čiastku</string>
<string name="failedToOpenUrl">Najprv nainštalujte webový prehliadač</string>
<string name="welcome">Vitajte v Catima</string>
@@ -291,4 +291,10 @@
<string name="show_archived_cards">Zobraziť archivované karty</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Vždy otáčať (ignoruje nastavenie systému)</string>
<string name="continue_">Pokračovať</string>
<string name="spend">Utratené</string>
<string name="receive">Prijaté</string>
<string name="amountParsingFailed">Neplatná hodnota</string>
<string name="add_manually_warning_title">Skenovanie je odporúčané</string>
<string name="add_manually_warning_message">V niektorých obchodoch nie je číslo na cenovke totožné s čiarovým kódom, preto je lepšie zoskenovať čiarový kód. Chcete napriek tomu pokračovať?</string>
</resources>

View File

@@ -185,7 +185,7 @@
<string name="failedLaunchingPhotoPicker">Ni mogoče najti podprte aplikacije za gledanje slik</string>
<string name="previousCard">Prejšnje</string>
<string name="nextCard">Naslednje</string>
<string name="updateBalanceTitle">Koliko ste porabili\?</string>
<string name="updateBalanceTitle">Koliko ste porabili?</string>
<string name="updateBalanceHint">Vpišite vrednost</string>
<string name="group_name_already_in_use">Ime skupine je že uporabljeno</string>
<string name="group_name_is_empty">Ime skupine ne more biti prazno polje</string>

View File

@@ -242,7 +242,7 @@
<string name="updateBalance">Uppdatera balans</string>
<string name="failedToRetrieveImageFile">Misslyckades att hämta bildfil</string>
<string name="barcodeLongPressMessage">Endast bilder kan öppnas i galleri app</string>
<string name="updateBalanceTitle">Hur mycket spenderade du\?</string>
<string name="updateBalanceTitle">Hur mycket spenderade du?</string>
<string name="updateBalanceHint">Ange summa</string>
<string name="newBalanceSentence">Ny balans: <xliff:g>%s</xliff:g></string>
<string name="openFrontImageInGalleryApp">Öppna bilden på framsidan i galleri-appen</string>

View File

@@ -235,7 +235,7 @@
<string name="noCameraPermissionDirectToSystemSetting">Barkodları taramak için Catima\'nın kameranıza erişmesi gerekecektir. İzin ayarlarınızı değiştirmek için buraya dokunun.</string>
<string name="currentBalanceSentence">Geçerli bakiye: <xliff:g>%s</xliff:g></string>
<string name="updateBalanceHint">Miktarı girin</string>
<string name="updateBalanceTitle">Ne kadar harcadınız\?</string>
<string name="updateBalanceTitle">Ne kadar harcadınız veya aldınız?</string>
<string name="newBalanceSentence">Yeni bakiye: <xliff:g>%s</xliff:g></string>
<string name="cameraPermissionDeniedTitle">Kameraya erişilemedi</string>
<string name="updateBalance">Bakiyeyi güncelle</string>
@@ -284,4 +284,15 @@
<string name="field_must_not_be_empty">Alan boş olamaz</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Her zaman döndür (sistem ayarlarını yok sayar)</string>
<string name="continue_">Devam et</string>
<string name="add_manually_warning_title">Tarama yapılması tavsiye edilir</string>
<string name="add_manually_warning_message">Bazı mağazalarda barkod değeri kartta yazan sayıdan farklıdır. Bu nedenle, bir barkodu elle girmek her zaman işe yaramayabilir. Bunun yerine barkodu kameranızla taramanız şiddetle tavsiye edilir. Yine de devam etmek istiyor musunuz?</string>
<string name="spend">Harca</string>
<string name="receive">Al</string>
<string name="amountParsingFailed">Geçersiz miktar</string>
<string name="errorReadingFile">Dosya okunamadı</string>
<string name="failedLaunchingFileManager">Desteklenen dosya yöneticisi bulunamadı</string>
<string name="addFromPdfFile">PDF dosyası seç</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Bulunan barkodlardan hangisini kullanmak istiyorsunuz?</string>
<string name="pageWithNumber">Sayfa <xliff:g>%d</xliff:g></string>
</resources>

View File

@@ -247,7 +247,7 @@
<string name="failedToRetrieveImageFile">Збій доступу до файлу зображення</string>
<string name="barcodeLongPressMessage">Галерея може відкривати лише зображення</string>
<string name="importCards">Імпорт карток</string>
<string name="updateBalanceTitle">Скільки витратили\?</string>
<string name="updateBalanceTitle">Скільки ви витратили або отримали?</string>
<string name="updateBalanceHint">Введіть суму</string>
<string name="currentBalanceSentence">Поточний баланс: <xliff:g>%s</xliff:g></string>
<string name="newBalanceSentence">Новий баланс: <xliff:g>%s</xliff:g></string>
@@ -298,4 +298,15 @@
<string name="field_must_not_be_empty">Поле вводу не повинно бути порожнім</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">Завжди обертати (ігнорувати системні налаштування)</string>
<string name="add_manually_warning_message">У деяких магазинах значення штрихкоду відрізняється від номера, записаного на картці. Через це введення штрихкоду вручну може не завжди спрацювати. Наполегливо рекомендуємо відсканувати штрихкод за допомогою камери. Ви все ще хочете продовжити?</string>
<string name="continue_">Продовжити</string>
<string name="add_manually_warning_title">Рекомендується відсканувати</string>
<string name="failedLaunchingFileManager">Не вдалося знайти підтримуваний файловий менеджер</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Який зі знайдених штрих-кодів ви хочете використати?</string>
<string name="addFromPdfFile">Виберіть PDF файл</string>
<string name="errorReadingFile">Не вдалося прочитати файл</string>
<string name="pageWithNumber">Сторінка <xliff:g>%d</xliff:g></string>
<string name="spend">Витратити</string>
<string name="receive">Отримайте</string>
<string name="amountParsingFailed">Неправильна сума</string>
</resources>

View File

@@ -86,7 +86,7 @@
<string name="yes"></string>
<string name="barcodeType">Loại mã vạch</string>
<string name="enter_card_id">Nhập số ID hoặc văn bản lên thẻ của bạn</string>
<string name="unarchived">Thẻ đã được mở khóa</string>
<string name="unarchived">Đã hủy lưu trữ thẻ</string>
<string name="noBarcode">Không có mã vạch</string>
<string name="chooseValidFromDate">Chọn ngày hợp lệ</string>
<string name="action_display_options">Tùy chỉnh hiển thị</string>
@@ -127,7 +127,7 @@
<string name="settings_brown_theme">Màu nâu</string>
<string name="app_copyright_short">Bản quyền © Sylvia van Os và các cộng sự</string>
<string name="importExportHelp">Sao lưu cho phép bạn chuyển dữ liệu của mình đến thiết bị khác.</string>
<string name="settings_oled_dark">Màu nền đen cho chủ đề tối</string>
<string name="settings_oled_dark">Nền đen tuyền cho chủ đề tối</string>
<string name="starred">Ưa thích</string>
<string name="field_must_not_be_empty">Không được để ô trống</string>
<string name="importOptionFilesystemExplanation">Chọn 1 tập tin cụ thể từ hệ thống (filesystem).</string>
@@ -228,7 +228,7 @@
<string name="importSuccessful">Nhập dữ liệu xong</string>
<string name="settings_card_orientation">Hướng đặt mã vạch</string>
<string name="app_libraries">Thư viện mở từ bên thứ 3: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="updateBalanceTitle">Bạn đã chi bao nhiêu\?</string>
<string name="updateBalanceTitle">Bạn đã chi tiêu hoặc nhận được bao nhiêu?</string>
<string name="editCardTitle">Sửa Thẻ</string>
<string name="archive">Lưu trữ</string>
<string name="settings_blue_theme">Màu xanh dương</string>
@@ -277,4 +277,15 @@
<string name="app_contributors">Được thực hiện bởi: <xliff:g id="app_contributors">%s</xliff:g></string>
<string name="app_license">Phần mềm libre được bảo vệ bản quyền theo giấy phép GPLv3+.</string>
<string name="settings_follow_sensor_orientation">Luôn xoay (bỏ qua thiết đặt hệ thống)</string>
<string name="continue_">Tiếp tục</string>
<string name="add_manually_warning_title">Nên quét</string>
<string name="spend">Tiêu</string>
<string name="receive">Nhận được</string>
<string name="amountParsingFailed">Số tiền không hợp lệ</string>
<string name="add_manually_warning_message">Đối với một số cửa hàng, giá trị mã vạch khác với số ghi trên thẻ. Vì lý do này, việc nhập mã vạch theo cách thủ công không phải lúc nào cũng hiệu quả. Thay vào đó, bạn nên quét mã vạch bằng máy ảnh của mình. Bạn vẫn muốn tiếp tục chứ?</string>
<string name="addFromPdfFile">Chọn tệp PDF</string>
<string name="errorReadingFile">Không thể đọc tệp</string>
<string name="pageWithNumber">Page <xliff:g>%d</xliff:g></string>
<string name="multipleBarcodesFoundPleaseChooseOne">Bạn muốn sử dụng mã vạch nào được tìm thấy?</string>
<string name="failedLaunchingFileManager">Không thể tìm thấy trình quản lý tệp được hỗ trợ</string>
</resources>

View File

@@ -227,7 +227,7 @@
<item quantity="other">查看存档(<xliff:g>%1$d</xliff:g> 张卡片)</item>
</plurals>
<string name="updateBalance">更新余额</string>
<string name="updateBalanceTitle">了多少钱?</string>
<string name="updateBalanceTitle">支出或者收到了多少钱?</string>
<string name="currentBalanceSentence">当前余额:<xliff:g>%s</xliff:g></string>
<string name="failedToRetrieveImageFile">无法检索图像文件</string>
<string name="newBalanceSentence">新余额:<xliff:g>%s</xliff:g></string>
@@ -277,4 +277,15 @@
<string name="field_must_not_be_empty">字段不能为空</string>
<string name="app_name">Catima</string>
<string name="settings_follow_sensor_orientation">始终旋转(忽略系统设置)</string>
<string name="add_manually_warning_title">建议扫描</string>
<string name="continue_">继续</string>
<string name="add_manually_warning_message">某些商店卡片的二维码值和刻在卡上的数字并不一样。由于这个原因,手动输入二维码可能并不总是有用。这种情况下,强烈建议你用相机扫描二维码。你仍要继续吗?</string>
<string name="receive">接收</string>
<string name="amountParsingFailed">无效金额</string>
<string name="spend">支出</string>
<string name="errorReadingFile">无法读取文件</string>
<string name="failedLaunchingFileManager">找不到支持的文件管理器</string>
<string name="pageWithNumber"><xliff:g>%d</xliff:g></string>
<string name="addFromPdfFile">选择 PDF 文件</string>
<string name="multipleBarcodesFoundPleaseChooseOne">找到的多个条形码中,你希望使用哪个?</string>
</resources>

View File

@@ -276,4 +276,10 @@
<string name="settings_display_barcode_max_brightness_summary">一些條碼掃描器需要此設定方能運作</string>
<string name="field_must_not_be_empty">欄位不能為空</string>
<string name="settings_follow_sensor_orientation">始終旋轉(忽略系統設定)</string>
<string name="add_manually_warning_title">建議掃描</string>
<string name="failedLaunchingFileManager">找不到支援的檔案管理器</string>
<string name="addFromPdfFile">選擇一個 PDF 檔案</string>
<string name="errorReadingFile">無法讀取此檔案</string>
<string name="receive">接收</string>
<string name="amountParsingFailed">無效的數值</string>
</resources>

View File

@@ -81,6 +81,7 @@
<item>eo</item>
<item>es</item>
<item>es-rAR</item>
<!-- <item>fa</item> -->
<item>fi</item>
<item>fr</item>
<item>he-rIL</item>

View File

@@ -296,7 +296,7 @@
</plurals>
<string name="welcome">Welcome to Catima</string>
<string name="importCards">Import cards</string>
<string name="updateBalanceTitle">How much did you spend?</string>
<string name="updateBalanceTitle">How much did you spend or receive?</string>
<string name="updateBalanceHint">Enter amount</string>
<string name="currentBalanceSentence">Current balance: <xliff:g>%s</xliff:g></string>
<string name="newBalanceSentence">New balance: <xliff:g>%s</xliff:g></string>
@@ -338,4 +338,15 @@
<string name="add_manually_warning_title">Scanning is recommended</string>
<string name="add_manually_warning_message">For some stores, the barcode value differs from the number written on the card. Because of this, entering a barcode manually may not always work. It is strongly recommended to scan the barcode with your camera instead. Do you still want to continue?</string>
<string name="continue_">Continue</string>
<string name="spend">Spend</string>
<string name="receive">Receive</string>
<string name="amountParsingFailed">Invalid amount</string>
<string name="addFromPdfFile">Select a PDF file</string>
<string name="errorReadingFile">Could not read the file</string>
<string name="failedLaunchingFileManager">Could not find a supported file manager</string>
<string name="multipleBarcodesFoundPleaseChooseOne">Which of the found barcodes do you want to use?</string>
<string name="pageWithNumber">Page <xliff:g>%d</xliff:g></string>
<string name="exportStartedCheckNotifications">Export started, check your notifications for the result</string>
<string name="importStartedCheckNotifications">Import started, check your notifications for the result</string>
<string name="postNotificationsPermissionRequired">Permission to show notifications needed for this action…</string>
</resources>

View File

@@ -574,72 +574,6 @@ public class ImportExportTest {
}
}
class TestTaskCompleteListener implements ImportExportTask.TaskCompleteListener {
ImportExportResult result;
public void onTaskComplete(ImportExportResult result, DataFormat dataFormat) {
this.result = result;
}
}
@Test
@LooperMode(LooperMode.Mode.PAUSED)
public void useImportExportTask() throws FileNotFoundException {
final int NUM_CARDS = 10;
final File sdcardDir = Environment.getExternalStorageDirectory();
final File exportFile = new File(sdcardDir, "Catima.csv");
TestHelpers.addLoyaltyCards(mDatabase, NUM_CARDS);
TestTaskCompleteListener listener = new TestTaskCompleteListener();
// Export to the file
final String password = "123456789";
FileOutputStream fileOutputStream = new FileOutputStream(exportFile);
ImportExportTask task = new ImportExportTask(activity, DataFormat.Catima, fileOutputStream, password.toCharArray(), listener);
TaskHandler mTasks = new TaskHandler();
mTasks.executeTask(TaskHandler.TYPE.EXPORT, task);
// Actually run the task to completion
mTasks.flushTaskList(TaskHandler.TYPE.EXPORT, false, false, true);
shadowOf(Looper.getMainLooper()).idleFor(Duration.ofMillis(5000));
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
// Check that the listener was executed
assertNotNull(listener.result);
assertEquals(ImportExportResultType.Success, listener.result.resultType());
TestHelpers.getEmptyDb(activity);
// Import everything back from the default location
listener = new TestTaskCompleteListener();
FileInputStream fileStream = new FileInputStream(exportFile);
task = new ImportExportTask(activity, DataFormat.Catima, fileStream, password.toCharArray(), listener);
mTasks.executeTask(TaskHandler.TYPE.IMPORT, task);
// Actually run the task to completion
// I am CONVINCED there must be a better way than to wait on this Queue with a flush.
mTasks.flushTaskList(TaskHandler.TYPE.IMPORT, false, false, true);
shadowOf(Looper.getMainLooper()).idleFor(Duration.ofMillis(5000));
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
// Check that the listener was executed
assertNotNull(listener.result);
assertEquals(ImportExportResultType.Success, listener.result.resultType());
assertEquals(NUM_CARDS, DBHelper.getLoyaltyCardCount(mDatabase));
checkLoyaltyCards();
// Clear the database for the next format under test
TestHelpers.getEmptyDb(activity);
}
@Test
public void importWithoutColorsV1() {
InputStream inputStream = getClass().getResourceAsStream("catima_v1_no_colors.csv");

View File

@@ -308,7 +308,7 @@ public class LoyaltyCardViewActivityTest {
final String barcodeId, final String barcodeType,
final Bitmap frontImage, final Bitmap backImage) {
if (mode == ViewMode.VIEW_CARD) {
checkFieldProperties(activity, R.id.card_id_view, View.VISIBLE, cardId, FieldTypeView.TextView);
checkFieldProperties(activity, R.id.main_image_description, View.VISIBLE, cardId, FieldTypeView.TextView);
} else {
int editVisibility = View.VISIBLE;

View File

@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.application") version "8.2.2" apply false
id("com.android.application") version "8.4.1" apply false
id("com.github.spotbugs") version "5.1.4" apply false
}

View File

@@ -4,7 +4,6 @@ Copylefted libre software (GPLv3+) card management app.
[![GitHub Version](https://img.shields.io/github/v/release/TheLastProject/Catima.svg?logo=github&label=GitHub)](https://github.com/TheLastProject/Catima/releases)
[![IzzyOnDroid Version](https://img.shields.io/endpoint?url=https://apt.izzysoft.de/fdroid/api/v1/shield/me.hackerchick.catima)](https://apt.izzysoft.de/fdroid/index/apk/me.hackerchick.catima)
[![F-Droid Version](https://img.shields.io/f-droid/v/me.hackerchick.catima.svg?logo=f-droid&label=F-Droid)](https://f-droid.org/packages/me.hackerchick.catima/)
[![Google Play Store Version](https://img.shields.io/endpoint?color=blue&logo=google-play&url=https%3A%2F%2Fplay.cuzi.workers.dev%2Fplay%3Fi%3Dme.hackerchick.catima%26l%3DGoogle%2520Play%26m%3D%24version)](https://play.google.com/store/apps/details?id=me.hackerchick.catima)
![Android CI](https://github.com/TheLastProject/Catima/workflows/Android%20CI/badge.svg)
@@ -14,8 +13,6 @@ Copylefted libre software (GPLv3+) card management app.
<a href="https://apt.izzysoft.de/fdroid/index/apk/me.hackerchick.catima" target="_blank">
<img src="https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png" alt="Get it on IzzyOnDroid" height="90"/></a>
<a href="https://f-droid.org/repository/browse/?fdid=me.hackerchick.catima" target="_blank">
<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="90"/></a>
<a href="https://play.google.com/store/apps/details?id=me.hackerchick.catima" target="_blank">
<img src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" alt="Get it on Google Play" height="90"/></a>
@@ -60,7 +57,7 @@ For FidMe you need to select the barcode type for each entry afterwards.
# Building
Building can either be done through Android Studio (not reproducible!) or the build.sh script in this repository (reproducibly with OpenJDK 17, same way F-Droid builds it). This script can also sign the build.
Building can either be done through Android Studio (not reproducible!) or the build.sh script in this repository (reproducible with OpenJDK 17). This script can also sign the build.
Build without signing:
```

View File

@@ -5,8 +5,9 @@
2. Merge Weblate pull request
3. Update `CHANGELOG.md` with the new version name and the release date
4. Update `app/build.gradle.kts` with the new `versionCode` and `versionName`
5. Build a new .apk: `KEYSTORE=/path/to/keystore KEYSTORE_ALIAS=catima ./build.sh`
6. Upload the APK to Google Play Open Testing
7. Push the version update: `git add CHANGELOG.md app/build.gradle.kts && git commit -m "Release Catima <VERSION>" && git push`
8. Create a new release on GitHub and attach the `app-release.apk` and `SHA256SUMS` files
9. After the release has been approved on Google Play Production, update the metadata there: `bundle exec fastlane supply --version_code <VERSION_CODE>`
5. Create a commit for the new release: `git add CHANGELOG.md app/build.gradle.kts && git commit -m "Release Catima <VERSION>"`
6. Build a new .apk: `KEYSTORE=/path/to/keystore KEYSTORE_ALIAS=catima ./build.sh`
7. Upload the APK to Google Play Open Testing
8. Push the version update commit: `git push`
9. Create a new release on GitHub and attach the `app-release.apk` and `SHA256SUMS` files
10. After the release has been approved on Google Play Production, update the metadata there: `bundle exec fastlane supply --version_code <VERSION_CODE>`

View File

@@ -0,0 +1 @@
- تم تغيير اسم ملف الاستيراد/التصدير الافتراضي. (سحب رقم 84 (https://github.com/brarcher/loyalty-card-locker/pull/84)) - السلسلة الصحيحة في صفحة الاستيراد/التصدير. (سحب رقم 87 (https://github.com/brarcher/loyalty-card-locker/pull/87)) - تحسين تخطيط صفحة عرض البطاقة. يجب أن يكون النص أسهل في القراءة، ويمكن تحديده بنقرة طويلة. (سحب رقم 91 (https://github.com/brarcher/loyalty-card-locker/pull/91))

View File

@@ -0,0 +1,3 @@
- إصلاح cropper لايمكنه استخدم لون السمة
- إصلاح مشاكل السمات البسيطة
- إضافة سمة سوداء خالصة داكنة لشاشات OLED

View File

@@ -0,0 +1,2 @@
- إصلاحات طفيفة مختلفة
- إصلاح العطل عند استخدام الترجمة النرويجية

View File

@@ -0,0 +1,2 @@
- إصلاح عدم تطبيق الاختيار اليدوي للغة في كل مكان
- إصلاح العطل في طريقة عرض التحرير على لغة بلا منطقة

View File

@@ -0,0 +1,2 @@
- حفظ حالة توسيع تفاصيل البطاقة
- إصلاحات بسيطة لواجهة المستخدم

View File

@@ -0,0 +1,2 @@
- إصلاح ظهور الكتلة الرمادية على قيمة غير صالحة للباركود
- إصلاحات استيراد Stocard

View File

@@ -0,0 +1 @@
- إصلاح بعض تسلسلات الأحرف التي تظهر كحرف واحد

View File

@@ -0,0 +1 @@
- إصلاحات استيراد Stocard

View File

@@ -1 +1,4 @@
- Cílový systém Android 14
- Otevření ikony karty v galerii na dotykovém displeji
- Vylepšení designu karty Fotografie ve zobrazení úprav
- Aktualizována obrazovka výdajů s podporou příjmů

View File

@@ -1,7 +1,7 @@
- Unterstützung der arabischen Sprache
- Arabisch wird unterstützt
- Anzeige der archivierten Kartenanzahl in der Gruppenübersicht
- Behebung von Fehlern bei der Guthabenanalyse (Karten in arabischer oder anderen nicht-westlichen Zahlen wurden nicht gespeichert)
- Benutzerdefiniertes Thema wird nicht korrekt auf den Hauptbildschirm angewendet
- Verbesserte Anzeige der ausgewählten Karten
- Absturz beim Verlassen der Kartenansicht in RTL-Layouts für Karten mit Ablaufdatum oder Guthaben behoben
- Rückwärtspfeil in der Kartenansicht zeigt in RTL-Layouts nicht mehr in die falsche Richtung
- Guthabenanalyse - Fehler beseitigt (Arabisch bzw. Sprachen mit nicht-westlichen Zahlen wurden nicht gespeichert)
- Benutzerdefiniertes Thema wird nun korrekt auf dem Hauptbildschirm gezeigt
- Verbesserte Anzeige ausgewählter Karten
- Kein Absturz beim Verlassen der Kartenansicht bei Karten mit Ablaufdatum/Guthaben
- Rückwärtspfeil in der Kartenansicht zeigt nicht mehr die falsche Richtung (RTL-Layout)

View File

@@ -1 +1,4 @@
- auf Android 14 richten
- Angepasst für Android 14
- „Touch“ auf Karten-Symbol öffnet dieses in Galerie
- Design der Registerkarte „Fotos“ in der Bearbeitungsansicht verbessert
- Bildschirm für „Guthaben“ aktualisiert, um auch „Einnahmen“ anzeigen zu können

View File

@@ -1,4 +1,4 @@
- Einstellung zur Steuerung der Bildschirmhelligkeit bei der Bacrode-Anzeige (Pull #259 (https://github.com/brarcher/loyalty-card-locker/pull/259))
- Griechische Übersetzungen hinzugefügt (Pull #252 (https://github.com/brarcher/loyalty-card-locker/pull/252))
- Slowenischen Übersetzungen hinzugefügt (Pull #260 (https://github.com/brarcher/loyalty-card-locker/pull/260))
- Steuerung der Bildschirmhelligkeit bei Anzeige des Barcode eingefügt (Pull #259 (https://github.com/brarcher/loyalty-card-locker/pull/259))
- Griechisch eingefügt (Pull #252 (https://github.com/brarcher/loyalty-card-locker/pull/252))
- Slowenisch eingefügt (Pull #260 (https://github.com/brarcher/loyalty-card-locker/pull/260))
- Übersetzungen aktualisiert (pull #260 (https://github.com/brarcher/loyalty-card-locker/pull/260), pull #254 (https://github.com/brarcher/loyalty-card-locker/pull/254))

View File

@@ -1,3 +1,4 @@
- Target Android 14
- Open card icon in gallery on touch
- Improve design of Photos tab in edit view
- Improve design of Photos tab in edit view
- Update spending screen to also support receiving

View File

@@ -0,0 +1,3 @@
- Support for scanning PDF files for barcodes
- Support for image files with multiple barcodes
- Minor UI fixes

View File

@@ -0,0 +1 @@
- Various fixes and improvements to balance handling

View File

@@ -0,0 +1,2 @@
- Support for creating a card when sharing plain text
- Display image type instead of barcode below images

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 104 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 56 KiB

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