mirror of
https://github.com/CatimaLoyalty/Android.git
synced 2025-12-26 16:47:57 -05:00
Compare commits
229 Commits
create-pul
...
remove/col
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0160511a7 | ||
|
|
d4cf9afa77 | ||
|
|
104e2dff05 | ||
|
|
7681b1bc94 | ||
|
|
87b39c518d | ||
|
|
2940f4a8e8 | ||
|
|
31fc10bda5 | ||
|
|
1fc0777efe | ||
|
|
df22a638da | ||
|
|
150e895c9d | ||
|
|
69c38966f2 | ||
|
|
73b6cc9fda | ||
|
|
f683b6bdb6 | ||
|
|
94beaef74b | ||
|
|
7a44108cf6 | ||
|
|
4a5006adef | ||
|
|
61e26262b0 | ||
|
|
6ca0f0e176 | ||
|
|
7f9ae158ec | ||
|
|
2b1c7f739d | ||
|
|
5a3f7c17ed | ||
|
|
329c2049c3 | ||
|
|
2e51bd1ffa | ||
|
|
1a8c6d6e90 | ||
|
|
64a31b5729 | ||
|
|
2dcc94e534 | ||
|
|
81cbc9f5e9 | ||
|
|
0d68735b60 | ||
|
|
bb8591b0ef | ||
|
|
e513ab4a09 | ||
|
|
e162fac30a | ||
|
|
3ae93cc1ad | ||
|
|
59001d466a | ||
|
|
c8dcdedae0 | ||
|
|
0c61abf4f0 | ||
|
|
8e5e875fe0 | ||
|
|
e6d7065461 | ||
|
|
8b87a4612c | ||
|
|
e8d7293e2a | ||
|
|
c283feb699 | ||
|
|
b895a9bc48 | ||
|
|
0d33319ad4 | ||
|
|
2af9d58f06 | ||
|
|
427e9d6482 | ||
|
|
e21fd954d3 | ||
|
|
e7f47c7a5a | ||
|
|
54c6dac322 | ||
|
|
cf64958562 | ||
|
|
ea31a3b42a | ||
|
|
353dbedbb9 | ||
|
|
a87c446c31 | ||
|
|
85f1d06b02 | ||
|
|
17d3e9b3d0 | ||
|
|
de47b9e774 | ||
|
|
acfa8d9fe2 | ||
|
|
930246e6c5 | ||
|
|
c6b8272448 | ||
|
|
24b832a217 | ||
|
|
3acf002f95 | ||
|
|
16f9b3f6b1 | ||
|
|
3c38c7cc25 | ||
|
|
efbc930125 | ||
|
|
90b326e6b9 | ||
|
|
d3e7fe212d | ||
|
|
803d83f8e1 | ||
|
|
59b060fbc0 | ||
|
|
6d64bd4cdf | ||
|
|
ada4850f65 | ||
|
|
479fce68d5 | ||
|
|
2c0b49d7f8 | ||
|
|
e534eebc4d | ||
|
|
db16676cc4 | ||
|
|
0f1e5b858b | ||
|
|
a39d2e46e1 | ||
|
|
4370cd2383 | ||
|
|
0c4ef730e0 | ||
|
|
ee909e0047 | ||
|
|
6eee4a25f3 | ||
|
|
ffa99231c6 | ||
|
|
cbcd74f735 | ||
|
|
4f46a3c8ab | ||
|
|
5cec75c4c7 | ||
|
|
38d3731027 | ||
|
|
2a9f911a39 | ||
|
|
c762fcf6cc | ||
|
|
59db6642c3 | ||
|
|
eb5168ef83 | ||
|
|
7221ea64c8 | ||
|
|
af17bde7c5 | ||
|
|
67e2abde8b | ||
|
|
f28a9e7ba3 | ||
|
|
96f01b6a2c | ||
|
|
56bc429c4b | ||
|
|
163da4b021 | ||
|
|
6d9c168125 | ||
|
|
ccaef1adc5 | ||
|
|
f73222597c | ||
|
|
1714606744 | ||
|
|
ac3ef7fb36 | ||
|
|
9417814268 | ||
|
|
72737074fb | ||
|
|
e05386620b | ||
|
|
7cfe1ad833 | ||
|
|
00b975a140 | ||
|
|
424e57e41a | ||
|
|
cdb169c4e0 | ||
|
|
17aa18397e | ||
|
|
bb72eefc7f | ||
|
|
a007ed6a8f | ||
|
|
2219e86576 | ||
|
|
7f90e06ac5 | ||
|
|
5dd089c976 | ||
|
|
ef9aacd609 | ||
|
|
fa19960c5e | ||
|
|
a5428b80ff | ||
|
|
56512101c2 | ||
|
|
2bc8312511 | ||
|
|
43ccf9b48e | ||
|
|
e1a4ed6634 | ||
|
|
272e249d5e | ||
|
|
5636653c16 | ||
|
|
06b1b32ce7 | ||
|
|
202936b21f | ||
|
|
122f7f64b7 | ||
|
|
fbb913862a | ||
|
|
61892f9f22 | ||
|
|
166056fedd | ||
|
|
e03c883a9c | ||
|
|
1b4559fa3c | ||
|
|
ae8487f8d9 | ||
|
|
922b517d37 | ||
|
|
5a0d99fc80 | ||
|
|
c89a759c8b | ||
|
|
4c81fdcefb | ||
|
|
7a35b7f598 | ||
|
|
e1108c08ac | ||
|
|
6ab943f776 | ||
|
|
aac3570431 | ||
|
|
3abf287c67 | ||
|
|
cb26d23b02 | ||
|
|
9afcb0d7c6 | ||
|
|
acc50c4fda | ||
|
|
91fab12da6 | ||
|
|
e094b969ee | ||
|
|
3103d3a9cf | ||
|
|
c82b255eaa | ||
|
|
9ee4f0da9b | ||
|
|
3b5e6ac450 | ||
|
|
7ab270f323 | ||
|
|
6f9b4739c8 | ||
|
|
e654a657a0 | ||
|
|
ae6567a784 | ||
|
|
be12707ab1 | ||
|
|
e8d40ec679 | ||
|
|
e9c40c88a9 | ||
|
|
82bb9b2817 | ||
|
|
976dd6f80b | ||
|
|
2ac36fa415 | ||
|
|
19399dd17f | ||
|
|
acae8c1a0d | ||
|
|
64073e210e | ||
|
|
3adbf61be7 | ||
|
|
f0df4622eb | ||
|
|
81c0f284f6 | ||
|
|
fce60ca712 | ||
|
|
2be4d1cd2b | ||
|
|
72b19a8272 | ||
|
|
9f9d404632 | ||
|
|
157d1ecc49 | ||
|
|
54b21167ec | ||
|
|
34a125008f | ||
|
|
1776f8fd90 | ||
|
|
55269f748f | ||
|
|
6e42d0dcd9 | ||
|
|
48113eba18 | ||
|
|
41c8bb1815 | ||
|
|
eab4f9e123 | ||
|
|
05f4cfc07b | ||
|
|
b07b09e703 | ||
|
|
42e69916f0 | ||
|
|
254c9fee14 | ||
|
|
66e568aa06 | ||
|
|
1f38110e94 | ||
|
|
e92a98a956 | ||
|
|
875e90e940 | ||
|
|
5ebd23a88a | ||
|
|
6559857ba2 | ||
|
|
684b3e9836 | ||
|
|
d4b4599496 | ||
|
|
decd0a104d | ||
|
|
177f8e43e2 | ||
|
|
75234a6cd4 | ||
|
|
86b5c2998e | ||
|
|
0fee650cee | ||
|
|
61ee8b5910 | ||
|
|
dae66a63f1 | ||
|
|
934d7ba041 | ||
|
|
32b4dd73aa | ||
|
|
e558e7f6e4 | ||
|
|
20cc714b52 | ||
|
|
abf26c92e4 | ||
|
|
89bdbe1544 | ||
|
|
afe930a29f | ||
|
|
fc28ad0088 | ||
|
|
58b1c67abf | ||
|
|
ba563023c1 | ||
|
|
efe9487a44 | ||
|
|
2140066c4d | ||
|
|
32a70f10c0 | ||
|
|
c5ef9f4b1d | ||
|
|
91a3548613 | ||
|
|
1f370b86dd | ||
|
|
a93ddcb76e | ||
|
|
69aa985318 | ||
|
|
2855cf4569 | ||
|
|
01878a5ced | ||
|
|
bfb68e4118 | ||
|
|
709fffcfe5 | ||
|
|
5c0474b38e | ||
|
|
986ae4f0cb | ||
|
|
04937e8839 | ||
|
|
071062a939 | ||
|
|
058dc6c79b | ||
|
|
13a78dadb4 | ||
|
|
bf12bc4f9d | ||
|
|
7986428149 | ||
|
|
e17cbd5c9a | ||
|
|
ebfb105fe4 | ||
|
|
7f4937552d |
5
.github/dependabot.yml
vendored
5
.github/dependabot.yml
vendored
@@ -9,10 +9,15 @@ updates:
|
||||
- mavenCentral
|
||||
schedule:
|
||||
interval: "daily"
|
||||
cooldown:
|
||||
default-days: 7
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
cooldown:
|
||||
default-days: 7
|
||||
|
||||
# Workaround for https://github.com/dependabot/dependabot-core/issues/6888
|
||||
registries:
|
||||
|
||||
6
.github/workflows/android.yml
vendored
6
.github/workflows/android.yml
vendored
@@ -32,9 +32,7 @@ jobs:
|
||||
matrix:
|
||||
flavor: [Foss, Gplay]
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Fail on bad translations
|
||||
run: if grep -ri "<xliff" app/src/main/res/values*/strings.xml; then echo "Invalidly escaped translations found"; exit 1; fi
|
||||
- uses: actions/checkout@v6
|
||||
- uses: gradle/actions/wrapper-validation@v5
|
||||
- name: set up OpenJDK 21
|
||||
run: |
|
||||
@@ -66,7 +64,7 @@ jobs:
|
||||
script: ./gradlew connected${{ matrix.flavor }}DebugAndroidTest
|
||||
- name: Archive test results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v5.0.0
|
||||
uses: actions/upload-artifact@v6.0.0
|
||||
with:
|
||||
name: test-results-flavor${{ matrix.flavor }}
|
||||
path: app/build/reports
|
||||
|
||||
6
.github/workflows/changelog-to-fastlane.yml
vendored
6
.github/workflows/changelog-to-fastlane.yml
vendored
@@ -19,15 +19,15 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
id: checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6.0.0
|
||||
uses: actions/setup-python@v6.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@v7.0.8
|
||||
uses: peter-evans/create-pull-request@v8.0.0
|
||||
with:
|
||||
title: "Update Fastlane changelogs"
|
||||
commit-message: "Update Fastlane changelogs"
|
||||
|
||||
4
.github/workflows/contributors-to-file.yml
vendored
4
.github/workflows/contributors-to-file.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
id: checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
- name: Update contributors
|
||||
id: update_contributors
|
||||
uses: TheLastProject/contributors-to-file-action@v3.2.0
|
||||
@@ -25,7 +25,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@v7.0.8
|
||||
uses: peter-evans/create-pull-request@v8.0.0
|
||||
with:
|
||||
title: "Update contributors"
|
||||
commit-message: "Update contributors"
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
generate-feature-graphic:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install requirements
|
||||
run: |
|
||||
sudo apt-get update
|
||||
@@ -31,7 +31,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@v7.0.8
|
||||
uses: peter-evans/create-pull-request@v8.0.0
|
||||
with:
|
||||
title: "Update feature graphic"
|
||||
commit-message: "Update feature graphic"
|
||||
|
||||
34
.github/workflows/i18n-check.yml
vendored
Normal file
34
.github/workflows/i18n-check.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
name: i18n check
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- staging
|
||||
- trying
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
permissions:
|
||||
actions: none
|
||||
checks: none
|
||||
contents: read
|
||||
deployments: none
|
||||
discussions: none
|
||||
id-token: none
|
||||
issues: none
|
||||
packages: none
|
||||
pages: none
|
||||
pull-requests: none
|
||||
repository-projects: none
|
||||
security-events: none
|
||||
statuses: none
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Fail on bad translations
|
||||
run: if grep -ri "<xliff" app/src/main/res/values*/strings.xml; then echo "Invalidly escaped translations found"; exit 1; fi
|
||||
- name: Check app_name consistency
|
||||
run: bash .scripts/check_app_name.sh
|
||||
2
.github/workflows/update-gradle-wrapper.yml
vendored
2
.github/workflows/update-gradle-wrapper.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Update Gradle Wrapper
|
||||
uses: gradle-update/update-gradle-wrapper-action@v2
|
||||
|
||||
4
.github/workflows/update-locales.yml
vendored
4
.github/workflows/update-locales.yml
vendored
@@ -17,13 +17,13 @@ jobs:
|
||||
update-locales:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- 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@v7.0.8
|
||||
uses: peter-evans/create-pull-request@v8.0.0
|
||||
with:
|
||||
title: "Update locales"
|
||||
commit-message: "Update locales"
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -19,8 +19,8 @@
|
||||
/app/*.log
|
||||
/app/build
|
||||
/app/release
|
||||
/.idea
|
||||
|
||||
/.idea/*
|
||||
!/.idea/icon.svg
|
||||
# Bundle
|
||||
/.bundle/
|
||||
/vendor/bundle
|
||||
|
||||
1
.idea/icon.svg
generated
Symbolic link
1
.idea/icon.svg
generated
Symbolic link
@@ -0,0 +1 @@
|
||||
../.design/ic_launcher_foreground.svg
|
||||
71
.scripts/check_app_name.sh
Normal file
71
.scripts/check_app_name.sh
Normal file
@@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
shopt -s lastpipe # Run last command in a pipeline in the current shell.
|
||||
|
||||
# Colors
|
||||
LIGHTCYAN='\033[1;36m'
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Vars
|
||||
SUCCESS=1
|
||||
CANONICAL_TITLE="Catima"
|
||||
ALLOWLIST=("ar" "bn" "fa" "fa-IR" "he-IL" "hi" "hi-IN" "kn" "kn-IN" "ml" "mr" "ta" "ta-IN" "zh-rTW" "zh-TW") # TODO: Link values and fastlane with different codes together
|
||||
|
||||
function get_lang() {
|
||||
LANG_DIRNAME=$(dirname "$FILE" | xargs basename)
|
||||
LANG=${LANG_DIRNAME#values-} # Fetch lang name
|
||||
LANG=${LANG#values} # Handle "app/src/main/res/values"
|
||||
LANG=${LANG:-en} # Default to en
|
||||
}
|
||||
|
||||
# FIXME: This function should use its own variables and return a success/fail status, instead of working on global variables
|
||||
function check() {
|
||||
# FIXME: This allows inconsistency between values and fastlane if the app name is not Catima
|
||||
# When the app name is not Catima, it should still check if title.txt and strings.xml use the same app name (or start)
|
||||
if echo "${ALLOWLIST[*]}" | grep -w -q "${LANG}" || [[ -z ${APP_NAME} ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ ${FILE} == *"title.txt" ]]; then
|
||||
if [[ ! ${APP_NAME} =~ ^${CANONICAL_TITLE} ]]; then
|
||||
echo -e "${RED}Error: ${LIGHTCYAN}title in $FILE ($LANG) is ${RED}'$APP_NAME'${LIGHTCYAN}, expected to start with ${GREEN}'$CANONICAL_TITLE'. ${NC}"
|
||||
SUCCESS=0
|
||||
fi
|
||||
else
|
||||
if [[ ${APP_NAME} != "${CANONICAL_TITLE}" ]]; then
|
||||
echo -e "${RED}Error: ${LIGHTCYAN}app_name in $FILE ($LANG) is ${RED}'$APP_NAME'${LIGHTCYAN}, expected ${GREEN}'$CANONICAL_TITLE'. ${NC}"
|
||||
SUCCESS=0
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# FIXME: This checks all title.txt and strings.xml files separately, but it needs to check if the title.txt and strings.xml match for a language as well
|
||||
echo -e "${LIGHTCYAN}Checking title.txt's. ${NC}"
|
||||
|
||||
find fastlane/metadata/android/* -maxdepth 1 -type f -name "title.txt" | while read -r FILE; do
|
||||
APP_NAME=$(head -n 1 "$FILE")
|
||||
|
||||
get_lang
|
||||
check
|
||||
done
|
||||
|
||||
echo -e "${LIGHTCYAN}Checking string.xml's. ${NC}"
|
||||
|
||||
find app/src/main/res/values* -maxdepth 1 -type f -name "strings.xml" | while read -r FILE; do
|
||||
# FIXME: This only checks app_name, but there are more strings with Catima inside it
|
||||
# It should check the original English text for all strings that contain Catima and ensure they use the correct app_name for consistency
|
||||
APP_NAME=$(grep -oP '<string name="app_name">\K[^<]+' "$FILE" | head -n1)
|
||||
|
||||
get_lang
|
||||
check
|
||||
done
|
||||
|
||||
if [[ $SUCCESS -eq 1 ]]; then
|
||||
echo -e "\n${GREEN}Success!! All app_name values match the canonical title. ${NC}"
|
||||
else
|
||||
echo -e "\n${RED}Unsuccessful!! Some app_name values did not match the canonical titles. ${NC}"
|
||||
exit 1
|
||||
fi
|
||||
@@ -42,7 +42,7 @@ for lang in "$script_location/../../fastlane/metadata/android/"*; do
|
||||
ja-JP) sed -i "s/Lexend/Noto Sans CJK JP/" featureGraphic.svg ;;
|
||||
kn-IN) sed -i -e 's/font-size="150"/font-size="125"/' -e 's/\(<tspan x="469" \)y="270"/\1y="240"/' -e "s/Lobster/Noto Sans Kannada/" -e "s/Lexend/Noto Sans Kannada/" featureGraphic.svg ;;
|
||||
ko) sed -i "s/Lexend/Noto Sans CJK KR/" featureGraphic.svg ;;
|
||||
ta-IN) sed -i -e 's/font-size="150"/font-size="125"/' featureGraphic.svg ;;
|
||||
ta-IN) sed -i -e 's/font-size="150"/font-size="125"/' -e 's/\(<tspan x="469" \)y="270"/\1y="240"/' featureGraphic.svg ;;
|
||||
zh-CN) sed -i "s/Lexend/Noto Sans CJK SC/" featureGraphic.svg ;;
|
||||
zh-TW) sed -i -e "s/Lobster/Noto Sans CJK TC/" -e "s/Lexend/Noto Sans CJK TC/" featureGraphic.svg ;;
|
||||
*) ;;
|
||||
|
||||
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,5 +1,21 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased - 157
|
||||
|
||||
- Add support for UTF-8 barcodes
|
||||
- Add duplicate option to main screen and reorder options slightly
|
||||
- Fix column count setting not being applied to group card list
|
||||
- Reduce max photo size to reduce storage use (only for newly added photos)
|
||||
|
||||
## v2.40.0 - 156 (2025-12-08)
|
||||
|
||||
- Copy card ID to clipboard from view dialog or long press
|
||||
- Swap balance and currency fields to hopefully reduce unintended rounding
|
||||
|
||||
## v2.39.2 - 155 (2025-11-04)
|
||||
|
||||
- Preparations for future improvements (rewrote many classes to Kotlin)
|
||||
|
||||
## v2.39.1 - 154 (2025-10-01)
|
||||
|
||||
- Fix possible crash that could occur for cards missing colour information in the database
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import com.android.build.gradle.internal.tasks.factory.dependsOn
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.com.android.application)
|
||||
alias(libs.plugins.org.jetbrains.kotlin.android)
|
||||
alias(libs.plugins.org.jetbrains.kotlin.plugin.compose)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
@@ -17,8 +19,8 @@ android {
|
||||
applicationId = "me.hackerchick.catima"
|
||||
minSdk = 21
|
||||
targetSdk = 36
|
||||
versionCode = 154
|
||||
versionName = "2.39.1"
|
||||
versionCode = 156
|
||||
versionName = "2.40.0"
|
||||
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
multiDexEnabled = true
|
||||
@@ -47,6 +49,7 @@ android {
|
||||
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
compose = true
|
||||
viewBinding = true
|
||||
}
|
||||
|
||||
@@ -74,16 +77,6 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
encoding = "UTF-8"
|
||||
|
||||
// Flag to enable support for the new language APIs
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
getByName("test") {
|
||||
resources.srcDirs("src/test/res")
|
||||
@@ -102,12 +95,21 @@ android {
|
||||
lint {
|
||||
lintConfig = file("lint.xml")
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = "21"
|
||||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
jvmTarget = JvmTarget.JVM_17
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
encoding = "UTF-8"
|
||||
|
||||
// Flag to enable support for the new language APIs
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +126,19 @@ dependencies {
|
||||
implementation(libs.com.google.android.material.material)
|
||||
coreLibraryDesugaring(libs.com.android.tools.desugar.jdk.libs)
|
||||
|
||||
// Compose
|
||||
implementation(libs.androidx.activity.activity.compose)
|
||||
val composeBom = platform(libs.androidx.compose.compose.bom)
|
||||
implementation(composeBom)
|
||||
implementation(libs.androidx.compose.foundation.foundation)
|
||||
implementation(libs.androidx.compose.material3.material3)
|
||||
implementation(libs.androidx.compose.material.material.icons.extended)
|
||||
implementation(libs.androidx.compose.ui.ui.tooling.preview.android)
|
||||
debugImplementation(libs.androidx.compose.ui.ui.test.manifest)
|
||||
|
||||
androidTestImplementation(composeBom)
|
||||
androidTestImplementation(libs.androidx.compose.ui.ui.test.junit4)
|
||||
|
||||
// Third-party
|
||||
implementation(libs.com.journeyapps.zxing.android.embedded)
|
||||
implementation(libs.com.github.yalantis.ucrop)
|
||||
@@ -143,6 +158,8 @@ dependencies {
|
||||
androidTestImplementation(libs.bundles.androidx.test)
|
||||
androidTestImplementation(libs.junit.junit)
|
||||
androidTestImplementation(libs.androidx.test.ext.junit)
|
||||
androidTestImplementation(libs.androidx.test.rules)
|
||||
androidTestImplementation(libs.androidx.test.runner)
|
||||
androidTestImplementation(libs.androidx.test.uiautomator.uiautomator)
|
||||
androidTestImplementation(libs.androidx.test.espresso.espresso.core)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package protect.card_locker
|
||||
|
||||
import android.app.Instrumentation
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.assertIsNotDisplayed
|
||||
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performScrollTo
|
||||
import androidx.compose.ui.test.runComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import protect.card_locker.compose.theme.CatimaTheme
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class AboutActivityTest {
|
||||
@get:Rule
|
||||
private val rule: ComposeContentTestRule = createComposeRule()
|
||||
|
||||
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
|
||||
|
||||
private val content: AboutContent = AboutContent(instrumentation.targetContext)
|
||||
|
||||
@Test
|
||||
fun testInitialState(): Unit = runComposeUiTest {
|
||||
setContent {
|
||||
AboutScreenContent(content = content)
|
||||
}
|
||||
|
||||
onNodeWithTag("topbar_catima").assertIsDisplayed()
|
||||
|
||||
onNodeWithTag("card_version_history").assertIsDisplayed()
|
||||
onNodeWithText(content.versionHistory).assertIsDisplayed()
|
||||
|
||||
onNodeWithTag("card_credits").assertIsDisplayed()
|
||||
onNodeWithText(content.copyrightShort).assertIsDisplayed()
|
||||
|
||||
onNodeWithTag("card_translate").assertIsDisplayed()
|
||||
onNodeWithTag("card_license").assertIsDisplayed()
|
||||
|
||||
// We might be off the screen so start scrolling
|
||||
onNodeWithTag("card_source_github").performScrollTo().assertIsDisplayed()
|
||||
onNodeWithTag("card_privacy_policy").performScrollTo().assertIsDisplayed()
|
||||
onNodeWithTag("card_donate").performScrollTo().assertIsDisplayed()
|
||||
// Dont scroll to this, since its not displayed
|
||||
onNodeWithTag("card_rate_google").assertIsNotDisplayed()
|
||||
onNodeWithTag("card_report_error").performScrollTo().assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDonateAndGoogleCardVisible(): Unit = runComposeUiTest {
|
||||
setContent {
|
||||
CatimaTheme {
|
||||
AboutScreenContent(
|
||||
content = content,
|
||||
showDonate = true,
|
||||
showRateOnGooglePlay = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
onNodeWithTag("card_donate").performScrollTo().assertIsDisplayed()
|
||||
onNodeWithTag("card_rate_google").performScrollTo().assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDonateAndGoogleCardHidden(): Unit = runComposeUiTest {
|
||||
setContent {
|
||||
CatimaTheme {
|
||||
AboutScreenContent(
|
||||
content = content,
|
||||
showDonate = false,
|
||||
showRateOnGooglePlay = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
onNodeWithTag("card_privacy_policy").performScrollTo().assertIsDisplayed()
|
||||
onNodeWithTag("card_donate").assertIsNotDisplayed()
|
||||
onNodeWithTag("card_rate_google").assertIsNotDisplayed()
|
||||
onNodeWithTag("card_report_error").performScrollTo().assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
@@ -1,149 +1,167 @@
|
||||
package protect.card_locker
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.Spanned
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.ScrollView
|
||||
import android.widget.TextView
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.OnBackPressedDispatcher
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.TextLinkStyles
|
||||
import androidx.compose.ui.text.fromHtml
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import protect.card_locker.compose.CatimaAboutSection
|
||||
import protect.card_locker.compose.CatimaTopAppBar
|
||||
import protect.card_locker.compose.theme.CatimaTheme
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.view.isVisible
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
|
||||
import protect.card_locker.databinding.AboutActivityBinding
|
||||
|
||||
class AboutActivity : CatimaAppCompatActivity() {
|
||||
private companion object {
|
||||
private const val TAG = "Catima"
|
||||
}
|
||||
|
||||
private lateinit var binding: AboutActivityBinding
|
||||
class AboutActivity : ComponentActivity() {
|
||||
private lateinit var content: AboutContent
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = AboutActivityBinding.inflate(layoutInflater)
|
||||
content = AboutContent(this)
|
||||
title = content.pageTitle
|
||||
setContentView(binding.root)
|
||||
setSupportActionBar(binding.toolbar)
|
||||
enableToolbarBackButton()
|
||||
|
||||
binding.apply {
|
||||
creditsSub.text = content.copyrightShort
|
||||
versionHistorySub.text = content.versionHistory
|
||||
|
||||
versionHistory.tag = "https://catima.app/changelog/"
|
||||
translate.tag = "https://hosted.weblate.org/engage/catima/"
|
||||
license.tag = "https://github.com/CatimaLoyalty/Android/blob/main/LICENSE"
|
||||
repo.tag = "https://github.com/CatimaLoyalty/Android/"
|
||||
privacy.tag = "https://catima.app/privacy-policy/"
|
||||
reportError.tag = "https://github.com/CatimaLoyalty/Android/issues"
|
||||
rate.tag = "https://play.google.com/store/apps/details?id=me.hackerchick.catima"
|
||||
donate.tag = "https://catima.app/donate"
|
||||
|
||||
// Hide Google Play rate button if not on Google Play
|
||||
rate.isVisible = BuildConfig.showRateOnGooglePlay
|
||||
// Hide donate button on Google Play (Google Play doesn't allow donation links)
|
||||
donate.isVisible = BuildConfig.showDonate
|
||||
}
|
||||
|
||||
bindClickListeners()
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
finish()
|
||||
true
|
||||
setContent {
|
||||
CatimaTheme {
|
||||
AboutScreenContent(
|
||||
content = content,
|
||||
showDonate = BuildConfig.showDonate,
|
||||
showRateOnGooglePlay = BuildConfig.showRateOnGooglePlay,
|
||||
onBackPressedDispatcher = onBackPressedDispatcher
|
||||
)
|
||||
}
|
||||
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
content.destroy()
|
||||
clearClickListeners()
|
||||
}
|
||||
|
||||
private fun bindClickListeners() {
|
||||
binding.apply {
|
||||
versionHistory.setOnClickListener { showHistory(it) }
|
||||
translate.setOnClickListener { openExternalBrowser(it) }
|
||||
license.setOnClickListener { showLicense(it) }
|
||||
repo.setOnClickListener { openExternalBrowser(it) }
|
||||
privacy.setOnClickListener { showPrivacy(it) }
|
||||
reportError.setOnClickListener { openExternalBrowser(it) }
|
||||
rate.setOnClickListener { openExternalBrowser(it) }
|
||||
donate.setOnClickListener { openExternalBrowser(it) }
|
||||
credits.setOnClickListener { showCredits() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearClickListeners() {
|
||||
binding.apply {
|
||||
versionHistory.setOnClickListener(null)
|
||||
translate.setOnClickListener(null)
|
||||
license.setOnClickListener(null)
|
||||
repo.setOnClickListener(null)
|
||||
privacy.setOnClickListener(null)
|
||||
reportError.setOnClickListener(null)
|
||||
rate.setOnClickListener(null)
|
||||
donate.setOnClickListener(null)
|
||||
credits.setOnClickListener(null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showCredits() {
|
||||
showHTML(R.string.credits, content.contributorInfo, null)
|
||||
}
|
||||
|
||||
private fun showHistory(view: View) {
|
||||
showHTML(R.string.version_history, content.historyInfo, view)
|
||||
}
|
||||
|
||||
private fun showLicense(view: View) {
|
||||
showHTML(R.string.license, content.licenseInfo, view)
|
||||
}
|
||||
|
||||
private fun showPrivacy(view: View) {
|
||||
showHTML(R.string.privacy_policy, content.privacyInfo, view)
|
||||
}
|
||||
|
||||
private fun showHTML(@StringRes title: Int, text: Spanned, view: View?) {
|
||||
val dialogContentPadding = resources.getDimensionPixelSize(R.dimen.alert_dialog_content_padding)
|
||||
val textView = TextView(this).apply {
|
||||
setText(text)
|
||||
Utils.makeTextViewLinksClickable(this, text)
|
||||
}
|
||||
|
||||
val scrollView = ScrollView(this).apply {
|
||||
addView(textView)
|
||||
setPadding(dialogContentPadding, dialogContentPadding / 2, dialogContentPadding, 0)
|
||||
}
|
||||
|
||||
MaterialAlertDialogBuilder(this).apply {
|
||||
setTitle(title)
|
||||
setView(scrollView)
|
||||
setPositiveButton(R.string.ok, null)
|
||||
|
||||
// Add View online button if an URL is linked to this view
|
||||
view?.tag?.let {
|
||||
setNeutralButton(R.string.view_online) { _, _ -> openExternalBrowser(view) }
|
||||
}
|
||||
|
||||
show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun openExternalBrowser(view: View) {
|
||||
val tag = view.tag
|
||||
if (tag is String && tag.startsWith("https://")) {
|
||||
OpenWebLinkHandler().openBrowser(this, tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AboutScreenContent(
|
||||
content: AboutContent,
|
||||
showDonate: Boolean = true,
|
||||
showRateOnGooglePlay: Boolean = false,
|
||||
onBackPressedDispatcher: OnBackPressedDispatcher? = null,
|
||||
) {
|
||||
Scaffold(
|
||||
topBar = { CatimaTopAppBar(content.pageTitle.toString(), onBackPressedDispatcher) }
|
||||
) { innerPadding ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(innerPadding)
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
CatimaAboutSection(
|
||||
stringResource(R.string.version_history),
|
||||
content.versionHistory,
|
||||
modifier = Modifier.testTag("card_version_history"),
|
||||
onClickUrl = "https://catima.app/changelog/",
|
||||
onClickDialogText = AnnotatedString.fromHtml(
|
||||
htmlString = content.historyHtml,
|
||||
linkStyles = TextLinkStyles(
|
||||
style = SpanStyle(
|
||||
textDecoration = TextDecoration.Underline,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
CatimaAboutSection(
|
||||
stringResource(R.string.credits),
|
||||
content.copyrightShort,
|
||||
modifier = Modifier.testTag("card_credits"),
|
||||
onClickDialogText = AnnotatedString.fromHtml(
|
||||
htmlString = content.contributorInfoHtml,
|
||||
linkStyles = TextLinkStyles(
|
||||
style = SpanStyle(
|
||||
textDecoration = TextDecoration.Underline,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
CatimaAboutSection(
|
||||
stringResource(R.string.help_translate_this_app),
|
||||
stringResource(R.string.translate_platform),
|
||||
modifier = Modifier.testTag("card_translate"),
|
||||
onClickUrl = "https://hosted.weblate.org/engage/catima/"
|
||||
)
|
||||
CatimaAboutSection(
|
||||
stringResource(R.string.license),
|
||||
stringResource(R.string.app_license),
|
||||
modifier = Modifier.testTag("card_license"),
|
||||
onClickUrl = "https://github.com/CatimaLoyalty/Android/blob/main/LICENSE",
|
||||
onClickDialogText = AnnotatedString.fromHtml(
|
||||
htmlString = content.licenseHtml,
|
||||
linkStyles = TextLinkStyles(
|
||||
style = SpanStyle(
|
||||
textDecoration = TextDecoration.Underline,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
CatimaAboutSection(
|
||||
stringResource(R.string.source_repository),
|
||||
stringResource(R.string.on_github),
|
||||
modifier = Modifier.testTag("card_source_github"),
|
||||
onClickUrl = "https://github.com/CatimaLoyalty/Android/"
|
||||
)
|
||||
CatimaAboutSection(
|
||||
stringResource(R.string.privacy_policy),
|
||||
stringResource(R.string.and_data_usage),
|
||||
modifier = Modifier.testTag("card_privacy_policy"),
|
||||
onClickUrl = "https://catima.app/privacy-policy/",
|
||||
onClickDialogText = AnnotatedString.fromHtml(
|
||||
htmlString = content.privacyHtml,
|
||||
linkStyles = TextLinkStyles(
|
||||
style = SpanStyle(
|
||||
textDecoration = TextDecoration.Underline,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
if (showDonate) {
|
||||
CatimaAboutSection(
|
||||
stringResource(R.string.donate),
|
||||
"",
|
||||
modifier = Modifier.testTag("card_donate"),
|
||||
onClickUrl = "https://catima.app/donate"
|
||||
)
|
||||
}
|
||||
if (showRateOnGooglePlay) {
|
||||
CatimaAboutSection(
|
||||
stringResource(R.string.rate_this_app),
|
||||
stringResource(R.string.on_google_play),
|
||||
modifier = Modifier.testTag("card_rate_google"),
|
||||
onClickUrl = "https://play.google.com/store/apps/details?id=me.hackerchick.catima"
|
||||
)
|
||||
}
|
||||
CatimaAboutSection(
|
||||
stringResource(R.string.report_error),
|
||||
stringResource(R.string.on_github),
|
||||
modifier = Modifier.testTag("card_report_error"),
|
||||
onClickUrl = "https://github.com/CatimaLoyalty/Android/issues"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun AboutActivityPreview() {
|
||||
AboutScreenContent(AboutContent(LocalContext.current))
|
||||
}
|
||||
|
||||
@@ -3,11 +3,8 @@ package protect.card_locker;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.text.Spanned;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.text.HtmlCompat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
@@ -55,7 +52,7 @@ public class AboutContent {
|
||||
return context.getString(R.string.app_copyright_short);
|
||||
}
|
||||
|
||||
public String getContributors() {
|
||||
public String getContributorsHtml() {
|
||||
String contributors;
|
||||
try {
|
||||
contributors = "<br/>" + Utils.readTextFile(context, R.raw.contributors);
|
||||
@@ -65,7 +62,7 @@ public class AboutContent {
|
||||
return contributors.replace("\n", "<br />");
|
||||
}
|
||||
|
||||
public String getHistory() {
|
||||
public String getHistoryHtml() {
|
||||
String versionHistory;
|
||||
try {
|
||||
versionHistory = Utils.readTextFile(context, R.raw.changelog)
|
||||
@@ -77,7 +74,7 @@ public class AboutContent {
|
||||
.replace("\n", "<br />");
|
||||
}
|
||||
|
||||
public String getLicense() {
|
||||
public String getLicenseHtml() {
|
||||
try {
|
||||
return Utils.readTextFile(context, R.raw.license);
|
||||
} catch (IOException ignored) {
|
||||
@@ -85,7 +82,7 @@ public class AboutContent {
|
||||
}
|
||||
}
|
||||
|
||||
public String getPrivacy() {
|
||||
public String getPrivacyHtml() {
|
||||
String privacyPolicy;
|
||||
try {
|
||||
privacyPolicy = Utils.readTextFile(context, R.raw.privacy)
|
||||
@@ -97,7 +94,7 @@ public class AboutContent {
|
||||
.replace("\n", "<br />");
|
||||
}
|
||||
|
||||
public String getThirdPartyLibraries() {
|
||||
public String getThirdPartyLibrariesHtml() {
|
||||
final List<ThirdPartyInfo> usedLibraries = new ArrayList<>();
|
||||
usedLibraries.add(new ThirdPartyInfo("ACRA", "https://github.com/ACRA/acra", "Apache 2.0"));
|
||||
usedLibraries.add(new ThirdPartyInfo("Color Picker", "https://github.com/jaredrummler/ColorPicker", "Apache 2.0"));
|
||||
@@ -116,7 +113,7 @@ public class AboutContent {
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public String getUsedThirdPartyAssets() {
|
||||
public String getUsedThirdPartyAssetsHtml() {
|
||||
final List<ThirdPartyInfo> usedAssets = new ArrayList<>();
|
||||
usedAssets.add(new ThirdPartyInfo("Android icons", "https://fonts.google.com/icons?selected=Material+Icons", "Apache 2.0"));
|
||||
|
||||
@@ -129,31 +126,19 @@ public class AboutContent {
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public Spanned getContributorInfo() {
|
||||
public String getContributorInfoHtml() {
|
||||
StringBuilder contributorInfo = new StringBuilder();
|
||||
contributorInfo.append(getCopyright());
|
||||
contributorInfo.append("<br/><br/>");
|
||||
contributorInfo.append(context.getString(R.string.app_copyright_old));
|
||||
contributorInfo.append("<br/><br/>");
|
||||
contributorInfo.append(String.format(context.getString(R.string.app_contributors), getContributors()));
|
||||
contributorInfo.append(String.format(context.getString(R.string.app_contributors), getContributorsHtml()));
|
||||
contributorInfo.append("<br/><br/>");
|
||||
contributorInfo.append(String.format(context.getString(R.string.app_libraries), getThirdPartyLibraries()));
|
||||
contributorInfo.append(String.format(context.getString(R.string.app_libraries), getThirdPartyLibrariesHtml()));
|
||||
contributorInfo.append("<br/><br/>");
|
||||
contributorInfo.append(String.format(context.getString(R.string.app_resources), getUsedThirdPartyAssets()));
|
||||
contributorInfo.append(String.format(context.getString(R.string.app_resources), getUsedThirdPartyAssetsHtml()));
|
||||
|
||||
return HtmlCompat.fromHtml(contributorInfo.toString(), HtmlCompat.FROM_HTML_MODE_COMPACT);
|
||||
}
|
||||
|
||||
public Spanned getHistoryInfo() {
|
||||
return HtmlCompat.fromHtml(getHistory(), HtmlCompat.FROM_HTML_MODE_COMPACT);
|
||||
}
|
||||
|
||||
public Spanned getLicenseInfo() {
|
||||
return HtmlCompat.fromHtml(getLicense(), HtmlCompat.FROM_HTML_MODE_LEGACY);
|
||||
}
|
||||
|
||||
public Spanned getPrivacyInfo() {
|
||||
return HtmlCompat.fromHtml(getPrivacy(), HtmlCompat.FROM_HTML_MODE_COMPACT);
|
||||
return contributorInfo.toString();
|
||||
}
|
||||
|
||||
public String getVersionHistory() {
|
||||
|
||||
@@ -4,17 +4,24 @@ import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.zxing.EncodeHintType;
|
||||
import com.google.zxing.MultiFormatWriter;
|
||||
import com.google.zxing.WriterException;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.common.StringUtils;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Map;
|
||||
|
||||
import protect.card_locker.async.CompatCallable;
|
||||
|
||||
@@ -39,6 +46,7 @@ public class BarcodeImageWriterTask implements CompatCallable<Bitmap> {
|
||||
private final WeakReference<TextView> textViewReference;
|
||||
private String cardId;
|
||||
private final CatimaBarcode format;
|
||||
private final Charset encoding;
|
||||
private final int imageHeight;
|
||||
private final int imageWidth;
|
||||
private final int imagePadding;
|
||||
@@ -48,7 +56,7 @@ public class BarcodeImageWriterTask implements CompatCallable<Bitmap> {
|
||||
|
||||
BarcodeImageWriterTask(
|
||||
Context context, ImageView imageView, String cardIdString,
|
||||
CatimaBarcode barcodeFormat, TextView textView,
|
||||
CatimaBarcode barcodeFormat, @Nullable Charset barcodeEncoding, TextView textView,
|
||||
boolean showFallback, BarcodeImageWriterResultCallback callback, boolean roundCornerPadding, boolean isFullscreen
|
||||
) {
|
||||
mContext = context;
|
||||
@@ -62,6 +70,7 @@ public class BarcodeImageWriterTask implements CompatCallable<Bitmap> {
|
||||
|
||||
cardId = cardIdString;
|
||||
format = barcodeFormat;
|
||||
encoding = barcodeEncoding;
|
||||
|
||||
int imageViewHeight = imageView.getHeight();
|
||||
int imageViewWidth = imageView.getWidth();
|
||||
@@ -172,10 +181,22 @@ public class BarcodeImageWriterTask implements CompatCallable<Bitmap> {
|
||||
}
|
||||
|
||||
MultiFormatWriter writer = new MultiFormatWriter();
|
||||
|
||||
Map<EncodeHintType, Object> encodeHints = new ArrayMap<>();
|
||||
// Use charset if defined or guess otherwise
|
||||
if (encoding != null) {
|
||||
Log.d(TAG, "Encoding explicitly set, " + encoding.name());
|
||||
encodeHints.put(EncodeHintType.CHARACTER_SET, encoding);
|
||||
} else {
|
||||
String guessedEncoding = StringUtils.guessEncoding(cardId.getBytes(), new ArrayMap<>());
|
||||
Log.d(TAG, "Guessed encoding: " + guessedEncoding);
|
||||
encodeHints.put(EncodeHintType.CHARACTER_SET, Charset.forName(guessedEncoding));
|
||||
}
|
||||
|
||||
BitMatrix bitMatrix;
|
||||
try {
|
||||
try {
|
||||
bitMatrix = writer.encode(cardId, format.format(), imageWidth, imageHeight, null);
|
||||
bitMatrix = writer.encode(cardId, format.format(), imageWidth, imageHeight, encodeHints);
|
||||
} catch (Exception e) {
|
||||
// Cast a wider net here and catch any exception, as there are some
|
||||
// cases where an encoder may fail if the data is invalid for the
|
||||
|
||||
@@ -92,13 +92,13 @@ public class BarcodeSelectorAdapter extends ArrayAdapter<CatimaBarcodeWithValue>
|
||||
|
||||
Log.d(TAG, "Generating barcode for type " + formatType);
|
||||
|
||||
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getContext(), image, cardId, format, text, true, null, true, false);
|
||||
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getContext(), image, cardId, format, null, text, true, null, true, false);
|
||||
mTasks.executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.d(TAG, "Generating barcode for type " + formatType);
|
||||
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getContext(), image, cardId, format, text, true, null, true, false);
|
||||
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getContext(), image, cardId, format, null, text, true, null, true, false);
|
||||
mTasks.executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,11 @@ import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Currency;
|
||||
@@ -23,7 +26,7 @@ import java.util.Set;
|
||||
public class DBHelper extends SQLiteOpenHelper {
|
||||
public static final String DATABASE_NAME = "Catima.db";
|
||||
public static final int ORIGINAL_DATABASE_VERSION = 1;
|
||||
public static final int DATABASE_VERSION = 17;
|
||||
public static final int DATABASE_VERSION = 18;
|
||||
|
||||
// NB: changing these values requires a migration
|
||||
public static final int DEFAULT_ZOOM_LEVEL = 100;
|
||||
@@ -49,6 +52,7 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
public static final String CARD_ID = "cardid";
|
||||
public static final String BARCODE_ID = "barcodeid";
|
||||
public static final String BARCODE_TYPE = "barcodetype";
|
||||
public static final String BARCODE_ENCODING = "barcodeencoding";
|
||||
public static final String STAR_STATUS = "starstatus";
|
||||
public static final String LAST_USED = "lastused";
|
||||
public static final String ZOOM_LEVEL = "zoomlevel";
|
||||
@@ -112,6 +116,7 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
LoyaltyCardDbIds.CARD_ID + " TEXT not null," +
|
||||
LoyaltyCardDbIds.BARCODE_ID + " TEXT," +
|
||||
LoyaltyCardDbIds.BARCODE_TYPE + " TEXT," +
|
||||
LoyaltyCardDbIds.BARCODE_ENCODING + " TEXT," +
|
||||
LoyaltyCardDbIds.STAR_STATUS + " INTEGER DEFAULT '0'," +
|
||||
LoyaltyCardDbIds.LAST_USED + " INTEGER DEFAULT '0', " +
|
||||
LoyaltyCardDbIds.ZOOM_LEVEL + " INTEGER DEFAULT '" + DEFAULT_ZOOM_LEVEL + "', " +
|
||||
@@ -335,6 +340,11 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
db.execSQL("ALTER TABLE " + LoyaltyCardDbIds.TABLE
|
||||
+ " ADD COLUMN " + LoyaltyCardDbIds.ZOOM_LEVEL_WIDTH + " INTEGER DEFAULT '100' ");
|
||||
}
|
||||
|
||||
if (oldVersion < 18 && newVersion >= 18) {
|
||||
db.execSQL("ALTER TABLE " + LoyaltyCardDbIds.TABLE
|
||||
+ " ADD COLUMN " + LoyaltyCardDbIds.BARCODE_ENCODING + " TEXT");
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<String> imageFiles(Context context, final SQLiteDatabase database) {
|
||||
@@ -396,7 +406,8 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
public static long insertLoyaltyCard(
|
||||
final SQLiteDatabase database, final String store, final String note, final Date validFrom,
|
||||
final Date expiry, final BigDecimal balance, final Currency balanceType, final String cardId,
|
||||
final String barcodeId, final CatimaBarcode barcodeType, final Integer headerColor,
|
||||
final String barcodeId, final CatimaBarcode barcodeType, final @Nullable Charset barcodeEncoding,
|
||||
final Integer headerColor,
|
||||
final int starStatus, final Long lastUsed, final int archiveStatus) {
|
||||
database.beginTransaction();
|
||||
|
||||
@@ -411,6 +422,7 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_ID, barcodeId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType != null ? barcodeType.name() : null);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_ENCODING, barcodeEncoding != null ? barcodeEncoding.name() : null);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_COLOR, headerColor);
|
||||
contentValues.put(LoyaltyCardDbIds.STAR_STATUS, starStatus);
|
||||
contentValues.put(LoyaltyCardDbIds.LAST_USED, lastUsed != null ? lastUsed : Utils.getUnixTime());
|
||||
@@ -430,7 +442,8 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
final SQLiteDatabase database, final int id, final String store, final String note,
|
||||
final Date validFrom, final Date expiry, final BigDecimal balance,
|
||||
final Currency balanceType, final String cardId, final String barcodeId,
|
||||
final CatimaBarcode barcodeType, final Integer headerColor, final int starStatus,
|
||||
final CatimaBarcode barcodeType, final @Nullable Charset barcodeEncoding,
|
||||
final Integer headerColor, final int starStatus,
|
||||
final Long lastUsed, final int archiveStatus) {
|
||||
database.beginTransaction();
|
||||
|
||||
@@ -446,6 +459,7 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_ID, barcodeId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType != null ? barcodeType.name() : null);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_ENCODING, barcodeEncoding != null ? barcodeEncoding.name() : null);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_COLOR, headerColor);
|
||||
contentValues.put(LoyaltyCardDbIds.STAR_STATUS, starStatus);
|
||||
contentValues.put(LoyaltyCardDbIds.LAST_USED, lastUsed != null ? lastUsed : Utils.getUnixTime());
|
||||
@@ -465,7 +479,8 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
SQLiteDatabase database, final int id, final String store, final String note,
|
||||
final Date validFrom, final Date expiry, final BigDecimal balance,
|
||||
final Currency balanceType, final String cardId, final String barcodeId,
|
||||
final CatimaBarcode barcodeType, final Integer headerColor, final int starStatus,
|
||||
final CatimaBarcode barcodeType, final @Nullable Charset barcodeEncoding,
|
||||
final Integer headerColor, final int starStatus,
|
||||
final Long lastUsed, final int archiveStatus) {
|
||||
database.beginTransaction();
|
||||
|
||||
@@ -480,6 +495,7 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_ID, barcodeId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType != null ? barcodeType.name() : null);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_ENCODING, barcodeEncoding != null ? barcodeEncoding.name() : null);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_COLOR, headerColor);
|
||||
contentValues.put(LoyaltyCardDbIds.STAR_STATUS, starStatus);
|
||||
contentValues.put(LoyaltyCardDbIds.LAST_USED, lastUsed != null ? lastUsed : Utils.getUnixTime());
|
||||
|
||||
@@ -4,11 +4,14 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Currency;
|
||||
import java.util.Date;
|
||||
@@ -25,6 +28,7 @@ public class ImportURIHelper {
|
||||
private static final String CARD_ID = DBHelper.LoyaltyCardDbIds.CARD_ID;
|
||||
private static final String BARCODE_ID = DBHelper.LoyaltyCardDbIds.BARCODE_ID;
|
||||
private static final String BARCODE_TYPE = DBHelper.LoyaltyCardDbIds.BARCODE_TYPE;
|
||||
private static final String BARCODE_ENCODING = DBHelper.LoyaltyCardDbIds.BARCODE_ENCODING;
|
||||
private static final String HEADER_COLOR = DBHelper.LoyaltyCardDbIds.HEADER_COLOR;
|
||||
|
||||
private final Context context;
|
||||
@@ -66,6 +70,7 @@ public class ImportURIHelper {
|
||||
try {
|
||||
// These values are allowed to be null
|
||||
CatimaBarcode barcodeType = null;
|
||||
Charset barcodeEncoding = null;
|
||||
Date validFrom = null;
|
||||
Date expiry = null;
|
||||
BigDecimal balance = new BigDecimal("0");
|
||||
@@ -103,6 +108,11 @@ public class ImportURIHelper {
|
||||
barcodeType = CatimaBarcode.fromName(unparsedBarcodeType);
|
||||
}
|
||||
|
||||
String unparsedBarcodeEncoding = kv.get(BARCODE_ENCODING);
|
||||
if (unparsedBarcodeEncoding != null && !unparsedBarcodeEncoding.equals("")) {
|
||||
barcodeEncoding = Charset.forName(unparsedBarcodeEncoding);
|
||||
}
|
||||
|
||||
String unparsedBalance = kv.get(BALANCE);
|
||||
if (unparsedBalance != null && !unparsedBalance.equals("")) {
|
||||
balance = new BigDecimal(unparsedBalance);
|
||||
@@ -136,6 +146,7 @@ public class ImportURIHelper {
|
||||
cardId,
|
||||
barcodeId,
|
||||
barcodeType,
|
||||
barcodeEncoding,
|
||||
headerColor,
|
||||
0,
|
||||
Utils.getUnixTime(),
|
||||
@@ -195,6 +206,9 @@ public class ImportURIHelper {
|
||||
if (loyaltyCard.barcodeType != null) {
|
||||
fragment = appendFragment(fragment, BARCODE_TYPE, loyaltyCard.barcodeType.name());
|
||||
}
|
||||
if (loyaltyCard.barcodeEncoding != null) {
|
||||
fragment = appendFragment(fragment, BARCODE_ENCODING, loyaltyCard.barcodeEncoding.name());
|
||||
}
|
||||
if (loyaltyCard.headerColor != null) {
|
||||
fragment = appendFragment(fragment, HEADER_COLOR, loyaltyCard.headerColor.toString());
|
||||
}
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.TextPaint;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.graphics.PaintCompat;
|
||||
|
||||
/**
|
||||
* Original from https://github.com/andOTP/andOTP/blob/master/app/src/main/java/org/shadowice/flocke/andotp/Utilities/LetterBitmap.java
|
||||
* which was originally from http://stackoverflow.com/questions/23122088/colored-boxed-with-letters-a-la-gmail
|
||||
* Used to create a {@link Bitmap} that contains a letter used in the English
|
||||
* alphabet or digit, if there is no letter or digit available, a default image
|
||||
* is shown instead.
|
||||
*/
|
||||
class LetterBitmap {
|
||||
/**
|
||||
* The letter bitmap
|
||||
*/
|
||||
private final Bitmap mBitmap;
|
||||
/**
|
||||
* The background color of the letter bitmap
|
||||
*/
|
||||
private final Integer mColor;
|
||||
|
||||
/**
|
||||
* Constructor for <code>LetterTileProvider</code>
|
||||
*
|
||||
* @param context The {@link Context} to use
|
||||
* @param displayName The name used to create the letter for the tile
|
||||
* @param key The key used to generate the background color for the tile
|
||||
* @param tileLetterFontSize The font size used to display the letter
|
||||
* @param width The desired width of the tile
|
||||
* @param height The desired height of the tile
|
||||
* @param backgroundColor (optional) color to use for background.
|
||||
* @param textColor (optional) color to use for text.
|
||||
*/
|
||||
public LetterBitmap(Context context, String displayName, String key, int tileLetterFontSize,
|
||||
int width, int height, Integer backgroundColor, Integer textColor) {
|
||||
TextPaint paint = new TextPaint();
|
||||
|
||||
if (textColor != null) {
|
||||
paint.setColor(textColor);
|
||||
} else {
|
||||
paint.setColor(Color.WHITE);
|
||||
}
|
||||
|
||||
paint.setTextAlign(Paint.Align.CENTER);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setTextSize(tileLetterFontSize);
|
||||
paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
|
||||
|
||||
if (backgroundColor == null) {
|
||||
mColor = getDefaultColor(context, key);
|
||||
} else {
|
||||
mColor = backgroundColor;
|
||||
}
|
||||
|
||||
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
String firstChar = displayName.substring(0, 1).toUpperCase();
|
||||
int firstCharEnd = 2;
|
||||
while (firstCharEnd <= displayName.length()) {
|
||||
// Test for the longest render-able string
|
||||
// But ignore containing only a-Z0-9 to not render things like ffi as a single character
|
||||
String test = displayName.substring(0, firstCharEnd);
|
||||
if (!isAlphabetical(test) && PaintCompat.hasGlyph(paint, test)) {
|
||||
firstChar = test;
|
||||
}
|
||||
firstCharEnd++;
|
||||
}
|
||||
|
||||
Log.d("LetterBitmap", "using sequence " + firstChar + " to render first char which has length " + firstChar.length());
|
||||
|
||||
final Canvas c = new Canvas();
|
||||
c.setBitmap(mBitmap);
|
||||
c.drawColor(mColor);
|
||||
|
||||
Rect bounds = new Rect();
|
||||
paint.getTextBounds(firstChar, 0, firstChar.length(), bounds);
|
||||
c.drawText(firstChar,
|
||||
0, firstChar.length(),
|
||||
width / 2.0f, (height - (bounds.bottom + bounds.top)) / 2.0f
|
||||
, paint);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A {@link Bitmap} that contains a letter used in the English
|
||||
* alphabet or digit, if there is no letter or digit available, a
|
||||
* default image is shown instead
|
||||
*/
|
||||
public Bitmap getLetterTile() {
|
||||
return mBitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return background color used for letter title.
|
||||
*/
|
||||
public int getBackgroundColor() {
|
||||
return mColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key The key used to generate the tile color
|
||||
* @return A new or previously chosen color for <code>key</code> used as the
|
||||
* tile background color
|
||||
*/
|
||||
private static int pickColor(String key, TypedArray colors) {
|
||||
// String.hashCode() is not supposed to change across java versions, so
|
||||
// this should guarantee the same key always maps to the same color
|
||||
final int color = Math.abs(key.hashCode()) % colors.length();
|
||||
return colors.getColor(color, Color.BLACK);
|
||||
}
|
||||
|
||||
private static boolean isAlphabetical(String string) {
|
||||
return string.matches("[a-zA-Z0-9]*");
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the color which the letter tile will use if no default
|
||||
* color is provided.
|
||||
*/
|
||||
public static int getDefaultColor(Context context, String key) {
|
||||
final Resources res = context.getResources();
|
||||
|
||||
TypedArray colors = res.obtainTypedArray(R.array.letter_tile_colors);
|
||||
int color = pickColor(key, colors);
|
||||
colors.recycle();
|
||||
|
||||
return color;
|
||||
}
|
||||
}
|
||||
136
app/src/main/java/protect/card_locker/LetterBitmap.kt
Normal file
136
app/src/main/java/protect/card_locker/LetterBitmap.kt
Normal file
@@ -0,0 +1,136 @@
|
||||
package protect.card_locker
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.TypedArray
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Rect
|
||||
import android.graphics.Typeface
|
||||
import android.text.TextPaint
|
||||
import android.util.Log
|
||||
import androidx.core.graphics.PaintCompat
|
||||
import java.util.Locale
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
* Original from https://github.com/andOTP/andOTP/blob/master/app/src/main/java/org/shadowice/flocke/andotp/Utilities/LetterBitmap.java
|
||||
* which was originally from http://stackoverflow.com/questions/23122088/colored-boxed-with-letters-a-la-gmail
|
||||
* Used to create a {@link Bitmap} that contains a letter used in the English
|
||||
* alphabet or digit, if there is no letter or digit available, a default image
|
||||
* is shown instead.
|
||||
*
|
||||
* @constructor Constructor for <code>LetterTileProvider</code>
|
||||
* @param context The {@link Context} to use
|
||||
* @param displayName The name used to create the letter for the tile
|
||||
* @param key The key used to generate the background color for the tile
|
||||
* @param tileLetterFontSize The font size used to display the letter
|
||||
* @param width The desired width of the tile
|
||||
* @param height The desired height of the tile
|
||||
* @param backgroundColor (optional) color to use for background.
|
||||
* @param textColor (optional) color to use for text.
|
||||
*/
|
||||
class LetterBitmap(
|
||||
context: Context, displayName: String, key: String, tileLetterFontSize: Int,
|
||||
width: Int, height: Int, backgroundColor: Int?, textColor: Int?
|
||||
) {
|
||||
/**
|
||||
* A {@link Bitmap} that contains a letter used in the English
|
||||
* alphabet or digit, if there is no letter or digit available, a
|
||||
* default image is shown instead
|
||||
*/
|
||||
private val letterTile: Bitmap
|
||||
|
||||
/**
|
||||
* The background color of the letter bitmap
|
||||
*/
|
||||
private val mColor: Int
|
||||
|
||||
init {
|
||||
val paint = TextPaint().apply {
|
||||
color = textColor ?: Color.WHITE
|
||||
textAlign = Paint.Align.CENTER
|
||||
isAntiAlias = true
|
||||
textSize = tileLetterFontSize.toFloat()
|
||||
typeface = Typeface.defaultFromStyle(Typeface.BOLD)
|
||||
}
|
||||
|
||||
mColor = backgroundColor ?: getDefaultColor(context, key)
|
||||
|
||||
this.letterTile = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
|
||||
var firstChar = displayName.substring(0, 1).uppercase(Locale.getDefault())
|
||||
var firstCharEnd = 2
|
||||
while (firstCharEnd <= displayName.length) {
|
||||
// Test for the longest render-able string
|
||||
// But ignore containing only a-Z0-9 to not render things like ffi as a single character
|
||||
val test = displayName.substring(0, firstCharEnd)
|
||||
if (!isAlphabetical(test) && PaintCompat.hasGlyph(paint, test)) {
|
||||
firstChar = test
|
||||
}
|
||||
firstCharEnd++
|
||||
}
|
||||
|
||||
Log.d(
|
||||
"LetterBitmap",
|
||||
"using sequence $firstChar to render first char which has length ${firstChar.length}"
|
||||
)
|
||||
|
||||
Canvas().apply {
|
||||
setBitmap(this@LetterBitmap.letterTile)
|
||||
drawColor(mColor)
|
||||
|
||||
val bounds = Rect()
|
||||
paint.getTextBounds(firstChar, 0, firstChar.length, bounds)
|
||||
drawText(
|
||||
firstChar,
|
||||
0, firstChar.length,
|
||||
width / 2.0f, (height - (bounds.bottom + bounds.top)) / 2.0f,
|
||||
paint
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val backgroundColor: Int
|
||||
/**
|
||||
* @return background color used for letter title.
|
||||
*/
|
||||
get() = mColor
|
||||
|
||||
fun getLetterTile(): Bitmap {
|
||||
return letterTile
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* @param key The key used to generate the tile color
|
||||
* @return A new or previously chosen color for `key` used as the
|
||||
* tile background color
|
||||
*/
|
||||
private fun pickColor(key: String, colors: TypedArray): Int {
|
||||
// String.hashCode() is not supposed to change across java versions, so
|
||||
// this should guarantee the same key always maps to the same color
|
||||
val color = abs(key.hashCode()) % colors.length()
|
||||
return colors.getColor(color, Color.BLACK)
|
||||
}
|
||||
|
||||
private fun isAlphabetical(string: String): Boolean {
|
||||
return string.matches("[a-zA-Z0-9]*".toRegex())
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the color which the letter tile will use if no default
|
||||
* color is provided.
|
||||
*/
|
||||
fun getDefaultColor(context: Context, key: String): Int {
|
||||
val res = context.resources
|
||||
|
||||
val colors = res.obtainTypedArray(R.array.letter_tile_colors)
|
||||
val color: Int = pickColor(key, colors)
|
||||
colors.recycle()
|
||||
|
||||
return color
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Currency;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@@ -31,6 +32,8 @@ public class LoyaltyCard {
|
||||
@Nullable
|
||||
public CatimaBarcode barcodeType;
|
||||
@Nullable
|
||||
public Charset barcodeEncoding;
|
||||
@Nullable
|
||||
public Integer headerColor;
|
||||
public int starStatus;
|
||||
public long lastUsed;
|
||||
@@ -62,6 +65,7 @@ public class LoyaltyCard {
|
||||
public static final String BUNDLE_LOYALTY_CARD_CARD_ID = "loyaltyCardCardId";
|
||||
public static final String BUNDLE_LOYALTY_CARD_BARCODE_ID = "loyaltyCardBarcodeId";
|
||||
public static final String BUNDLE_LOYALTY_CARD_BARCODE_TYPE = "loyaltyCardBarcodeType";
|
||||
public static final String BUNDLE_LOYALTY_CARD_BARCODE_ENCODING = "loyaltyCardBarcodeEncoding";
|
||||
public static final String BUNDLE_LOYALTY_CARD_HEADER_COLOR = "loyaltyCardHeaderColor";
|
||||
public static final String BUNDLE_LOYALTY_CARD_STAR_STATUS = "loyaltyCardStarStatus";
|
||||
public static final String BUNDLE_LOYALTY_CARD_LAST_USED = "loyaltyCardLastUsed";
|
||||
@@ -90,6 +94,7 @@ public class LoyaltyCard {
|
||||
setCardId("");
|
||||
setBarcodeId(null);
|
||||
setBarcodeType(null);
|
||||
setBarcodeEncoding(null);
|
||||
setHeaderColor(null);
|
||||
setStarStatus(0);
|
||||
setLastUsed(Utils.getUnixTime());
|
||||
@@ -124,7 +129,7 @@ public class LoyaltyCard {
|
||||
public LoyaltyCard(final int id, final String store, final String note, @Nullable final Date validFrom,
|
||||
@Nullable final Date expiry, final BigDecimal balance, @Nullable final Currency balanceType,
|
||||
final String cardId, @Nullable final String barcodeId, @Nullable final CatimaBarcode barcodeType,
|
||||
@Nullable final Integer headerColor, final int starStatus,
|
||||
@Nullable final Charset barcodeEncoding, @Nullable final Integer headerColor, final int starStatus,
|
||||
final long lastUsed, final int zoomLevel, final int zoomLevelWidth, final int archiveStatus,
|
||||
@Nullable Bitmap imageThumbnail, @Nullable String imageThumbnailPath,
|
||||
@Nullable Bitmap imageFront, @Nullable String imageFrontPath,
|
||||
@@ -139,6 +144,7 @@ public class LoyaltyCard {
|
||||
setCardId(cardId);
|
||||
setBarcodeId(barcodeId);
|
||||
setBarcodeType(barcodeType);
|
||||
setBarcodeEncoding(barcodeEncoding);
|
||||
setHeaderColor(headerColor);
|
||||
setStarStatus(starStatus);
|
||||
setLastUsed(lastUsed);
|
||||
@@ -244,6 +250,10 @@ public class LoyaltyCard {
|
||||
this.barcodeType = barcodeType;
|
||||
}
|
||||
|
||||
public void setBarcodeEncoding(@Nullable Charset barcodeEncoding) {
|
||||
this.barcodeEncoding = barcodeEncoding;
|
||||
}
|
||||
|
||||
public void setHeaderColor(@Nullable Integer headerColor) {
|
||||
this.headerColor = headerColor;
|
||||
}
|
||||
@@ -379,6 +389,11 @@ public class LoyaltyCard {
|
||||
} else if (requireFull) {
|
||||
throw new IllegalArgumentException("Missing key " + BUNDLE_LOYALTY_CARD_BARCODE_TYPE);
|
||||
}
|
||||
if (bundle.containsKey(BUNDLE_LOYALTY_CARD_BARCODE_ENCODING)) {
|
||||
setBarcodeEncoding(Charset.forName(bundle.getString(BUNDLE_LOYALTY_CARD_BARCODE_ENCODING)));
|
||||
} else if (requireFull) {
|
||||
throw new IllegalArgumentException("Missing key " + BUNDLE_LOYALTY_CARD_BARCODE_ENCODING);
|
||||
}
|
||||
if (bundle.containsKey(BUNDLE_LOYALTY_CARD_HEADER_COLOR)) {
|
||||
int tmpHeaderColor = bundle.getInt(BUNDLE_LOYALTY_CARD_HEADER_COLOR);
|
||||
setHeaderColor(tmpHeaderColor != -1 ? tmpHeaderColor : null);
|
||||
@@ -462,6 +477,9 @@ public class LoyaltyCard {
|
||||
if (!exportIsLimited || exportLimit.contains(BUNDLE_LOYALTY_CARD_BARCODE_TYPE)) {
|
||||
bundle.putString(BUNDLE_LOYALTY_CARD_BARCODE_TYPE, barcodeType != null ? barcodeType.name() : null);
|
||||
}
|
||||
if (!exportIsLimited || exportLimit.contains(BUNDLE_LOYALTY_CARD_BARCODE_ENCODING)) {
|
||||
bundle.putString(BUNDLE_LOYALTY_CARD_BARCODE_ENCODING, barcodeEncoding != null ? barcodeEncoding.name() : null);
|
||||
}
|
||||
if (!exportIsLimited || exportLimit.contains(BUNDLE_LOYALTY_CARD_HEADER_COLOR)) {
|
||||
bundle.putInt(BUNDLE_LOYALTY_CARD_HEADER_COLOR, headerColor != null ? headerColor : -1);
|
||||
}
|
||||
@@ -539,6 +557,9 @@ public class LoyaltyCard {
|
||||
// barcodeType
|
||||
int barcodeTypeColumn = cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE);
|
||||
CatimaBarcode barcodeType = !cursor.isNull(barcodeTypeColumn) ? CatimaBarcode.fromName(cursor.getString(barcodeTypeColumn)) : null;
|
||||
// barcodeEncoding
|
||||
int barcodeEncodingColumn = cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_ENCODING);
|
||||
Charset barcodeEncoding = !cursor.isNull(barcodeEncodingColumn) ? Charset.forName(cursor.getString(barcodeEncodingColumn)) : null;
|
||||
// headerColor
|
||||
int headerColorColumn = cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_COLOR);
|
||||
Integer headerColor = !cursor.isNull(headerColorColumn) ? cursor.getInt(headerColorColumn) : null;
|
||||
@@ -564,6 +585,7 @@ public class LoyaltyCard {
|
||||
cardId,
|
||||
barcodeId,
|
||||
barcodeType,
|
||||
barcodeEncoding,
|
||||
headerColor,
|
||||
starStatus,
|
||||
lastUsed,
|
||||
@@ -593,6 +615,7 @@ public class LoyaltyCard {
|
||||
Utils.equals(a.barcodeId, b.barcodeId) && // nullable String
|
||||
Utils.equals(a.barcodeType == null ? null : a.barcodeType.format(),
|
||||
b.barcodeType == null ? null : b.barcodeType.format()) && // nullable CatimaBarcode with no overridden .equals(), so we need to check .format()
|
||||
Utils.equals(a.barcodeEncoding, b.barcodeEncoding) && // nullable String
|
||||
Utils.equals(a.headerColor, b.headerColor) && // nullable Integer
|
||||
a.starStatus == b.starStatus && // non-nullable int
|
||||
a.archiveStatus == b.archiveStatus && // non-nullable int
|
||||
@@ -619,7 +642,7 @@ public class LoyaltyCard {
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"LoyaltyCard{%n id=%s,%n store=%s,%n note=%s,%n validFrom=%s,%n expiry=%s,%n"
|
||||
+ " balance=%s,%n balanceType=%s,%n cardId=%s,%n barcodeId=%s,%n barcodeType=%s,%n"
|
||||
+ " balance=%s,%n balanceType=%s,%n cardId=%s,%n barcodeId=%s,%n barcodeType=%s,%n barcodeEncoding=%s,%n"
|
||||
+ " headerColor=%s,%n starStatus=%s,%n lastUsed=%s,%n zoomLevel=%s,%n zoomLevelWidth=%s,%n archiveStatus=%s%n"
|
||||
+ " imageThumbnail=%s,%n imageThumbnailPath=%s,%n imageFront=%s,%n imageFrontPath=%s,%n imageBack=%s,%n imageBackPath=%s,%n}",
|
||||
this.id,
|
||||
@@ -632,6 +655,7 @@ public class LoyaltyCard {
|
||||
this.cardId,
|
||||
this.barcodeId,
|
||||
this.barcodeType != null ? this.barcodeType.format() : null,
|
||||
this.barcodeEncoding != null ? this.barcodeEncoding.name() : null,
|
||||
this.headerColor,
|
||||
this.starStatus,
|
||||
this.lastUsed,
|
||||
|
||||
@@ -70,6 +70,8 @@ import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
@@ -123,11 +125,12 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
|
||||
ChipGroup groupsChips;
|
||||
AutoCompleteTextView validFromField;
|
||||
AutoCompleteTextView expiryField;
|
||||
EditText balanceField;
|
||||
AutoCompleteTextView balanceCurrencyField;
|
||||
EditText balanceField;
|
||||
TextView cardIdFieldView;
|
||||
AutoCompleteTextView barcodeIdField;
|
||||
AutoCompleteTextView barcodeTypeField;
|
||||
AutoCompleteTextView barcodeEncodingField;
|
||||
ImageView barcodeImage;
|
||||
View barcodeImageLayout;
|
||||
View barcodeCaptureLayout;
|
||||
@@ -148,9 +151,9 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
|
||||
boolean onRestoring = false;
|
||||
AlertDialog confirmExitDialog = null;
|
||||
|
||||
boolean validBalance = true;
|
||||
HashMap<String, Currency> currencies = new HashMap<>();
|
||||
HashMap<String, String> currencySymbols = new HashMap<>();
|
||||
boolean validBalance = true;
|
||||
|
||||
ActivityResultLauncher<Uri> mPhotoTakerLauncher;
|
||||
ActivityResultLauncher<Intent> mPhotoPickerLauncher;
|
||||
@@ -193,14 +196,14 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
|
||||
viewModel.setHasChanged(true);
|
||||
}
|
||||
|
||||
protected void setLoyaltyCardBalance(@NonNull BigDecimal balance) {
|
||||
viewModel.getLoyaltyCard().setBalance(balance);
|
||||
protected void setLoyaltyCardBalanceType(@Nullable Currency balanceType) {
|
||||
viewModel.getLoyaltyCard().setBalanceType(balanceType);
|
||||
|
||||
viewModel.setHasChanged(true);
|
||||
}
|
||||
|
||||
protected void setLoyaltyCardBalanceType(@Nullable Currency balanceType) {
|
||||
viewModel.getLoyaltyCard().setBalanceType(balanceType);
|
||||
protected void setLoyaltyCardBalance(@NonNull BigDecimal balance) {
|
||||
viewModel.getLoyaltyCard().setBalance(balance);
|
||||
|
||||
viewModel.setHasChanged(true);
|
||||
}
|
||||
@@ -229,6 +232,14 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
|
||||
viewModel.setHasChanged(true);
|
||||
}
|
||||
|
||||
protected void setLoyaltyCardBarcodeEncoding(@Nullable Charset barcodeEncoding) {
|
||||
viewModel.getLoyaltyCard().setBarcodeEncoding(barcodeEncoding);
|
||||
|
||||
generateBarcode();
|
||||
|
||||
viewModel.setHasChanged(true);
|
||||
}
|
||||
|
||||
protected void setLoyaltyCardHeaderColor(@Nullable Integer headerColor) {
|
||||
viewModel.getLoyaltyCard().setHeaderColor(headerColor);
|
||||
|
||||
@@ -329,11 +340,12 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
|
||||
groupsChips = binding.groupChips;
|
||||
validFromField = binding.validFromField;
|
||||
expiryField = binding.expiryField;
|
||||
balanceField = binding.balanceField;
|
||||
balanceCurrencyField = binding.balanceCurrencyField;
|
||||
balanceField = binding.balanceField;
|
||||
cardIdFieldView = binding.cardIdView;
|
||||
barcodeIdField = binding.barcodeIdField;
|
||||
barcodeTypeField = binding.barcodeTypeField;
|
||||
barcodeEncodingField = binding.barcodeEncodingField;
|
||||
barcodeImage = binding.barcode;
|
||||
barcodeImage.setClipToOutline(true);
|
||||
barcodeImageLayout = binding.barcodeLayout;
|
||||
@@ -373,33 +385,6 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
|
||||
|
||||
setMaterialDatePickerResultListener();
|
||||
|
||||
balanceField.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (!hasFocus && !onResuming && !onRestoring) {
|
||||
if (balanceField.getText().toString().isEmpty()) {
|
||||
setLoyaltyCardBalance(BigDecimal.valueOf(0));
|
||||
}
|
||||
|
||||
balanceField.setText(Utils.formatBalanceWithoutCurrencySymbol(viewModel.getLoyaltyCard().balance, viewModel.getLoyaltyCard().balanceType));
|
||||
}
|
||||
});
|
||||
|
||||
balanceField.addTextChangedListener(new SimpleTextWatcher() {
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
if (onResuming || onRestoring) return;
|
||||
try {
|
||||
BigDecimal balance = Utils.parseBalance(s.toString(), viewModel.getLoyaltyCard().balanceType);
|
||||
setLoyaltyCardBalance(balance);
|
||||
balanceField.setError(null);
|
||||
validBalance = true;
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
balanceField.setError(getString(R.string.balanceParsingFailed));
|
||||
validBalance = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
balanceCurrencyField.addTextChangedListener(new SimpleTextWatcher() {
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
@@ -452,6 +437,33 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
|
||||
}
|
||||
});
|
||||
|
||||
balanceField.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (!hasFocus && !onResuming && !onRestoring) {
|
||||
if (balanceField.getText().toString().isEmpty()) {
|
||||
setLoyaltyCardBalance(BigDecimal.valueOf(0));
|
||||
}
|
||||
|
||||
balanceField.setText(Utils.formatBalanceWithoutCurrencySymbol(viewModel.getLoyaltyCard().balance, viewModel.getLoyaltyCard().balanceType));
|
||||
}
|
||||
});
|
||||
|
||||
balanceField.addTextChangedListener(new SimpleTextWatcher() {
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
if (onResuming || onRestoring) return;
|
||||
try {
|
||||
BigDecimal balance = Utils.parseBalance(s.toString(), viewModel.getLoyaltyCard().balanceType);
|
||||
setLoyaltyCardBalance(balance);
|
||||
balanceField.setError(null);
|
||||
validBalance = true;
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
balanceField.setError(getString(R.string.balanceParsingFailed));
|
||||
validBalance = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cardIdFieldView.addTextChangedListener(new SimpleTextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
@@ -577,6 +589,30 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
|
||||
}
|
||||
});
|
||||
|
||||
barcodeEncodingField.addTextChangedListener(new SimpleTextWatcher() {
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
if (!s.toString().isEmpty()) {
|
||||
Log.d(TAG, "Setting barcode encoding to " + s.toString());
|
||||
if (s.toString().equals(getString(R.string.automatic))) {
|
||||
setLoyaltyCardBarcodeEncoding(null);
|
||||
} else {
|
||||
setLoyaltyCardBarcodeEncoding(Charset.forName(s.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
ArrayList<String> barcodeEncodingList = new ArrayList<>();
|
||||
barcodeEncodingList.add(getString(R.string.automatic));
|
||||
barcodeEncodingList.add(StandardCharsets.ISO_8859_1.name());
|
||||
barcodeEncodingList.add(StandardCharsets.UTF_8.name());
|
||||
ArrayAdapter<String> barcodeEncodingAdapter = new ArrayAdapter<>(LoyaltyCardEditActivity.this, android.R.layout.select_dialog_item, barcodeEncodingList);
|
||||
barcodeEncodingField.setAdapter(barcodeEncodingAdapter);
|
||||
}
|
||||
});
|
||||
|
||||
binding.tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||
@Override
|
||||
public void onTabSelected(TabLayout.Tab tab) {
|
||||
@@ -773,6 +809,8 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
|
||||
barcodeIdField.setText(barcodeId != null && !barcodeId.isEmpty() ? barcodeId : getString(R.string.sameAsCardId));
|
||||
CatimaBarcode barcodeType = viewModel.getLoyaltyCard().barcodeType;
|
||||
barcodeTypeField.setText(barcodeType != null ? barcodeType.prettyName() : getString(R.string.noBarcode));
|
||||
Charset barcodeEncoding = viewModel.getLoyaltyCard().barcodeEncoding;
|
||||
barcodeEncodingField.setText(barcodeEncoding != null ? barcodeEncoding.name() : getString(R.string.automatic));
|
||||
|
||||
// We set the balance here (with onResuming/onRestoring == true) to prevent formatBalanceCurrencyField() from setting it (via onTextChanged),
|
||||
// which can cause issues when switching locale because it parses the balance and e.g. the decimal separator may have changed.
|
||||
@@ -1479,9 +1517,9 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
|
||||
// This makes the DBHelper set it to the current date
|
||||
// So that new and edited card are always on top when sorting by recently used
|
||||
if (viewModel.getUpdateLoyaltyCard()) {
|
||||
DBHelper.updateLoyaltyCard(mDatabase, viewModel.getLoyaltyCardId(), viewModel.getLoyaltyCard().store, viewModel.getLoyaltyCard().note, viewModel.getLoyaltyCard().validFrom, viewModel.getLoyaltyCard().expiry, viewModel.getLoyaltyCard().balance, viewModel.getLoyaltyCard().balanceType, viewModel.getLoyaltyCard().cardId, viewModel.getLoyaltyCard().barcodeId, viewModel.getLoyaltyCard().barcodeType, viewModel.getLoyaltyCard().headerColor, viewModel.getLoyaltyCard().starStatus, null, viewModel.getLoyaltyCard().archiveStatus);
|
||||
DBHelper.updateLoyaltyCard(mDatabase, viewModel.getLoyaltyCardId(), viewModel.getLoyaltyCard().store, viewModel.getLoyaltyCard().note, viewModel.getLoyaltyCard().validFrom, viewModel.getLoyaltyCard().expiry, viewModel.getLoyaltyCard().balance, viewModel.getLoyaltyCard().balanceType, viewModel.getLoyaltyCard().cardId, viewModel.getLoyaltyCard().barcodeId, viewModel.getLoyaltyCard().barcodeType, viewModel.getLoyaltyCard().barcodeEncoding, viewModel.getLoyaltyCard().headerColor, viewModel.getLoyaltyCard().starStatus, null, viewModel.getLoyaltyCard().archiveStatus);
|
||||
} else {
|
||||
viewModel.setLoyaltyCardId((int) DBHelper.insertLoyaltyCard(mDatabase, viewModel.getLoyaltyCard().store, viewModel.getLoyaltyCard().note, viewModel.getLoyaltyCard().validFrom, viewModel.getLoyaltyCard().expiry, viewModel.getLoyaltyCard().balance, viewModel.getLoyaltyCard().balanceType, viewModel.getLoyaltyCard().cardId, viewModel.getLoyaltyCard().barcodeId, viewModel.getLoyaltyCard().barcodeType, viewModel.getLoyaltyCard().headerColor, 0, null, 0));
|
||||
viewModel.setLoyaltyCardId((int) DBHelper.insertLoyaltyCard(mDatabase, viewModel.getLoyaltyCard().store, viewModel.getLoyaltyCard().note, viewModel.getLoyaltyCard().validFrom, viewModel.getLoyaltyCard().expiry, viewModel.getLoyaltyCard().balance, viewModel.getLoyaltyCard().balanceType, viewModel.getLoyaltyCard().cardId, viewModel.getLoyaltyCard().barcodeId, viewModel.getLoyaltyCard().barcodeType, viewModel.getLoyaltyCard().barcodeEncoding, viewModel.getLoyaltyCard().headerColor, 0, null, 0));
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -1596,6 +1634,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
|
||||
|
||||
String cardIdString = viewModel.getLoyaltyCard().barcodeId != null ? viewModel.getLoyaltyCard().barcodeId : viewModel.getLoyaltyCard().cardId;
|
||||
CatimaBarcode barcodeFormat = viewModel.getLoyaltyCard().barcodeType;
|
||||
Charset barcodeEncoding = viewModel.getLoyaltyCard().barcodeEncoding;
|
||||
|
||||
if (cardIdString == null || cardIdString.isEmpty() || barcodeFormat == null) {
|
||||
barcodeImageLayout.setVisibility(View.GONE);
|
||||
@@ -1615,13 +1654,13 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
|
||||
barcodeImage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
|
||||
Log.d(TAG, "ImageView size now known");
|
||||
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, null, false, LoyaltyCardEditActivity.this, true, false);
|
||||
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, barcodeEncoding, null, false, LoyaltyCardEditActivity.this, true, false);
|
||||
viewModel.getTaskHandler().executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.d(TAG, "ImageView size known known, creating barcode");
|
||||
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, null, false, this, true, false);
|
||||
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, barcodeEncoding, null, false, this, true, false);
|
||||
viewModel.getTaskHandler().executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
@@ -38,6 +39,7 @@ import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
@@ -57,6 +59,7 @@ import com.google.zxing.BarcodeFormat;
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
@@ -86,6 +89,8 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
String cardIdString;
|
||||
String barcodeIdString;
|
||||
CatimaBarcode format;
|
||||
@Nullable
|
||||
Charset barcodeEncoding;
|
||||
|
||||
Bitmap frontImageBitmap;
|
||||
Bitmap backImageBitmap;
|
||||
@@ -685,6 +690,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
format = loyaltyCard.barcodeType;
|
||||
cardIdString = loyaltyCard.cardId;
|
||||
barcodeIdString = loyaltyCard.barcodeId;
|
||||
barcodeEncoding = loyaltyCard.barcodeEncoding;
|
||||
|
||||
binding.mainImageDescription.setText(loyaltyCard.cardId);
|
||||
|
||||
@@ -704,10 +710,22 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(LoyaltyCardViewActivity.this);
|
||||
builder.setTitle(R.string.cardId);
|
||||
builder.setView(cardIdView);
|
||||
builder.setPositiveButton(R.string.ok, (dialogInterface, i) -> dialogInterface.dismiss());
|
||||
builder.setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.dismiss());
|
||||
builder.setNeutralButton(R.string.copy_value, (dialog, which) -> {
|
||||
copyCardIdToClipboard();
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
});
|
||||
binding.mainImageDescription.setOnLongClickListener(view -> {
|
||||
if (mainImageIndex != 0) {
|
||||
// Don't copy to clipboard, we're showing something else
|
||||
return false;
|
||||
}
|
||||
|
||||
copyCardIdToClipboard();
|
||||
return true;
|
||||
});
|
||||
|
||||
int backgroundHeaderColor = Utils.getHeaderColor(this, loyaltyCard);
|
||||
|
||||
@@ -946,6 +964,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
barcodeRenderTarget,
|
||||
barcodeIdString != null ? barcodeIdString : cardIdString,
|
||||
format,
|
||||
barcodeEncoding,
|
||||
null,
|
||||
false,
|
||||
this,
|
||||
@@ -1247,4 +1266,20 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void copyCardIdToClipboard() {
|
||||
// Take the value that’s already displayed to the user
|
||||
String value = loyaltyCard.cardId;
|
||||
|
||||
if (value == null || value.isEmpty()) {
|
||||
Toast.makeText(this, R.string.nothing_to_copy, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText(getString(R.string.cardId), value);
|
||||
cm.setPrimaryClip(clip);
|
||||
|
||||
Toast.makeText(this, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,882 +0,0 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.SearchManager;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.CursorIndexOutOfBoundsException;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.view.ActionMode;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.core.splashscreen.SplashScreen;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
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.preferences.Settings;
|
||||
import protect.card_locker.preferences.SettingsActivity;
|
||||
|
||||
public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCardCursorAdapter.CardAdapterListener {
|
||||
private MainActivityBinding binding;
|
||||
private ContentMainBinding contentMainBinding;
|
||||
private static final String TAG = "Catima";
|
||||
public static final String RESTART_ACTIVITY_INTENT = "restart_activity_intent";
|
||||
|
||||
private static final int MEDIUM_SCALE_FACTOR_DIP = 460;
|
||||
static final String STATE_SEARCH_QUERY = "SEARCH_QUERY";
|
||||
|
||||
private SQLiteDatabase mDatabase;
|
||||
private LoyaltyCardCursorAdapter mAdapter;
|
||||
private ActionMode mCurrentActionMode;
|
||||
private SearchView mSearchView;
|
||||
private int mLoyaltyCardCount = 0;
|
||||
protected String mFilter = "";
|
||||
private String currentQuery = "";
|
||||
private String finalQuery = "";
|
||||
protected Object mGroup = null;
|
||||
protected DBHelper.LoyaltyCardOrder mOrder = DBHelper.LoyaltyCardOrder.Alpha;
|
||||
protected DBHelper.LoyaltyCardOrderDirection mOrderDirection = DBHelper.LoyaltyCardOrderDirection.Ascending;
|
||||
protected int selectedTab = 0;
|
||||
private RecyclerView mCardList;
|
||||
private View mHelpSection;
|
||||
private View mNoMatchingCardsText;
|
||||
private View mNoGroupCardsText;
|
||||
private TabLayout groupsTabLayout;
|
||||
private Runnable mUpdateLoyaltyCardListRunnable;
|
||||
private ActivityResultLauncher<Intent> mBarcodeScannerLauncher;
|
||||
private ActivityResultLauncher<Intent> mSettingsLauncher;
|
||||
|
||||
private ActionMode.Callback mCurrentActionModeCallback = new ActionMode.Callback() {
|
||||
@Override
|
||||
public boolean onCreateActionMode(ActionMode inputMode, Menu inputMenu) {
|
||||
inputMode.getMenuInflater().inflate(R.menu.card_longclick_menu, inputMenu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareActionMode(ActionMode inputMode, Menu inputMenu) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode inputMode, MenuItem inputItem) {
|
||||
if (inputItem.getItemId() == R.id.action_share) {
|
||||
final ImportURIHelper importURIHelper = new ImportURIHelper(MainActivity.this);
|
||||
try {
|
||||
importURIHelper.startShareIntent(mAdapter.getSelectedItems());
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
Toast.makeText(MainActivity.this, R.string.failedGeneratingShareURL, Toast.LENGTH_LONG).show();
|
||||
e.printStackTrace();
|
||||
}
|
||||
inputMode.finish();
|
||||
return true;
|
||||
} else if (inputItem.getItemId() == R.id.action_edit) {
|
||||
if (mAdapter.getSelectedItemCount() != 1) {
|
||||
throw new IllegalArgumentException("Cannot edit more than 1 card at a time");
|
||||
}
|
||||
|
||||
Intent intent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(LoyaltyCardEditActivity.BUNDLE_ID, mAdapter.getSelectedItems().get(0).id);
|
||||
bundle.putBoolean(LoyaltyCardEditActivity.BUNDLE_UPDATE, true);
|
||||
intent.putExtras(bundle);
|
||||
startActivity(intent);
|
||||
inputMode.finish();
|
||||
return true;
|
||||
} else if (inputItem.getItemId() == R.id.action_delete) {
|
||||
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(MainActivity.this);
|
||||
// The following may seem weird, but it is necessary to give translators enough flexibility.
|
||||
// For example, in Russian, Android's plural quantity "one" actually refers to "any number ending on 1 but not ending in 11".
|
||||
// So while in English the extra non-plural form seems unnecessary duplication, it is necessary to give translators enough flexibility.
|
||||
// In here, we use the plain string when meaning exactly 1, and otherwise use the plural forms
|
||||
if (mAdapter.getSelectedItemCount() == 1) {
|
||||
builder.setTitle(R.string.deleteTitle);
|
||||
builder.setMessage(R.string.deleteConfirmation);
|
||||
} else {
|
||||
builder.setTitle(getResources().getQuantityString(R.plurals.deleteCardsTitle, mAdapter.getSelectedItemCount(), mAdapter.getSelectedItemCount()));
|
||||
builder.setMessage(getResources().getQuantityString(R.plurals.deleteCardsConfirmation, mAdapter.getSelectedItemCount(), mAdapter.getSelectedItemCount()));
|
||||
}
|
||||
|
||||
builder.setPositiveButton(R.string.confirm, (dialog, which) -> {
|
||||
for (LoyaltyCard loyaltyCard : mAdapter.getSelectedItems()) {
|
||||
Log.d(TAG, "Deleting card: " + loyaltyCard.id);
|
||||
|
||||
DBHelper.deleteLoyaltyCard(mDatabase, MainActivity.this, loyaltyCard.id);
|
||||
|
||||
ShortcutHelper.removeShortcut(MainActivity.this, loyaltyCard.id);
|
||||
}
|
||||
|
||||
TabLayout.Tab tab = groupsTabLayout.getTabAt(selectedTab);
|
||||
mGroup = tab != null ? tab.getTag() : null;
|
||||
|
||||
updateLoyaltyCardList(true);
|
||||
|
||||
dialog.dismiss();
|
||||
});
|
||||
builder.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
|
||||
return true;
|
||||
} else if (inputItem.getItemId() == R.id.action_archive) {
|
||||
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();
|
||||
}
|
||||
return true;
|
||||
} else if (inputItem.getItemId() == R.id.action_unarchive) {
|
||||
for (LoyaltyCard loyaltyCard : mAdapter.getSelectedItems()) {
|
||||
Log.d(TAG, "Unarchiving card: " + loyaltyCard.id);
|
||||
DBHelper.updateLoyaltyCardArchiveStatus(mDatabase, loyaltyCard.id, 0);
|
||||
updateLoyaltyCardList(false);
|
||||
inputMode.finish();
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
return true;
|
||||
} else if (inputItem.getItemId() == R.id.action_star) {
|
||||
for (LoyaltyCard loyaltyCard : mAdapter.getSelectedItems()) {
|
||||
Log.d(TAG, "Starring card: " + loyaltyCard.id);
|
||||
DBHelper.updateLoyaltyCardStarStatus(mDatabase, loyaltyCard.id, 1);
|
||||
updateLoyaltyCardList(false);
|
||||
inputMode.finish();
|
||||
}
|
||||
return true;
|
||||
} else if (inputItem.getItemId() == R.id.action_unstar) {
|
||||
for (LoyaltyCard loyaltyCard : mAdapter.getSelectedItems()) {
|
||||
Log.d(TAG, "Unstarring card: " + loyaltyCard.id);
|
||||
DBHelper.updateLoyaltyCardStarStatus(mDatabase, loyaltyCard.id, 0);
|
||||
updateLoyaltyCardList(false);
|
||||
inputMode.finish();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyActionMode(ActionMode inputMode) {
|
||||
mAdapter.clearSelections();
|
||||
mCurrentActionMode = null;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle inputSavedInstanceState) {
|
||||
SplashScreen.installSplashScreen(this);
|
||||
super.onCreate(inputSavedInstanceState);
|
||||
|
||||
// Delete old cache files
|
||||
// These could be temporary images for the cropper, temporary images in LoyaltyCard toBundle/writeParcel/ etc.
|
||||
new Thread(() -> {
|
||||
long twentyFourHoursAgo = System.currentTimeMillis() - (1000 * 60 * 60 * 24);
|
||||
|
||||
File[] tempFiles = getCacheDir().listFiles();
|
||||
|
||||
if (tempFiles == null) {
|
||||
Log.e(TAG, "getCacheDir().listFiles() somehow returned null, this should never happen... Skipping cache cleanup...");
|
||||
return;
|
||||
}
|
||||
|
||||
for (File file : tempFiles) {
|
||||
if (file.lastModified() < twentyFourHoursAgo) {
|
||||
if (!file.delete()) {
|
||||
Log.w(TAG, "Failed to delete cache file " + file.getPath());
|
||||
}
|
||||
};
|
||||
}
|
||||
}).start();
|
||||
|
||||
// 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());
|
||||
Utils.applyWindowInsets(binding.getRoot());
|
||||
setSupportActionBar(binding.toolbar);
|
||||
groupsTabLayout = binding.groups;
|
||||
contentMainBinding = ContentMainBinding.bind(binding.include.getRoot());
|
||||
|
||||
mDatabase = new DBHelper(this).getWritableDatabase();
|
||||
|
||||
mUpdateLoyaltyCardListRunnable = () -> {
|
||||
updateLoyaltyCardList(false);
|
||||
};
|
||||
|
||||
groupsTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||
@Override
|
||||
public void onTabSelected(TabLayout.Tab tab) {
|
||||
selectedTab = tab.getPosition();
|
||||
Log.d("onTabSelected", "Tab Position " + tab.getPosition());
|
||||
mGroup = tab.getTag();
|
||||
updateLoyaltyCardList(false);
|
||||
// Store active tab in Shared Preference to restore next app launch
|
||||
SharedPreferences activeTabPref = getApplicationContext().getSharedPreferences(
|
||||
getString(R.string.sharedpreference_active_tab),
|
||||
Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor activeTabPrefEditor = activeTabPref.edit();
|
||||
activeTabPrefEditor.putInt(getString(R.string.sharedpreference_active_tab), tab.getPosition());
|
||||
activeTabPrefEditor.apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(TabLayout.Tab tab) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(TabLayout.Tab tab) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
mHelpSection = contentMainBinding.helpSection;
|
||||
mNoMatchingCardsText = contentMainBinding.noMatchingCardsText;
|
||||
mNoGroupCardsText = contentMainBinding.noGroupCardsText;
|
||||
mCardList = contentMainBinding.list;
|
||||
|
||||
mAdapter = new LoyaltyCardCursorAdapter(this, null, this, mUpdateLoyaltyCardListRunnable);
|
||||
mCardList.setAdapter(mAdapter);
|
||||
registerForContextMenu(mCardList);
|
||||
|
||||
mBarcodeScannerLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
|
||||
// Exit early if the user cancelled the scan (pressed back/home)
|
||||
if (result.getResultCode() != RESULT_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
Intent editIntent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
|
||||
editIntent.putExtras(result.getData().getExtras());
|
||||
startActivity(editIntent);
|
||||
});
|
||||
|
||||
mSettingsLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
|
||||
if (result.getResultCode() == Activity.RESULT_OK) {
|
||||
Intent intent = result.getData();
|
||||
if (intent != null && intent.getBooleanExtra(RESTART_ACTIVITY_INTENT, false)) {
|
||||
recreate();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
|
||||
@Override
|
||||
public void handleOnBackPressed() {
|
||||
if (mSearchView != null && !mSearchView.isIconified()) {
|
||||
mSearchView.setIconified(true);
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (mCurrentActionMode != null) {
|
||||
mAdapter.clearSelections();
|
||||
mCurrentActionMode.finish();
|
||||
}
|
||||
|
||||
if (mSearchView != null && !mSearchView.isIconified()) {
|
||||
mFilter = mSearchView.getQuery().toString();
|
||||
}
|
||||
// Start of active tab logic
|
||||
updateTabGroups(groupsTabLayout);
|
||||
|
||||
// Restore selected tab from Shared Preference
|
||||
SharedPreferences activeTabPref = getApplicationContext().getSharedPreferences(
|
||||
getString(R.string.sharedpreference_active_tab),
|
||||
Context.MODE_PRIVATE);
|
||||
selectedTab = activeTabPref.getInt(getString(R.string.sharedpreference_active_tab), 0);
|
||||
|
||||
// Restore sort preferences from Shared Preferences
|
||||
mOrder = Utils.getLoyaltyCardOrder(this);
|
||||
mOrderDirection = Utils.getLoyaltyCardOrderDirection(this);
|
||||
|
||||
mGroup = null;
|
||||
|
||||
if (groupsTabLayout.getTabCount() != 0) {
|
||||
TabLayout.Tab tab = groupsTabLayout.getTabAt(selectedTab);
|
||||
if (tab == null) {
|
||||
tab = groupsTabLayout.getTabAt(0);
|
||||
}
|
||||
|
||||
groupsTabLayout.selectTab(tab);
|
||||
assert tab != null;
|
||||
mGroup = tab.getTag();
|
||||
} else {
|
||||
scaleScreen();
|
||||
}
|
||||
|
||||
updateLoyaltyCardList(true);
|
||||
// End of active tab logic
|
||||
|
||||
FloatingActionButton addButton = binding.fabAdd;
|
||||
|
||||
addButton.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(getApplicationContext(), ScanActivity.class);
|
||||
Bundle bundle = new Bundle();
|
||||
if (selectedTab != 0) {
|
||||
bundle.putString(LoyaltyCardEditActivity.BUNDLE_ADDGROUP, groupsTabLayout.getTabAt(selectedTab).getText().toString());
|
||||
}
|
||||
intent.putExtras(bundle);
|
||||
mBarcodeScannerLauncher.launch(intent);
|
||||
});
|
||||
addButton.bringToFront();
|
||||
|
||||
var layoutManager = (GridLayoutManager) mCardList.getLayoutManager();
|
||||
if (layoutManager != null) {
|
||||
var settings = new Settings(this);
|
||||
layoutManager.setSpanCount(settings.getPreferredColumnCount());
|
||||
}
|
||||
}
|
||||
|
||||
private void displayCardSetupOptions(Menu menu, boolean shouldShow) {
|
||||
for (int id : new int[]{R.id.action_search, R.id.action_display_options, R.id.action_sort}) {
|
||||
menu.findItem(id).setVisible(shouldShow);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLoyaltyCardCount() {
|
||||
mLoyaltyCardCount = DBHelper.getLoyaltyCardCount(mDatabase);
|
||||
}
|
||||
|
||||
private void updateLoyaltyCardList(boolean updateCount) {
|
||||
Group group = null;
|
||||
if (mGroup != null) {
|
||||
group = (Group) mGroup;
|
||||
}
|
||||
|
||||
mAdapter.swapCursor(DBHelper.getLoyaltyCardCursor(mDatabase, mFilter, group, mOrder, mOrderDirection, mAdapter.showingArchivedCards() ? DBHelper.LoyaltyCardArchiveFilter.All : DBHelper.LoyaltyCardArchiveFilter.Unarchived));
|
||||
|
||||
if (updateCount) {
|
||||
updateLoyaltyCardCount();
|
||||
// Update menu icons if necessary
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
if (mLoyaltyCardCount > 0) {
|
||||
// We want the cardList to be visible regardless of the filtered match count
|
||||
// to ensure that the noMatchingCardsText doesn't end up being shown below
|
||||
// the keyboard
|
||||
mHelpSection.setVisibility(View.GONE);
|
||||
mNoGroupCardsText.setVisibility(View.GONE);
|
||||
|
||||
if (mAdapter.getItemCount() > 0) {
|
||||
mCardList.setVisibility(View.VISIBLE);
|
||||
mNoMatchingCardsText.setVisibility(View.GONE);
|
||||
} else {
|
||||
mCardList.setVisibility(View.GONE);
|
||||
if (!mFilter.isEmpty()) {
|
||||
// Actual Empty Search Result
|
||||
mNoMatchingCardsText.setVisibility(View.VISIBLE);
|
||||
mNoGroupCardsText.setVisibility(View.GONE);
|
||||
} else {
|
||||
// Group Tab with no Group Cards
|
||||
mNoMatchingCardsText.setVisibility(View.GONE);
|
||||
mNoGroupCardsText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mCardList.setVisibility(View.GONE);
|
||||
mHelpSection.setVisibility(View.VISIBLE);
|
||||
|
||||
mNoMatchingCardsText.setVisibility(View.GONE);
|
||||
mNoGroupCardsText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (mCurrentActionMode != null) {
|
||||
mCurrentActionMode.finish();
|
||||
}
|
||||
|
||||
new ListWidget().updateAll(mAdapter.mContext);
|
||||
}
|
||||
|
||||
private void processParseResultList(List<ParseResult> parseResultList, String group, boolean closeAppOnNoBarcode) {
|
||||
if (parseResultList.isEmpty()) {
|
||||
throw new IllegalArgumentException("parseResultList may not be empty");
|
||||
}
|
||||
|
||||
Utils.makeUserChooseParseResultFromList(MainActivity.this, parseResultList, new ParseResultListDisambiguatorCallback() {
|
||||
@Override
|
||||
public void onUserChoseParseResult(ParseResult parseResult) {
|
||||
Intent intent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
|
||||
Bundle bundle = parseResult.toLoyaltyCardBundle(MainActivity.this);
|
||||
if (group != null) {
|
||||
bundle.putString(LoyaltyCardEditActivity.BUNDLE_ADDGROUP, group);
|
||||
}
|
||||
intent.putExtras(bundle);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserDismissedSelector() {
|
||||
if (closeAppOnNoBarcode) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onSharedIntent(Intent intent) {
|
||||
String receivedAction = intent.getAction();
|
||||
String receivedType = intent.getType();
|
||||
|
||||
if (receivedAction == null || receivedType == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<ParseResult> parseResultList;
|
||||
|
||||
// Check for shared text
|
||||
if (receivedAction.equals(Intent.ACTION_SEND) && receivedType.equals("text/plain")) {
|
||||
LoyaltyCard loyaltyCard = new LoyaltyCard();
|
||||
loyaltyCard.setCardId(intent.getStringExtra(Intent.EXTRA_TEXT));
|
||||
parseResultList = Collections.singletonList(new ParseResult(ParseResultType.BARCODE_ONLY, loyaltyCard));
|
||||
} else {
|
||||
// Parse whatever file was sent, regardless of opening or sharing
|
||||
Uri data;
|
||||
if (receivedAction.equals(Intent.ACTION_VIEW)) {
|
||||
data = intent.getData();
|
||||
} else if (receivedAction.equals(Intent.ACTION_SEND)) {
|
||||
data = intent.getParcelableExtra(Intent.EXTRA_STREAM);
|
||||
} else {
|
||||
Log.e(TAG, "Wrong action type to parse intent");
|
||||
return;
|
||||
}
|
||||
|
||||
if (receivedType.startsWith("image/")) {
|
||||
parseResultList = Utils.retrieveBarcodesFromImage(this, data);
|
||||
} else if (receivedType.equals("application/pdf")) {
|
||||
parseResultList = Utils.retrieveBarcodesFromPdf(this, data);
|
||||
} else if (Arrays.asList("application/vnd.apple.pkpass", "application/vnd-com.apple.pkpass").contains(receivedType)) {
|
||||
parseResultList = Utils.retrieveBarcodesFromPkPass(this, data);
|
||||
} else if (receivedType.equals("application/vnd.espass-espass")) {
|
||||
// FIXME: espass is not pkpass
|
||||
// However, several users stated in https://github.com/CatimaLoyalty/Android/issues/2197 that the formats are extremely similar to the point they could rename an .espass file to .pkpass and have it imported
|
||||
// So it makes sense to "unofficially" treat it as a PKPASS for now, even though not completely correct
|
||||
parseResultList = Utils.retrieveBarcodesFromPkPass(this, data);
|
||||
} else if (receivedType.equals("application/vnd.apple.pkpasses")) {
|
||||
parseResultList = Utils.retrieveBarcodesFromPkPasses(this, data);
|
||||
} else {
|
||||
Log.e(TAG, "Wrong mime-type");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Give up if we should parse but there is nothing to parse
|
||||
if (parseResultList == null || parseResultList.isEmpty()) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
processParseResultList(parseResultList, null, true);
|
||||
}
|
||||
|
||||
private void extractIntentFields(Intent intent) {
|
||||
onSharedIntent(intent);
|
||||
}
|
||||
|
||||
public void updateTabGroups(TabLayout groupsTabLayout) {
|
||||
List<Group> newGroups = DBHelper.getGroups(mDatabase);
|
||||
|
||||
if (newGroups.size() == 0) {
|
||||
groupsTabLayout.removeAllTabs();
|
||||
groupsTabLayout.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
groupsTabLayout.removeAllTabs();
|
||||
|
||||
TabLayout.Tab allTab = groupsTabLayout.newTab();
|
||||
allTab.setText(R.string.all);
|
||||
allTab.setTag(null);
|
||||
groupsTabLayout.addTab(allTab, false);
|
||||
|
||||
for (Group group : newGroups) {
|
||||
TabLayout.Tab tab = groupsTabLayout.newTab();
|
||||
tab.setText(group._id);
|
||||
tab.setTag(group);
|
||||
groupsTabLayout.addTab(tab, false);
|
||||
}
|
||||
|
||||
groupsTabLayout.setVisibility(View.VISIBLE);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
// Saving currentQuery to finalQuery for user, this will be used to restore search history, happens when user clicks a card from list
|
||||
protected void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
finalQuery = currentQuery;
|
||||
// Putting the query also into outState for later use in onRestoreInstanceState when rotating screen
|
||||
if (mSearchView != null) {
|
||||
outState.putString(STATE_SEARCH_QUERY, finalQuery);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
// Restoring instance state when rotation of screen happens with the goal to restore search query for user
|
||||
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
finalQuery = savedInstanceState.getString(STATE_SEARCH_QUERY, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu inputMenu) {
|
||||
getMenuInflater().inflate(R.menu.main_menu, inputMenu);
|
||||
|
||||
displayCardSetupOptions(inputMenu, mLoyaltyCardCount > 0);
|
||||
|
||||
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
|
||||
if (searchManager != null) {
|
||||
MenuItem searchMenuItem = inputMenu.findItem(R.id.action_search);
|
||||
mSearchView = (SearchView) searchMenuItem.getActionView();
|
||||
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
|
||||
mSearchView.setSubmitButtonEnabled(false);
|
||||
mSearchView.setOnCloseListener(() -> {
|
||||
invalidateOptionsMenu();
|
||||
return false;
|
||||
});
|
||||
|
||||
/*
|
||||
* On Android 13 and later, pressing Back while the search view is open hides the keyboard
|
||||
* and collapses the search view at the same time.
|
||||
* This brings back the old behavior on Android 12 and lower: pressing Back once
|
||||
* hides the keyboard, press again while keyboard is hidden to collapse the search view.
|
||||
*/
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
searchMenuItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
|
||||
@Override
|
||||
public boolean onMenuItemActionExpand(@NonNull MenuItem item) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemActionCollapse(@NonNull MenuItem item) {
|
||||
if (mSearchView.hasFocus()) {
|
||||
mSearchView.clearFocus();
|
||||
return false;
|
||||
}
|
||||
currentQuery = "";
|
||||
mFilter = "";
|
||||
updateLoyaltyCardList(false);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
mFilter = newText;
|
||||
// New logic to ensure search history after coming back from picked card - user will see the last search query
|
||||
if (newText.isEmpty()) {
|
||||
if(!finalQuery.isEmpty()){
|
||||
// Setting the query text for user after coming back from picked card from finalQuery
|
||||
mSearchView.setQuery(finalQuery, false);
|
||||
}
|
||||
else if(!currentQuery.isEmpty()){
|
||||
// Else if is needed in case user deletes search - expected behaviour is to show all cards
|
||||
currentQuery = "";
|
||||
mSearchView.setQuery(currentQuery, false);
|
||||
}
|
||||
} else {
|
||||
// Setting search query each time user changes the text in search to temporary variable to be used later in finalQuery String which will be used to restore search history
|
||||
currentQuery = newText;
|
||||
}
|
||||
TabLayout.Tab currentTab = groupsTabLayout.getTabAt(groupsTabLayout.getSelectedTabPosition());
|
||||
mGroup = currentTab != null ? currentTab.getTag() : null;
|
||||
|
||||
updateLoyaltyCardList(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
// Check if we came from a picked card back to search, in that case we want to show the search view with previous search query
|
||||
if(!finalQuery.isEmpty()){
|
||||
// Expand the search view to show the query
|
||||
searchMenuItem.expandActionView();
|
||||
// Setting the query text to empty String due to behaviour of onQueryTextChange after coming back from picked card - onQueryTextChange is called automatically without users interaction
|
||||
finalQuery = "";
|
||||
mSearchView.setQuery(currentQuery, false);
|
||||
}
|
||||
}
|
||||
|
||||
return super.onCreateOptionsMenu(inputMenu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem inputItem) {
|
||||
int id = inputItem.getItemId();
|
||||
|
||||
if (id == android.R.id.home) {
|
||||
getOnBackPressedDispatcher().onBackPressed();
|
||||
}
|
||||
|
||||
if (id == R.id.action_display_options) {
|
||||
mAdapter.showDisplayOptionsDialog();
|
||||
invalidateOptionsMenu();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (id == R.id.action_sort) {
|
||||
AtomicInteger currentIndex = new AtomicInteger();
|
||||
List<DBHelper.LoyaltyCardOrder> loyaltyCardOrders = Arrays.asList(DBHelper.LoyaltyCardOrder.values());
|
||||
for (int i = 0; i < loyaltyCardOrders.size(); i++) {
|
||||
if (mOrder == loyaltyCardOrders.get(i)) {
|
||||
currentIndex.set(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(MainActivity.this);
|
||||
builder.setTitle(R.string.sort_by);
|
||||
|
||||
SortingOptionBinding sortingOptionBinding = SortingOptionBinding
|
||||
.inflate(LayoutInflater.from(MainActivity.this), null, false);
|
||||
final View customLayout = sortingOptionBinding.getRoot();
|
||||
builder.setView(customLayout);
|
||||
|
||||
CheckBox showReversed = sortingOptionBinding.checkBoxReverse;
|
||||
|
||||
|
||||
showReversed.setChecked(mOrderDirection == DBHelper.LoyaltyCardOrderDirection.Descending);
|
||||
|
||||
|
||||
builder.setSingleChoiceItems(R.array.sort_types_array, currentIndex.get(), (dialog, which) -> currentIndex.set(which));
|
||||
|
||||
builder.setPositiveButton(R.string.sort, (dialog, which) -> {
|
||||
|
||||
setSort(
|
||||
loyaltyCardOrders.get(currentIndex.get()),
|
||||
showReversed.isChecked() ? DBHelper.LoyaltyCardOrderDirection.Descending : DBHelper.LoyaltyCardOrderDirection.Ascending
|
||||
);
|
||||
|
||||
new ListWidget().updateAll(this);
|
||||
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
builder.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (id == R.id.action_manage_groups) {
|
||||
Intent i = new Intent(getApplicationContext(), ManageGroupsActivity.class);
|
||||
startActivity(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (id == R.id.action_import_export) {
|
||||
Intent i = new Intent(getApplicationContext(), ImportExportActivity.class);
|
||||
startActivity(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (id == R.id.action_settings) {
|
||||
Intent i = new Intent(getApplicationContext(), SettingsActivity.class);
|
||||
mSettingsLauncher.launch(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (id == R.id.action_about) {
|
||||
Intent i = new Intent(getApplicationContext(), AboutActivity.class);
|
||||
startActivity(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return super.onOptionsItemSelected(inputItem);
|
||||
}
|
||||
|
||||
private void setSort(DBHelper.LoyaltyCardOrder order, DBHelper.LoyaltyCardOrderDirection direction) {
|
||||
// Update values
|
||||
mOrder = order;
|
||||
mOrderDirection = direction;
|
||||
|
||||
// Store in Shared Preference to restore next app launch
|
||||
SharedPreferences sortPref = getApplicationContext().getSharedPreferences(
|
||||
getString(R.string.sharedpreference_sort),
|
||||
Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor sortPrefEditor = sortPref.edit();
|
||||
sortPrefEditor.putString(getString(R.string.sharedpreference_sort_order), order.name());
|
||||
sortPrefEditor.putString(getString(R.string.sharedpreference_sort_direction), direction.name());
|
||||
sortPrefEditor.apply();
|
||||
|
||||
// Update card list
|
||||
updateLoyaltyCardList(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRowLongClicked(int inputPosition) {
|
||||
enableActionMode(inputPosition);
|
||||
}
|
||||
|
||||
private void enableActionMode(int inputPosition) {
|
||||
if (mCurrentActionMode == null) {
|
||||
mCurrentActionMode = startSupportActionMode(mCurrentActionModeCallback);
|
||||
}
|
||||
toggleSelection(inputPosition);
|
||||
}
|
||||
|
||||
private void scaleScreen() {
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||
int screenHeight = displayMetrics.heightPixels;
|
||||
float mediumSizePx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,MEDIUM_SCALE_FACTOR_DIP,getResources().getDisplayMetrics());
|
||||
boolean shouldScaleSmaller = screenHeight < mediumSizePx;
|
||||
|
||||
binding.include.welcomeIcon.setVisibility(shouldScaleSmaller ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
private void toggleSelection(int inputPosition) {
|
||||
mAdapter.toggleSelection(inputPosition);
|
||||
int count = mAdapter.getSelectedItemCount();
|
||||
|
||||
if (count == 0) {
|
||||
mCurrentActionMode.finish();
|
||||
} else {
|
||||
mCurrentActionMode.setTitle(getResources().getQuantityString(R.plurals.selectedCardCount, count, count));
|
||||
|
||||
MenuItem editItem = mCurrentActionMode.getMenu().findItem(R.id.action_edit);
|
||||
MenuItem archiveItem = mCurrentActionMode.getMenu().findItem(R.id.action_archive);
|
||||
MenuItem unarchiveItem = mCurrentActionMode.getMenu().findItem(R.id.action_unarchive);
|
||||
MenuItem starItem = mCurrentActionMode.getMenu().findItem(R.id.action_star);
|
||||
MenuItem unstarItem = mCurrentActionMode.getMenu().findItem(R.id.action_unstar);
|
||||
|
||||
boolean hasStarred = false;
|
||||
boolean hasUnstarred = false;
|
||||
boolean hasArchived = false;
|
||||
boolean hasUnarchived = false;
|
||||
|
||||
for (LoyaltyCard loyaltyCard : mAdapter.getSelectedItems()) {
|
||||
if (loyaltyCard.starStatus == 1) {
|
||||
hasStarred = true;
|
||||
} else {
|
||||
hasUnstarred = true;
|
||||
}
|
||||
|
||||
if (loyaltyCard.archiveStatus == 1) {
|
||||
hasArchived = true;
|
||||
} else {
|
||||
hasUnarchived = true;
|
||||
}
|
||||
|
||||
// We have all types, no need to keep checking
|
||||
if (hasStarred && hasUnstarred && hasArchived && hasUnarchived) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unarchiveItem.setVisible(hasArchived);
|
||||
archiveItem.setVisible(hasUnarchived);
|
||||
|
||||
if (count == 1) {
|
||||
starItem.setVisible(!hasStarred);
|
||||
unstarItem.setVisible(!hasUnstarred);
|
||||
editItem.setVisible(true);
|
||||
editItem.setEnabled(true);
|
||||
} else {
|
||||
starItem.setVisible(hasUnstarred);
|
||||
unstarItem.setVisible(hasStarred);
|
||||
|
||||
editItem.setVisible(false);
|
||||
editItem.setEnabled(false);
|
||||
}
|
||||
|
||||
mCurrentActionMode.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRowClicked(int inputPosition) {
|
||||
if (mAdapter.getSelectedItemCount() > 0) {
|
||||
enableActionMode(inputPosition);
|
||||
} else {
|
||||
// FIXME
|
||||
//
|
||||
// There is a really nasty edge case that can happen when someone taps a card but right
|
||||
// after it swipes (very small window, hard to reproduce). The cursor gets replaced and
|
||||
// may not have a card at the ID number that is returned from onRowClicked.
|
||||
//
|
||||
// The proper fix, obviously, would involve makes sure an onFling can't happen while a
|
||||
// click is being processed. Sadly, I have not yet found a way to make that possible.
|
||||
LoyaltyCard loyaltyCard;
|
||||
try {
|
||||
loyaltyCard = mAdapter.getCard(inputPosition);
|
||||
} catch (CursorIndexOutOfBoundsException e) {
|
||||
Log.w(TAG, "Prevented crash from tap + swipe on ID " + inputPosition + ": " + e);
|
||||
return;
|
||||
}
|
||||
|
||||
Intent intent = new Intent(this, LoyaltyCardViewActivity.class);
|
||||
intent.setAction("");
|
||||
final Bundle b = new Bundle();
|
||||
b.putInt(LoyaltyCardViewActivity.BUNDLE_ID, loyaltyCard.id);
|
||||
|
||||
ArrayList<Integer> cardList = new ArrayList<>();
|
||||
for (int i = 0; i < mAdapter.getItemCount(); i++) {
|
||||
cardList.add(mAdapter.getCard(i).id);
|
||||
}
|
||||
|
||||
b.putIntegerArrayList(LoyaltyCardViewActivity.BUNDLE_CARDLIST, cardList);
|
||||
intent.putExtras(b);
|
||||
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
946
app/src/main/java/protect/card_locker/MainActivity.kt
Normal file
946
app/src/main/java/protect/card_locker/MainActivity.kt
Normal file
@@ -0,0 +1,946 @@
|
||||
package protect.card_locker
|
||||
|
||||
import android.app.SearchManager
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.database.CursorIndexOutOfBoundsException
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.DisplayMetrics
|
||||
import android.util.Log
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.ActivityResultCallback
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
|
||||
import protect.card_locker.DBHelper.LoyaltyCardOrder
|
||||
import protect.card_locker.DBHelper.LoyaltyCardOrderDirection
|
||||
import protect.card_locker.LoyaltyCardCursorAdapter.CardAdapterListener
|
||||
import protect.card_locker.databinding.ContentMainBinding
|
||||
import protect.card_locker.databinding.MainActivityBinding
|
||||
import protect.card_locker.databinding.SortingOptionBinding
|
||||
import protect.card_locker.preferences.Settings
|
||||
import protect.card_locker.preferences.SettingsActivity
|
||||
import java.io.UnsupportedEncodingException
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import androidx.core.content.edit
|
||||
|
||||
class MainActivity : CatimaAppCompatActivity(), CardAdapterListener {
|
||||
private lateinit var binding: MainActivityBinding
|
||||
private lateinit var contentMainBinding: ContentMainBinding
|
||||
private lateinit var mDatabase: SQLiteDatabase
|
||||
private lateinit var mAdapter: LoyaltyCardCursorAdapter
|
||||
private var mCurrentActionMode: ActionMode? = null
|
||||
private var mSearchView: SearchView? = null
|
||||
private var mLoyaltyCardCount = 0
|
||||
@JvmField
|
||||
var mFilter: String = ""
|
||||
private var currentQuery = ""
|
||||
private var finalQuery = ""
|
||||
private var mGroup: Any? = null
|
||||
private var mOrder: LoyaltyCardOrder = LoyaltyCardOrder.Alpha
|
||||
private var mOrderDirection: LoyaltyCardOrderDirection = LoyaltyCardOrderDirection.Ascending
|
||||
private var selectedTab: Int = 0
|
||||
private lateinit var groupsTabLayout: TabLayout
|
||||
private lateinit var mUpdateLoyaltyCardListRunnable: Runnable
|
||||
private lateinit var mBarcodeScannerLauncher: ActivityResultLauncher<Intent>
|
||||
private lateinit var mSettingsLauncher: ActivityResultLauncher<Intent>
|
||||
|
||||
private val mCurrentActionModeCallback: ActionMode.Callback = object : ActionMode.Callback {
|
||||
override fun onCreateActionMode(inputMode: ActionMode, inputMenu: Menu?): Boolean {
|
||||
inputMode.menuInflater.inflate(R.menu.card_longclick_menu, inputMenu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(inputMode: ActionMode?, inputMenu: Menu?): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onActionItemClicked(inputMode: ActionMode, inputItem: MenuItem): Boolean {
|
||||
when (inputItem.itemId) {
|
||||
R.id.action_share -> {
|
||||
try {
|
||||
ImportURIHelper(this@MainActivity).startShareIntent(mAdapter.getSelectedItems())
|
||||
} catch (e: UnsupportedEncodingException) {
|
||||
Toast.makeText(
|
||||
this@MainActivity,
|
||||
R.string.failedGeneratingShareURL,
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
e.printStackTrace()
|
||||
}
|
||||
inputMode.finish()
|
||||
return true
|
||||
}
|
||||
R.id.action_edit -> {
|
||||
require(mAdapter.selectedItemCount == 1) { "Cannot edit more than 1 card at a time" }
|
||||
|
||||
startActivity(
|
||||
Intent(applicationContext, LoyaltyCardEditActivity::class.java).apply {
|
||||
putExtras(Bundle().apply {
|
||||
putInt(
|
||||
LoyaltyCardEditActivity.BUNDLE_ID,
|
||||
mAdapter.getSelectedItems()[0].id
|
||||
)
|
||||
putBoolean(LoyaltyCardEditActivity.BUNDLE_UPDATE, true)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
inputMode.finish()
|
||||
return true
|
||||
}
|
||||
R.id.action_duplicate -> {
|
||||
require(mAdapter.selectedItemCount == 1) { "Cannot duplicate more than 1 card at a time" }
|
||||
|
||||
startActivity(
|
||||
Intent(applicationContext, LoyaltyCardEditActivity::class.java).apply {
|
||||
putExtras(Bundle().apply {
|
||||
putInt(
|
||||
LoyaltyCardEditActivity.BUNDLE_ID,
|
||||
mAdapter.getSelectedItems()[0].id
|
||||
)
|
||||
putBoolean(LoyaltyCardEditActivity.BUNDLE_DUPLICATE_ID, true)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
inputMode.finish()
|
||||
return true
|
||||
}
|
||||
R.id.action_delete -> {
|
||||
MaterialAlertDialogBuilder(this@MainActivity).apply {
|
||||
// The following may seem weird, but it is necessary to give translators enough flexibility.
|
||||
// For example, in Russian, Android's plural quantity "one" actually refers to "any number ending on 1 but not ending in 11".
|
||||
// So while in English the extra non-plural form seems unnecessary duplication, it is necessary to give translators enough flexibility.
|
||||
// In here, we use the plain string when meaning exactly 1, and otherwise use the plural forms
|
||||
if (mAdapter.selectedItemCount == 1) {
|
||||
setTitle(R.string.deleteTitle)
|
||||
setMessage(R.string.deleteConfirmation)
|
||||
} else {
|
||||
setTitle(
|
||||
getResources().getQuantityString(
|
||||
R.plurals.deleteCardsTitle,
|
||||
mAdapter.selectedItemCount,
|
||||
mAdapter.selectedItemCount
|
||||
)
|
||||
)
|
||||
setMessage(
|
||||
getResources().getQuantityString(
|
||||
R.plurals.deleteCardsConfirmation,
|
||||
mAdapter.selectedItemCount,
|
||||
mAdapter.selectedItemCount
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
setPositiveButton(
|
||||
R.string.confirm
|
||||
) { dialog, _ ->
|
||||
for (loyaltyCard in mAdapter.getSelectedItems()) {
|
||||
Log.d(TAG, "Deleting card: " + loyaltyCard.id)
|
||||
|
||||
DBHelper.deleteLoyaltyCard(mDatabase, this@MainActivity, loyaltyCard.id)
|
||||
|
||||
ShortcutHelper.removeShortcut(this@MainActivity, loyaltyCard.id)
|
||||
}
|
||||
val tab = groupsTabLayout.getTabAt(selectedTab)
|
||||
mGroup = tab?.tag
|
||||
|
||||
updateLoyaltyCardList(true)
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
setNegativeButton(R.string.cancel) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
}
|
||||
}.create().show()
|
||||
|
||||
return true
|
||||
}
|
||||
R.id.action_archive -> {
|
||||
for (loyaltyCard in mAdapter.getSelectedItems()) {
|
||||
Log.d(TAG, "Archiving card: " + loyaltyCard.id)
|
||||
DBHelper.updateLoyaltyCardArchiveStatus(mDatabase, loyaltyCard.id, 1)
|
||||
ShortcutHelper.removeShortcut(this@MainActivity, loyaltyCard.id)
|
||||
updateLoyaltyCardList(false)
|
||||
inputMode.finish()
|
||||
invalidateOptionsMenu()
|
||||
}
|
||||
return true
|
||||
}
|
||||
R.id.action_unarchive -> {
|
||||
for (loyaltyCard in mAdapter.getSelectedItems()) {
|
||||
Log.d(TAG, "Unarchiving card: " + loyaltyCard.id)
|
||||
DBHelper.updateLoyaltyCardArchiveStatus(mDatabase, loyaltyCard.id, 0)
|
||||
updateLoyaltyCardList(false)
|
||||
inputMode.finish()
|
||||
invalidateOptionsMenu()
|
||||
}
|
||||
return true
|
||||
}
|
||||
R.id.action_star -> {
|
||||
for (loyaltyCard in mAdapter.getSelectedItems()) {
|
||||
Log.d(TAG, "Starring card: " + loyaltyCard.id)
|
||||
DBHelper.updateLoyaltyCardStarStatus(mDatabase, loyaltyCard.id, 1)
|
||||
updateLoyaltyCardList(false)
|
||||
inputMode.finish()
|
||||
}
|
||||
return true
|
||||
}
|
||||
R.id.action_unstar -> {
|
||||
for (loyaltyCard in mAdapter.getSelectedItems()) {
|
||||
Log.d(TAG, "Unstarring card: " + loyaltyCard.id)
|
||||
DBHelper.updateLoyaltyCardStarStatus(mDatabase, loyaltyCard.id, 0)
|
||||
updateLoyaltyCardList(false)
|
||||
inputMode.finish()
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(inputMode: ActionMode?) {
|
||||
mAdapter.clearSelections()
|
||||
mCurrentActionMode = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(inputSavedInstanceState: Bundle?) {
|
||||
installSplashScreen()
|
||||
super.onCreate(inputSavedInstanceState)
|
||||
|
||||
// Delete old cache files
|
||||
// These could be temporary images for the cropper, temporary images in LoyaltyCard toBundle/writeParcel/ etc.
|
||||
Thread {
|
||||
val twentyFourHoursAgo = System.currentTimeMillis() - (1000 * 60 * 60 * 24)
|
||||
val tempFiles = cacheDir.listFiles()
|
||||
|
||||
if (tempFiles == null) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"getCacheDir().listFiles() somehow returned null, this should never happen... Skipping cache cleanup..."
|
||||
)
|
||||
return@Thread
|
||||
}
|
||||
for (file in tempFiles) {
|
||||
if (file.lastModified() < twentyFourHoursAgo) {
|
||||
if (!file.delete()) {
|
||||
Log.w(TAG, "Failed to delete cache file " + file.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
|
||||
// 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(intent)
|
||||
|
||||
binding = MainActivityBinding.inflate(layoutInflater)
|
||||
setContentView(binding.getRoot())
|
||||
Utils.applyWindowInsets(binding.getRoot())
|
||||
setSupportActionBar(binding.toolbar)
|
||||
groupsTabLayout = binding.groups
|
||||
contentMainBinding = ContentMainBinding.bind(binding.include.getRoot())
|
||||
|
||||
mDatabase = DBHelper(this).writableDatabase
|
||||
|
||||
mUpdateLoyaltyCardListRunnable = Runnable {
|
||||
updateLoyaltyCardList(false)
|
||||
}
|
||||
|
||||
groupsTabLayout.addOnTabSelectedListener(object : OnTabSelectedListener {
|
||||
override fun onTabSelected(tab: TabLayout.Tab) {
|
||||
selectedTab = tab.position
|
||||
Log.d("onTabSelected", "Tab Position " + tab.position)
|
||||
mGroup = tab.tag
|
||||
updateLoyaltyCardList(false)
|
||||
// Store active tab in Shared Preference to restore next app launch
|
||||
applicationContext.getSharedPreferences(
|
||||
getString(R.string.sharedpreference_active_tab),
|
||||
MODE_PRIVATE
|
||||
).edit {
|
||||
putInt(
|
||||
getString(R.string.sharedpreference_active_tab),
|
||||
tab.position
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTabUnselected(tab: TabLayout.Tab?) {
|
||||
}
|
||||
|
||||
override fun onTabReselected(tab: TabLayout.Tab?) {
|
||||
}
|
||||
})
|
||||
|
||||
mAdapter = LoyaltyCardCursorAdapter(this, null, this, mUpdateLoyaltyCardListRunnable)
|
||||
contentMainBinding.list.setAdapter(mAdapter)
|
||||
registerForContextMenu(contentMainBinding.list)
|
||||
|
||||
mBarcodeScannerLauncher = registerForActivityResult(
|
||||
StartActivityForResult(),
|
||||
ActivityResultCallback registerForActivityResult@{ result: ActivityResult? ->
|
||||
// Exit early if the user cancelled the scan (pressed back/home)
|
||||
if (result == null || result.resultCode != RESULT_OK) {
|
||||
return@registerForActivityResult
|
||||
}
|
||||
|
||||
startActivity(
|
||||
Intent(applicationContext, LoyaltyCardEditActivity::class.java).apply {
|
||||
putExtras(result.data!!.extras!!)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
mSettingsLauncher = registerForActivityResult(
|
||||
StartActivityForResult()
|
||||
) { result: ActivityResult? ->
|
||||
if (result?.resultCode == RESULT_OK) {
|
||||
val intent = result.data
|
||||
if (intent != null && intent.getBooleanExtra(RESTART_ACTIVITY_INTENT, false)) {
|
||||
recreate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
if (mSearchView != null && !mSearchView!!.isIconified) {
|
||||
mSearchView!!.isIconified = true
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
if (mCurrentActionMode != null) {
|
||||
mAdapter.clearSelections()
|
||||
mCurrentActionMode!!.finish()
|
||||
}
|
||||
|
||||
if (mSearchView != null && !mSearchView!!.isIconified) {
|
||||
mFilter = mSearchView!!.query.toString()
|
||||
}
|
||||
// Start of active tab logic
|
||||
updateTabGroups(groupsTabLayout)
|
||||
|
||||
// Restore selected tab from Shared Preference
|
||||
selectedTab = applicationContext.getSharedPreferences(
|
||||
getString(R.string.sharedpreference_active_tab),
|
||||
MODE_PRIVATE
|
||||
).getInt(getString(R.string.sharedpreference_active_tab), 0)
|
||||
|
||||
// Restore sort preferences from Shared Preferences
|
||||
mOrder = Utils.getLoyaltyCardOrder(this)
|
||||
mOrderDirection = Utils.getLoyaltyCardOrderDirection(this)
|
||||
|
||||
mGroup = null
|
||||
|
||||
if (groupsTabLayout.tabCount != 0) {
|
||||
var tab = groupsTabLayout.getTabAt(selectedTab)
|
||||
if (tab == null) {
|
||||
tab = groupsTabLayout.getTabAt(0)
|
||||
}
|
||||
|
||||
groupsTabLayout.selectTab(tab)
|
||||
checkNotNull(tab)
|
||||
mGroup = tab.tag
|
||||
} else {
|
||||
scaleScreen()
|
||||
}
|
||||
|
||||
updateLoyaltyCardList(true)
|
||||
|
||||
// End of active tab logic
|
||||
|
||||
binding.fabAdd.setOnClickListener {
|
||||
mBarcodeScannerLauncher.launch(
|
||||
Intent(applicationContext, ScanActivity::class.java).apply {
|
||||
putExtras(Bundle().apply {
|
||||
if (selectedTab != 0) {
|
||||
putString(
|
||||
LoyaltyCardEditActivity.BUNDLE_ADDGROUP,
|
||||
groupsTabLayout.getTabAt(selectedTab)!!.text.toString()
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
binding.fabAdd.bringToFront()
|
||||
|
||||
// Apply column count setting to card list
|
||||
val layoutManager = contentMainBinding.list.layoutManager as GridLayoutManager?
|
||||
if (layoutManager != null) {
|
||||
val settings = Settings(this)
|
||||
layoutManager.setSpanCount(settings.getPreferredColumnCount())
|
||||
}
|
||||
}
|
||||
|
||||
private fun displayCardSetupOptions(menu: Menu, shouldShow: Boolean) {
|
||||
for (id in intArrayOf(R.id.action_search, R.id.action_display_options, R.id.action_sort)) {
|
||||
menu.findItem(id).isVisible = shouldShow
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateLoyaltyCardCount() {
|
||||
mLoyaltyCardCount = DBHelper.getLoyaltyCardCount(mDatabase)
|
||||
}
|
||||
|
||||
private fun updateLoyaltyCardList(updateCount: Boolean) {
|
||||
var group: Group? = null
|
||||
if (mGroup != null) {
|
||||
group = mGroup as Group
|
||||
}
|
||||
|
||||
mAdapter.swapCursor(
|
||||
DBHelper.getLoyaltyCardCursor(
|
||||
mDatabase,
|
||||
mFilter,
|
||||
group,
|
||||
mOrder,
|
||||
mOrderDirection,
|
||||
if (mAdapter.showingArchivedCards()) DBHelper.LoyaltyCardArchiveFilter.All else DBHelper.LoyaltyCardArchiveFilter.Unarchived
|
||||
)
|
||||
)
|
||||
|
||||
if (updateCount) {
|
||||
updateLoyaltyCardCount()
|
||||
// Update menu icons if necessary
|
||||
invalidateOptionsMenu()
|
||||
}
|
||||
|
||||
if (mLoyaltyCardCount > 0) {
|
||||
// We want the cardList to be visible regardless of the filtered match count
|
||||
// to ensure that the noMatchingCardsText doesn't end up being shown below
|
||||
// the keyboard
|
||||
contentMainBinding.helpSection.visibility = View.GONE
|
||||
contentMainBinding.noGroupCardsText.visibility = View.GONE
|
||||
|
||||
if (mAdapter.itemCount > 0) {
|
||||
contentMainBinding.list.visibility = View.VISIBLE
|
||||
contentMainBinding.noMatchingCardsText.visibility = View.GONE
|
||||
} else {
|
||||
contentMainBinding.list.visibility = View.GONE
|
||||
if (!mFilter.isEmpty()) {
|
||||
// Actual Empty Search Result
|
||||
contentMainBinding.noMatchingCardsText.visibility = View.VISIBLE
|
||||
contentMainBinding.noGroupCardsText.visibility = View.GONE
|
||||
} else {
|
||||
// Group Tab with no Group Cards
|
||||
contentMainBinding.noMatchingCardsText.visibility = View.GONE
|
||||
contentMainBinding.noGroupCardsText.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
} else {
|
||||
contentMainBinding.list.visibility = View.GONE
|
||||
contentMainBinding.helpSection.visibility = View.VISIBLE
|
||||
|
||||
contentMainBinding.noMatchingCardsText.visibility = View.GONE
|
||||
contentMainBinding.noGroupCardsText.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (mCurrentActionMode != null) {
|
||||
mCurrentActionMode!!.finish()
|
||||
}
|
||||
|
||||
ListWidget().updateAll(mAdapter.mContext)
|
||||
}
|
||||
|
||||
private fun processParseResultList(
|
||||
parseResultList: MutableList<ParseResult?>,
|
||||
group: String?,
|
||||
closeAppOnNoBarcode: Boolean
|
||||
) {
|
||||
require(!parseResultList.isEmpty()) { "parseResultList may not be empty" }
|
||||
|
||||
Utils.makeUserChooseParseResultFromList(
|
||||
this@MainActivity,
|
||||
parseResultList,
|
||||
object : ParseResultListDisambiguatorCallback {
|
||||
override fun onUserChoseParseResult(parseResult: ParseResult) {
|
||||
val intent =
|
||||
Intent(applicationContext, LoyaltyCardEditActivity::class.java)
|
||||
val bundle = parseResult.toLoyaltyCardBundle(this@MainActivity)
|
||||
if (group != null) {
|
||||
bundle.putString(LoyaltyCardEditActivity.BUNDLE_ADDGROUP, group)
|
||||
}
|
||||
intent.putExtras(bundle)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
override fun onUserDismissedSelector() {
|
||||
if (closeAppOnNoBarcode) {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun onSharedIntent(intent: Intent) {
|
||||
val receivedAction = intent.action
|
||||
val receivedType = intent.type
|
||||
|
||||
if (receivedAction == null || receivedType == null) {
|
||||
return
|
||||
}
|
||||
|
||||
val parseResultList: MutableList<ParseResult?>?
|
||||
|
||||
// Check for shared text
|
||||
if (receivedAction == Intent.ACTION_SEND && receivedType == "text/plain") {
|
||||
val loyaltyCard = LoyaltyCard()
|
||||
loyaltyCard.setCardId(intent.getStringExtra(Intent.EXTRA_TEXT)!!)
|
||||
parseResultList = mutableListOf(ParseResult(ParseResultType.BARCODE_ONLY, loyaltyCard))
|
||||
} else {
|
||||
// Parse whatever file was sent, regardless of opening or sharing
|
||||
val data: Uri? = when (receivedAction) {
|
||||
Intent.ACTION_VIEW -> {
|
||||
intent.data
|
||||
}
|
||||
Intent.ACTION_SEND -> {
|
||||
intent.getParcelableExtra(Intent.EXTRA_STREAM)
|
||||
}
|
||||
else -> {
|
||||
Log.e(TAG, "Wrong action type to parse intent")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (receivedType.startsWith("image/")) {
|
||||
parseResultList = Utils.retrieveBarcodesFromImage(this, data)
|
||||
} else if (receivedType == "application/pdf") {
|
||||
parseResultList = Utils.retrieveBarcodesFromPdf(this, data)
|
||||
} else if (mutableListOf<String?>(
|
||||
"application/vnd.apple.pkpass",
|
||||
"application/vnd-com.apple.pkpass"
|
||||
).contains(receivedType)
|
||||
) {
|
||||
parseResultList = Utils.retrieveBarcodesFromPkPass(this, data)
|
||||
} else if (receivedType == "application/vnd.espass-espass") {
|
||||
// FIXME: espass is not pkpass
|
||||
// However, several users stated in https://github.com/CatimaLoyalty/Android/issues/2197 that the formats are extremely similar to the point they could rename an .espass file to .pkpass and have it imported
|
||||
// So it makes sense to "unofficially" treat it as a PKPASS for now, even though not completely correct
|
||||
parseResultList = Utils.retrieveBarcodesFromPkPass(this, data)
|
||||
} else if (receivedType == "application/vnd.apple.pkpasses") {
|
||||
parseResultList = Utils.retrieveBarcodesFromPkPasses(this, data)
|
||||
} else {
|
||||
Log.e(TAG, "Wrong mime-type")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Give up if we should parse but there is nothing to parse
|
||||
if (parseResultList == null || parseResultList.isEmpty()) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
processParseResultList(parseResultList, null, true)
|
||||
}
|
||||
|
||||
private fun extractIntentFields(intent: Intent) {
|
||||
onSharedIntent(intent)
|
||||
}
|
||||
|
||||
fun updateTabGroups(groupsTabLayout: TabLayout) {
|
||||
val newGroups = DBHelper.getGroups(mDatabase)
|
||||
|
||||
if (newGroups.isEmpty()) {
|
||||
groupsTabLayout.removeAllTabs()
|
||||
groupsTabLayout.visibility = View.GONE
|
||||
return
|
||||
}
|
||||
|
||||
groupsTabLayout.removeAllTabs()
|
||||
groupsTabLayout.addTab(
|
||||
groupsTabLayout.newTab().apply {
|
||||
setText(R.string.all)
|
||||
tag = null
|
||||
},
|
||||
false
|
||||
)
|
||||
|
||||
for (group in newGroups) {
|
||||
groupsTabLayout.addTab(
|
||||
groupsTabLayout.newTab().apply {
|
||||
text = group._id
|
||||
tag = group
|
||||
},
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
groupsTabLayout.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
// Saving currentQuery to finalQuery for user, this will be used to restore search history, happens when user clicks a card from list
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
finalQuery = currentQuery
|
||||
// Putting the query also into outState for later use in onRestoreInstanceState when rotating screen
|
||||
if (mSearchView != null) {
|
||||
outState.putString(STATE_SEARCH_QUERY, finalQuery)
|
||||
}
|
||||
}
|
||||
|
||||
// Restoring instance state when rotation of screen happens with the goal to restore search query for user
|
||||
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
|
||||
super.onRestoreInstanceState(savedInstanceState)
|
||||
finalQuery = savedInstanceState.getString(STATE_SEARCH_QUERY, "")
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(inputMenu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.main_menu, inputMenu)
|
||||
|
||||
displayCardSetupOptions(inputMenu, mLoyaltyCardCount > 0)
|
||||
|
||||
val searchManager = getSystemService(SEARCH_SERVICE) as SearchManager?
|
||||
if (searchManager != null) {
|
||||
val searchMenuItem = inputMenu.findItem(R.id.action_search)
|
||||
mSearchView = searchMenuItem.actionView as SearchView?
|
||||
mSearchView!!.setSearchableInfo(searchManager.getSearchableInfo(componentName))
|
||||
mSearchView!!.setSubmitButtonEnabled(false)
|
||||
mSearchView!!.setOnCloseListener {
|
||||
invalidateOptionsMenu()
|
||||
false
|
||||
}
|
||||
|
||||
/*
|
||||
* On Android 13 and later, pressing Back while the search view is open hides the keyboard
|
||||
* and collapses the search view at the same time.
|
||||
* This brings back the old behavior on Android 12 and lower: pressing Back once
|
||||
* hides the keyboard, press again while keyboard is hidden to collapse the search view.
|
||||
*/
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
searchMenuItem.setOnActionExpandListener(object : MenuItem.OnActionExpandListener {
|
||||
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
|
||||
if (mSearchView!!.hasFocus()) {
|
||||
mSearchView!!.clearFocus()
|
||||
return false
|
||||
}
|
||||
currentQuery = ""
|
||||
mFilter = ""
|
||||
updateLoyaltyCardList(false)
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
mSearchView!!.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String): Boolean {
|
||||
mFilter = newText
|
||||
// New logic to ensure search history after coming back from picked card - user will see the last search query
|
||||
if (newText.isEmpty()) {
|
||||
if (!finalQuery.isEmpty()) {
|
||||
// Setting the query text for user after coming back from picked card from finalQuery
|
||||
mSearchView!!.setQuery(finalQuery, false)
|
||||
} else if (!currentQuery.isEmpty()) {
|
||||
// Else if is needed in case user deletes search - expected behaviour is to show all cards
|
||||
currentQuery = ""
|
||||
mSearchView!!.setQuery(currentQuery, false)
|
||||
}
|
||||
} else {
|
||||
// Setting search query each time user changes the text in search to temporary variable to be used later in finalQuery String which will be used to restore search history
|
||||
currentQuery = newText
|
||||
}
|
||||
val currentTab =
|
||||
groupsTabLayout.getTabAt(groupsTabLayout.selectedTabPosition)
|
||||
mGroup = currentTab?.tag
|
||||
|
||||
updateLoyaltyCardList(false)
|
||||
|
||||
return true
|
||||
}
|
||||
})
|
||||
// Check if we came from a picked card back to search, in that case we want to show the search view with previous search query
|
||||
if (!finalQuery.isEmpty()) {
|
||||
// Expand the search view to show the query
|
||||
searchMenuItem.expandActionView()
|
||||
// Setting the query text to empty String due to behaviour of onQueryTextChange after coming back from picked card - onQueryTextChange is called automatically without users interaction
|
||||
finalQuery = ""
|
||||
mSearchView!!.setQuery(currentQuery, false)
|
||||
}
|
||||
}
|
||||
|
||||
return super.onCreateOptionsMenu(inputMenu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(inputItem: MenuItem): Boolean {
|
||||
when (inputItem.itemId) {
|
||||
android.R.id.home -> {
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
R.id.action_display_options -> {
|
||||
mAdapter.showDisplayOptionsDialog()
|
||||
invalidateOptionsMenu()
|
||||
return true
|
||||
}
|
||||
R.id.action_sort -> {
|
||||
val currentIndex = AtomicInteger()
|
||||
val loyaltyCardOrders = listOf<LoyaltyCardOrder?>(*LoyaltyCardOrder.entries.toTypedArray())
|
||||
for (i in loyaltyCardOrders.indices) {
|
||||
if (mOrder == loyaltyCardOrders[i]) {
|
||||
currentIndex.set(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
MaterialAlertDialogBuilder(this@MainActivity).apply {
|
||||
setTitle(R.string.sort_by)
|
||||
|
||||
val sortingOptionBinding = SortingOptionBinding.inflate(LayoutInflater.from(this@MainActivity), null, false)
|
||||
val customLayout: View = sortingOptionBinding.getRoot()
|
||||
setView(customLayout)
|
||||
|
||||
val showReversed = sortingOptionBinding.checkBoxReverse
|
||||
|
||||
showReversed.isChecked = mOrderDirection == LoyaltyCardOrderDirection.Descending
|
||||
|
||||
setSingleChoiceItems(
|
||||
R.array.sort_types_array,
|
||||
currentIndex.get()
|
||||
) { _: DialogInterface?, which: Int ->
|
||||
currentIndex.set(which)
|
||||
}
|
||||
|
||||
setPositiveButton(
|
||||
R.string.sort
|
||||
) { dialog, _ ->
|
||||
setSort(
|
||||
loyaltyCardOrders[currentIndex.get()]!!,
|
||||
if (showReversed.isChecked) LoyaltyCardOrderDirection.Descending else LoyaltyCardOrderDirection.Ascending
|
||||
)
|
||||
ListWidget().updateAll(this@MainActivity)
|
||||
dialog?.dismiss()
|
||||
}
|
||||
|
||||
setNegativeButton(R.string.cancel) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
}
|
||||
}.create().show()
|
||||
|
||||
return true
|
||||
}
|
||||
R.id.action_manage_groups -> {
|
||||
startActivity(
|
||||
Intent(applicationContext, ManageGroupsActivity::class.java)
|
||||
)
|
||||
return true
|
||||
}
|
||||
R.id.action_import_export -> {
|
||||
startActivity(
|
||||
Intent(applicationContext, ImportExportActivity::class.java)
|
||||
)
|
||||
return true
|
||||
}
|
||||
R.id.action_settings -> {
|
||||
mSettingsLauncher.launch(
|
||||
Intent(applicationContext, SettingsActivity::class.java)
|
||||
)
|
||||
return true
|
||||
}
|
||||
R.id.action_about -> {
|
||||
startActivity(
|
||||
Intent(applicationContext, AboutActivity::class.java)
|
||||
)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(inputItem)
|
||||
}
|
||||
|
||||
private fun setSort(order: LoyaltyCardOrder, direction: LoyaltyCardOrderDirection) {
|
||||
// Update values
|
||||
mOrder = order
|
||||
mOrderDirection = direction
|
||||
|
||||
// Store in Shared Preference to restore next app launch
|
||||
applicationContext.getSharedPreferences(
|
||||
getString(R.string.sharedpreference_sort),
|
||||
MODE_PRIVATE
|
||||
).edit {
|
||||
putString(
|
||||
getString(R.string.sharedpreference_sort_order),
|
||||
order.name
|
||||
)
|
||||
putString(
|
||||
getString(R.string.sharedpreference_sort_direction),
|
||||
direction.name
|
||||
)
|
||||
}
|
||||
|
||||
// Update card list
|
||||
updateLoyaltyCardList(false)
|
||||
}
|
||||
|
||||
override fun onRowLongClicked(inputPosition: Int) {
|
||||
enableActionMode(inputPosition)
|
||||
}
|
||||
|
||||
private fun enableActionMode(inputPosition: Int) {
|
||||
if (mCurrentActionMode == null) {
|
||||
mCurrentActionMode = startSupportActionMode(mCurrentActionModeCallback)
|
||||
}
|
||||
toggleSelection(inputPosition)
|
||||
}
|
||||
|
||||
private fun scaleScreen() {
|
||||
val displayMetrics = DisplayMetrics()
|
||||
windowManager.defaultDisplay.getMetrics(displayMetrics)
|
||||
val screenHeight = displayMetrics.heightPixels
|
||||
val mediumSizePx = TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
MEDIUM_SCALE_FACTOR_DIP.toFloat(),
|
||||
getResources().displayMetrics
|
||||
)
|
||||
val shouldScaleSmaller = screenHeight < mediumSizePx
|
||||
|
||||
binding.include.welcomeIcon.visibility = if (shouldScaleSmaller) View.GONE else View.VISIBLE
|
||||
}
|
||||
|
||||
private fun toggleSelection(inputPosition: Int) {
|
||||
mAdapter.toggleSelection(inputPosition)
|
||||
val count = mAdapter.selectedItemCount
|
||||
|
||||
if (count == 0) {
|
||||
mCurrentActionMode!!.finish()
|
||||
} else {
|
||||
mCurrentActionMode!!.title = getResources().getQuantityString(
|
||||
R.plurals.selectedCardCount,
|
||||
count,
|
||||
count
|
||||
)
|
||||
|
||||
val editItem = mCurrentActionMode!!.menu.findItem(R.id.action_edit)
|
||||
val duplicateItem = mCurrentActionMode!!.menu.findItem(R.id.action_duplicate)
|
||||
val archiveItem = mCurrentActionMode!!.menu.findItem(R.id.action_archive)
|
||||
val unarchiveItem = mCurrentActionMode!!.menu.findItem(R.id.action_unarchive)
|
||||
val starItem = mCurrentActionMode!!.menu.findItem(R.id.action_star)
|
||||
val unstarItem = mCurrentActionMode!!.menu.findItem(R.id.action_unstar)
|
||||
|
||||
var hasStarred = false
|
||||
var hasUnstarred = false
|
||||
var hasArchived = false
|
||||
var hasUnarchived = false
|
||||
|
||||
for (loyaltyCard in mAdapter.getSelectedItems()) {
|
||||
if (loyaltyCard.starStatus == 1) {
|
||||
hasStarred = true
|
||||
} else {
|
||||
hasUnstarred = true
|
||||
}
|
||||
|
||||
if (loyaltyCard.archiveStatus == 1) {
|
||||
hasArchived = true
|
||||
} else {
|
||||
hasUnarchived = true
|
||||
}
|
||||
|
||||
// We have all types, no need to keep checking
|
||||
if (hasStarred && hasUnstarred && hasArchived && hasUnarchived) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
unarchiveItem.isVisible = hasArchived
|
||||
archiveItem.isVisible = hasUnarchived
|
||||
|
||||
if (count == 1) {
|
||||
starItem.isVisible = !hasStarred
|
||||
unstarItem.isVisible = !hasUnstarred
|
||||
editItem.isVisible = true
|
||||
editItem.isEnabled = true
|
||||
duplicateItem.isVisible = true
|
||||
duplicateItem.isEnabled = true
|
||||
} else {
|
||||
starItem.isVisible = hasUnstarred
|
||||
unstarItem.isVisible = hasStarred
|
||||
|
||||
editItem.isVisible = false
|
||||
editItem.isEnabled = false
|
||||
duplicateItem.isVisible = false
|
||||
duplicateItem.isEnabled = false
|
||||
}
|
||||
|
||||
mCurrentActionMode!!.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onRowClicked(inputPosition: Int) {
|
||||
if (mAdapter.selectedItemCount > 0) {
|
||||
enableActionMode(inputPosition)
|
||||
} else {
|
||||
// FIXME
|
||||
//
|
||||
// There is a really nasty edge case that can happen when someone taps a card but right
|
||||
// after it swipes (very small window, hard to reproduce). The cursor gets replaced and
|
||||
// may not have a card at the ID number that is returned from onRowClicked.
|
||||
//
|
||||
// The proper fix, obviously, would involve makes sure an onFling can't happen while a
|
||||
// click is being processed. Sadly, I have not yet found a way to make that possible.
|
||||
val loyaltyCard: LoyaltyCard
|
||||
try {
|
||||
loyaltyCard = mAdapter.getCard(inputPosition)
|
||||
} catch (e: CursorIndexOutOfBoundsException) {
|
||||
Log.w(TAG, "Prevented crash from tap + swipe on ID $inputPosition: $e")
|
||||
return
|
||||
}
|
||||
|
||||
startActivity(
|
||||
Intent(this, LoyaltyCardViewActivity::class.java).apply {
|
||||
action = ""
|
||||
putExtras(Bundle().apply {
|
||||
putInt(LoyaltyCardViewActivity.BUNDLE_ID, loyaltyCard.id)
|
||||
|
||||
val cardList = ArrayList<Int?>()
|
||||
for (i in 0..<mAdapter.itemCount) {
|
||||
cardList.add(mAdapter.getCard(i).id)
|
||||
}
|
||||
|
||||
putIntegerArrayList(LoyaltyCardViewActivity.BUNDLE_CARDLIST, cardList)
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "Catima"
|
||||
const val RESTART_ACTIVITY_INTENT: String = "restart_activity_intent"
|
||||
|
||||
private const val MEDIUM_SCALE_FACTOR_DIP = 460
|
||||
const val STATE_SEARCH_QUERY: String = "SEARCH_QUERY"
|
||||
}
|
||||
}
|
||||
@@ -12,10 +12,12 @@ import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import protect.card_locker.LoyaltyCardCursorAdapter.CardAdapterListener
|
||||
import protect.card_locker.databinding.ActivityManageGroupBinding
|
||||
import protect.card_locker.preferences.Settings
|
||||
|
||||
class ManageGroupActivity : CatimaAppCompatActivity(), CardAdapterListener {
|
||||
private lateinit var binding: ActivityManageGroupBinding
|
||||
@@ -132,7 +134,15 @@ class ManageGroupActivity : CatimaAppCompatActivity(), CardAdapterListener {
|
||||
override fun handleOnBackPressed() {
|
||||
leaveWithoutSaving()
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
// Apply column count setting to card list
|
||||
val layoutManager = mCardList.layoutManager as GridLayoutManager?
|
||||
if (layoutManager != null) {
|
||||
val settings = Settings(this)
|
||||
layoutManager.setSpanCount(settings.getPreferredColumnCount())
|
||||
}
|
||||
}
|
||||
|
||||
private fun adapterStateToBundle(adapterState: HashMap<Int, Boolean>): Bundle {
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
public class OpenWebLinkHandler {
|
||||
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
public void openBrowser(AppCompatActivity activity, String url) {
|
||||
public void openBrowser(Activity activity, String url) {
|
||||
if (url == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.json.JSONObject
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.math.BigDecimal
|
||||
import java.nio.charset.Charset
|
||||
import java.text.DateFormat
|
||||
import java.text.ParseException
|
||||
import java.time.ZonedDateTime
|
||||
@@ -40,6 +41,7 @@ class PkpassParser(context: Context, uri: Uri?) {
|
||||
private var cardId: String = context.getString(R.string.noBarcode)
|
||||
private var barcodeId: String? = null
|
||||
private var barcodeType: CatimaBarcode? = null
|
||||
private var barcodeEncoding: Charset? = null
|
||||
private var headerColor: Int? = null
|
||||
private val starStatus = 0
|
||||
private val lastUsed: Long = 0
|
||||
@@ -134,6 +136,7 @@ class PkpassParser(context: Context, uri: Uri?) {
|
||||
cardId,
|
||||
barcodeId,
|
||||
barcodeType,
|
||||
barcodeEncoding,
|
||||
headerColor,
|
||||
starStatus,
|
||||
lastUsed,
|
||||
@@ -342,13 +345,14 @@ class PkpassParser(context: Context, uri: Uri?) {
|
||||
else -> throw IllegalArgumentException("No valid barcode type")
|
||||
}
|
||||
|
||||
// FIXME: We probably need to do something with the messageEncoding field
|
||||
try {
|
||||
cardId = barcodeInfo.getString("altText")
|
||||
barcodeId = barcodeInfo.getString("message")
|
||||
barcodeEncoding = Charset.forName(barcodeInfo.getString("messageEncoding"))
|
||||
} catch (ignored: JSONException) {
|
||||
cardId = barcodeInfo.getString("message")
|
||||
barcodeId = null
|
||||
barcodeEncoding = Charset.forName(barcodeInfo.getString("messageEncoding"))
|
||||
}
|
||||
|
||||
// Don't set barcodeId if it's the same as cardId
|
||||
|
||||
@@ -538,7 +538,7 @@ class ScanActivity : CatimaAppCompatActivity() {
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<String?>,
|
||||
permissions: Array<String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
@@ -548,7 +548,7 @@ class ScanActivity : CatimaAppCompatActivity() {
|
||||
|
||||
override fun onMockedRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<String?>,
|
||||
permissions: Array<String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
val granted =
|
||||
|
||||
@@ -118,7 +118,7 @@ public class Utils {
|
||||
static final double LUMINANCE_MIDPOINT = 0.5;
|
||||
|
||||
static final int BITMAP_SIZE_SMALL = 512;
|
||||
static final int BITMAP_SIZE_BIG = 2048;
|
||||
static final int BITMAP_SIZE_BIG = 1600;
|
||||
|
||||
static public LetterBitmap generateIcon(Context context, LoyaltyCard loyaltyCard, boolean forShortcut) {
|
||||
return generateIcon(context, loyaltyCard.store, loyaltyCard.headerColor, forShortcut);
|
||||
@@ -143,7 +143,7 @@ public class Utils {
|
||||
int pixelSize = context.getResources().getDimensionPixelSize(R.dimen.tileLetterImageSize);
|
||||
|
||||
if (backgroundColor == null) {
|
||||
backgroundColor = LetterBitmap.getDefaultColor(context, store);
|
||||
backgroundColor = LetterBitmap.Companion.getDefaultColor(context, store);
|
||||
}
|
||||
|
||||
return new LetterBitmap(context, store, store,
|
||||
@@ -963,31 +963,9 @@ public class Utils {
|
||||
// replace colors in the current theme
|
||||
public static void patchColors(AppCompatActivity activity) {
|
||||
Settings settings = new Settings(activity);
|
||||
String color = settings.getColor();
|
||||
|
||||
Resources.Theme theme = activity.getTheme();
|
||||
Resources resources = activity.getResources();
|
||||
if (color.equals(resources.getString(R.string.settings_key_pink_theme))) {
|
||||
theme.applyStyle(R.style.pink, true);
|
||||
} else if (color.equals(resources.getString(R.string.settings_key_magenta_theme))) {
|
||||
theme.applyStyle(R.style.magenta, true);
|
||||
} else if (color.equals(resources.getString(R.string.settings_key_violet_theme))) {
|
||||
theme.applyStyle(R.style.violet, true);
|
||||
} else if (color.equals(resources.getString(R.string.settings_key_blue_theme))) {
|
||||
theme.applyStyle(R.style.blue, true);
|
||||
} else if (color.equals(resources.getString(R.string.settings_key_sky_blue_theme))) {
|
||||
theme.applyStyle(R.style.skyblue, true);
|
||||
} else if (color.equals(resources.getString(R.string.settings_key_green_theme))) {
|
||||
theme.applyStyle(R.style.green, true);
|
||||
} else if (color.equals(resources.getString(R.string.settings_key_brown_theme))) {
|
||||
theme.applyStyle(R.style.brown, true);
|
||||
} else if (color.equals(resources.getString(R.string.settings_key_catima_theme))) {
|
||||
// catima theme is AppTheme itself, no dynamic colors nor applyStyle
|
||||
} else {
|
||||
// final catch all in case of invalid theme value from older versions
|
||||
// also handles R.string.settings_key_system_theme
|
||||
DynamicColors.applyToActivityIfAvailable(activity);
|
||||
}
|
||||
DynamicColors.applyToActivityIfAvailable(activity);
|
||||
|
||||
if (isDarkModeEnabled(activity) && settings.getOledDark()) {
|
||||
theme.applyStyle(R.style.DarkBackground, true);
|
||||
@@ -1129,7 +1107,7 @@ public class Utils {
|
||||
}
|
||||
|
||||
public static int getHeaderColor(Context context, LoyaltyCard loyaltyCard) {
|
||||
return loyaltyCard.headerColor != null ? loyaltyCard.headerColor : LetterBitmap.getDefaultColor(context, loyaltyCard.store);
|
||||
return loyaltyCard.headerColor != null ? loyaltyCard.headerColor : LetterBitmap.Companion.getDefaultColor(context, loyaltyCard.store);
|
||||
}
|
||||
|
||||
public static String checksum(InputStream input) throws IOException {
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package protect.card_locker.compose
|
||||
|
||||
import androidx.activity.compose.LocalActivity
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.unit.dp
|
||||
import protect.card_locker.OpenWebLinkHandler
|
||||
import protect.card_locker.R
|
||||
|
||||
@Composable
|
||||
fun CatimaAboutSection(
|
||||
title: String,
|
||||
message: String,
|
||||
modifier: Modifier = Modifier,
|
||||
onClickUrl: String? = null,
|
||||
onClickDialogText: AnnotatedString? = null,
|
||||
) {
|
||||
val activity = LocalActivity.current
|
||||
|
||||
val openDialog = remember { mutableStateOf(false) }
|
||||
|
||||
Row(
|
||||
modifier = modifier
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
.clickable {
|
||||
if (onClickDialogText != null) {
|
||||
openDialog.value = true
|
||||
} else if (onClickUrl != null) {
|
||||
OpenWebLinkHandler().openBrowser(activity, onClickUrl)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Column(modifier = Modifier.weight(1F)) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
Text(text = message)
|
||||
}
|
||||
Text(modifier = Modifier.align(Alignment.CenterVertically),
|
||||
text = ">",
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
if (openDialog.value && onClickDialogText != null) {
|
||||
AlertDialog(
|
||||
icon = {},
|
||||
title = {
|
||||
Text(text = title)
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
text = onClickDialogText,
|
||||
modifier = Modifier.verticalScroll(rememberScrollState())
|
||||
)
|
||||
},
|
||||
onDismissRequest = {
|
||||
openDialog.value = false
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
openDialog.value = false
|
||||
}
|
||||
) {
|
||||
Text(stringResource(R.string.ok))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
if (onClickUrl != null) {
|
||||
TextButton(
|
||||
onClick = {
|
||||
OpenWebLinkHandler().openBrowser(activity, onClickUrl)
|
||||
}
|
||||
) {
|
||||
Text(stringResource(R.string.view_online))
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
34
app/src/main/java/protect/card_locker/compose/Catima.kt
Normal file
34
app/src/main/java/protect/card_locker/compose/Catima.kt
Normal file
@@ -0,0 +1,34 @@
|
||||
package protect.card_locker.compose
|
||||
|
||||
import androidx.activity.OnBackPressedDispatcher
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import protect.card_locker.R
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun CatimaTopAppBar(title: String, onBackPressedDispatcher: OnBackPressedDispatcher?) {
|
||||
TopAppBar(
|
||||
modifier = Modifier.testTag("topbar_catima"),
|
||||
title = { Text(text = title) },
|
||||
navigationIcon = {
|
||||
if (onBackPressedDispatcher != null) {
|
||||
IconButton(onClick = { onBackPressedDispatcher.onBackPressed() }) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = stringResource(R.string.back)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
51
app/src/main/java/protect/card_locker/compose/theme/Theme.kt
Normal file
51
app/src/main/java/protect/card_locker/compose/theme/Theme.kt
Normal file
@@ -0,0 +1,51 @@
|
||||
package protect.card_locker.compose.theme
|
||||
|
||||
import android.os.Build
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.material3.dynamicLightColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import protect.card_locker.R
|
||||
import protect.card_locker.preferences.Settings
|
||||
|
||||
@Composable
|
||||
fun CatimaTheme(content: @Composable () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
val settings = Settings(context)
|
||||
|
||||
val isDynamicColorSupported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||
|
||||
val lightTheme = if (isDynamicColorSupported) {
|
||||
dynamicLightColorScheme(context)
|
||||
} else {
|
||||
lightColorScheme(primary = colorResource(id = R.color.md_theme_light_primary))
|
||||
}
|
||||
|
||||
var darkTheme = if (isDynamicColorSupported) {
|
||||
dynamicDarkColorScheme(context)
|
||||
} else {
|
||||
darkColorScheme(primary = colorResource(id = R.color.md_theme_dark_primary))
|
||||
}
|
||||
|
||||
if (settings.oledDark) {
|
||||
darkTheme = darkTheme.copy(background = Color.Black)
|
||||
}
|
||||
|
||||
val colorScheme = when (settings.theme) {
|
||||
AppCompatDelegate.MODE_NIGHT_NO -> lightTheme
|
||||
AppCompatDelegate.MODE_NIGHT_YES -> darkTheme
|
||||
else -> if (isSystemInDarkTheme()) darkTheme else lightTheme
|
||||
}
|
||||
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
@@ -52,6 +52,7 @@ public class CardsContentProvider extends ContentProvider {
|
||||
LoyaltyCardDbIds.CARD_ID,
|
||||
LoyaltyCardDbIds.BARCODE_ID,
|
||||
LoyaltyCardDbIds.BARCODE_TYPE,
|
||||
// FIXME: Expose BARCODE_ENCODING but without ever exposing the null value (so apps using this don't have to guess)
|
||||
LoyaltyCardDbIds.STAR_STATUS,
|
||||
LoyaltyCardDbIds.LAST_USED,
|
||||
LoyaltyCardDbIds.ARCHIVE_STATUS,
|
||||
|
||||
@@ -134,6 +134,7 @@ public class CatimaExporter implements Exporter {
|
||||
DBHelper.LoyaltyCardDbIds.CARD_ID,
|
||||
DBHelper.LoyaltyCardDbIds.BARCODE_ID,
|
||||
DBHelper.LoyaltyCardDbIds.BARCODE_TYPE,
|
||||
DBHelper.LoyaltyCardDbIds.BARCODE_ENCODING,
|
||||
DBHelper.LoyaltyCardDbIds.HEADER_COLOR,
|
||||
DBHelper.LoyaltyCardDbIds.STAR_STATUS,
|
||||
DBHelper.LoyaltyCardDbIds.LAST_USED,
|
||||
@@ -154,6 +155,7 @@ public class CatimaExporter implements Exporter {
|
||||
card.cardId,
|
||||
card.barcodeId,
|
||||
card.barcodeType != null ? card.barcodeType.name() : "",
|
||||
card.barcodeEncoding != null ? card.barcodeEncoding.name() : "",
|
||||
card.headerColor,
|
||||
card.starStatus,
|
||||
card.lastUsed,
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringReader;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Currency;
|
||||
@@ -127,10 +128,10 @@ public class CatimaImporter implements Importer {
|
||||
LoyaltyCard existing = DBHelper.getLoyaltyCard(context, database, card.id);
|
||||
if (existing == null) {
|
||||
DBHelper.insertLoyaltyCard(database, card.id, card.store, card.note, card.validFrom, card.expiry, card.balance, card.balanceType,
|
||||
card.cardId, card.barcodeId, card.barcodeType, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
|
||||
card.cardId, card.barcodeId, card.barcodeType, card.barcodeEncoding, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
|
||||
} else if (!isDuplicate(context, existing, card, existingImages, imageChecksums)) {
|
||||
long newId = DBHelper.insertLoyaltyCard(database, card.store, card.note, card.validFrom, card.expiry, card.balance, card.balanceType,
|
||||
card.cardId, card.barcodeId, card.barcodeType, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
|
||||
card.cardId, card.barcodeId, card.barcodeType, card.barcodeEncoding, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
|
||||
idMap.put(card.id, (int) newId);
|
||||
}
|
||||
}
|
||||
@@ -458,6 +459,12 @@ public class CatimaImporter implements Importer {
|
||||
barcodeType = CatimaBarcode.fromName(unparsedBarcodeType);
|
||||
}
|
||||
|
||||
Charset barcodeEncoding = null;
|
||||
String unparsedBarcodeEncoding = CSVHelpers.extractString(DBHelper.LoyaltyCardDbIds.BARCODE_ENCODING, record, "");
|
||||
if (!unparsedBarcodeEncoding.isEmpty()) {
|
||||
barcodeEncoding = Charset.forName(unparsedBarcodeEncoding);
|
||||
}
|
||||
|
||||
Integer headerColor = null;
|
||||
try {
|
||||
headerColor = CSVHelpers.extractInt(DBHelper.LoyaltyCardDbIds.HEADER_COLOR, record);
|
||||
@@ -501,6 +508,7 @@ public class CatimaImporter implements Importer {
|
||||
cardId,
|
||||
barcodeId,
|
||||
barcodeType,
|
||||
barcodeEncoding,
|
||||
headerColor,
|
||||
starStatus,
|
||||
lastUsed,
|
||||
|
||||
@@ -160,6 +160,7 @@ public class FidmeImporter implements Importer {
|
||||
cardId,
|
||||
null,
|
||||
barcodeType,
|
||||
null,
|
||||
headerColor,
|
||||
starStatus,
|
||||
Utils.getUnixTime(),
|
||||
@@ -181,7 +182,7 @@ public class FidmeImporter implements Importer {
|
||||
for (LoyaltyCard card : data.cards) {
|
||||
// Do not use card.id which is set to -1
|
||||
DBHelper.insertLoyaltyCard(database, card.store, card.note, card.validFrom, card.expiry, card.balance, card.balanceType,
|
||||
card.cardId, card.barcodeId, card.barcodeType, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
|
||||
card.cardId, card.barcodeId, card.barcodeType, card.barcodeEncoding, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,7 @@ public class VoucherVaultImporter implements Importer {
|
||||
cardId,
|
||||
null,
|
||||
barcodeType,
|
||||
null,
|
||||
headerColor,
|
||||
0,
|
||||
Utils.getUnixTime(),
|
||||
@@ -186,7 +187,7 @@ public class VoucherVaultImporter implements Importer {
|
||||
for (LoyaltyCard card : data.cards) {
|
||||
// Do not use card.id which is set to -1
|
||||
DBHelper.insertLoyaltyCard(database, card.store, card.note, card.validFrom, card.expiry, card.balance, card.balanceType,
|
||||
card.cardId, card.barcodeId, card.barcodeType, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
|
||||
card.cardId, card.barcodeId, card.barcodeType, card.barcodeEncoding, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,10 +90,6 @@ public class Settings {
|
||||
return getBoolean(R.string.settings_key_oled_dark, false);
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return getString(R.string.setting_key_theme_color, mContext.getResources().getString(R.string.settings_key_system_theme));
|
||||
}
|
||||
|
||||
public int getPreferredColumnCount() {
|
||||
var defaultSymbol = mContext.getResources().getString(R.string.settings_key_automatic_column_count);
|
||||
var defaultColumnCount = mContext.getResources().getInteger(R.integer.main_view_card_columns);
|
||||
|
||||
@@ -11,7 +11,6 @@ import androidx.core.os.LocaleListCompat
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.google.android.material.color.DynamicColors
|
||||
import protect.card_locker.BuildConfig
|
||||
import protect.card_locker.CatimaAppCompatActivity
|
||||
import protect.card_locker.MainActivity
|
||||
@@ -103,16 +102,6 @@ class SettingsActivity : CatimaAppCompatActivity() {
|
||||
true
|
||||
}
|
||||
|
||||
val themeColorPreference = findPreference<ListPreference>(getString(R.string.setting_key_theme_color))
|
||||
themeColorPreference!!.setOnPreferenceChangeListener { _, _ ->
|
||||
refreshActivity(true)
|
||||
true
|
||||
}
|
||||
if (!DynamicColors.isDynamicColorAvailable()) {
|
||||
themeColorPreference.setEntryValues(R.array.color_values_no_dynamic)
|
||||
themeColorPreference.setEntries(R.array.color_value_strings_no_dynamic)
|
||||
}
|
||||
|
||||
val oledDarkPreference = findPreference<Preference>(getString(R.string.settings_key_oled_dark))
|
||||
oledDarkPreference!!.setOnPreferenceChangeListener { _, _ ->
|
||||
refreshActivity(true)
|
||||
|
||||
@@ -1,421 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context="protect.card_locker.MainActivity">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
style="?attr/toolbarStyle" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="?attr/actionBarSize"
|
||||
android:paddingVertical="8dp"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/version_history"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="8dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:background="?android:selectableItemBackground">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/version_history_main"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/version_history"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/version_history_sub"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/version_history_main" />
|
||||
|
||||
<TextView
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:text="@string/arrow"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/credits"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="8dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:background="?android:selectableItemBackground">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/credits_main"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/credits"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/credits_sub"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/credits_main" />
|
||||
|
||||
<TextView
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:text="@string/arrow"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/translate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="8dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:background="?android:selectableItemBackground">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/translate_main"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/help_translate_this_app"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/translate_sub"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/translate_platform"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/translate_main"/>
|
||||
|
||||
<TextView
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:text="@string/arrow"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/license"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="8dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:background="?android:selectableItemBackground">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/license_main"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/license"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/license_sub"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/app_license"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/license_main"/>
|
||||
|
||||
<TextView
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:text="@string/arrow"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/repo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="8dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:background="?android:selectableItemBackground">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/repo_main"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/source_repository"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/repo_sub"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/on_github"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/repo_main" />
|
||||
|
||||
<TextView
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:text="@string/arrow"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/privacy"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="8dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:background="?android:selectableItemBackground">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/privacy_main"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/privacy_policy"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/privacy_sub"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/and_data_usage"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/privacy_main" />
|
||||
|
||||
<TextView
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:text="@string/arrow"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/donate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="8dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:background="?android:selectableItemBackground">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/donate_main"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/donate"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:text="@string/arrow"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/rate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="8dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:background="?android:selectableItemBackground">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/rate_main"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/rate_this_app"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/rate_sub"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/on_google_play"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/rate_main" />
|
||||
|
||||
<TextView
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:text="@string/arrow"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/report_error"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="8dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:background="?android:selectableItemBackground">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/report_error_main"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:text="@string/report_error"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/report_error_sub"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/report_error_main"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:textSize="16sp"
|
||||
android:text="@string/on_github" />
|
||||
|
||||
<TextView
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:text="@string/arrow"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@@ -191,6 +191,32 @@
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Barcode encoding -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="@dimen/inputPadding"
|
||||
android:paddingTop="@dimen/inputPadding"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<!-- Barcode type -->
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/barcodeEncodingView"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0"
|
||||
android:hint="@string/barcodeEncoding"
|
||||
android:labelFor="@+id/barcodeEncodingField">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/barcodeEncodingField"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"/>
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Barcode -->
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:layout_marginTop="10.0dp"
|
||||
@@ -276,6 +302,24 @@
|
||||
android:paddingTop="@dimen/inputPadding"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<!-- Currency -->
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/balanceCurrencyView"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0"
|
||||
android:hint="@string/currency"
|
||||
android:labelFor="@+id/balanceCurrencyField">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/balanceCurrencyField"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<!-- Balance -->
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/balanceView"
|
||||
@@ -294,24 +338,6 @@
|
||||
android:digits="0123456789,." />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<!-- Currency -->
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/balanceCurrencyView"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0"
|
||||
android:hint="@string/currency"
|
||||
android:labelFor="@+id/balanceCurrencyField">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/balanceCurrencyField"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Valid from -->
|
||||
|
||||
@@ -40,10 +40,16 @@
|
||||
android:titleCondensed="@string/unarchive"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_duplicate"
|
||||
android:title="@string/duplicateCard"
|
||||
android:titleCondensed="@string/duplicateCard"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_delete"
|
||||
android:icon="@drawable/ic_delete_white_24dp"
|
||||
android:title="@string/delete"
|
||||
android:titleCondensed="@string/delete"
|
||||
app:showAsAction="never"/>
|
||||
</menu>
|
||||
</menu>
|
||||
|
||||
@@ -21,25 +21,25 @@
|
||||
app:showAsAction="always">
|
||||
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/action_archive"
|
||||
android:title="@string/archive"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_unarchive"
|
||||
android:title="@string/unarchive"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_duplicate"
|
||||
android:title="@string/duplicateCard"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_archive"
|
||||
android:title="@string/archive"
|
||||
app:showAsAction="never"/>
|
||||
<item
|
||||
android:id="@+id/action_unarchive"
|
||||
android:title="@string/unarchive"
|
||||
app:showAsAction="never"/>
|
||||
<item
|
||||
android:id="@+id/action_delete"
|
||||
android:title="@string/delete"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
</menu>
|
||||
|
||||
</item>
|
||||
|
||||
@@ -7,26 +7,26 @@ Heimen Stoffels
|
||||
Oğuz Ersen
|
||||
FC (Fay) Stegerman
|
||||
StoyanDimitrov
|
||||
SlavekB
|
||||
大王叫我来巡山
|
||||
Katharine Chui
|
||||
B o d o
|
||||
SlavekB
|
||||
Katharine Chui
|
||||
mondstern
|
||||
IllusiveMan196
|
||||
Altonss
|
||||
Silvério Santos
|
||||
Altonss
|
||||
Edgars Andersons
|
||||
Michael Moroni
|
||||
Joel A
|
||||
Eric
|
||||
Priit Jõerüüt
|
||||
Максим Горпиніч
|
||||
Michael Moroni
|
||||
Liner Seven
|
||||
GM
|
||||
Petr Novák
|
||||
laralem
|
||||
Priit Jõerüüt
|
||||
Eric
|
||||
Максим Горпиніч
|
||||
GitSpoon
|
||||
GM
|
||||
Fjuro
|
||||
laralem
|
||||
Petr Novák
|
||||
Taco
|
||||
nadiafekihahmed
|
||||
pfaffenrodt
|
||||
@@ -38,44 +38,47 @@ Nyatsuki
|
||||
Giovanni Donisi
|
||||
Milo Ivir
|
||||
HudobniVolk
|
||||
Jiri Grönroos
|
||||
Vasilis
|
||||
Warder
|
||||
Kachelkaiser
|
||||
Samantaz Fox
|
||||
Горпиніч Максим Олександрович
|
||||
Vasilis
|
||||
Kachelkaiser
|
||||
Jiri Grönroos
|
||||
Warder
|
||||
Samantaz Fox
|
||||
Balázs Meskó
|
||||
Feike Donia
|
||||
Arno-github
|
||||
Ankit Tiwari
|
||||
Cliff Heraldo
|
||||
Sergio Paredes
|
||||
Jose Delvani
|
||||
Ankit Tiwari
|
||||
109247019824
|
||||
mdvhimself
|
||||
Feike Donia
|
||||
Arno-github
|
||||
Jose Delvani
|
||||
Milan Šalka
|
||||
Robin
|
||||
mdvhimself
|
||||
தமிழ்நேரம்
|
||||
huuhaa
|
||||
Skrripy
|
||||
Govindgopalyadav
|
||||
damjang
|
||||
Projjal Moitra
|
||||
Quentin PAGÈS
|
||||
StellarSand
|
||||
aradxxx
|
||||
ngocanhtve
|
||||
Marnick L'Eau
|
||||
Govindgopalyadav
|
||||
Skrripy
|
||||
huuhaa
|
||||
waffshappen
|
||||
Marnick L'Eau
|
||||
ngocanhtve
|
||||
aradxxx
|
||||
StellarSand
|
||||
Quentin PAGÈS
|
||||
Projjal Moitra
|
||||
e-michalak
|
||||
JungHee Lee
|
||||
hajertabbane
|
||||
inavleb
|
||||
Ziad OUALHADJ
|
||||
Robin Liu
|
||||
Aliaksandr Trush
|
||||
Denis Shilin
|
||||
Traductor
|
||||
Gideon
|
||||
Renko
|
||||
Ricky Tigg
|
||||
Robin Liu
|
||||
Ziad OUALHADJ
|
||||
delvani
|
||||
しいたけ
|
||||
Alexander Ivanov
|
||||
Miha Frangež
|
||||
@@ -84,15 +87,13 @@ mrestivill
|
||||
ehrt74
|
||||
Virginie
|
||||
Tim Trek
|
||||
Peter Dave Hello
|
||||
Aliaksandr Trush
|
||||
MisterCosta96
|
||||
arshbeerSingh
|
||||
Augustin LAVILLE
|
||||
Freddo espresso
|
||||
Gideon
|
||||
n3m0-blip
|
||||
vasudev-cell
|
||||
Kim Seohyun
|
||||
rudy3
|
||||
Michael Gangolf
|
||||
PRATHAMESH BHAGAT
|
||||
Peter Dave Hello
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
<string name="privacy_policy">سياسة الخصوصية</string>
|
||||
<string name="accept">قبول</string>
|
||||
<string name="importCatima">الاستيراد من Catima</string>
|
||||
<string name="importCatimaMessage">حدّد ملفك <i>catima.zip</i> تصدير من Catima للاستيراد. \nإنشئها من قائمة الاستيراد / التصدير لتطبيق Catima آخر بالضغط على تصدير هناك أولاً.</string>
|
||||
<string name="importCatimaMessage">حدّد ملفك تصدير من Catima للاستيراد.\nإنشئها من قائمة الاستيراد / التصدير لتطبيق Catima آخر بالضغط على تصدير .</string>
|
||||
<string name="importFidme">الاستيراد من FidMe</string>
|
||||
<string name="importFidmeMessage">حدّد ملفك <i>fidme-export-request-xxxxxx.zip</i> تصدير من FidMe للاستيراد، ثم حدد أنواع الباركود يدويًا بعد ذلك. \nإنشئها من ملف تعريف FidMe الخاص بك عن طريق اختيار حماية البيانات ثم الضغط على استخراج بياناتي أولاً.</string>
|
||||
<string name="importVoucherVault">الاستيراد من Voucher Vault</string>
|
||||
@@ -101,14 +101,6 @@
|
||||
<string name="settings_locale">لغة</string>
|
||||
<string name="settings_system_locale">النظام</string>
|
||||
<string name="setIcon">تعيين الصورة المصغرة</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_pink_theme">زهري</string>
|
||||
<string name="settings_magenta_theme">أرجواني</string>
|
||||
<string name="settings_violet_theme">البنفسجي</string>
|
||||
<string name="settings_blue_theme">أزرق</string>
|
||||
<string name="settings_sky_blue_theme">أزرق سماوي</string>
|
||||
<string name="settings_green_theme">أخضر</string>
|
||||
<string name="settings_brown_theme">بني</string>
|
||||
<string name="app_contributors">أصبح ممكنًا بواسطة: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="sort">فرز</string>
|
||||
<string name="showMoreInfo">اظهر المعلومات</string>
|
||||
@@ -225,7 +217,6 @@
|
||||
<string name="failedGeneratingShareURL">تعذر إنشاء عنوان URL قابل للمشاركة</string>
|
||||
<string name="help_translate_this_app">ساعد في ترجمة هذا التطبيق</string>
|
||||
<string name="on_google_play">على Google Play</string>
|
||||
<string name="settings_theme_color">لون المظهر</string>
|
||||
<string name="previousCard">السابق</string>
|
||||
<string name="nextCard">التالي</string>
|
||||
<string name="failedToRetrieveImageFile">فشل في استخراج ملف الصورة</string>
|
||||
|
||||
@@ -158,9 +158,6 @@
|
||||
<string name="settings_oled_dark">Чысты чорны фон для цёмнай тэмы</string>
|
||||
<string name="selectColor">Выбраць колер</string>
|
||||
<string name="setIcon">Задаць мініяцюру</string>
|
||||
<string name="settings_theme_color">Колер тэмы</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_magenta_theme">Пурпурны</string>
|
||||
<string name="app_contributors">Стала магчымым дзякуючы: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="sort">Сартаваць</string>
|
||||
<string name="showMoreInfo">Паказаць інфармацыю</string>
|
||||
@@ -275,8 +272,6 @@
|
||||
<string name="switchToBackImage">Пераключыцца на задні відарыс</string>
|
||||
<string name="importFidmeMessage">Каб імпартаваць, выберыце файл <i>fidme-export-request-xxxxxx.zip</i> з FidMe, а потым уручную выберыце тыпы штрыхкодаў. \nСтварыце яго з вашага профілю FidMe, выбраўшы \"Абарону даных\", а затым націснуўшы \"Выняць мае даныя\".</string>
|
||||
<string name="importCatimaMessage">Каб імпартаваць, выберыце файл <i>catima.zip</i> з Catima. \nСтварыце яго з меню \"Імпарт/Экспарт\" іншай праграмы Catima, спачатку націснуўшы там \"Экспарт\".</string>
|
||||
<string name="settings_sky_blue_theme">Нябесна-блакітны</string>
|
||||
<string name="settings_brown_theme">Карычневы</string>
|
||||
<string name="switchToBarcode">Пераключыцца на штрыхкод</string>
|
||||
<string name="settings_locale">Мова</string>
|
||||
<plurals name="groupCardCountWithArchived">
|
||||
@@ -288,12 +283,8 @@
|
||||
<string name="unarchived">Карта разархівавана</string>
|
||||
<string name="updateBarcodeQuestionText">Вы змянілі ID. Вы хочаце таксама абнавіць штрыхкод, каб выкарыстоўваць тое ж значэнне?</string>
|
||||
<string name="no">Не</string>
|
||||
<string name="settings_pink_theme">Ружовы</string>
|
||||
<string name="settings_system_locale">Сістэма</string>
|
||||
<string name="settings_violet_theme">Фіялетавы</string>
|
||||
<string name="multipleBarcodesFoundPleaseChooseOne">Які са знойдзеных штрыхкодаў вы хочаце выкарыстоўваць?</string>
|
||||
<string name="settings_blue_theme">Сіні</string>
|
||||
<string name="settings_green_theme">Зялёны</string>
|
||||
<string name="report_error">Паведаміць пра памылку</string>
|
||||
<string name="failedLaunchingPhotoPicker">Не атрымалася знайсці праграму для галерэі, якая падтрымліваецца</string>
|
||||
<string name="unsupportedFile">Гэты файл не падтрымліваецца</string>
|
||||
@@ -306,4 +297,14 @@
|
||||
<string name="generic_error_please_retry">На жаль, нешта пайшло не так, паспрабуйце яшчэ раз...</string>
|
||||
<string name="setBarcodeWidth">Задаць шырыню штрыхкода</string>
|
||||
<string name="app_license">Свабоднае копілефт праграмнае забеспячэнне, ліцэнзаванае паводле GPLv3+</string>
|
||||
<string name="cardWithNumber">Карта <xliff:g>%d</xliff:g></string>
|
||||
<string name="cardWithNumberAndLocale">Карта <xliff:g>%d</xliff:g> (<xliff:g>%s</xliff:g>)</string>
|
||||
<string name="pleaseDoNotRotateTheDevice">Калі ласка, не паварочвайце прыладу, бо гэта адменіць дзеянне</string>
|
||||
<string name="acra_explain_crash">Калі магчыма, дадайце больш падрабязную інфармацыю пра тое, што вы тут рабілі:</string>
|
||||
<string name="acra_crash_email_subject">Справаздача аб збоі <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="pref_enable_acra">Запытваць дазвол на адпраўку справаздач аб збоях</string>
|
||||
<string name="pref_enable_acra_summary">Калі гэта ўключана, вам будзе прапанавана паведаміць пра збой, калі ён адбудзецца. Справаздачы аб збоях ніколі не адпраўляюцца аўтаматычна.</string>
|
||||
<string name="card_list_widget_name">Спіс карт</string>
|
||||
<string name="card_list_widget_empty">Пасля таго, як вы дадасце некалькі картак лаяльнасці ў Catima, яны з\'явяцца тут. Калі ў вас ёсць карты, пераканайцеся, што яны не ўсе заархіваваны.</string>
|
||||
<string name="acra_catima_has_crashed">Прабачце, але ў праграме <xliff:g id="app_name">%s</xliff:g> адбыўся збой. Калі ласка, дапамажыце нам выправіць гэту праблему, даслаўшы нам справаздачу аб памылцы.</string>
|
||||
</resources>
|
||||
|
||||
@@ -143,15 +143,6 @@
|
||||
<item quantity="other">Желаете ли тези <xliff:g>%d</xliff:g> карти да бъдат премахнати\?</item>
|
||||
</plurals>
|
||||
<string name="app_contributors">Осъществено от: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="settings_brown_theme">Кафяво</string>
|
||||
<string name="settings_green_theme">Зелено</string>
|
||||
<string name="settings_sky_blue_theme">Небесносиньо</string>
|
||||
<string name="settings_blue_theme">Синьо</string>
|
||||
<string name="settings_violet_theme">Виолетово</string>
|
||||
<string name="settings_magenta_theme">Цикламено</string>
|
||||
<string name="settings_pink_theme">Розово</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_theme_color">Цвят на темата</string>
|
||||
<string name="settings_system_locale">Система</string>
|
||||
<string name="settings_locale">Език</string>
|
||||
<string name="noGroupCards">Групата е празна</string>
|
||||
@@ -305,4 +296,7 @@
|
||||
<string name="pref_enable_acra">Питане преди изпращане на доклад за срив</string>
|
||||
<string name="pref_enable_acra_summary">Когато е отметнато, при срив ще ви бъде предложено да докладвате за него. Докладите никога не се изпращат автоматично.</string>
|
||||
<string name="acra_explain_crash">Ако е възможно добавете подробности за вашите действия:</string>
|
||||
<string name="copy_value">Копиране на стойността</string>
|
||||
<string name="copied_to_clipboard">Копирано</string>
|
||||
<string name="nothing_to_copy">Няма стойност</string>
|
||||
</resources>
|
||||
|
||||
@@ -50,15 +50,6 @@
|
||||
<string name="turn_flashlight_off">টর্চলাইট বন্ধ করুন</string>
|
||||
<string name="settings_locale">লোকেল</string>
|
||||
<string name="settings_system_locale">সিস্টেম লোকেল</string>
|
||||
<string name="settings_theme_color">থিম রঙ</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>
|
||||
<string name="settings_blue_theme">নীল থিম</string>
|
||||
<string name="settings_sky_blue_theme">আকাশী নীল থিম</string>
|
||||
<string name="settings_green_theme">সবুজ থিম</string>
|
||||
<string name="settings_brown_theme">বাদামী থিম</string>
|
||||
<string name="sort">সাজান</string>
|
||||
<string name="sort_by_name">নামের দ্বারা সাজান</string>
|
||||
<string name="sort_by_most_recently_used">সর্বাধিক সম্প্রতি ব্যবহৃত দ্বারা সাজান</string>
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="settings_locale">ভাষা</string>
|
||||
<string name="action_search">খুঁজুন</string>
|
||||
<string name="settings_pink_theme">গুলাপি</string>
|
||||
<string name="settings_blue_theme">নীল</string>
|
||||
<string name="settings_green_theme">সবুজ</string>
|
||||
<string name="settings_brown_theme">বাদামি</string>
|
||||
<string name="save">সংরক্ষণ</string>
|
||||
<string name="cardId">কার্ড আইডি</string>
|
||||
<string name="barcodeType">বারকোডের ধরন</string>
|
||||
@@ -19,7 +15,6 @@
|
||||
<string name="all">সকল</string>
|
||||
<string name="never">কখনো না</string>
|
||||
<string name="currency">মুদ্রা</string>
|
||||
<string name="settings_violet_theme">বেগুনি</string>
|
||||
<string name="no">না</string>
|
||||
<string name="nextCard">পরবর্তী</string>
|
||||
<string name="action_add">যুক্ত করুন</string>
|
||||
|
||||
@@ -50,15 +50,6 @@
|
||||
<string name="turn_flashlight_off">Ugasi lampu</string>
|
||||
<string name="settings_locale">Jezik</string>
|
||||
<string name="settings_system_locale">Sistem</string>
|
||||
<string name="settings_theme_color">Boja teme</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_pink_theme">Ružičasto</string>
|
||||
<string name="settings_magenta_theme">Ljubičasto</string>
|
||||
<string name="settings_violet_theme">Ljubičasto</string>
|
||||
<string name="settings_blue_theme">Plavo</string>
|
||||
<string name="settings_sky_blue_theme">Nebo plavo</string>
|
||||
<string name="settings_green_theme">Zeleno</string>
|
||||
<string name="settings_brown_theme">Braun</string>
|
||||
<string name="sort">Poništi sortiranje</string>
|
||||
<string name="sort_by_name">Ime</string>
|
||||
<string name="sort_by_most_recently_used">Nedavno Korišten</string>
|
||||
|
||||
@@ -42,10 +42,6 @@
|
||||
<string name="leaveWithoutSaveConfirmation">Vols sortir sense grabar?</string>
|
||||
<string name="passwordRequired">Introdueixi el password</string>
|
||||
<string name="turn_flashlight_on">Encendre el llum flash</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_violet_theme">Violeta</string>
|
||||
<string name="settings_blue_theme">Blau</string>
|
||||
<string name="settings_green_theme">Verd</string>
|
||||
<string name="translate_platform">a la Pàgina Web</string>
|
||||
<string name="report_error">Informar un Error</string>
|
||||
<string name="archived">Targeta arxivada</string>
|
||||
@@ -74,7 +70,6 @@
|
||||
</plurals>
|
||||
<string name="importOptionFilesystemExplanation">Escull un fitxer especific del sistema de fitxers</string>
|
||||
<string name="no">No</string>
|
||||
<string name="settings_pink_theme">Rosa</string>
|
||||
<string name="sort">Ordenar</string>
|
||||
<string name="failedToRetrieveImageFile">Ha fallat l\'obtenció del fitxer d\'imatge</string>
|
||||
<string name="barcodeLongPressMessage">Les imatges només es poden obrir desde la app galeria</string>
|
||||
@@ -146,7 +141,6 @@
|
||||
<string name="settings_oled_dark">Negre pur en el tema fosc</string>
|
||||
<string name="selectColor">Sel•leccioni el color</string>
|
||||
<string name="setIcon">Setegi la miniatura</string>
|
||||
<string name="settings_theme_color">Color del tema</string>
|
||||
<string name="app_contributors">Fet possible per: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="updateBalance">Actualitzar el balanç</string>
|
||||
<string name="sort_by_name">Nom</string>
|
||||
@@ -176,13 +170,11 @@
|
||||
<string name="openFrontImageInGalleryApp">Obrir la imatge frontal a l\'app de galeria</string>
|
||||
<string name="settings_use_volume_keys_navigation_summary">Utilitza els botons de volum per canviar la targeta que es mostra</string>
|
||||
<string name="updateBarcodeQuestionText">Ha canviat el valor ID. Vol actualitzar també el codi de barres per uter utilitzar el mateix valor?</string>
|
||||
<string name="settings_sky_blue_theme">Blau fluix</string>
|
||||
<string name="starred">Preferides</string>
|
||||
<string name="deleteConfirmationGroup">Vols eliminar aquest grup?</string>
|
||||
<string name="removeImage">Eliminar imatge</string>
|
||||
<string name="app_libraries">Llibreries de tercers: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="settings_display_barcode_max_brightness">Màxima iluminació</string>
|
||||
<string name="settings_brown_theme">Marró</string>
|
||||
<string name="manually_enter_barcode_instructions">Introdueixi el ID de la targeta manualment i trii un codi de barres que s\'assembli al de la seva targeta.</string>
|
||||
<string name="rate_this_app">Valora aquesta app</string>
|
||||
<string name="exportPasswordHint">Introdueixi el password</string>
|
||||
@@ -236,7 +228,6 @@
|
||||
<string name="turn_flashlight_off">Apagar el llum Flash</string>
|
||||
<string name="settings_oled_dark_summary">Redueix l\'ús de la bateria en pantalles OLED</string>
|
||||
<string name="settings_system_locale">Idioma del sistema</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="spend">Gastar</string>
|
||||
<string name="importExportHelp">Fer una còpia de seguretat de les dades permet moure-les a un altre dispositiu</string>
|
||||
<string name="importSuccessfulTitle">Importat</string>
|
||||
|
||||
@@ -83,15 +83,6 @@
|
||||
<string name="expiryStateSentence">Platí do: <xliff:g>%s</xliff:g></string>
|
||||
<string name="moveDown">Přesunout dolů</string>
|
||||
<string name="moveUp">Přesunout nahoru</string>
|
||||
<string name="settings_brown_theme">Hnědá</string>
|
||||
<string name="settings_green_theme">Zelená</string>
|
||||
<string name="settings_sky_blue_theme">Azurová</string>
|
||||
<string name="settings_blue_theme">Modrá</string>
|
||||
<string name="settings_violet_theme">Fialová</string>
|
||||
<string name="settings_magenta_theme">Purpurová</string>
|
||||
<string name="settings_pink_theme">Růžová</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_theme_color">Barva motivu</string>
|
||||
<string name="settings_system_locale">Podle systému</string>
|
||||
<string name="settings_locale">Jazyk</string>
|
||||
<string name="turn_flashlight_off">Vypnout světlo</string>
|
||||
@@ -311,4 +302,7 @@
|
||||
<string name="acra_crash_email_subject">Hlášení o pádu <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="pref_enable_acra">Ptát se na odesílání hlášení o pádech</string>
|
||||
<string name="pref_enable_acra_summary">Pokud je povoleno, budete při pádu aplikace dotázáni na jeho nahlášení. Hlášení nejsou nikdy odesílána automaticky.</string>
|
||||
<string name="copy_value">Kopírovat hodnotu</string>
|
||||
<string name="copied_to_clipboard">Zkopírováno do schránky</string>
|
||||
<string name="nothing_to_copy">Nenalezena žádná hodnota</string>
|
||||
</resources>
|
||||
|
||||
@@ -144,15 +144,6 @@
|
||||
</plurals>
|
||||
<string name="settings_system_locale">System</string>
|
||||
<string name="settings_locale">Sprache</string>
|
||||
<string name="settings_brown_theme">Braun</string>
|
||||
<string name="settings_green_theme">Grün</string>
|
||||
<string name="settings_sky_blue_theme">Himmelblau</string>
|
||||
<string name="settings_blue_theme">Blau</string>
|
||||
<string name="settings_violet_theme">Violett</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_pink_theme">Rosa</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_theme_color">Designfarbe</string>
|
||||
<string name="app_contributors">Ermöglicht durch: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="barcodeImageDescriptionWithType">Bild <xliff:g>%s</xliff:g> Barcode</string>
|
||||
<string name="sort_by">Sortieren nach</string>
|
||||
@@ -305,4 +296,7 @@
|
||||
<string name="acra_explain_crash">Wenn möglich, bitte übermittle mehr Details zu dem, was du hier getan hast:</string>
|
||||
<string name="acra_catima_has_crashed">Es tut uns leid, aber <xliff:g id="app_name">%s</xliff:g> ist abgestürzt. Bitte hilf uns diesen Fehler zu beheben und übermittle uns einen Absturzbericht.</string>
|
||||
<string name="pleaseDoNotRotateTheDevice">Bitte drehe nicht das Gerät, weil sonst die Aktion abbricht</string>
|
||||
<string name="copy_value">Kopiere Betrag</string>
|
||||
<string name="copied_to_clipboard">In die Zwischenablage kopiert</string>
|
||||
<string name="nothing_to_copy">Keinen Betrag gefunden</string>
|
||||
</resources>
|
||||
|
||||
@@ -137,9 +137,6 @@
|
||||
<string name="app_resources">Πηγές τρίτων: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="selectColor">Επιλογή χρώματος</string>
|
||||
<string name="setIcon">Ορισμός εικονιδίου</string>
|
||||
<string name="settings_sky_blue_theme">Γαλάζιο</string>
|
||||
<string name="settings_green_theme">Πράσινο</string>
|
||||
<string name="settings_brown_theme">Καφέ</string>
|
||||
<string name="sort_by_expiry">Λήξη</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> κάρτα</item>
|
||||
@@ -187,12 +184,6 @@
|
||||
<string name="settings_locale">Γλώσσα</string>
|
||||
<string name="settings_oled_dark">Απόλυτο μαύρο φόντο για το μαύρο θέμα</string>
|
||||
<string name="settings_system_locale">Σύστημα</string>
|
||||
<string name="settings_theme_color">Χρώμα θέματος</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>
|
||||
<string name="settings_blue_theme">Μπλε</string>
|
||||
<string name="app_contributors">Δημιουργήθηκε από: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="showMoreInfo">Εμφάνιση πληροφοριών</string>
|
||||
<string name="sort_by_name">Όνομα</string>
|
||||
@@ -305,4 +296,7 @@
|
||||
<string name="acra_crash_email_subject">Αναφορά σφάλματος <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="pref_enable_acra">Ερώτηση για αποστολή αναφορών σφαλμάτων</string>
|
||||
<string name="pref_enable_acra_summary">Όταν είναι ενεργοποιημένη, θα σας ζητηθεί να αναφέρετε ένα σφάλμα όταν συμβεί. Οι αναφορές σφάλματος δεν αποστέλλονται ποτέ αυτόματα.</string>
|
||||
<string name="copy_value">Αντιγραφή τιμής</string>
|
||||
<string name="copied_to_clipboard">Αντιγράφηκε στο πρόχειρο</string>
|
||||
<string name="nothing_to_copy">Δεν βρέθηκε τιμή</string>
|
||||
</resources>
|
||||
|
||||
@@ -101,7 +101,6 @@
|
||||
<string name="balance">Saldo</string>
|
||||
<string name="moveBarcodeToTopOfScreen">Movi la strekodon al la supro de la ekrano</string>
|
||||
<string name="errorReadingImage">Ne eblis legi bildon</string>
|
||||
<string name="settings_brown_theme">Bruna</string>
|
||||
<string name="showMoreInfo">Montri informojn</string>
|
||||
<string name="on_github">sur GitHub</string>
|
||||
<string name="archive">Enarkivigi</string>
|
||||
@@ -127,7 +126,6 @@
|
||||
<string name="validFromDate">Valida ekde</string>
|
||||
<string name="accept">Akcepti</string>
|
||||
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
|
||||
<string name="settings_sky_blue_theme">Ĉielblua</string>
|
||||
<string name="unarchive">Elarkivigi</string>
|
||||
<string name="switchToBarcode">Ŝanĝi al strikodo</string>
|
||||
<string name="currentBalanceSentence">Nuna saldo: <xliff:g>%s</xliff:g></string>
|
||||
@@ -166,7 +164,6 @@
|
||||
<string name="balanceParsingFailed">Nevalida saldo</string>
|
||||
<string name="chooseImportType">Importi datumojn de</string>
|
||||
<string name="importCatima">Importi el Catima</string>
|
||||
<string name="settings_green_theme">Verda</string>
|
||||
<string name="updateBalance">Ĝisdatigi saldon</string>
|
||||
<string name="barcodeLongPressMessage">Nur bildoj povas esti malfermitaj en la galeria apo</string>
|
||||
<string name="sort_by_name">Nomo</string>
|
||||
@@ -225,8 +222,6 @@
|
||||
<string name="settings_oled_dark_summary">Malpligrandigas baterian uzadon sur OLED-ekranoj</string>
|
||||
<string name="selectColor">Elekti koloron</string>
|
||||
<string name="setIcon">Starigi bildeton</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_pink_theme">Rozkolora</string>
|
||||
<string name="field_must_not_be_empty">Kampo devas ne esti malplena</string>
|
||||
<string name="manually_enter_barcode_instructions">Entajpu la identigilon aŭ tekston sur via karto kaj premu la strikodon kiu aspektas kiel tiu sur via karto.</string>
|
||||
<string name="turn_flashlight_off">Malŝalti poŝlampon</string>
|
||||
@@ -241,7 +236,6 @@
|
||||
<string name="wrongValueForBarcodeType">La valoro ne validas por la elektita tipo de strikodo</string>
|
||||
<string name="importCancelled">Importado nuligita</string>
|
||||
<string name="exportCancelled">Eksportado nuligita</string>
|
||||
<string name="settings_theme_color">Koloro de la temo</string>
|
||||
<string name="app_libraries">Liberaj triaj bibliotekoj: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="addFromPdfFile">Elekti PDF-dosieron</string>
|
||||
<string name="failedLaunchingFileManager">Subtenata dosiermastrumilo ne trovebla</string>
|
||||
@@ -267,9 +261,6 @@
|
||||
<string name="importVoucherVault">Importi el Voucher Vault</string>
|
||||
<string name="turn_flashlight_on">Enŝalti poŝlampon</string>
|
||||
<string name="settings_locale">Lingvo</string>
|
||||
<string name="settings_magenta_theme">Maĝenta</string>
|
||||
<string name="settings_violet_theme">Viola</string>
|
||||
<string name="settings_blue_theme">Blua</string>
|
||||
<string name="enter_card_id">Entajpu la identigilon aŭ tekston sur via karto</string>
|
||||
<string name="card_id_must_not_be_empty">Identigilo devas ne esti malplena</string>
|
||||
<string name="add_a_card_in_a_different_way">Aldoni karton alimaniere</string>
|
||||
|
||||
@@ -169,11 +169,7 @@
|
||||
<string name="updateBarcodeQuestionText">Has cambiado el ID. ¿Quieres actualizar también el código de barras para usar el mismo valor?</string>
|
||||
<string name="settings_locale">Idioma</string>
|
||||
<string name="settings_system_locale">Sistema</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_pink_theme">Rosa</string>
|
||||
<string name="exportPassword">Configura una contraseña para proteger tu exportación (opcional)</string>
|
||||
<string name="settings_sky_blue_theme">Celeste</string>
|
||||
<string name="settings_green_theme">Verde</string>
|
||||
<string name="exportPasswordHint">Ingresar contraseña</string>
|
||||
<string name="setIcon">Establecer miniatura</string>
|
||||
<string name="showMoreInfo">Mostrar información</string>
|
||||
@@ -184,12 +180,7 @@
|
||||
<string name="settings_oled_dark_summary">Reduce uso de batería en pantallas OLED</string>
|
||||
<string name="settings_oled_dark">Fondo negro puro para tema oscuro</string>
|
||||
<string name="selectColor">Seleccionar color</string>
|
||||
<string name="settings_theme_color">Color del tema</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_violet_theme">Violeta</string>
|
||||
<string name="settings_brown_theme">Marrón</string>
|
||||
<string name="sort">Ordenar</string>
|
||||
<string name="settings_blue_theme">Azul</string>
|
||||
<string name="app_contributors">Hecho posible por: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="barcodeLongPressMessage">Solo se puede abrir imágenes en la aplicación de galería</string>
|
||||
<string name="yes">Si</string>
|
||||
|
||||
@@ -147,15 +147,6 @@
|
||||
<item quantity="other">Borrar <xliff:g>%d</xliff:g> tarjetas</item>
|
||||
</plurals>
|
||||
<string name="app_contributors">Hecho posible por: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="settings_brown_theme">Marrón</string>
|
||||
<string name="settings_green_theme">Verde</string>
|
||||
<string name="settings_sky_blue_theme">Azul cielo</string>
|
||||
<string name="settings_blue_theme">Azul</string>
|
||||
<string name="settings_violet_theme">Violeta</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_pink_theme">Rosa</string>
|
||||
<string name="settings_theme_color">Color del tema</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_system_locale">Sistema</string>
|
||||
<string name="settings_locale">Idioma</string>
|
||||
<string name="noGroupCards">Este grupo está vacío</string>
|
||||
@@ -232,7 +223,7 @@
|
||||
<string name="height">Alto</string>
|
||||
<string name="switchToFrontImage">Cambiar a imagen frontal</string>
|
||||
<string name="openFrontImageInGalleryApp">Abrir imagen frontal en la aplicación de la galería</string>
|
||||
<string name="openBackImageInGalleryApp">Abrir imagen trasera en la aplicación de la galería</string>
|
||||
<string name="openBackImageInGalleryApp">Abrir imagen trasera en la aplicación de visor de imagen</string>
|
||||
<string name="setBarcodeHeight">Ajustar la altura del código de barras</string>
|
||||
<string name="donate">Donar</string>
|
||||
<string name="switchToBarcode">Cambiar a código de barras</string>
|
||||
@@ -268,7 +259,7 @@
|
||||
<string name="app_name">Catima</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="add_manually_warning_message">En algunas tarjetas, el valor del código de barras difiere del número escrito en la tarjeta. Por este motivo, introducir manualmente puede que no siempre funcione. Se recomienda analizar el código de barras con su cámara en su lugar. ¿Aún desea continuar?</string>
|
||||
<string name="spend">Gastar</string>
|
||||
<string name="receive">Recibió</string>
|
||||
<string name="amountParsingFailed">Importe incorrecto</string>
|
||||
@@ -311,4 +302,7 @@
|
||||
<string name="acra_crash_email_subject">Reporte del fallo <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="pref_enable_acra">Solicitar envío de reportes de fallos</string>
|
||||
<string name="pref_enable_acra_summary">Cuando está activado, se le pedirá que informe sobre un fallo cuando ocurra. Los informes de fallo nunca se envían automáticamente.</string>
|
||||
<string name="copy_value">Copia valor</string>
|
||||
<string name="copied_to_clipboard">Copiado al portapapeles</string>
|
||||
<string name="nothing_to_copy">Ningún valor encontrado</string>
|
||||
</resources>
|
||||
|
||||
@@ -118,8 +118,6 @@
|
||||
<string name="updateBarcodeQuestionTitle">Kas uuendame triipkoodi väärtust?</string>
|
||||
<string name="yes">Jah</string>
|
||||
<string name="no">Ei</string>
|
||||
<string name="settings_theme_color">Kujunduse värv</string>
|
||||
<string name="settings_pink_theme">Roosa</string>
|
||||
<string name="barcodeLongPressMessage">Galeriirakenduses saad avada vaid pilte</string>
|
||||
<string name="sort_by_most_recently_used">Viimati kasutatud</string>
|
||||
<string name="sort_by_expiry">Aegumine</string>
|
||||
@@ -201,13 +199,6 @@
|
||||
<string name="settings_system_locale">Süsteemi keel</string>
|
||||
<string name="selectColor">Vali värv</string>
|
||||
<string name="setIcon">Lisa pisipilt</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_magenta_theme">Fuksiapunane</string>
|
||||
<string name="settings_violet_theme">Punakassinine</string>
|
||||
<string name="settings_blue_theme">Sinine</string>
|
||||
<string name="settings_sky_blue_theme">Taevasinine</string>
|
||||
<string name="settings_green_theme">Roheline</string>
|
||||
<string name="settings_brown_theme">Pruun</string>
|
||||
<string name="app_contributors">Seda rakendust on aidanud teha: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="sort">Järjesta</string>
|
||||
<string name="updateBalance">Uuenda maksejääki</string>
|
||||
@@ -305,4 +296,7 @@
|
||||
<string name="acra_crash_email_subject">Kokkujooksmise aruanne: <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="pref_enable_acra">Küsi luba kokkujooksmiste aruannete saatmiseks</string>
|
||||
<string name="pref_enable_acra_summary">Kui eelistus on kasutusel, siis rakendus küsib sinult luba veateate saatmiseks. Seda ei tehta iialgi automaatselt.</string>
|
||||
<string name="copy_value">Kopeeri väärtus</string>
|
||||
<string name="copied_to_clipboard">Kopeeritud lõikelauale</string>
|
||||
<string name="nothing_to_copy">Ühtegi väärtust ei leidu</string>
|
||||
</resources>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<string name="scanCardBarcode">اسکن بارکد</string>
|
||||
<string name="cardShortcut">میانبر کارت</string>
|
||||
<string name="noCardsMessage">ابتدا یک کارت بیافزایید</string>
|
||||
<string name="noCardExistsError">کارت پیدا نشد</string>
|
||||
<string name="noCardExistsError">آن کارت پیدا نشد</string>
|
||||
<string name="importFailedTitle">ایمپورت ناموفق بود</string>
|
||||
<string name="importFailed">نمیتوان ایمپورت کرد</string>
|
||||
<string name="exportSuccessfulTitle">خروجی گرفته شده</string>
|
||||
@@ -68,7 +68,7 @@
|
||||
<string name="permissionReadCardsDescription">کارت های کاتیما و تمام جزئیاتشان از جمله یادداشتها و عکسها را بخوانید</string>
|
||||
<string name="cameraPermissionDeniedTitle">نمیتوان به دوربین دسترسی پیدا کرد</string>
|
||||
<string name="noCameraPermissionDirectToSystemSetting">برای اسکن بارکد ها، کاتیما نیاز دارد به دوربین شما دسترسی داشته باشد. اینجا بزنید تا تنظیمات دسترسی خود را تغییر دهید.</string>
|
||||
<string name="importExport">ایمپورت/خروجی گرفتن</string>
|
||||
<string name="importExport">واردات/صادرات</string>
|
||||
<string name="settings_category_title_privacy">حریم شخصی</string>
|
||||
<string name="settings_category_title_general">عمومی</string>
|
||||
<string name="settings_category_title_cards">نمایش کارت</string>
|
||||
@@ -117,8 +117,8 @@
|
||||
<string name="importCatimaMessage">فایل <i>catima.zip</i> خروجی خود را از Catima برای وارد کردن انتخاب کنید.\nآن را از منوی وارد/صادر کردن در یک اپلیکیشن دیگر Catima با فشردن دکمه صادرکردن ابتدا ایجاد کنید.</string>
|
||||
<string name="unsupportedBarcodeType">این نوع بارکد هنوز نمیتواند نمایش داده شود. ممکن است در نسخه آینده برنامه پشتیبانی شود.</string>
|
||||
<plurals name="balancePoints">
|
||||
<item quantity="one"><xliff:g>%s</xliff:g> امتیاز</item>
|
||||
<item quantity="other"><xliff:g>%s</xliff:g> امتیاز</item>
|
||||
<item quantity="one"><xliff:g>%s</xliff:g> نقطه</item>
|
||||
<item quantity="other"><xliff:g>%s</xliff:g> نقطه</item>
|
||||
</plurals>
|
||||
<string name="importFidmeMessage">فایل خروجی <i>fidme-export-request-xxxxxx.zip</i> خود را از FidMe برای وارد کردن انتخاب کنید، و سپس نوع بارکدها را به صورت دستی مشخص کنید.\nآن را از پروفایل FidMe خود با انتخاب گزینه حفاظت از داده و سپس فشار دادن گزینه استخراج داده من ابتدا ایجاد کنید.</string>
|
||||
<string name="leaveWithoutSaveTitle">خروج</string>
|
||||
@@ -180,7 +180,6 @@
|
||||
<string name="height">ارتفاع</string>
|
||||
<string name="add_manually_warning_message">برای برخی از فروشگاهها، مقدار بارکد با عدد نوشته شده روی کارت متفاوت است. به همین دلیل، وارد کردن دستی بارکد ممکن است همیشه کار نکند. اکیداً توصیه میشود که به جای آن، بارکد را با دوربین خود اسکن کنید. آیا هنوز میخواهید ادامه دهید؟</string>
|
||||
<string name="generic_error_please_retry">ببخشید، مشکلی پیش آمده، لطفا دوباره امتحان کنید...</string>
|
||||
<string name="settings_magenta_theme">سرخابی</string>
|
||||
<string name="welcome">یه کتیما خوش آمدید</string>
|
||||
<string name="chooseValidFromDate">مقداری درست از تاریخ برگزینید</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">میخواهم چند کارت به شما بدهم</string>
|
||||
@@ -198,15 +197,8 @@
|
||||
<string name="settings_oled_dark">پسزمینهی یکدست سیاه برای حالت تاریک</string>
|
||||
<string name="settings_oled_dark_summary">استفادهی باتری را برای نمایشگرهای OLED کاهش میدهد</string>
|
||||
<string name="setIcon">قالب پیشنمایه را بگمارید</string>
|
||||
<string name="settings_theme_color">رنگ زمینه</string>
|
||||
<string name="settings_catima_theme">کتیما</string>
|
||||
<string name="settings_system_locale">سیستم</string>
|
||||
<string name="selectColor">رنگ را برگزینید</string>
|
||||
<string name="settings_violet_theme">بنفش</string>
|
||||
<string name="settings_blue_theme">آبی</string>
|
||||
<string name="settings_sky_blue_theme">آبی آسمانی</string>
|
||||
<string name="settings_green_theme">سبز</string>
|
||||
<string name="settings_brown_theme">قهوهای</string>
|
||||
<string name="app_contributors">با کمک او ممکن شد: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="sort">مرتبکردن</string>
|
||||
<string name="showMoreInfo">نمایش اطلاعات</string>
|
||||
@@ -220,7 +212,6 @@
|
||||
<string name="passwordRequired">لطفا گذرواژه را وارد کنید</string>
|
||||
<string name="previousCard">پیشین</string>
|
||||
<string name="turn_flashlight_off">چراغقوه را خاموش کنید</string>
|
||||
<string name="settings_pink_theme">صورتی</string>
|
||||
<string name="updateBalance">بهروزرسانی موجودی</string>
|
||||
<string name="barcodeLongPressMessage">تنها عکس میتواند در گالری برنامه باز شود</string>
|
||||
<string name="sort_by_name">نام</string>
|
||||
@@ -294,4 +285,5 @@
|
||||
<string name="spend">خرج کردن</string>
|
||||
<string name="addFromPkpass">یک فایل دفترچه حساب (.pkpass) انتخاب کنید</string>
|
||||
<string name="noCameraFoundGuideText">به نظر نمیرسد دستگاه شما دوربین داشته باشد. اگر دارد، دستگاه را مجدداً راهاندازی کنید. در غیر این صورت، از دکمه گزینههای بیشتر در زیر برای افزودن بارکد به روش دیگری استفاده کنید.</string>
|
||||
<string name="card_list_widget_empty">بعد از اینکه چند کارت وفاداری در کاتیما اضافه کردید، آنها اینجا ظاهر میشوند. اگر کارت دارید، مطمئن شوید که همه آنها بایگانی نشدهاند.</string>
|
||||
</resources>
|
||||
|
||||
@@ -147,15 +147,6 @@
|
||||
<string name="turn_flashlight_on">Käytä taskulamppua</string>
|
||||
<string name="turn_flashlight_off">Sammuta salamavalo</string>
|
||||
<string name="app_contributors">Mahdollistanut: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="settings_brown_theme">Ruskea</string>
|
||||
<string name="settings_green_theme">Vihreä</string>
|
||||
<string name="settings_sky_blue_theme">Taivaansininen</string>
|
||||
<string name="settings_blue_theme">Siniset</string>
|
||||
<string name="settings_violet_theme">Violetti</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_pink_theme">Pinkki</string>
|
||||
<string name="settings_theme_color">Teeman väri</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_system_locale">Järjestelmä</string>
|
||||
<string name="settings_locale">Kieli</string>
|
||||
<string name="noGroupCards">Tämä ryhmä on tyhjä</string>
|
||||
|
||||
@@ -15,4 +15,16 @@
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> napili</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> ang napili</item>
|
||||
</plurals>
|
||||
<string name="star">Sa card viewing, ang text ay naka-display lamang tuwing naka-long press ang star icon</string>
|
||||
<string name="cancel">I-kansela</string>
|
||||
<string name="save">I-save</string>
|
||||
<string name="edit">I-edit</string>
|
||||
<string name="delete">I-delete</string>
|
||||
<string name="confirm">I-confirm</string>
|
||||
<string name="share">I-share</string>
|
||||
<string name="sendLabel">I-send…</string>
|
||||
<string name="editCardTitle">I-edit ang card</string>
|
||||
<string name="noCardsMessage">Mag-add ng card muna</string>
|
||||
<string name="noCardExistsError">Hindi mahanap ang card</string>
|
||||
<string name="exportName">I-export</string>
|
||||
</resources>
|
||||
|
||||
@@ -147,15 +147,6 @@
|
||||
</plurals>
|
||||
<string name="settings_system_locale">Système</string>
|
||||
<string name="settings_locale">Langue</string>
|
||||
<string name="settings_brown_theme">Marron</string>
|
||||
<string name="settings_green_theme">Vert</string>
|
||||
<string name="settings_sky_blue_theme">Bleu ciel</string>
|
||||
<string name="settings_blue_theme">Bleu</string>
|
||||
<string name="settings_violet_theme">Violet</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_pink_theme">Rose</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_theme_color">Couleur du thème</string>
|
||||
<string name="app_contributors">Rendu possible par : <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="noGroupCards">Ce groupe est vide</string>
|
||||
<string name="barcodeImageDescriptionWithType">Image <xliff:g>%s</xliff:g> code-barres</string>
|
||||
@@ -311,4 +302,7 @@
|
||||
<string name="acra_crash_email_subject">Rapport de plantage de <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="pref_enable_acra">Demander pour envoyer des rapports de plantage</string>
|
||||
<string name="pref_enable_acra_summary">Quand activé, il vous sera demandé d\'envoyer un rapport de plantage en cas de plantage. Les rapports de plantage ne sont jamais envoyés automatiquement.</string>
|
||||
<string name="copy_value">Copier la valeur</string>
|
||||
<string name="copied_to_clipboard">Copié dans le presse-papier</string>
|
||||
<string name="nothing_to_copy">Aucune valeur trouvée</string>
|
||||
</resources>
|
||||
|
||||
@@ -145,14 +145,6 @@
|
||||
<string name="settings_oled_dark_summary">Diminúe o uso da batería nas pantallas OLED</string>
|
||||
<string name="settings_system_locale">Sistema</string>
|
||||
<string name="selectColor">Elixir cor</string>
|
||||
<string name="settings_theme_color">Cor do decorado</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_pink_theme">Rosa</string>
|
||||
<string name="settings_magenta_theme">Maxenta</string>
|
||||
<string name="settings_violet_theme">Violeta</string>
|
||||
<string name="settings_sky_blue_theme">Azul celeste</string>
|
||||
<string name="settings_green_theme">Verde</string>
|
||||
<string name="settings_brown_theme">Marrón</string>
|
||||
<string name="app_contributors">Creada grazas a: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="sort">Orde</string>
|
||||
<string name="showMoreInfo">Ver info</string>
|
||||
@@ -269,7 +261,6 @@
|
||||
<string name="deleteConfirmationGroup">Eliminar grupo?</string>
|
||||
<string name="failedOpeningFileManager">Non puido abrir un xestor de ficheiros</string>
|
||||
<string name="settings_locale">Idioma</string>
|
||||
<string name="settings_blue_theme">Azul</string>
|
||||
<string name="passwordRequired">Escribe o contrasinal</string>
|
||||
<string name="exportPassword">Establece un contrasinal para protexer a exportación (optativo)</string>
|
||||
<string name="exportPasswordHint">Escribe o contrasinal</string>
|
||||
@@ -304,4 +295,7 @@
|
||||
<string name="acra_crash_email_subject">Informe do fallo de <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="pref_enable_acra">Solicitar informar sobre os fallos</string>
|
||||
<string name="pref_enable_acra_summary">Se está activo, váiseche pedir informar sobre os fallos cando acontezan. Os informes nunca se envían automaticamente.</string>
|
||||
<string name="copy_value">Copiar valor</string>
|
||||
<string name="copied_to_clipboard">Copiado ao portapapeis</string>
|
||||
<string name="nothing_to_copy">Non hai ningún valor</string>
|
||||
</resources>
|
||||
|
||||
@@ -170,28 +170,19 @@
|
||||
<string name="action_more_options">अधिक विकल्प</string>
|
||||
<string name="frontImageDescription">सामने की छवि</string>
|
||||
<string name="anyDate">कोई दिन</string>
|
||||
<string name="settings_green_theme">हरा</string>
|
||||
<string name="settings_pink_theme">गुलाबी</string>
|
||||
<string name="action_display_options">प्रदर्शन विकल्प</string>
|
||||
<string name="settings_category_title_cards">कार्ड</string>
|
||||
<string name="addWithoutBarcode">बिना बारकोड वाला कार्ड जोड़ें</string>
|
||||
<string name="on_google_play">गूगल प्ले पर</string>
|
||||
<string name="report_error">गलती की रिपोर्ट करें</string>
|
||||
<string name="passwordRequired">कृपया पासवर्ड दर्ज करें</string>
|
||||
<string name="settings_brown_theme">भूरा</string>
|
||||
<string name="field_must_not_be_empty">फ़ील्ड खाली नहीं होनी चाहिए</string>
|
||||
<string name="settings_catima_theme">कैटिमा</string>
|
||||
<string name="options">विकल्प</string>
|
||||
<string name="settings_magenta_theme">मैजेंटा</string>
|
||||
<string name="failedGeneratingShareURL">साझा करने योग्य URL जनरेट नहीं किया जा सकता. कृपया इसकी रिपोर्ट करें</string>
|
||||
<string name="sort_by_most_recently_used">सबसे हाल ही में उपयोग किया गया</string>
|
||||
<string name="settings_theme_color">थीम का रंग</string>
|
||||
<string name="settings_sky_blue_theme">आसमानी नीला (हल्का नीला)</string>
|
||||
<string name="updateBalanceHint">राशि डालें</string>
|
||||
<string name="on_github">गिटहब पर</string>
|
||||
<string name="donate">दान करें /भेंट दें</string>
|
||||
<string name="settings_violet_theme">बैंगनी</string>
|
||||
<string name="settings_blue_theme">नीला</string>
|
||||
<string name="shortcutSelectCard">एक कार्ड चुनें</string>
|
||||
<string name="settings_category_title_privacy">गोपनीयता</string>
|
||||
<string name="show_balance">शेष राशि दिखाएं</string>
|
||||
@@ -298,4 +289,13 @@
|
||||
<string name="card_list_widget_empty">कैटिमा में कुछ लॉयल्टी कार्ड जोड़ने के बाद, वे यहाँ दिखाई देंगे। अगर आपके पास कार्ड हैं, तो सुनिश्चित करें कि वे सभी संग्रहित न हों।</string>
|
||||
<string name="cardWithNumber">कार्ड <xliff:g>%d</xliff:g></string>
|
||||
<string name="cardWithNumberAndLocale">कार्ड <xliff:g>%d</xliff:g> (<xliff:g>%s</xliff:g>)</string>
|
||||
<string name="pleaseDoNotRotateTheDevice">कृपया डिवाइस को घुमाएँ नहीं, क्योंकि इससे कार्रवाई रद्द हो जाएगी</string>
|
||||
<string name="acra_catima_has_crashed">हमें खेद है, लेकिन <xliff:g id="app_name">%s</xliff:g> क्रैश हो गया है। कृपया हमें एक त्रुटि रिपोर्ट भेजकर इस समस्या को ठीक करने में हमारी सहायता करें।</string>
|
||||
<string name="acra_explain_crash">यदि संभव हो तो कृपया यहां आप क्या कर रहे थे, इसके बारे में अधिक विवरण जोड़ें:</string>
|
||||
<string name="acra_crash_email_subject"><xliff:g id="app_name">%s</xliff:g> क्रैश रिपोर्ट</string>
|
||||
<string name="pref_enable_acra">दुर्घटना रिपोर्ट भेजने के लिए कहें</string>
|
||||
<string name="pref_enable_acra_summary">सक्षम होने पर, क्रैश होने पर आपको रिपोर्ट करने के लिए कहा जाएगा। क्रैश रिपोर्ट कभी भी स्वचालित रूप से नहीं भेजी जाती हैं।</string>
|
||||
<string name="copy_value">मान कॉपी करें</string>
|
||||
<string name="copied_to_clipboard">क्लिपबोर्ड पर कॉपी किया गया</string>
|
||||
<string name="nothing_to_copy">कोई मूल्य नहीं मिला</string>
|
||||
</resources>
|
||||
|
||||
@@ -88,8 +88,6 @@
|
||||
<string name="importCards">Uvezi kartice</string>
|
||||
<string name="selectColor">Odaberi boju</string>
|
||||
<string name="setIcon">Postavi sličicu</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_green_theme">Zelena</string>
|
||||
<string name="sort_by_expiry">Istek</string>
|
||||
<string name="barcodeImageDescriptionWithType">Slika vrste crtičnog koda <xliff:g>%s</xliff:g></string>
|
||||
<string name="importLoyaltyCardKeychain">Uvezi iz Loyalty Card Keychain</string>
|
||||
@@ -99,9 +97,6 @@
|
||||
<string name="failedGeneratingShareURL">Nije bilo moguće generirati URL za dijeljenje</string>
|
||||
<string name="turn_flashlight_off">Isključi bljeskalicu</string>
|
||||
<string name="settings_locale">Jezik</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_violet_theme">Ljubičasta</string>
|
||||
<string name="settings_sky_blue_theme">Nebesko plava</string>
|
||||
<string name="sort">Razvrstaj</string>
|
||||
<string name="updateBalance">Aktualiziraj saldo</string>
|
||||
<string name="sort_by">Razvrstaj po</string>
|
||||
@@ -162,8 +157,6 @@
|
||||
<string name="balanceSentence">Saldo: <xliff:g>%s</xliff:g></string>
|
||||
<string name="importFidmeMessage">Odaberi tvoj izvoz iz FidMe za uvoz i ručno odaberi vste crtičnog koda nakon toga. \nStvori ga putem tvog FidMe profila biranjem „Zaštita podataka” a zatim pritisni „Dekomprimiraj moje podatke”.</string>
|
||||
<string name="importVoucherVaultMessage">Odaberi tvoj izvoz iz Voucher Vault za uvoz. \nStvori ga u aplikaciji Voucher Vault pritiskom na „Izvoz”.</string>
|
||||
<string name="settings_pink_theme">Ružičasta</string>
|
||||
<string name="settings_blue_theme">Plava</string>
|
||||
<string name="failedToRetrieveImageFile">Neuspjelo dohvaćanje slikovne datoteke</string>
|
||||
<string name="license">Licenca</string>
|
||||
<string name="barcodeLongPressMessage">U aplikaciji galerije se mogu otvoriiti samo slike</string>
|
||||
@@ -223,8 +216,6 @@
|
||||
<string name="passwordRequired">Upiši lozinku</string>
|
||||
<string name="exportPassword">Postavi lozinku za zaštitu tvog izvoza (opcionalno)</string>
|
||||
<string name="settings_oled_dark">Potpuno crna pozadina za tamnu temu</string>
|
||||
<string name="settings_theme_color">Boja teme</string>
|
||||
<string name="settings_brown_theme">Smeđa</string>
|
||||
<string name="app_contributors">Doprinositelji: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="showMoreInfo">Prikaži informacije</string>
|
||||
<string name="sort_by_name">Ime</string>
|
||||
|
||||
@@ -52,14 +52,11 @@
|
||||
<string name="noCardExistsError">A kártya nem található</string>
|
||||
<string name="importVoucherVault">Importálás a Voucher Vaultból</string>
|
||||
<string name="wrongValueForBarcodeType">Ez az érték meg megfelelő a kiválasztott vonalkódtípushoz</string>
|
||||
<string name="settings_green_theme">Zöld</string>
|
||||
<string name="setBackImage">Hátlapi kép beállítása</string>
|
||||
<string name="no">Nem</string>
|
||||
<string name="passwordRequired">Adja meg a jelszót</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="exportPasswordHint">Kód beírása</string>
|
||||
<string name="failedGeneratingShareURL">Nem lehetett megosztható webcímet előállítani. Kérjük, ezt jelentse.</string>
|
||||
<string name="settings_theme_color">Téma színe</string>
|
||||
<string name="sort">Rendezés</string>
|
||||
<string name="on_google_play">a Google Playen</string>
|
||||
<string name="and_data_usage">és adathasználat</string>
|
||||
@@ -146,12 +143,6 @@
|
||||
<string name="settings_system_locale">Rendszer</string>
|
||||
<string name="selectColor">Szín kiválasztása</string>
|
||||
<string name="setIcon">Miniatűr beállítása</string>
|
||||
<string name="settings_pink_theme">Rózsaszín</string>
|
||||
<string name="settings_magenta_theme">Bíbor</string>
|
||||
<string name="settings_violet_theme">Ibolya</string>
|
||||
<string name="settings_blue_theme">Kék</string>
|
||||
<string name="settings_sky_blue_theme">Égszínkék</string>
|
||||
<string name="settings_brown_theme">Barna</string>
|
||||
<string name="app_contributors">Lehetővé tették: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="showMoreInfo">Információk megjelenítése</string>
|
||||
<string name="reverse">…fordított sorrendben</string>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<string name="license">Lisensi</string>
|
||||
<string name="settings">Pengaturan</string>
|
||||
<string name="settings_system_theme">Sistem</string>
|
||||
<string name="selectBarcodeTitle">Pilih Barcode</string>
|
||||
<string name="selectBarcodeTitle">Pilih barcode</string>
|
||||
<string name="deleteConfirmation">Hapus kartu ini secara permanen?</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="share">Bagikan</string>
|
||||
@@ -27,7 +27,7 @@
|
||||
<string name="addCardTitle">Tambah Kartu</string>
|
||||
<string name="scanCardBarcode">Pindai Barcode</string>
|
||||
<string name="cancel">Batalkan</string>
|
||||
<string name="importExport">Impor/Ekspor</string>
|
||||
<string name="importExport">Impor/ekspor</string>
|
||||
<string name="settings_theme">Tema</string>
|
||||
<string name="all">Semua</string>
|
||||
<string name="leaveWithoutSaveTitle">Keluar</string>
|
||||
@@ -46,19 +46,10 @@
|
||||
<string name="setBarcodeId">Tentukan nilai barcode</string>
|
||||
<string name="photos">Foto</string>
|
||||
<string name="setFrontImage">Atur gambar bagian depan</string>
|
||||
<string name="report_error">Lapor Kesalahan</string>
|
||||
<string name="report_error">Laporkan kesalahan</string>
|
||||
<string name="rate_this_app">Beri nilai pada aplikasi ini</string>
|
||||
<string name="sort_by_expiry">Masa berlaku</string>
|
||||
<string name="sort_by_most_recently_used">Paling banyak digunakan</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_pink_theme">Merah Muda</string>
|
||||
<string name="settings_blue_theme">Biru</string>
|
||||
<string name="settings_green_theme">Hijau</string>
|
||||
<string name="settings_sky_blue_theme">Biru Langit</string>
|
||||
<string name="settings_brown_theme">Cokelat</string>
|
||||
<string name="settings_violet_theme">Ungu</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_theme_color">Warna tema</string>
|
||||
<string name="sort_by_most_recently_used">Yang paling baru digunakan</string>
|
||||
<string name="settings_system_locale">Sistem</string>
|
||||
<string name="settings_locale">Bahasa</string>
|
||||
<string name="turn_flashlight_on">Hidupkan lampu flash</string>
|
||||
@@ -87,9 +78,9 @@
|
||||
<string name="exportFailed">Tidak dapat mengekspor</string>
|
||||
<string name="importing">Sedang mengimpor…</string>
|
||||
<string name="exporting">Sedang mengekspor…</string>
|
||||
<string name="exportOptionExplanation">Data akan ditulis ke lokasi pilihan Anda.</string>
|
||||
<string name="exportOptionExplanation">Data akan ditulis ke lokasi yang Anda pilih</string>
|
||||
<string name="importOptionFilesystemTitle">Impor dari pengelola file bawaan</string>
|
||||
<string name="importOptionFilesystemExplanation">Pilih file dari pengelola file bawaan.</string>
|
||||
<string name="importOptionFilesystemExplanation">Pilih berkas tertentu dari sistem berkas</string>
|
||||
<string name="importOptionFilesystemButton">Dari pengelola file bawaan</string>
|
||||
<string name="about">Tentang</string>
|
||||
<string name="app_copyright_fmt">Hak Cipta © 2019–<xliff:g>%d</xliff:g> Sylvia van Os dan para kontributor</string>
|
||||
@@ -98,8 +89,8 @@
|
||||
<string name="app_license">Perangkat lunak bebas copyleft, berlisensi GPLv3+</string>
|
||||
<string name="about_title_fmt">Tentang <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Versi: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_libraries">Pustaka pihak ketiga gratis: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources">Sumber daya pihak ketiga gratis: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_libraries">Perpustakaan pihak ketiga: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources">Sumber daya pihak ketiga: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="thumbnailDescription">Gambar tampilan</string>
|
||||
<string name="starImage">Favorit</string>
|
||||
<string name="settings_light_theme">Terang</string>
|
||||
@@ -112,10 +103,10 @@
|
||||
<string name="exportSuccessful">Data terekspor</string>
|
||||
<string name="enter_group_name">Masukan nama grup</string>
|
||||
<string name="groups">Grup</string>
|
||||
<string name="noGroups">Klik pada tombol tambah + untuk menambahkan grup untuk pengkategorian.</string>
|
||||
<string name="noGroups">Klik tombol + untuk menambahkan grup untuk pengelompokan</string>
|
||||
<string name="noGroupCards">Grup ini kosong</string>
|
||||
<string name="deleteConfirmationGroup">Hapus grup?</string>
|
||||
<string name="failedOpeningFileManager">Pasang aplikasi pengelola berkas terlebih dahulu.</string>
|
||||
<string name="failedOpeningFileManager">Gagal membuka pengelola berkas</string>
|
||||
<string name="moveUp">Pindah ke atas</string>
|
||||
<string name="moveDown">Pindah ke bawah</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Keluar tanpa menyimpan?</string>
|
||||
@@ -132,36 +123,32 @@
|
||||
<string name="points">Poin</string>
|
||||
<string name="app_loyalty_card_keychain">Gantungan kunci kartu kesetiaan</string>
|
||||
<string name="privacy_policy">Kebijakan Privasi</string>
|
||||
<string name="importCatimaMessage">Pilih ekspor <i>catima.zip</i> Anda dari Catima untuk diimpor.
|
||||
\nBuat dari menu Impor/Ekspor aplikasi Catima lain dengan menekan Ekspor di sana terlebih dahulu.</string>
|
||||
<string name="importFidmeMessage">Pilih ekspor <i>fidme-export-request-xxxxxx.zip</i> Anda dari FidMe untuk diimpor, dan pilih jenis barcode secara manual setelahnya.
|
||||
\nBuat dari profil FidMe Anda dengan memilih Perlindungan Data lalu tekan Ekstrak data saya terlebih dahulu.</string>
|
||||
<string name="importCatimaMessage">Pilih ekspor Anda dari Catima untuk diimpor.\nBuatlah dari menu Impor/Ekspor aplikasi Catima lainnya dengan menekan Ekspor.</string>
|
||||
<string name="importFidmeMessage">Pilih ekspor Anda dari FidMe untuk diimpor, lalu pilih jenis barcode secara manual setelahnya.\nBuatlah dari profil FidMe Anda dengan memilih Data Protection, lalu tekan Extract my data.</string>
|
||||
<string name="importLoyaltyCardKeychain">Impor dari Loyalty Card Keychain</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Pilih ekspor <i>LoyaltyCardKeychain.csv</i> Anda dari Loyalty Card Keychain untuk diimpor.
|
||||
\nBuat dari menu Import/Export di Loyalty Card Keychain dengan menekan Export terlebih dahulu.</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Pilih ekspor Anda dari Loyalty Card Keychain untuk diimpor.\nBuatlah dari menu Impor/Ekspor di Loyalty Card Keychain dengan menekan Ekspor.</string>
|
||||
<string name="importVoucherVault">Impor dari Voucher Vault</string>
|
||||
<string name="importVoucherVaultMessage">Pilih ekspor <i>vouchervault.json</i> Anda dari Voucher Vault untuk diimpor.
|
||||
\nBuat dengan menekan Ekspor di Voucher Vault terlebih dahulu.</string>
|
||||
<string name="importVoucherVaultMessage">Pilih ekspor Anda dari Voucher Vault untuk diimpor.\nBuatlah dengan menekan tombol Ekspor di Voucher Vault.</string>
|
||||
<string name="unsupportedBarcodeType">Jenis barcode ini belum dapat ditampilkan. Ini mungkin didukung di versi aplikasi yang lebih baru.</string>
|
||||
<string name="wrongValueForBarcodeType">Nilai tidak berlaku untuk jenis barcode yang dipilih</string>
|
||||
<string name="wrongValueForBarcodeType">Nilai tersebut tidak valid untuk jenis barcode yang dipilih</string>
|
||||
<string name="frontImageDescription">Gambar depan</string>
|
||||
<string name="backImageDescription">Gambar belakang</string>
|
||||
<string name="updateBarcodeQuestionTitle">Perbarui barcode?</string>
|
||||
<string name="updateBarcodeQuestionText">Anda mengubah ID. Apakah Anda juga ingin memperbarui barcode untuk menggunakan nilai yang sama\?</string>
|
||||
<string name="passwordRequired">Silahkan masukan kata sandi</string>
|
||||
<string name="passwordRequired">Masukkan kata sandi</string>
|
||||
<string name="exportPassword">Tetapkan kata sandi untuk melindungi ekspor anda (opsional)</string>
|
||||
<string name="failedGeneratingShareURL">Tidak dapat membuat alamat berbagi. Mohon laporkan ini.</string>
|
||||
<string name="failedGeneratingShareURL">Tidak dapat menghasilkan URL yang dapat dibagikan</string>
|
||||
<string name="app_contributors">Pengembangan dibantu oleh: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="reverse">…dalam urutan terbalik</string>
|
||||
<string name="version_history">Riwayat Versi</string>
|
||||
<string name="version_history">Riwayat versi</string>
|
||||
<string name="help_translate_this_app">Bantu terjemahkan aplikasi ini</string>
|
||||
<string name="source_repository">Sumber Repositori</string>
|
||||
<string name="source_repository">Repositori sumber</string>
|
||||
<string name="on_github">di GitHub</string>
|
||||
<string name="and_data_usage">dan penggunaan data</string>
|
||||
<string name="on_google_play">di Google Play</string>
|
||||
<string name="cardShortcut">Pintasan Kartu</string>
|
||||
<string name="barcodeImageDescriptionWithType">Gambar <xliff:g>%s</xliff:g> barcode</string>
|
||||
<string name="importExportHelp">Mencadangkan data anda akan memungkinkan memindahkannya ke perangkat lain.</string>
|
||||
<string name="importExportHelp">Membackup data Anda memungkinkan Anda memindahkan data tersebut ke perangkat lain</string>
|
||||
<plurals name="selectedCardCount">
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> kartu dipilih</item>
|
||||
</plurals>
|
||||
@@ -174,7 +161,7 @@
|
||||
<plurals name="deleteCardsTitle">
|
||||
<item quantity="other">Hapus <xliff:g>%d</xliff:g> kartu</item>
|
||||
</plurals>
|
||||
<string name="editGroup">Menyunting Grup: <xliff:g>%s</xliff:g></string>
|
||||
<string name="editGroup">Kelompok pengeditan: <xliff:g>%s</xliff:g></string>
|
||||
<string name="selectColor">Pilih warna</string>
|
||||
<string name="noGiftCardsGroup">Buat beberapa kartu, kemudian masukkan mereka ke grup di sini</string>
|
||||
<string name="group_name_already_in_use">Nama grup telah dipakai</string>
|
||||
@@ -189,7 +176,7 @@
|
||||
<string name="translate_platform">di Weblate</string>
|
||||
<string name="welcome">Selamat datang di Catima</string>
|
||||
<string name="failedToOpenUrl">Install browser web terlebih dahulu</string>
|
||||
<string name="failedLaunchingPhotoPicker">Tidak dapat menemukan aplikasi galeri yang didukung</string>
|
||||
<string name="failedLaunchingPhotoPicker">Tidak dapat menemukan pemilih gambar yang didukung</string>
|
||||
<string name="previousCard">Sebelumnya</string>
|
||||
<string name="nextCard">Berikutnya</string>
|
||||
<plurals name="balancePoints">
|
||||
@@ -225,8 +212,8 @@
|
||||
<string name="switchToFrontImage">Ubah ke depan gambar</string>
|
||||
<string name="switchToBackImage">Ubah ke belakang gambar</string>
|
||||
<string name="switchToBarcode">Ubah ke kode batang</string>
|
||||
<string name="openFrontImageInGalleryApp">Buka gambar didepan di galeri app</string>
|
||||
<string name="openBackImageInGalleryApp">Buka gambar dibelakang di galeri app</string>
|
||||
<string name="openFrontImageInGalleryApp">Buka gambar depan di aplikasi penampil gambar</string>
|
||||
<string name="openBackImageInGalleryApp">Buka gambar di aplikasi penampil gambar</string>
|
||||
<string name="setBarcodeHeight">Atur tinggi kode batang</string>
|
||||
<string name="donate">Donasi</string>
|
||||
<string name="show_validity">Tunjukkan validitas</string>
|
||||
@@ -234,7 +221,7 @@
|
||||
<string name="icon_header_click_text">Tekan lama untuk mengedit thumbnail</string>
|
||||
<string name="show_name_below_image_thumbnail">Tampilkan nama di bawah thumbnail gambar</string>
|
||||
<string name="show_note">Tampilkan catatan</string>
|
||||
<string name="permissionReadCardsLabel">Baca Kartu Catima</string>
|
||||
<string name="permissionReadCardsLabel">Bacalah kartu Catima</string>
|
||||
<string name="permissionReadCardsDescription">baca kartu Anda dan semua detailnya, termasuk catatan dan gambar</string>
|
||||
<string name="settings_allow_content_provider_read_title">Izinkan aplikasi lain mengakses data saya</string>
|
||||
<string name="settings_allow_content_provider_read_summary">Aplikasi masih harus meminta izin untuk diberikan akses</string>
|
||||
@@ -260,15 +247,15 @@
|
||||
<string name="app_name">Catima</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="failedLaunchingFileManager">Tidak dapat menemukan pengelola berkas yang didukung</string>
|
||||
<string name="errorReadingFile">Tidak dapat membaca berkas</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>
|
||||
<string name="add_manually_warning_message">Untuk beberapa kartu, nilai barcode berbeda dengan angka yang tertulis di kartu. Karena itu, memasukkan barcode secara manual mungkin tidak selalu berhasil. Disarankan untuk memindai barcode menggunakan kamera Anda. Apakah Anda tetap ingin melanjutkan?</string>
|
||||
<string name="noCameraFoundGuideText">Perangkat Anda sepertinya tidak memiliki kamera. Jika iya, coba mulai ulang perangkat. Jika tidak, gunakan tombol Opsi lainnya di bawah untuk menambahkan barcode dengan cara lain.</string>
|
||||
<string name="importCancelled">Impor dibatalkan</string>
|
||||
<string name="exportCancelled">Ekspor dibatalkan</string>
|
||||
@@ -289,10 +276,18 @@
|
||||
<string name="settings_column_count_5">5</string>
|
||||
<string name="addFromPkpass">Pilih file Buku Tabungan (.pkpass / .pkpasses)</string>
|
||||
<string name="unsupportedFile">File ini tidak didukung</string>
|
||||
<string name="generic_error_please_retry">Maaf, terjadi kesalahan, silakan coba lagi...</string>
|
||||
<string name="sort_by_valid_from">Berlaku dari</string>
|
||||
<string name="generic_error_please_retry">Terjadi kesalahan</string>
|
||||
<string name="sort_by_valid_from">Berlaku mulai</string>
|
||||
<string name="width">Lebar</string>
|
||||
<string name="card_list_widget_name">Daftar kartu</string>
|
||||
<string name="setBarcodeWidth">Atur Lebar Barcode</string>
|
||||
<string name="setBarcodeWidth">Atur lebar barcode</string>
|
||||
<string name="card_list_widget_empty">Setelah Anda menambahkan beberapa kartu loyalitas di Catima, kartu tersebut akan muncul di sini. Jika Anda memiliki kartu sebelumnya, pastikan tidak semuanya diarsipkan.</string>
|
||||
<string name="cardWithNumber">Kartu <xliff:g>%d</xliff:g></string>
|
||||
<string name="cardWithNumberAndLocale">Kartu <xliff:g>%d</xliff:g> (<xliff:g>%s</xliff:g>)</string>
|
||||
<string name="pleaseDoNotRotateTheDevice">Jangan memutar perangkat, karena hal ini akan membatalkan tindakan</string>
|
||||
<string name="acra_catima_has_crashed">Kami mohon maaf, tetapi <xliff:g id="app_name">%s</xliff:g> telah mengalami crash. Tolong bantu kami memperbaiki masalah ini dengan mengirimkan laporan kesalahan kepada kami.</string>
|
||||
<string name="acra_explain_crash">Jika memungkinkan, tolong tambahkan detail lebih lanjut tentang apa yang Anda lakukan di sini:</string>
|
||||
<string name="acra_crash_email_subject">Laporan crash <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="pref_enable_acra">Minta untuk mengirimkan laporan crash</string>
|
||||
<string name="pref_enable_acra_summary">Ketika diaktifkan, Anda akan diminta untuk melaporkan crash saat terjadi. Laporan crash tidak pernah dikirim secara otomatis.</string>
|
||||
</resources>
|
||||
|
||||
@@ -76,11 +76,7 @@
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> valin</item>
|
||||
</plurals>
|
||||
<string name="noGiftCardsGroup">Búðu til nokkur kort og settu þau síðan í hópinn hér.</string>
|
||||
<string name="settings_brown_theme">Brún</string>
|
||||
<string name="settings_green_theme">Grænn</string>
|
||||
<string name="sort">flokka</string>
|
||||
<string name="sort_by">flokka Eftir</string>
|
||||
<string name="nextCard">Næsta</string>
|
||||
<string name="settings_blue_theme">Blár</string>
|
||||
<string name="settings_sky_blue_theme">Himinblár</string>
|
||||
</resources>
|
||||
@@ -17,14 +17,14 @@
|
||||
<string name="sendLabel">Invia…</string>
|
||||
<string name="editCardTitle">Modifica carta</string>
|
||||
<string name="addCardTitle">Aggiungi carta</string>
|
||||
<string name="scanCardBarcode">Scansiona il codice</string>
|
||||
<string name="scanCardBarcode">Scansiona codice a barre</string>
|
||||
<string name="cardShortcut">Scorciatoia per la carta</string>
|
||||
<string name="noCardsMessage">Aggiungi prima una carta</string>
|
||||
<string name="noCardExistsError">Impossibile trovare quella carta</string>
|
||||
<string name="failedParsingImportUriError">Impossibile analizzare l\'URI di importazione</string>
|
||||
<string name="importExport">Importa/Esporta</string>
|
||||
<string name="importExport">Importa/esporta</string>
|
||||
<string name="exportName">Esporta</string>
|
||||
<string name="importExportHelp">Il backup dei dati permette di spostarli su un altro dispositivo.</string>
|
||||
<string name="importExportHelp">Il backup dei dati permette di spostarli su un altro dispositivo</string>
|
||||
<string name="importSuccessfulTitle">Importato</string>
|
||||
<string name="importFailedTitle">Importazione fallita</string>
|
||||
<string name="importFailed">Impossibile eseguire l\'importazione</string>
|
||||
@@ -151,15 +151,6 @@
|
||||
</plurals>
|
||||
<string name="settings_system_locale">Sistema</string>
|
||||
<string name="settings_locale">Lingua</string>
|
||||
<string name="settings_brown_theme">Marrone</string>
|
||||
<string name="settings_green_theme">Verde</string>
|
||||
<string name="settings_sky_blue_theme">Azzurro</string>
|
||||
<string name="settings_blue_theme">Blu</string>
|
||||
<string name="settings_violet_theme">Viola</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_pink_theme">Rosa</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_theme_color">Colore del tema</string>
|
||||
<string name="app_contributors">Reso possibile da: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="noGroupCards">Questo gruppo è vuoto</string>
|
||||
<string name="barcodeImageDescriptionWithType">Immagine del codice a barre in formato <xliff:g>%s</xliff:g></string>
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<string name="enter_group_name">グループ名を入力</string>
|
||||
<string name="exportSuccessful">データがエクスポートされました</string>
|
||||
<string name="importSuccessful">データがインポートされました</string>
|
||||
<string name="intent_import_card_from_url_share_text">カード共有をしましょう</string>
|
||||
<string name="intent_import_card_from_url_share_text">カードを共有しましょう</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">バーコード表示中に画面をロックしない</string>
|
||||
<string name="settings_keep_screen_on">バーコード表示中に画面を点けたままにする</string>
|
||||
<string name="settings_display_barcode_max_brightness">画面を明るくする</string>
|
||||
@@ -109,8 +109,8 @@
|
||||
<string name="action_add">追加</string>
|
||||
<string name="action_search">検索</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">カードを共有しましょう</string>
|
||||
<string name="turn_flashlight_off">ライトをオフにする</string>
|
||||
<string name="turn_flashlight_on">ライトをオンにする</string>
|
||||
<string name="turn_flashlight_off">ライトを消灯する</string>
|
||||
<string name="turn_flashlight_on">ライトを点灯する</string>
|
||||
<string name="failedGeneratingShareURL">共有可能なURLを作成できませんでした</string>
|
||||
<string name="passwordRequired">パスワードを入力</string>
|
||||
<string name="no">いいえ</string>
|
||||
@@ -119,11 +119,11 @@
|
||||
<string name="updateBarcodeQuestionTitle">バーコードの番号を変更しますか?</string>
|
||||
<string name="takePhoto">写真を撮影する</string>
|
||||
<string name="removeImage">画像を削除</string>
|
||||
<string name="setBackImage">裏面の画像を設定</string>
|
||||
<string name="setFrontImage">表面の画像を設定</string>
|
||||
<string name="setBackImage">背面の画像を設定</string>
|
||||
<string name="setFrontImage">前面の画像を設定</string>
|
||||
<string name="photos">画像</string>
|
||||
<string name="backImageDescription">裏</string>
|
||||
<string name="frontImageDescription">表</string>
|
||||
<string name="backImageDescription">背面</string>
|
||||
<string name="frontImageDescription">前面</string>
|
||||
<plurals name="selectedCardCount">
|
||||
<item quantity="other">選択済み: <xliff:g>%d</xliff:g> 枚</item>
|
||||
</plurals>
|
||||
@@ -137,15 +137,6 @@
|
||||
</plurals>
|
||||
<string name="barcodeImageDescriptionWithType">バーコード形式の画像 <xliff:g>%s</xliff:g></string>
|
||||
<string name="app_contributors">Made possible by: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="settings_brown_theme">ブラウン/茶色</string>
|
||||
<string name="settings_green_theme">グリーン/緑色</string>
|
||||
<string name="settings_sky_blue_theme">スカイブルー/水色</string>
|
||||
<string name="settings_blue_theme">ブルー/青色</string>
|
||||
<string name="settings_violet_theme">バイオレット/菫色</string>
|
||||
<string name="settings_magenta_theme">マゼンタ/赤紫色</string>
|
||||
<string name="settings_pink_theme">ピンク/桃色</string>
|
||||
<string name="settings_catima_theme">Catimaテーマ</string>
|
||||
<string name="settings_theme_color">テーマカラー</string>
|
||||
<string name="settings_system_locale">システムに従う</string>
|
||||
<string name="settings_locale">言語</string>
|
||||
<string name="noGroupCards">このグループにはカードがありません</string>
|
||||
@@ -298,4 +289,7 @@
|
||||
<string name="acra_crash_email_subject"><xliff:g id="app_name">%s</xliff:g> クラッシュレポート</string>
|
||||
<string name="pref_enable_acra">クラッシュレポートを送信する</string>
|
||||
<string name="pref_enable_acra_summary">有効にすると、クラッシュ発生時に報告するかを確認されます。クラッシュレポートが自動送信されることはありません。</string>
|
||||
<string name="copy_value">値をコピー</string>
|
||||
<string name="copied_to_clipboard">クリップボードへコピー</string>
|
||||
<string name="nothing_to_copy">値が見つかりません</string>
|
||||
</resources>
|
||||
|
||||
@@ -87,12 +87,6 @@
|
||||
<string name="settings_locale">언어</string>
|
||||
<string name="settings_system_locale">시스템</string>
|
||||
<string name="selectColor">색상 선택</string>
|
||||
<string name="settings_theme_color">테마 색상</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_pink_theme">핑크색</string>
|
||||
<string name="settings_magenta_theme">자홍색</string>
|
||||
<string name="settings_violet_theme">보라색</string>
|
||||
<string name="settings_blue_theme">파란색</string>
|
||||
<string name="app_contributors">기여자: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="showMoreInfo">정보 보기</string>
|
||||
<string name="updateBalance">잔액 업데이트</string>
|
||||
@@ -228,9 +222,6 @@
|
||||
<string name="importVoucherVaultMessage">가져올 Voucher Vault에서 <i>vouchervault.json</i> 내보내기를 선택합니다.
|
||||
\n먼저 바우처 금고에서 내보내기를 눌러 생성하세요.</string>
|
||||
<string name="sameAsCardId">아이디와 동일</string>
|
||||
<string name="settings_sky_blue_theme">하늘색</string>
|
||||
<string name="settings_green_theme">초록색</string>
|
||||
<string name="settings_brown_theme">갈색</string>
|
||||
<string name="previousCard">이전의</string>
|
||||
<string name="nextCard">다음</string>
|
||||
<string name="failedToOpenUrl">먼저 웹 브라우저를 설치하십시오</string>
|
||||
|
||||
@@ -152,15 +152,6 @@
|
||||
</plurals>
|
||||
<string name="settings_system_locale">Sistemos</string>
|
||||
<string name="settings_locale">Kalba</string>
|
||||
<string name="settings_brown_theme">Ruda</string>
|
||||
<string name="settings_green_theme">Žalia</string>
|
||||
<string name="settings_sky_blue_theme">Dangaus mėlynumo</string>
|
||||
<string name="settings_blue_theme">Mėlyna</string>
|
||||
<string name="settings_violet_theme">Violetinė</string>
|
||||
<string name="settings_magenta_theme">Rausvai raudona</string>
|
||||
<string name="settings_pink_theme">Rožinė</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_theme_color">Temos spalva</string>
|
||||
<string name="app_contributors">Tapo įmanoma su pagalba: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="noGroupCards">Grupėje yra tuščia</string>
|
||||
<string name="barcodeImageDescriptionWithType"><xliff:g>%s</xliff:g> brūkšninio kodo vaizdas</string>
|
||||
|
||||
@@ -76,16 +76,16 @@
|
||||
<string name="leaveWithoutSaveConfirmation">Iziet nesaglabājot\?</string>
|
||||
<string name="addFromImage">Atlasīt attēlu no galerijas</string>
|
||||
<string name="card">Karte</string>
|
||||
<string name="expiryDate">Derīguma termiņš</string>
|
||||
<string name="expiryDate">Derīguma beigu datums</string>
|
||||
<string name="never">Nekad</string>
|
||||
<string name="chooseExpiryDate">Izvēlēties beigu datumu</string>
|
||||
<string name="failedToRetrieveImageFile">Neizdevās iegūt attēla datni</string>
|
||||
<string name="barcodeLongPressMessage">Galerijas lietotnē var atvērt tikai attēlus</string>
|
||||
<string name="sort_by_expiry">Derīguma termiņš</string>
|
||||
<string name="sort_by_expiry">Derīgums</string>
|
||||
<string name="reverse">...apgrieztā secībā</string>
|
||||
<string name="credits">Pateicības</string>
|
||||
<string name="shortcutSelectCard">Atlasīt karti</string>
|
||||
<string name="duplicateCard">Dublēt</string>
|
||||
<string name="duplicateCard">Pavairot</string>
|
||||
<string name="archive">Arhivēt</string>
|
||||
<string name="translate_platform">Weblate</string>
|
||||
<string name="starred">Izlase</string>
|
||||
@@ -96,13 +96,8 @@
|
||||
<item quantity="other">Neatgriezeniski dzēst šīs <xliff:g>%d</xliff:g> kartes\?</item>
|
||||
</plurals>
|
||||
<string name="about_title_fmt">Par <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Derīguma termiņš beidzās: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Derīgums beidzās: <xliff:g>%s</xliff:g></string>
|
||||
<string name="selectColor">Atlasīt krāsu</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_pink_theme">Rozā</string>
|
||||
<string name="settings_magenta_theme">Purpura</string>
|
||||
<string name="settings_sky_blue_theme">Gaiši zila</string>
|
||||
<string name="settings_green_theme">Zaļa</string>
|
||||
<string name="sort_by_name">Nosaukums</string>
|
||||
<string name="on_google_play">pakalpojumā Google Play</string>
|
||||
<string name="report_error">Ziņot par kļūdu</string>
|
||||
@@ -129,7 +124,7 @@
|
||||
<string name="source_repository">Pirmkoda glabātava</string>
|
||||
<string name="rate_this_app">Novērtēt šo lietotni</string>
|
||||
<string name="noGiftCardsGroup">Izveido kādas kartes, tad šeit pievieno tās kopai</string>
|
||||
<string name="options">Parametri</string>
|
||||
<string name="options">Iespējas</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="zero"><xliff:g>%d</xliff:g> kartes</item>
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> karte</item>
|
||||
@@ -150,7 +145,6 @@
|
||||
<string name="privacy_policy">Privātuma politika</string>
|
||||
<string name="accept">Pieņemt</string>
|
||||
<string name="editGroup">Kopas labošana: <xliff:g>%s</xliff:g></string>
|
||||
<string name="settings_brown_theme">Brūna</string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Autortiesības © 2019–<xliff:g>%d</xliff:g> Sylvia van Os</string>
|
||||
<string name="app_copyright_old">Balstīta uz Loyalty Card Keychain
|
||||
\nautortiesības © 2016–2020 Branden Archer</string>
|
||||
@@ -165,7 +159,7 @@
|
||||
<string name="group_updated">Kopa atjaunināta</string>
|
||||
<string name="addManually">Pašrocīgi ievadīt svītrkodu</string>
|
||||
<string name="groupsList">Kopas: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Derīguma termiņš: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Derīgums beigsies: <xliff:g>%s</xliff:g></string>
|
||||
<string name="balanceSentence">Atlikums: <xliff:g>%s</xliff:g></string>
|
||||
<string name="editBarcode">Labot svītrkodu</string>
|
||||
<string name="importCatima">Ievietot no Catima</string>
|
||||
@@ -182,18 +176,15 @@
|
||||
<string name="intent_import_card_from_url_share_multiple_text">Vēlos ar Tevi kopīgot dažas kartes</string>
|
||||
<string name="frontImageDescription">Priekšpuses attēls</string>
|
||||
<string name="backImageDescription">Aizmugures attēls</string>
|
||||
<string name="photos">Foto</string>
|
||||
<string name="photos">Fotoattēli</string>
|
||||
<string name="setFrontImage">Iestatīt priekšpuses attēlu</string>
|
||||
<string name="setBackImage">Iestatīt aizmugures attēlu</string>
|
||||
<string name="takePhoto">Fotografēt</string>
|
||||
<string name="takePhoto">Uzņemt attēlu</string>
|
||||
<string name="passwordRequired">Jāievada parole</string>
|
||||
<string name="exportPassword">Iestatīt paroli, lai aizsargātu savu izguves datni (pēc izvēles)</string>
|
||||
<string name="turn_flashlight_on">Ieslēgt zibspuldzi</string>
|
||||
<string name="settings_oled_dark">Tīri melns fons tumšajam izskatam</string>
|
||||
<string name="setIcon">Iestatīt sīktēlu</string>
|
||||
<string name="settings_theme_color">Izskata krāsa</string>
|
||||
<string name="settings_violet_theme">Violeta</string>
|
||||
<string name="settings_blue_theme">Zila</string>
|
||||
<string name="sort">Kārtot</string>
|
||||
<string name="showMoreInfo">Rādīt informāciju</string>
|
||||
<string name="sort_by_most_recently_used">Visnesenāk izmantotās</string>
|
||||
@@ -311,4 +302,7 @@
|
||||
<string name="acra_crash_email_subject"><xliff:g id="app_name">%s</xliff:g> avārijas ziņojums</string>
|
||||
<string name="pref_enable_acra">Vaicāt, lai nosūtītu ziņojumus par avārijām</string>
|
||||
<string name="pref_enable_acra_summary">Kad iespējots, tiks vaicāts ziņot par avāriju, kad tā notiek. Ziņojumi par avārijām nekad netiks automātiski nosūtīti.</string>
|
||||
<string name="copy_value">Ievietot vērtību starpliktuvē</string>
|
||||
<string name="copied_to_clipboard">Ievietots starpliktuvē</string>
|
||||
<string name="nothing_to_copy">Nav atrasta vērtība</string>
|
||||
</resources>
|
||||
|
||||
@@ -146,16 +146,7 @@
|
||||
</plurals>
|
||||
<string name="settings_system_locale">System</string>
|
||||
<string name="settings_locale">Språk</string>
|
||||
<string name="settings_violet_theme">Fiolett</string>
|
||||
<string name="settings_magenta_theme">Magentarød</string>
|
||||
<string name="app_contributors">Muliggjort av: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="settings_brown_theme">Brun</string>
|
||||
<string name="settings_green_theme">Grønn</string>
|
||||
<string name="settings_sky_blue_theme">Himmelblå</string>
|
||||
<string name="settings_blue_theme">Blå</string>
|
||||
<string name="settings_pink_theme">Rosa</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_theme_color">Draktfarge</string>
|
||||
<string name="noGroupCards">Denne gruppen er tom</string>
|
||||
<string name="barcodeImageDescriptionWithType">Bilde av <xliff:g>%s</xliff:g>-strekkode</string>
|
||||
<string name="sort_by">Sortering</string>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="Theme.Material3.Dark.NoActionBar">
|
||||
<item name="colorPrimary">@color/md_theme_dark_primary</item>
|
||||
<item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item>
|
||||
@@ -46,208 +45,4 @@
|
||||
<item name="android:colorBackground">#000000</item>
|
||||
<item name="colorSurface">#000000</item>
|
||||
</style>
|
||||
|
||||
<!-- color themes -->
|
||||
<style name="pink">
|
||||
<item name="colorPrimary">#FFB2C0</item>
|
||||
<item name="colorOnPrimary">#670024</item>
|
||||
<item name="colorPrimaryContainer">#900036</item>
|
||||
<item name="colorOnPrimaryContainer">#FFD9DF</item>
|
||||
<item name="colorSecondary">#E5BDC2</item>
|
||||
<item name="colorOnSecondary">#43292D</item>
|
||||
<item name="colorSecondaryContainer">#5C3F43</item>
|
||||
<item name="colorOnSecondaryContainer">#FFD9DE</item>
|
||||
<item name="colorTertiary">#EBBF90</item>
|
||||
<item name="colorOnTertiary">#452B08</item>
|
||||
<item name="colorTertiaryContainer">#5F411C</item>
|
||||
<item name="colorOnTertiaryContainer">#FFDDB8</item>
|
||||
<item name="colorError">#FFB4A9</item>
|
||||
<item name="colorErrorContainer">#930006</item>
|
||||
<item name="colorOnError">#680003</item>
|
||||
<item name="colorOnErrorContainer">#FFDAD4</item>
|
||||
<item name="android:colorBackground">#201A1B</item>
|
||||
<item name="colorOnBackground">#ECE0E0</item>
|
||||
<item name="colorSurface">#201A1B</item>
|
||||
<item name="colorOnSurface">#ECE0E0</item>
|
||||
<item name="colorSurfaceVariant">#524345</item>
|
||||
<item name="colorOnSurfaceVariant">#D6C1C3</item>
|
||||
<item name="colorOutline">#9F8C8E</item>
|
||||
<item name="colorOnSurfaceInverse">#201A1B</item>
|
||||
<item name="colorSurfaceInverse">#ECE0E0</item>
|
||||
<item name="colorPrimaryInverse">#BC0049</item>
|
||||
</style>
|
||||
|
||||
<style name="magenta">
|
||||
<item name="colorPrimary">#FBAAFF</item>
|
||||
<item name="colorOnPrimary">#570068</item>
|
||||
<item name="colorPrimaryContainer">#7B0091</item>
|
||||
<item name="colorOnPrimaryContainer">#FFD5FF</item>
|
||||
<item name="colorSecondary">#D7BFD5</item>
|
||||
<item name="colorOnSecondary">#3B2B3B</item>
|
||||
<item name="colorSecondaryContainer">#534153</item>
|
||||
<item name="colorOnSecondaryContainer">#F5DBF2</item>
|
||||
<item name="colorTertiary">#F6B8AE</item>
|
||||
<item name="colorOnTertiary">#4C251F</item>
|
||||
<item name="colorTertiaryContainer">#663B34</item>
|
||||
<item name="colorOnTertiaryContainer">#FFDAD2</item>
|
||||
<item name="colorError">#FFB4A9</item>
|
||||
<item name="colorErrorContainer">#930006</item>
|
||||
<item name="colorOnError">#680003</item>
|
||||
<item name="colorOnErrorContainer">#FFDAD4</item>
|
||||
<item name="android:colorBackground">#1E1A1D</item>
|
||||
<item name="colorOnBackground">#E9E0E5</item>
|
||||
<item name="colorSurface">#1E1A1D</item>
|
||||
<item name="colorOnSurface">#E9E0E5</item>
|
||||
<item name="colorSurfaceVariant">#4D444C</item>
|
||||
<item name="colorOnSurfaceVariant">#D0C3CC</item>
|
||||
<item name="colorOutline">#998E96</item>
|
||||
<item name="colorOnSurfaceInverse">#1E1A1D</item>
|
||||
<item name="colorSurfaceInverse">#E9E0E5</item>
|
||||
<item name="colorPrimaryInverse">#9A25AE</item>
|
||||
</style>
|
||||
|
||||
<style name="violet">
|
||||
<item name="colorPrimary">#D4BAFF</item>
|
||||
<item name="colorOnPrimary">#3E008E</item>
|
||||
<item name="colorPrimaryContainer">#5727A7</item>
|
||||
<item name="colorOnPrimaryContainer">#ECDCFF</item>
|
||||
<item name="colorSecondary">#CDC2DB</item>
|
||||
<item name="colorOnSecondary">#342D41</item>
|
||||
<item name="colorSecondaryContainer">#4B4358</item>
|
||||
<item name="colorOnSecondaryContainer">#E9DEF7</item>
|
||||
<item name="colorTertiary">#F0B8C5</item>
|
||||
<item name="colorOnTertiary">#4A2530</item>
|
||||
<item name="colorTertiaryContainer">#643A46</item>
|
||||
<item name="colorOnTertiaryContainer">#FFD9E2</item>
|
||||
<item name="colorError">#FFB4A9</item>
|
||||
<item name="colorErrorContainer">#930006</item>
|
||||
<item name="colorOnError">#680003</item>
|
||||
<item name="colorOnErrorContainer">#FFDAD4</item>
|
||||
<item name="android:colorBackground">#1D1B1F</item>
|
||||
<item name="colorOnBackground">#E6E1E5</item>
|
||||
<item name="colorSurface">#1D1B1F</item>
|
||||
<item name="colorOnSurface">#E6E1E5</item>
|
||||
<item name="colorSurfaceVariant">#49454E</item>
|
||||
<item name="colorOnSurfaceVariant">#CBC4CF</item>
|
||||
<item name="colorOutline">#948E99</item>
|
||||
<item name="colorOnSurfaceInverse">#1D1B1F</item>
|
||||
<item name="colorSurfaceInverse">#E6E1E5</item>
|
||||
<item name="colorPrimaryInverse">#6F43BF</item>
|
||||
</style>
|
||||
|
||||
<style name="blue">
|
||||
<item name="colorPrimary">#B9C3FF</item>
|
||||
<item name="colorOnPrimary">#08218A</item>
|
||||
<item name="colorPrimaryContainer">#293CA0</item>
|
||||
<item name="colorOnPrimaryContainer">#DDE0FF</item>
|
||||
<item name="colorSecondary">#C4C5DD</item>
|
||||
<item name="colorOnSecondary">#2D2F42</item>
|
||||
<item name="colorSecondaryContainer">#43465A</item>
|
||||
<item name="colorOnSecondaryContainer">#E0E1FA</item>
|
||||
<item name="colorTertiary">#E5BAD7</item>
|
||||
<item name="colorOnTertiary">#45263E</item>
|
||||
<item name="colorTertiaryContainer">#5D3C55</item>
|
||||
<item name="colorOnTertiaryContainer">#FFD7F3</item>
|
||||
<item name="colorError">#FFB4A9</item>
|
||||
<item name="colorErrorContainer">#930006</item>
|
||||
<item name="colorOnError">#680003</item>
|
||||
<item name="colorOnErrorContainer">#FFDAD4</item>
|
||||
<item name="android:colorBackground">#1B1B1F</item>
|
||||
<item name="colorOnBackground">#E4E1E6</item>
|
||||
<item name="colorSurface">#1B1B1F</item>
|
||||
<item name="colorOnSurface">#E4E1E6</item>
|
||||
<item name="colorSurfaceVariant">#46464F</item>
|
||||
<item name="colorOnSurfaceVariant">#C6C5D0</item>
|
||||
<item name="colorOutline">#90909A</item>
|
||||
<item name="colorOnSurfaceInverse">#1B1B1F</item>
|
||||
<item name="colorSurfaceInverse">#E4E1E6</item>
|
||||
<item name="colorPrimaryInverse">#4355B9</item>
|
||||
</style>
|
||||
|
||||
<style name="skyblue">
|
||||
<item name="colorPrimary">#8BCEFF</item>
|
||||
<item name="colorOnPrimary">#003450</item>
|
||||
<item name="colorPrimaryContainer">#004B71</item>
|
||||
<item name="colorOnPrimaryContainer">#C8E6FF</item>
|
||||
<item name="colorSecondary">#B7C8D8</item>
|
||||
<item name="colorOnSecondary">#22323F</item>
|
||||
<item name="colorSecondaryContainer">#384956</item>
|
||||
<item name="colorOnSecondaryContainer">#D3E4F5</item>
|
||||
<item name="colorTertiary">#CFBFE8</item>
|
||||
<item name="colorOnTertiary">#362B4B</item>
|
||||
<item name="colorTertiaryContainer">#4D4162</item>
|
||||
<item name="colorOnTertiaryContainer">#ECDCFF</item>
|
||||
<item name="colorError">#FFB4A9</item>
|
||||
<item name="colorErrorContainer">#930006</item>
|
||||
<item name="colorOnError">#680003</item>
|
||||
<item name="colorOnErrorContainer">#FFDAD4</item>
|
||||
<item name="android:colorBackground">#1A1C1E</item>
|
||||
<item name="colorOnBackground">#E2E2E5</item>
|
||||
<item name="colorSurface">#1A1C1E</item>
|
||||
<item name="colorOnSurface">#E2E2E5</item>
|
||||
<item name="colorSurfaceVariant">#41474D</item>
|
||||
<item name="colorOnSurfaceVariant">#C1C7CE</item>
|
||||
<item name="colorOutline">#8B9198</item>
|
||||
<item name="colorOnSurfaceInverse">#1A1C1E</item>
|
||||
<item name="colorSurfaceInverse">#E2E2E5</item>
|
||||
<item name="colorPrimaryInverse">#006494</item>
|
||||
</style>
|
||||
|
||||
<style name="green">
|
||||
<item name="colorPrimary">#78DC77</item>
|
||||
<item name="colorOnPrimary">#003907</item>
|
||||
<item name="colorPrimaryContainer">#00530F</item>
|
||||
<item name="colorOnPrimaryContainer">#93F990</item>
|
||||
<item name="colorSecondary">#B9CCB3</item>
|
||||
<item name="colorOnSecondary">#253423</item>
|
||||
<item name="colorSecondaryContainer">#3B4B38</item>
|
||||
<item name="colorOnSecondaryContainer">#D5E8CE</item>
|
||||
<item name="colorTertiary">#A1CFD5</item>
|
||||
<item name="colorOnTertiary">#00363B</item>
|
||||
<item name="colorTertiaryContainer">#1E4D52</item>
|
||||
<item name="colorOnTertiaryContainer">#BCEBF0</item>
|
||||
<item name="colorError">#FFB4A9</item>
|
||||
<item name="colorErrorContainer">#930006</item>
|
||||
<item name="colorOnError">#680003</item>
|
||||
<item name="colorOnErrorContainer">#FFDAD4</item>
|
||||
<item name="android:colorBackground">#1A1C19</item>
|
||||
<item name="colorOnBackground">#E2E3DD</item>
|
||||
<item name="colorSurface">#1A1C19</item>
|
||||
<item name="colorOnSurface">#E2E3DD</item>
|
||||
<item name="colorSurfaceVariant">#424840</item>
|
||||
<item name="colorOnSurfaceVariant">#C2C8BD</item>
|
||||
<item name="colorOutline">#8C9288</item>
|
||||
<item name="colorOnSurfaceInverse">#1A1C19</item>
|
||||
<item name="colorSurfaceInverse">#E2E3DD</item>
|
||||
<item name="colorPrimaryInverse">#006E17</item>
|
||||
</style>
|
||||
|
||||
<style name="brown">
|
||||
<item name="colorPrimary">#FFB598</item>
|
||||
<item name="colorOnPrimary">#5C1A00</item>
|
||||
<item name="colorPrimaryContainer">#7B2E0D</item>
|
||||
<item name="colorOnPrimaryContainer">#FFDBCD</item>
|
||||
<item name="colorSecondary">#E7BEB0</item>
|
||||
<item name="colorOnSecondary">#442A20</item>
|
||||
<item name="colorSecondaryContainer">#5D4035</item>
|
||||
<item name="colorOnSecondaryContainer">#FFDBCD</item>
|
||||
<item name="colorTertiary">#D5C78E</item>
|
||||
<item name="colorOnTertiary">#383005</item>
|
||||
<item name="colorTertiaryContainer">#50461A</item>
|
||||
<item name="colorOnTertiaryContainer">#F1E2A7</item>
|
||||
<item name="colorError">#FFB4A9</item>
|
||||
<item name="colorErrorContainer">#930006</item>
|
||||
<item name="colorOnError">#680003</item>
|
||||
<item name="colorOnErrorContainer">#FFDAD4</item>
|
||||
<item name="android:colorBackground">#201A18</item>
|
||||
<item name="colorOnBackground">#EDE0DC</item>
|
||||
<item name="colorSurface">#201A18</item>
|
||||
<item name="colorOnSurface">#EDE0DC</item>
|
||||
<item name="colorSurfaceVariant">#52433E</item>
|
||||
<item name="colorOnSurfaceVariant">#D8C2BB</item>
|
||||
<item name="colorOutline">#A08C86</item>
|
||||
<item name="colorOnSurfaceInverse">#201A18</item>
|
||||
<item name="colorSurfaceInverse">#EDE0DC</item>
|
||||
<item name="colorPrimaryInverse">#9A4523</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -144,15 +144,6 @@
|
||||
</plurals>
|
||||
<string name="settings_system_locale">Systeemtaal</string>
|
||||
<string name="settings_locale">Taal</string>
|
||||
<string name="settings_brown_theme">Bruin</string>
|
||||
<string name="settings_green_theme">Groen</string>
|
||||
<string name="settings_sky_blue_theme">Hemelsblauw</string>
|
||||
<string name="settings_blue_theme">Blauw</string>
|
||||
<string name="settings_violet_theme">Violet</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_pink_theme">Roze</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_theme_color">Themakleur</string>
|
||||
<string name="app_contributors">Mede mogelijk gemaakt door: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="noGroupCards">Deze groep bevat geen kaarten</string>
|
||||
<string name="barcodeImageDescriptionWithType">Afbeelding van barcode <xliff:g>%s</xliff:g></string>
|
||||
@@ -305,4 +296,7 @@
|
||||
<string name="acra_crash_email_subject"><xliff:g id="app_name">%s</xliff:g> foutrapport</string>
|
||||
<string name="pref_enable_acra">Vraag om foutrapporten te versturen</string>
|
||||
<string name="pref_enable_acra_summary">Als dit aanstaat, zal je gevraagd worden om foutrapporten te sturen als de app crasht. Dit zal nooit automatisch gebeuren.</string>
|
||||
<string name="nothing_to_copy">Geen waarde gevonden</string>
|
||||
<string name="copied_to_clipboard">Gekopieerd naar klembord</string>
|
||||
<string name="copy_value">Kopieer waarde</string>
|
||||
</resources>
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
<string name="addFromImage">Causir a la galariá</string>
|
||||
<string name="groups">Grops</string>
|
||||
<string name="groupsList">Grops : <xliff:g>%s</xliff:g></string>
|
||||
<string name="settings_theme_color">Color del tèma</string>
|
||||
<string name="settings_locale">Lenga</string>
|
||||
<string name="noGiftCardsGroup">Creatz de cartas puèi ligatz-las al grop aicí.</string>
|
||||
</resources>
|
||||
|
||||
3
app/src/main/res/values-peo/strings.xml
Normal file
3
app/src/main/res/values-peo/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
@@ -67,15 +67,6 @@
|
||||
<string name="deleteTitle">Usuń kartę</string>
|
||||
<string name="deleteConfirmation">Usunąć tę kartę na stałe\?</string>
|
||||
<string name="app_contributors">Możliwe dzięki: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="settings_brown_theme">Brązowy</string>
|
||||
<string name="settings_green_theme">Zielony</string>
|
||||
<string name="settings_sky_blue_theme">Błękitny</string>
|
||||
<string name="settings_blue_theme">Niebieski</string>
|
||||
<string name="settings_violet_theme">Fioletowy</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_pink_theme">Różowy</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_theme_color">Kolor akcentowy motywu</string>
|
||||
<string name="settings_system_locale">System</string>
|
||||
<string name="settings_locale">Język</string>
|
||||
<string name="turn_flashlight_off">Wyłącz latarkę</string>
|
||||
|
||||
@@ -124,12 +124,6 @@
|
||||
<string name="settings_oled_dark_summary">Reduz o uso da bateria em telas OLED</string>
|
||||
<string name="settings_system_locale">Sistema</string>
|
||||
<string name="settings_oled_dark">Preto puro como cor de fundo para o tema escuro</string>
|
||||
<string name="settings_pink_theme">Rosa</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_blue_theme">Azul</string>
|
||||
<string name="settings_sky_blue_theme">Azul celeste</string>
|
||||
<string name="settings_green_theme">Verde</string>
|
||||
<string name="settings_brown_theme">Marrom</string>
|
||||
<string name="app_contributors">Só foi possível graças a: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="sort">Ordenar</string>
|
||||
<string name="showMoreInfo">Mostrar informações</string>
|
||||
@@ -176,10 +170,7 @@
|
||||
<string name="receive">Receber</string>
|
||||
<string name="amountParsingFailed">Quantidade inválida</string>
|
||||
<string name="addFromPdfFile">Selecionar arquivo PDF</string>
|
||||
<string name="settings_theme_color">Cor do tema</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="selectColor">Selecionar cor</string>
|
||||
<string name="settings_violet_theme">Violeta</string>
|
||||
<string name="sort_by_name">Nome</string>
|
||||
<string name="sort_by_expiry">Expiração</string>
|
||||
<string name="credits">Créditos</string>
|
||||
@@ -311,4 +302,7 @@
|
||||
<string name="acra_crash_email_subject">Relatório de falha em <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="pref_enable_acra">Solicitar o envio de relatórios de falhas</string>
|
||||
<string name="pref_enable_acra_summary">Quando ativado, você será solicitado a relatar uma falha quando isto ocorrer. Os relatórios de falhas nunca são enviados automaticamente.</string>
|
||||
<string name="copy_value">Copiar valor</string>
|
||||
<string name="copied_to_clipboard">Copiado para a área de transferência</string>
|
||||
<string name="nothing_to_copy">Nenhum valor encontrado</string>
|
||||
</resources>
|
||||
|
||||
@@ -71,7 +71,6 @@
|
||||
<string name="exportFailed">Não foi possível exportar</string>
|
||||
<string name="importing">A importar…</string>
|
||||
<string name="exporting">A exportar…</string>
|
||||
<string name="settings_sky_blue_theme">Azul céu</string>
|
||||
<string name="report_error">Reportar erro</string>
|
||||
<string name="chooseImportType">Importar dados de</string>
|
||||
<string name="card">Cartão</string>
|
||||
@@ -93,8 +92,6 @@
|
||||
<string name="frontImageDescription">Imagem frontal</string>
|
||||
<string name="photos">Fotografias</string>
|
||||
<string name="passwordRequired">Introduza a palavra-passe</string>
|
||||
<string name="settings_green_theme">Verde</string>
|
||||
<string name="settings_brown_theme">Castanho</string>
|
||||
<string name="updateBarcodeQuestionTitle">Atualizar o valor do código de barras\?</string>
|
||||
<string name="updateBarcodeQuestionText">Alterou o identificador. Também quer atualizar o código de barras para usar o mesmo valor\?</string>
|
||||
<string name="no">Não</string>
|
||||
@@ -143,12 +140,6 @@
|
||||
<string name="turn_flashlight_off">Desligar lanterna</string>
|
||||
<string name="settings_locale">Idioma</string>
|
||||
<string name="settings_system_locale">Sistema</string>
|
||||
<string name="settings_theme_color">Cor do tema</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_pink_theme">Rosa</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_violet_theme">Violeta</string>
|
||||
<string name="settings_blue_theme">Azul</string>
|
||||
<string name="app_contributors">Tornado possível por: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="sort">Ordenar</string>
|
||||
<string name="sort_by_name">Nome</string>
|
||||
|
||||
@@ -189,15 +189,6 @@
|
||||
<string name="settings_system_locale">Sistema</string>
|
||||
<string name="selectColor">Selecionar cor</string>
|
||||
<string name="setIcon">Definir miniatura</string>
|
||||
<string name="settings_theme_color">Cor do tema</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_pink_theme">Rosa</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_violet_theme">Violeta</string>
|
||||
<string name="settings_blue_theme">Azul</string>
|
||||
<string name="settings_sky_blue_theme">Azul celeste</string>
|
||||
<string name="settings_green_theme">Verde</string>
|
||||
<string name="settings_brown_theme">Marrom</string>
|
||||
<string name="app_contributors">Só foi possível graças a: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="sort">Ordenar</string>
|
||||
<string name="showMoreInfo">Mostrar informações</string>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<string name="note">Notă</string>
|
||||
<string name="storeName">Numele</string>
|
||||
<string name="noMatchingGiftCards">Nu au fost găsite rezultate. Încercați să schimbați termenii de căutare.</string>
|
||||
<string name="noGiftCards">Faceți clic pe butonul + plus pentru a adăuga o carte sau importați mai întâi una din meniul ⋮.</string>
|
||||
<string name="noGiftCards">Faceți clic pe butonul + plus pentru a adăuga o carte sau mai întâi importați una din meniu.</string>
|
||||
<string name="action_add">Adăugați</string>
|
||||
<string name="action_search">Căutare</string>
|
||||
<string name="sendLabel">Trimiteți…</string>
|
||||
@@ -88,7 +88,7 @@
|
||||
<string name="passwordRequired">Vă rugăm, introduceți parola</string>
|
||||
<string name="unsupportedBarcodeType">Acest tip de cod de bare nu poate fi afișat. Este posibil ca acesta să se poată afișa într-o versiune mai nouă a aplicației.</string>
|
||||
<string name="photos">Imagini</string>
|
||||
<string name="noGiftCardsGroup">Adăugați câteva carduri, iar apoi atribuiți-le grupului aici.</string>
|
||||
<string name="noGiftCardsGroup">Creați câteva carduri, iar apoi atribuiți-le grupului de aici.</string>
|
||||
<string name="importCatima">Importați din Catima</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">Aș dori să partajez niște carduri cu tine</string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Drepturi de autor © 2019–<xliff:g>%d</xliff:g> Sylvia van Os și contribuitorii</string>
|
||||
@@ -140,10 +140,8 @@
|
||||
<string name="setBackImage">Setați imaginea din spate</string>
|
||||
<string name="permissionReadCardsDescription">citiți cardurile dumneavoastră Catima și toate detaliile lor, inclusiv notițele și imaginile</string>
|
||||
<string name="anyDate">Orice dată</string>
|
||||
<string name="settings_green_theme">Verde</string>
|
||||
<string name="failedLaunchingPhotoPicker">Nu a putut fi găsită o aplicație galerie suportată</string>
|
||||
<string name="expiryStateSentenceExpired">Expirat: <xliff:g>%s</xliff:g></string>
|
||||
<string name="settings_pink_theme">Roz</string>
|
||||
<string name="source_repository">Repozitor Sursă</string>
|
||||
<string name="groupsList">Grupuri: <xliff:g>%s</xliff:g></string>
|
||||
<string name="enter_card_id">Introduceți numărul de identificare sau textul de pe cardul dumneavoastră</string>
|
||||
@@ -172,7 +170,6 @@
|
||||
<string name="report_error">Raportați o eroare</string>
|
||||
<string name="switchToBackImage">Comutați către imaginea din spate</string>
|
||||
<string name="reverse">...în ordine inversă</string>
|
||||
<string name="settings_brown_theme">Maro</string>
|
||||
<string name="app_contributors">Făcut posibil de: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="app_copyright_short">Drepturi de autor © Sylvia van Os și contribuitorii</string>
|
||||
<string name="settings_oled_dark">Fundal pur negru pentru tema întunecată</string>
|
||||
@@ -180,7 +177,6 @@
|
||||
<string name="field_must_not_be_empty">Câmpul nu poate fi gol</string>
|
||||
<string name="switchToFrontImage">Comutați către imaginea frontală</string>
|
||||
<string name="validFromSentence">Valid de la data de: <xliff:g>%s</xliff:g></string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="previousCard">Precedent</string>
|
||||
<string name="settings_allow_content_provider_read_summary">Aplicațiile vor trebui totuși să solicite permisiunea pentru a primi acces</string>
|
||||
<string name="license">Licență</string>
|
||||
@@ -193,7 +189,6 @@
|
||||
</plurals>
|
||||
<string name="sameAsCardId">Acelașil cu identificatorul</string>
|
||||
<string name="options">Opțiuni</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="failedGeneratingShareURL">Nu s-a putut genera un URL partajabil. Vă rugăm să raportați aceasta eroare.</string>
|
||||
<string name="selectColor">Selectați o culoare</string>
|
||||
<string name="setBarcodeHeight">Setați înălțimea codului de bare</string>
|
||||
@@ -202,13 +197,11 @@
|
||||
<string name="settings_system_locale">Sistem</string>
|
||||
<string name="updateBalance">Actualizați balanța</string>
|
||||
<string name="sort_by_most_recently_used">Cele mai recent utilizate</string>
|
||||
<string name="settings_theme_color">Culoare temă</string>
|
||||
<string name="importVoucherVault">Importați din Voucher Vault</string>
|
||||
<string name="barcodeId">Valoarea codului de bare</string>
|
||||
<string name="settings_locale">Limbă</string>
|
||||
<string name="sort_by_name">Nume</string>
|
||||
<string name="setFrontImage">Setați imaginea din față</string>
|
||||
<string name="settings_sky_blue_theme">Albastru ca cerul</string>
|
||||
<string name="cameraPermissionRequired">Pentru această acțiune este necesară permisiunea de acces la camera …</string>
|
||||
<string name="settings_allow_content_provider_read_title">Permiteți altor aplicații să acceseze datele mele</string>
|
||||
<string name="updateBarcodeQuestionText">Ați schimbat identificatorul. Doriți să actualizați și codul de bare pentru a utiliza aceeași valoare?</string>
|
||||
@@ -231,12 +224,10 @@
|
||||
<string name="failedToRetrieveImageFile">Nu s-a putut recupera fișierul imaginii</string>
|
||||
<string name="donate">Donați</string>
|
||||
<string name="group_name_already_in_use">Acest nume de grup este deja utilizat</string>
|
||||
<string name="settings_violet_theme">Mov</string>
|
||||
<string name="include_if_asking_support">Dacă doriți să cereți ajutor, includeți informațiile următoare:</string>
|
||||
<string name="show_archived_cards">Afișați cardurile arhivate</string>
|
||||
<string name="app_libraries">Listă de biblioteci libere de la terți: <xliff:g id="app_libraries_list">%s</xliff:g></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">Listă de resurse gratuite de la terți: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_name">Catima</string>
|
||||
<string name="shortcutSelectCard">Selectați un card</string>
|
||||
|
||||
@@ -152,15 +152,6 @@
|
||||
</plurals>
|
||||
<string name="settings_system_locale">Системный</string>
|
||||
<string name="settings_locale">Язык</string>
|
||||
<string name="settings_sky_blue_theme">Голубой</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_brown_theme">Коричневый</string>
|
||||
<string name="settings_green_theme">Зелёный</string>
|
||||
<string name="settings_blue_theme">Синий</string>
|
||||
<string name="settings_violet_theme">Фиолетовый</string>
|
||||
<string name="settings_magenta_theme">Пурпурный</string>
|
||||
<string name="settings_pink_theme">Розовый</string>
|
||||
<string name="settings_theme_color">Цвет темы</string>
|
||||
<string name="app_contributors">Создано при поддержке: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="noGroupCards">Группа пуста</string>
|
||||
<string name="barcodeImageDescriptionWithType">Изображение штрих-кода <xliff:g>%s</xliff:g></string>
|
||||
@@ -317,4 +308,7 @@
|
||||
<string name="acra_crash_email_subject">Отчёт об ошибке в <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="pref_enable_acra">Запрашивать отправку отчётов об ошибках</string>
|
||||
<string name="pref_enable_acra_summary">Если включено, то в случае сбоя вам будет предложено отправить отчёт о нём. Отчёты никогда не отправляются автоматически.</string>
|
||||
<string name="copy_value">Скопировать значение</string>
|
||||
<string name="copied_to_clipboard">Скопировано в буфер обмена</string>
|
||||
<string name="nothing_to_copy">Значение не найдено</string>
|
||||
</resources>
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
<string name="cardShortcut">Skratka karty</string>
|
||||
<string name="noCardsMessage">Najprv pridajte kartu</string>
|
||||
<string name="noCardExistsError">Nepodarilo sa nájsť túto kartu</string>
|
||||
<string name="importExport">Import/Export</string>
|
||||
<string name="importExport">Import/export</string>
|
||||
<string name="exportName">Export</string>
|
||||
<string name="importExportHelp">Zálohovanie vašich údajov umožňuje ich presun na iné zariadenie.</string>
|
||||
<string name="importExportHelp">Zálohovanie vašich údajov umožňuje ich presun na iné zariadenie</string>
|
||||
<string name="importSuccessfulTitle">Úspešne importované</string>
|
||||
<string name="importFailedTitle">Import zlyhal</string>
|
||||
<string name="importFailed">Nemožno vykonať import</string>
|
||||
@@ -30,7 +30,7 @@
|
||||
<string name="importing">Importujem…</string>
|
||||
<string name="exporting">Exportujem…</string>
|
||||
<string name="importOptionFilesystemTitle">Import zo súborového systému</string>
|
||||
<string name="importOptionFilesystemExplanation">Vyberte súbor zo súborového systému.</string>
|
||||
<string name="importOptionFilesystemExplanation">Vyberte uložený súbor</string>
|
||||
<string name="importOptionFilesystemButton">Zo súborového systému</string>
|
||||
<string name="about">O aplikácii</string>
|
||||
<string name="app_license">Slobodný softvér s copyleft licenciou GPLv3+</string>
|
||||
@@ -62,11 +62,11 @@
|
||||
<string name="leaveWithoutSaveTitle">Ukončiť</string>
|
||||
<string name="moveDown">Pohyb smerom nadol</string>
|
||||
<string name="moveUp">Pohyb smerom nahor</string>
|
||||
<string name="failedOpeningFileManager">Najprv nainštalujte správcu súborov.</string>
|
||||
<string name="failedOpeningFileManager">Nepodarilo sa otvoriť správcu súborov</string>
|
||||
<string name="deleteConfirmationGroup">Vymazať skupinu\?</string>
|
||||
<string name="all">Všetky</string>
|
||||
<string name="noGroupCards">Táto skupina je prázdna</string>
|
||||
<string name="noGroups">Kliknutím na tlačidlo + plus pridáte skupiny na kategorizáciu.</string>
|
||||
<string name="noGroups">Kliknutím na tlačidlo + (plus) pridáte skupiny na kategorizáciu</string>
|
||||
<string name="groups">Skupiny</string>
|
||||
<string name="enter_group_name">Zadajte názov skupiny</string>
|
||||
<string name="exportSuccessful">Údaje exportované</string>
|
||||
@@ -80,7 +80,7 @@
|
||||
<string name="settings_system_theme">Podľa nastavení systému</string>
|
||||
<string name="settings_theme">Téma</string>
|
||||
<string name="starImage">Obľúbená hviezda</string>
|
||||
<string name="exportOptionExplanation">Údaje sa zapíšu na vami zvolené miesto.</string>
|
||||
<string name="exportOptionExplanation">Údaje budú uložené na vami zvolené miesto</string>
|
||||
<string name="failedParsingImportUriError">Nepodarilo sa analyzovať import URI</string>
|
||||
<string name="share">Zdieľať</string>
|
||||
<string name="barcodeImageDescriptionWithType">Obrázok čiarového kódu <xliff:g>%s</xliff:g></string>
|
||||
@@ -114,11 +114,9 @@
|
||||
<string name="expiryStateSentenceExpired">Platnosť vypršala: <xliff:g>%s</xliff:g></string>
|
||||
<string name="balanceSentence">Zostatok: <xliff:g>%s</xliff:g></string>
|
||||
<string name="importCatima">Import z aplikácie Catima</string>
|
||||
<string name="settings_theme_color">Farba témy</string>
|
||||
<string name="app_libraries">Slobodné knižnice tretích strán: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources">Slobodné zdroje tretích strán: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="importCatimaMessage">Vyberte svoj <i>catima.zip</i> export z aplikácie Catima, ktorý chcete importovať.
|
||||
\nVytvorte ho z ponuky Import/Export inej aplikácie Catima tak, že stlačíte tlačidlo Exportovať.</string>
|
||||
<string name="app_libraries">Knižnice tretích strán: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources">Zdroje tretích strán: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="importCatimaMessage">Vyberte svoj export z aplikácie Catima, ktorý chcete importovať. \nVytvorte ho z ponuky Import/export inej aplikácie Catima tak, že stlačíte tlačidlo Exportovať.</string>
|
||||
<string name="accept">Prijať</string>
|
||||
<string name="importLoyaltyCardKeychain">Import z aplikácie Loyalty Card Keychain</string>
|
||||
<string name="importFidme">Import z aplikácie FidMe</string>
|
||||
@@ -138,14 +136,6 @@
|
||||
<string name="yes">Áno</string>
|
||||
<string name="selectColor">Vybrať farbu</string>
|
||||
<string name="setIcon">Nastavenie miniatúry</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_pink_theme">Ružová</string>
|
||||
<string name="settings_magenta_theme">Purpurová</string>
|
||||
<string name="settings_violet_theme">Fialová</string>
|
||||
<string name="settings_blue_theme">Modrá</string>
|
||||
<string name="settings_sky_blue_theme">Azurová</string>
|
||||
<string name="settings_green_theme">Zelená</string>
|
||||
<string name="settings_brown_theme">Hnedá</string>
|
||||
<string name="sort">Zoradiť</string>
|
||||
<string name="help_translate_this_app">Pomôžte preložiť túto aplikáciu</string>
|
||||
<string name="license">Licencia</string>
|
||||
@@ -154,7 +144,7 @@
|
||||
<string name="rate_this_app">Ohodnoťte túto aplikáciu</string>
|
||||
<string name="exportPassword">Nastavte heslo na ochranu exportu (voliteľné)</string>
|
||||
<string name="exportPasswordHint">Zadajte heslo</string>
|
||||
<string name="failedGeneratingShareURL">Nepodarilo sa vygenerovať zdieľateľnú adresu URL. Nahláste to, prosím.</string>
|
||||
<string name="failedGeneratingShareURL">Nepodarilo sa vygenerovať zdieľateľnú adresu URL</string>
|
||||
<string name="turn_flashlight_off">Vypnúť svetlo</string>
|
||||
<string name="settings_locale">Jazyk</string>
|
||||
<string name="settings_system_locale">Systém</string>
|
||||
@@ -179,7 +169,7 @@
|
||||
<string name="updateBarcodeQuestionTitle">Aktualizovať hodnotu čiarového kódu\?</string>
|
||||
<string name="updateBarcodeQuestionText">Zmenili ste ID. Chcete aktualizovať aj čiarový kód, aby používal rovnakú hodnotu\?</string>
|
||||
<string name="no">Nie</string>
|
||||
<string name="passwordRequired">Zadajte prosím heslo</string>
|
||||
<string name="passwordRequired">Zadajte heslo</string>
|
||||
<string name="noGiftCardsGroup">Zatiaľ nemáte žiadne vernostné karty. Keď nejaké pridáte, môžete ich priradiť ku skupine tu</string>
|
||||
<string name="noCameraPermissionDirectToSystemSetting">Na skenovanie čiarových kódov potrebuje Catima prístup k fotoaparátu. Ťuknite sem a zmeňte nastavenia oprávnení.</string>
|
||||
<string name="importCards">Importovať karty</string>
|
||||
@@ -211,10 +201,8 @@
|
||||
<string name="chooseValidFromDate">Zvoliť dátum platné od</string>
|
||||
<string name="validFromSentence">Platnosť od: <xliff:g>%s</xliff:g></string>
|
||||
<string name="cameraPermissionRequired">Pre túto akciu je potrebné oprávnenie na prístup k fotoaparátu…</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Vyberte svoj export <i>LoyaltyCardKeychain.csv</i> z Kľúčenky vernostných kariet, ktorý chcete importovať.
|
||||
\nVytvorte ho z ponuky Import/Export v aplikácii Loyalty Card Keychain tak, že tam najprv stlačíte tlačidlo Exportovať.</string>
|
||||
<string name="importVoucherVaultMessage">Vyberte svoj <i>vouchervault.json</i> export z Trezoru poukážok pre import.
|
||||
\nNajprv ho vytvorte stlačením tlačidla Export v aplikácii Voucher Vault.</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Vyberte svoj export z aplikácie Loyalty Card Keychain, ktorý chcete importovať. \nVytvorte ho z ponuky Import/Export v aplikácii Loyalty Card Keychain tak, že tam stlačíte tlačidlo Exportovať.</string>
|
||||
<string name="importVoucherVaultMessage">Vyberte svoj export z aplikácie Voucher Vault pre import.\nNajprv ho vytvorte stlačením tlačidla Export v aplikácii Voucher Vault.</string>
|
||||
<string name="shortcutSelectCard">Vybrať kartu</string>
|
||||
<string name="include_if_asking_support">Ak chcete požiadať o podporu, uveďte nasledujúce informácie:</string>
|
||||
<plurals name="groupCardCountWithArchived">
|
||||
@@ -225,13 +213,12 @@
|
||||
<string name="barcodeLongPressMessage">V aplikácii galéria je možné otvoriť iba obrázky</string>
|
||||
<string name="cameraPermissionDeniedTitle">Nepodarilo sa získať prístup k fotoaparátu</string>
|
||||
<string name="storageReadPermissionRequired">Pre túto akciu je potrebné oprávnenie na čítanie úložiska…</string>
|
||||
<string name="importFidmeMessage">Vyberte svoj <i>fidme-export-request-xxxxxx.zip</i> export zo služby FidMe pre import a potom vyberte typy čiarových kódov ručne.
|
||||
\nVytvorte ho z profilu FidMe tak, že najprv vyberiete položku Ochrana údajov a potom stlačíte tlačidlo Extrahovať moje údaje.</string>
|
||||
<string name="importFidmeMessage">Vyberte svoj export zo služby FidMe pre import a potom vyberte typy čiarových kódov ručne.\nVytvorte ho z profilu FidMe tak, že vyberiete položku Ochrana údajov a potom stlačíte tlačidlo Extrahovať moje údaje.</string>
|
||||
<string name="currentBalanceSentence">Aktuálny zostatok: <xliff:g>%s</xliff:g></string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">Chcem sa s vami zdielať karty</string>
|
||||
<string name="app_contributors">Podporili: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="newBalanceSentence">Nový zostatok: <xliff:g>%s</xliff:g></string>
|
||||
<string name="failedLaunchingPhotoPicker">Nepodarilo sa nájsť podporovanú aplikáciu galérie</string>
|
||||
<string name="failedLaunchingPhotoPicker">Nepodarilo sa nájsť podporovanú aplikáciu pre výber obrázkov</string>
|
||||
<string name="show_note">Zobraziť poznámku</string>
|
||||
<string name="icon_header_click_text">Dlhým stlačením upravíte miniatúru</string>
|
||||
<string name="settings_category_title_general">Všeobecné</string>
|
||||
@@ -239,13 +226,13 @@
|
||||
<string name="settings_keep_screen_on_summary">Ponechať obrazovku aktívnu počas prezerania karty</string>
|
||||
<string name="settings_display_barcode_max_brightness_summary">Pre zaistenie čitateľnosti pre niektoré skenery</string>
|
||||
<string name="settings_allow_content_provider_read_summary">Aplikácie budú musieť stále žiadať o povolenie, aby im bol udelený prístup</string>
|
||||
<string name="openBackImageInGalleryApp">Otvorenie zadného obrázka v aplikácii galéria</string>
|
||||
<string name="openFrontImageInGalleryApp">Otvorenie predného obrázka v aplikácii galéria</string>
|
||||
<string name="openBackImageInGalleryApp">Otvorenie zadného obrázka v prehliadači obrázkov</string>
|
||||
<string name="openFrontImageInGalleryApp">Otvorenie predného obrázka v prehliadači obrázkov</string>
|
||||
<string name="setBarcodeHeight">Nastavenie výšky čiarového kódu</string>
|
||||
<string name="show_balance">Ukážte zostatok</string>
|
||||
<string name="show_name_below_image_thumbnail">Zobraziť názov pod miniatúrou obrázka</string>
|
||||
<string name="show_validity">Zobraziť platnosť</string>
|
||||
<string name="permissionReadCardsLabel">Načítať Catima karty</string>
|
||||
<string name="permissionReadCardsLabel">Čítanie kariet Catima</string>
|
||||
<string name="permissionReadCardsDescription">čítať svoje Catima karty a všetky jeho podrobnosti, vrátane poznámky a obrázkov</string>
|
||||
<string name="switchToBackImage">Prepnutie na zadný obrázok</string>
|
||||
<string name="height">Výška</string>
|
||||
@@ -275,7 +262,7 @@
|
||||
<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 sa hodnota čiarového kódu líši od čísla uvedeného na karte. Z tohto dôvodu nemusí manuálne zadanie čiarového kódu vždy fungovať. Dôrazne odporúčame naskenovať čiarový kód pomocou fotoaparátu. Chcete napriek tomu pokračovať?</string>
|
||||
<string name="add_manually_warning_message">Pri niektorých kartách sa hodnota čiarového kódu líši od čísla uvedeného na karte. Z tohto dôvodu nemusí manuálne zadanie čiarového kódu vždy fungovať. Odporúčame naskenovať čiarový kód pomocou fotoaparátu. Chcete napriek tomu pokračovať?</string>
|
||||
<string name="addFromPdfFile">Vyberte súbor PDF</string>
|
||||
<string name="errorReadingFile">Súbor sa nepodarilo prečítať</string>
|
||||
<string name="failedLaunchingFileManager">Nepodarilo sa nájsť podporovaného správcu súborov</string>
|
||||
@@ -286,7 +273,7 @@
|
||||
<string name="exportCancelled">Export zrušený</string>
|
||||
<string name="useFrontImage">Použiť obrázok prednej strany</string>
|
||||
<string name="useBackImage">Použiť obrázok zadnej strany</string>
|
||||
<string name="generic_error_please_retry">Prepáčte, niečo sa pokazilo, skúste to znova...</string>
|
||||
<string name="generic_error_please_retry">Niečo sa pokazilo</string>
|
||||
<string name="settings_category_title_cards_overview">Prehľad kariet</string>
|
||||
<string name="width">Šírka</string>
|
||||
<string name="setBarcodeWidth">Nastaviť šírku čiarového kódu</string>
|
||||
@@ -308,5 +295,14 @@
|
||||
<string name="card_list_widget_name">Zoznam kariet</string>
|
||||
<string name="card_list_widget_empty">Po pridaní vernostných kariet do Catima sa zobrazia tu. Ak máte karty, uistite sa, že nie sú všetky archivované.</string>
|
||||
<string name="cardWithNumber">Karta <xliff:g>%d</xliff:g></string>
|
||||
<string name="cardWithNumberAndLocale">Karta <xliff:g>%d</xliff:g> (%s)</string>
|
||||
<string name="cardWithNumberAndLocale">Karta <xliff:g>%d</xliff:g> (<xliff:g>%s</xliff:g>)</string>
|
||||
<string name="pleaseDoNotRotateTheDevice">Neotáčajte zariadenie, inak akciu prerušíte</string>
|
||||
<string name="acra_catima_has_crashed">Ospravedlňujeme sa, aplikácia <xliff:g id="app_name">%s</xliff:g> spadla. Pomôžte nám tento problém opraviť zaslaním hlásenia o chybe.</string>
|
||||
<string name="acra_explain_crash">Ak je to možné, uveďte viac podrobností o tom, čo ste práve robili:</string>
|
||||
<string name="acra_crash_email_subject">Hlásenie o páde aplikácie <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="pref_enable_acra">Poskytovať možnosť zasielať hlásenia o chybách</string>
|
||||
<string name="pref_enable_acra_summary">Keď túto možnosť zapnete, pri páde aplikácie vás požiadame o zaslanie hlásenia o chybe. Tie sa nikdy nezasielajú automaticky.</string>
|
||||
<string name="copy_value">Kopírovať hodnotu</string>
|
||||
<string name="copied_to_clipboard">Skopírované do schránky</string>
|
||||
<string name="nothing_to_copy">Nenašla sa žiadna hodnota</string>
|
||||
</resources>
|
||||
|
||||
@@ -80,14 +80,6 @@
|
||||
<string name="exportPassword">Izberi geslo za zaščito izvoza (neobvezno)</string>
|
||||
<string name="help_translate_this_app">Pomagaj pri prevajanju aplikacije</string>
|
||||
<string name="version_history">Zgodovina različic</string>
|
||||
<string name="settings_brown_theme">Rjava</string>
|
||||
<string name="settings_green_theme">Zelena</string>
|
||||
<string name="settings_sky_blue_theme">Sinje modra</string>
|
||||
<string name="settings_blue_theme">Modra</string>
|
||||
<string name="settings_violet_theme">Vijolična</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_pink_theme">Roza</string>
|
||||
<string name="settings_theme_color">Barva teme</string>
|
||||
<string name="settings_system_locale">Sistem</string>
|
||||
<string name="settings_locale">Jezik</string>
|
||||
<string name="barcodeImageDescriptionWithType">Slika <xliff:g>%s</xliff:g> črtna koda</string>
|
||||
@@ -218,7 +210,6 @@
|
||||
<string name="failedGeneratingShareURL">URL-ja za skupno rabo ni bilo mogoče ustvariti</string>
|
||||
<string name="settings_oled_dark">Čisto črno ozadje za temno temo</string>
|
||||
<string name="selectColor">Izberi barvo</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="app_contributors">Omogočeno od: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="barcodeLongPressMessage">V aplikaciji za gledanje slik lahko odpremo samo slike</string>
|
||||
<plurals name="groupCardCountWithArchived">
|
||||
@@ -316,4 +307,7 @@
|
||||
<string name="acra_crash_email_subject">Poročilo o sesutju aplikacije <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="pref_enable_acra">Prosi za pošiljanje poročila o sesutju</string>
|
||||
<string name="pref_enable_acra_summary">Ko je ta možnost omogočena, boš ob pojavu sesutja pozvan, da prijaviš napako. Poročilo o sesutju se nikoli ne pošilja samodejno.</string>
|
||||
<string name="copy_value">Kopiraj vrednost</string>
|
||||
<string name="copied_to_clipboard">Kopirano v odložišče</string>
|
||||
<string name="nothing_to_copy">Nobena vrednost ni najdena</string>
|
||||
</resources>
|
||||
|
||||
@@ -128,12 +128,6 @@
|
||||
<string name="settings_system_locale">Sistem</string>
|
||||
<string name="selectColor">Odaberi boju</string>
|
||||
<string name="setIcon">Odaberi naslovnu fotografiju</string>
|
||||
<string name="settings_theme_color">Boja teme</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_pink_theme">Roze</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_violet_theme">Ljubičasta</string>
|
||||
<string name="settings_brown_theme">Braon</string>
|
||||
<string name="sort">Sortiranje</string>
|
||||
<string name="showMoreInfo">Prikaži informacije</string>
|
||||
<string name="updateBalance">Ažuriraj stanje</string>
|
||||
@@ -249,10 +243,7 @@
|
||||
<string name="updateBarcodeQuestionText">Promenio si broj kartice. Da li želiš da ažuriraš i bar-kod da bude iste vrednosti?</string>
|
||||
<string name="no">Ne</string>
|
||||
<string name="app_contributors">Saradnici: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="settings_sky_blue_theme">Nebo plava</string>
|
||||
<string name="settings_green_theme">Zelena</string>
|
||||
<string name="barcodeLongPressMessage">Samo fotografije mogu da se otvore u galerija aplikaciji</string>
|
||||
<string name="settings_blue_theme">Plava</string>
|
||||
<string name="translate_platform">na Weblate-u</string>
|
||||
<plurals name="groupCardCountWithArchived">
|
||||
<item quantity="one"><xliff:g>%1$d</xliff:g> kartica (<xliff:g id="archivedCount">%2$d</xliff:g> arhivirana)</item>
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> valt</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> valda</item>
|
||||
</plurals>
|
||||
<string name="app_loyalty_card_keychain">Nyckelring för bonuskort</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Välj den exporterade från Loyalty Card Keychain som du vill importera.\nSkapa den från Import/Export-menyn i Loyalty Card Keychain genom att trycka på Exportera.</string>
|
||||
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Välj det exporterade från Loyalty Card Keychain som du vill importera.\nSkapa det från Import/Export-menyn i Loyalty Card Keychain genom att trycka på Exportera.</string>
|
||||
<string name="importVoucherVaultMessage">Välj den exporterade från Voucher Vault som du vill importera. \nSkapa den genom att trycka på Exportera i Voucher Vault.</string>
|
||||
<string name="enter_group_name">Ange gruppnamn</string>
|
||||
<string name="groups">Grupper</string>
|
||||
@@ -24,7 +24,7 @@
|
||||
</plurals>
|
||||
<string name="all">Alla</string>
|
||||
<string name="deleteConfirmationGroup">Ta bort grupp\?</string>
|
||||
<string name="failedOpeningFileManager">Installera en filhanterare först.</string>
|
||||
<string name="failedOpeningFileManager">Kunde ej öppna en filhanterare</string>
|
||||
<string name="moveUp">Flytta uppåt</string>
|
||||
<string name="moveDown">Flytta nedåt</string>
|
||||
<string name="leaveWithoutSaveTitle">Avsluta</string>
|
||||
@@ -144,15 +144,6 @@
|
||||
<string name="settings_system_locale">System</string>
|
||||
<string name="settings_locale">Språk</string>
|
||||
<string name="app_contributors">Möjliggjordes av: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="settings_brown_theme">Brunt</string>
|
||||
<string name="settings_green_theme">Grönt</string>
|
||||
<string name="settings_sky_blue_theme">Himmelblått</string>
|
||||
<string name="settings_blue_theme">Blått</string>
|
||||
<string name="settings_violet_theme">Violett</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_pink_theme">Rosa</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_theme_color">Temafärg</string>
|
||||
<string name="noGroupCards">Denna grupp är tom</string>
|
||||
<string name="barcodeImageDescriptionWithType">Bild <xliff:g>%s</xliff:g> streckkod</string>
|
||||
<string name="reverse">...i omvänd ordning</string>
|
||||
@@ -192,7 +183,7 @@
|
||||
</plurals>
|
||||
<string name="include_if_asking_support">Om du vill be om hjälp, inkludera då följande information:</string>
|
||||
<string name="settings_oled_dark">Helsvart bakgrund för mörkt tema</string>
|
||||
<string name="failedLaunchingPhotoPicker">Kunde inte hitta kompatibelt bildprogram</string>
|
||||
<string name="failedLaunchingPhotoPicker">Kunde ej hitta kompatibel bildväljare</string>
|
||||
<string name="unarchive">Ta tillbaks från arkiv</string>
|
||||
<string name="archived">Kort arkiverat</string>
|
||||
<string name="duplicateCard">Kopiera</string>
|
||||
@@ -215,14 +206,14 @@
|
||||
<string name="storageReadPermissionRequired">Tillstånd att läsa lagring behövs för denna åtgärd…</string>
|
||||
<string name="currentBalanceSentence">Nuvarande balans: <xliff:g>%s</xliff:g></string>
|
||||
<string name="validFromDate">Giltig från</string>
|
||||
<string name="cameraPermissionRequired">Tillstånd att komma åt kameran krävs för denna åtgärd…</string>
|
||||
<string name="cameraPermissionRequired">Behörighet att komma åt kameran krävs för denna åtgärd…</string>
|
||||
<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="barcodeLongPressMessage">Endast bilder kan öppnas i galleriappen</string>
|
||||
<string name="updateBalanceTitle">Hur mycket spenderade du eller fick 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>
|
||||
<string name="openFrontImageInGalleryApp">Öppna bilden på framsidan i bildvisningsappen</string>
|
||||
<string name="show_name_below_image_thumbnail">Visa namnet nedanför bildens miniatyr</string>
|
||||
<string name="show_validity">Visa giltighet</string>
|
||||
<string name="view_online">Visa på internet</string>
|
||||
@@ -230,7 +221,7 @@
|
||||
<string name="settings_category_title_general">Generellt</string>
|
||||
<string name="switchToBarcode">Byt till streckkod</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card_summary">Stänger av skärmlåset medans kort visas</string>
|
||||
<string name="permissionReadCardsDescription">Se dina kort med alla dess detaljer, inklusive anteckningar och bilder</string>
|
||||
<string name="permissionReadCardsDescription">läsa dina Catima-kort med alla dess detaljer, inklusive anteckningar och bilder</string>
|
||||
<string name="action_display_options">Visningsalternativ</string>
|
||||
<string name="settings_display_barcode_max_brightness_summary">Nödvändigt för att en del skannrar ska fungera</string>
|
||||
<string name="settings_oled_dark_summary">Reducerar batterianvändning på OLED-skärmar</string>
|
||||
@@ -242,10 +233,10 @@
|
||||
<string name="switchToFrontImage">Byt till bilden på framsidan</string>
|
||||
<string name="settings_allow_content_provider_read_summary">Appar måste fortfarande begära åtkomst för att få tillgång</string>
|
||||
<string name="setBarcodeHeight">Ställ in streckkodens höjd</string>
|
||||
<string name="openBackImageInGalleryApp">Öppna bilden på baksidan i galleri-appen</string>
|
||||
<string name="openBackImageInGalleryApp">Öppna bilden på baksidan i bildvisningsappen</string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Kopieringsskydd © 2019–<xliff:g>%d</xliff:g> Sylvia van Os och medverkande</string>
|
||||
<string name="settings_allow_content_provider_read_title">Tillåt andra appar att komma åt min data</string>
|
||||
<string name="permissionReadCardsLabel">Läs Catima-kort</string>
|
||||
<string name="permissionReadCardsLabel">Läsa Catima-kort</string>
|
||||
<string name="donate">Donera</string>
|
||||
<string name="show_archived_cards">Visa arkiverade kort</string>
|
||||
<string name="settings_category_title_privacy">Sekretess</string>
|
||||
@@ -296,4 +287,16 @@
|
||||
<string name="generic_error_please_retry">Ett fel uppstod</string>
|
||||
<string name="cardWithNumber">Kort <xliff:g>%d</xliff:g></string>
|
||||
<string name="cardWithNumberAndLocale">Kort <xliff:g>%d</xliff:g> (<xliff:g>%s</xliff:g>)</string>
|
||||
<string name="setBarcodeWidth">Ange streckkodsbredd</string>
|
||||
<string name="card_list_widget_empty">Bonuskort som du lägger till i Catima kommer att dyka upp här. Om du redan har kort, kontrollera att de alla inte är arkiverade.</string>
|
||||
<string name="add_manually_warning_message">För vissa kort skiljer sig streckkodsvärdet från numret som är skrivet på kortet. På grund av detta kan det ibland ej vara möjligt att ange en streckkod manuellt. Det rekommenderas att istället skanna streckkoden med din kamera. Vill du ändå fortsätta?</string>
|
||||
<string name="pleaseDoNotRotateTheDevice">Var vänlig rotera ej enheten, då detta kommer att avbryta åtgärden</string>
|
||||
<string name="acra_catima_has_crashed">Vi beklagar, men <xliff:g id="app_name">%s</xliff:g> har kraschat. Vänligen hjälp oss att lösa detta problem genom att skicka en felrapport till oss.</string>
|
||||
<string name="acra_crash_email_subject">Kraschrapport för <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="pref_enable_acra">Be om att skicka kraschrapporter</string>
|
||||
<string name="pref_enable_acra_summary">När det är aktiverat kommer du att bli ombedd att rapportera en krasch när den inträffar. Kraschrapporter skickas aldrig automatiskt.</string>
|
||||
<string name="acra_explain_crash">Om möjligt, var vänlig lägg till fler detaljer om vad du höll på med här:</string>
|
||||
<string name="copy_value">Kopiera värde</string>
|
||||
<string name="copied_to_clipboard">Kopierade till urklipp</string>
|
||||
<string name="nothing_to_copy">Inget värde hittades</string>
|
||||
</resources>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> தேர்ந்தெடுக்கப்பட்டது</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> தேர்ந்தெடுக்கப்பட்டன</item>
|
||||
</plurals>
|
||||
<string name="noGiftCards">ஒரு அட்டையைச் சேர்க்க + பிளச் பொத்தானைக் சொடுக்கு செய்க அல்லது ⋮ மெனுவிலிருந்து இறக்குமதி செய்யுங்கள்.</string>
|
||||
<string name="noGiftCards">ஒரு அட்டையைச் சேர்க்க + சேர் பொத்தானைக் சொடுக்கு செய்க அல்லது ⋮ பட்டியலிருந்து இறக்குமதி செய்</string>
|
||||
<string name="noGiftCardsGroup">சில அட்டைகளை உருவாக்கி, பின்னர் அவற்றை இங்கே குழுவிற்கு ஒதுக்குங்கள்.</string>
|
||||
<string name="storeName">பெயர்</string>
|
||||
<string name="note">குறிப்பு</string>
|
||||
@@ -22,11 +22,11 @@
|
||||
<string name="share">பங்கு</string>
|
||||
<string name="sendLabel">அனுப்பு…</string>
|
||||
<string name="editCardTitle">அட்டையைத் திருத்து</string>
|
||||
<string name="addCardTitle">அட்டை சேர்க்கவும்</string>
|
||||
<string name="scanCardBarcode">ச்கேன் பார்கோடு</string>
|
||||
<string name="addCardTitle">அட்டை சேர்</string>
|
||||
<string name="scanCardBarcode">பட்டைகோடு வருடு</string>
|
||||
<string name="cardShortcut">அட்டை குறுக்குவழி</string>
|
||||
<string name="noCardExistsError">அந்த அட்டையை கண்டுபிடிக்க முடியவில்லை</string>
|
||||
<string name="failedParsingImportUriError">இறக்குமதி யூரியை அலச முடியவில்லை</string>
|
||||
<string name="noCardExistsError">அந்த அட்டையைக் கண்டுபிடிக்க முடியவில்லை</string>
|
||||
<string name="failedParsingImportUriError">இறக்குமதி முகவரியை அலச முடியவில்லை</string>
|
||||
<string name="importExport">இறக்குமதி/ஏற்றுமதி</string>
|
||||
<string name="exportName">ஏற்றுமதி</string>
|
||||
<string name="importFailedTitle">இறக்குமதி தோல்வியடைந்தது</string>
|
||||
@@ -49,7 +49,7 @@
|
||||
<string name="group_updated">குழு புதுப்பிக்கப்பட்டது</string>
|
||||
<string name="all">அனைத்தும்</string>
|
||||
<string name="deleteConfirmationGroup">குழுவை நீக்கவா?</string>
|
||||
<string name="failedOpeningFileManager">முதலில் கோப்பு மேலாளரை நிறுவவும்.</string>
|
||||
<string name="failedOpeningFileManager">கோப்பு மேலாளரைத் திறக்கமுடியவில்லை</string>
|
||||
<string name="leaveWithoutSaveTitle">வெளியேறு</string>
|
||||
<string name="leaveWithoutSaveConfirmation">சேமிக்காமல் விடலாமா?</string>
|
||||
<string name="addManually">பார்கோடு கைமுறையாக உள்ளிடவும்</string>
|
||||
@@ -70,8 +70,6 @@
|
||||
<string name="settings_system_locale">மண்டலம்</string>
|
||||
<string name="selectColor">வண்ணத்தைத் தேர்ந்தெடுக்கவும்</string>
|
||||
<string name="setIcon">சிறு உருவத்தை அமைக்கவும்</string>
|
||||
<string name="settings_blue_theme">நீலம்</string>
|
||||
<string name="settings_green_theme">பச்சை</string>
|
||||
<string name="sort">வரிசைப்படுத்து</string>
|
||||
<string name="showMoreInfo">தகவலைக் காட்டு</string>
|
||||
<string name="nextCard">அடுத்தது</string>
|
||||
@@ -89,21 +87,21 @@
|
||||
<string name="cancel">ரத்துசெய்</string>
|
||||
<string name="save">சேமி</string>
|
||||
<string name="noCardsMessage">முதலில் ஒரு அட்டையைச் சேர்க்கவும்</string>
|
||||
<string name="importExportHelp">உங்கள் தரவை காப்புப் பிரதி எடுப்பது அதை மற்றொரு சாதனத்திற்கு நகர்த்த அனுமதிக்கிறது.</string>
|
||||
<string name="importExportHelp">உங்கள் தரவைக் காப்புப் பிரதி எடுப்பது அதை மற்றொரு சாதனத்திற்கு நகர்த்த இசைகிறது</string>
|
||||
<string name="importSuccessfulTitle">இறக்குமதி செய்யப்பட்டது</string>
|
||||
<string name="permissionReadCardsLabel">கேட்டிமா அட்டைகளைப் படி</string>
|
||||
<string name="permissionReadCardsLabel">பூனையம்மா அட்டைகளைப் படி</string>
|
||||
<string name="permissionReadCardsDescription">உங்கள் கேட்டிமா அட்டைகள் மற்றும் குறிப்புகள் மற்றும் படங்கள் உட்பட அதன் அனைத்து விவரங்களையும் படி</string>
|
||||
<string name="exportOptionExplanation">தரவு உங்கள் விருப்பப்படி இடத்திற்கு எழுதப்படும்.</string>
|
||||
<string name="exportOptionExplanation">தரவு உங்கள் விருப்பப்படி இடத்திற்கு எழுதப்படும்</string>
|
||||
<string name="importOptionFilesystemTitle">கோப்பு முறைமையிலிருந்து இறக்குமதி</string>
|
||||
<string name="importOptionFilesystemExplanation">கோப்பு முறைமையிலிருந்து ஒரு குறிப்பிட்ட கோப்பைத் தேர்வுசெய்க.</string>
|
||||
<string name="importOptionFilesystemExplanation">கோப்பு முறைமையிலிருந்து ஒரு குறிப்பிட்ட கோப்பைத் தேர்வுசெய்க</string>
|
||||
<string name="importOptionFilesystemButton">கோப்பு முறைமையிலிருந்து</string>
|
||||
<string name="cameraPermissionDeniedTitle">கேமராவை அணுக முடியவில்லை</string>
|
||||
<string name="cameraPermissionDeniedTitle">கேமராவை இயக்க முடியவில்லை</string>
|
||||
<string name="noCameraPermissionDirectToSystemSetting">பார்கோடுகளை ஸ்கேன் செய்ய, கேட்டிமாவிற்கு உங்கள் கேமராவுக்கு அணுகல் தேவைப்படும். உங்கள் இசைவு அமைப்புகளை மாற்ற இங்கே தட்டவும்.</string>
|
||||
<string name="about">பற்றி</string>
|
||||
<string name="app_copyright_short">பதிப்புரிமை © சில்வியா வான் ஓஎச் மற்றும் பங்களிப்பாளர்கள்</string>
|
||||
<string name="app_copyright_old">விசுவாச அட்டை கீச்சின் அடிப்படையில்\n பதிப்புரிமை © 2016–2020 பிராண்டன் ஆர்ச்சர்</string>
|
||||
<string name="app_license">நகலெடுக்கப்பட்ட லிப்ரே மென்பொருள், உரிமம் பெற்ற GPLV3+</string>
|
||||
<string name="selectBarcodeTitle">பார்கோடு தேர்ந்தெடுக்கவும்</string>
|
||||
<string name="selectBarcodeTitle">பட்டைகோடு தேர்ந்தெடு</string>
|
||||
<string name="thumbnailDescription">சிறுபடம்</string>
|
||||
<string name="starImage">பிடித்த விண்மீன்</string>
|
||||
<string name="settings">அமைப்புகள்</string>
|
||||
@@ -120,7 +118,7 @@
|
||||
<string name="settings_allow_content_provider_read_summary">பயன்பாடுகள் இன்னும் அணுகல் வழங்க இசைவு கோர வேண்டும்</string>
|
||||
<string name="settings_use_volume_keys_navigation">தொகுதி பொத்தான்களைப் பயன்படுத்தி அட்டைகளை மாற்றவும்</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card_summary">அட்டையைப் பார்க்கும்போது திரை லாக் முடக்குகிறது</string>
|
||||
<string name="noGroups">வகைப்படுத்தலுக்கான குழுக்களைச் சேர்க்க + பிளச் பொத்தானைக் சொடுக்கு செய்க.</string>
|
||||
<string name="noGroups">வகைப்படுத்தலுக்கான குழுக்களைச் சேர்க்க + சேர் பொத்தானைக் சொடுக்குக</string>
|
||||
<string name="settings_use_volume_keys_navigation_summary">எந்த அட்டை காட்டப்படும் என்பதை மாற்ற தொகுதி பொத்தான்களைப் பயன்படுத்தவும்</string>
|
||||
<string name="noGroupCards">இந்த குழு காலியாக உள்ளது</string>
|
||||
<string name="moveUp">மேல்நோக்கி நகர்த்தவும்</string>
|
||||
@@ -138,9 +136,9 @@
|
||||
<string name="privacy_policy">தனியுரிமைக் கொள்கை</string>
|
||||
<string name="accept">ஏற்றுக்கொள்</string>
|
||||
<string name="importCatima">கேட்டிமாவில் இருந்து இறக்குமதி செய்</string>
|
||||
<string name="importCatimaMessage">நீங்கள் கேட்டிமாவில் இருந்து ஏற்றுமதி செய்த <i> catima.zip </i> தேர்ந்துஎடுத்து இறக்குமதி செய்யுங்கள்.\nமுதலில் மற்றொரு கேட்டிமா செயலியில் இறக்குமதி/ஏற்றுமதி மெனுவிலிருந்து ஏற்றுமதியை தேர்ந்துஎடுத்து இக்கோப்பை உருவாக்கவும்.</string>
|
||||
<string name="importCatimaMessage">நீங்கள் பூனையம்மாவிலிருந்து ஏற்றுமதியை தேர்ந்துஎடுத்து இறக்குமதி செய்.\nமற்றொரு பூனையம்மா செயலியில் இறக்குமதி/ஏற்றுமதி பட்டியலிலிருந்து ஏற்றுமதியை தேர்ந்துஎடுத்து இக்கோப்பை உருவாக்கு.</string>
|
||||
<string name="importLoyaltyCardKeychain">விசுவாச அட்டை கீச்சினிலிருந்து இறக்குமதி செய்யுங்கள்</string>
|
||||
<string name="importFidmeMessage">உங்கள் <i> fidme-export-request-xxxxxx.zip </i> இறக்குமதி செய்ய FIDME இலிருந்து ஏற்றுமதி செய்து, பின்னர் பார்கோடு வகைகளை கைமுறையாகத் தேர்ந்தெடுக்கவும்.\n தரவு பாதுகாப்பைத் தேர்ந்தெடுப்பதன் மூலம் உங்கள் FIDME சுயவிவரத்திலிருந்து அதை உருவாக்கவும், பின்னர் எனது தரவைப் பிரித்தெடுக்கவும் அழுத்தவும்.</string>
|
||||
<string name="importFidmeMessage">"உங்கள் இறக்குமதியை FIDME இலிருந்து ஏற்றுமதி செய்து, பின்னர் பட்டைகோடு வகைகளைக் கைமுறையாகத் தேர்ந்தெடு.\n தரவு பாதுகாப்பைத் தேர்ந்தெடுப்பதன் மூலம் உங்கள் FIDME தன்விவரத்திலிருந்து அதை உருவாக்கவும், பின்னர் எனது தரவைப் பிரித்தெடு அழுத்தவும்."</string>
|
||||
<string name="importVoucherVault">வவுச்சர் பெட்டகத்திலிருந்து இறக்குமதி</string>
|
||||
<string name="sameAsCardId">ஐடி அதே</string>
|
||||
<string name="setBarcodeId">பார்கோடு மதிப்பை அமைக்கவும்</string>
|
||||
@@ -161,17 +159,10 @@
|
||||
<string name="turn_flashlight_off">ஒளிரும் விளக்கை அணைக்கவும்</string>
|
||||
<string name="settings_locale">மொழி</string>
|
||||
<string name="settings_oled_dark">இருண்ட கருப்பொருளுக்கு தூய கருப்பு பின்னணி</string>
|
||||
<string name="settings_theme_color">கருப்பொருள் நிறம்</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>
|
||||
<string name="settings_sky_blue_theme">வானம் நீலம்</string>
|
||||
<string name="sort_by_name">பெயர்</string>
|
||||
<string name="sort_by_most_recently_used">மிக அண்மைக் காலத்தில் பயன்படுத்தப்பட்டது</string>
|
||||
<string name="sort_by_expiry">காலாவதியாகும்</string>
|
||||
<string name="reverse">… தலைகீழ் வரிசையில்</string>
|
||||
<string name="settings_brown_theme">பழுப்பு</string>
|
||||
<string name="updateBalance">இருப்பு புதுப்பிக்கவும்</string>
|
||||
<string name="failedToRetrieveImageFile">படக் கோப்பை மீட்டெடுப்பதில் தோல்வி</string>
|
||||
<string name="sort_by">வரிசைப்படுத்தவும்</string>
|
||||
@@ -281,7 +272,7 @@
|
||||
<string name="app_contributors">வழங்கியவர்: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="about_title_fmt">படம் <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="app_libraries">மூன்றாம் தரப்பு நூலகங்கள்: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">காலாவதியாகிறது: <xliff:g>%s</xliff:g></string>
|
||||
<string name="balanceSentence">இருப்பு: <xliff:g>%s</xliff:g></string>
|
||||
<plurals name="groupCardCountWithArchived">
|
||||
@@ -289,7 +280,7 @@
|
||||
<item quantity="other"><xliff:g>%1$d</xliff:g> அட்டைகள் (<xliff:g id="archivedCount">%2$d</xliff:g> காப்பகப்படுத்தப்பட்டது)</item>
|
||||
</plurals>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">பதிப்புரிமை © 2019–<xliff:g>%d</xliff:g> சில்வியா வான் ஓஎச் மற்றும் பங்களிப்பாளர்கள்</string>
|
||||
<string name="app_resources">விடுதலை மூன்றாம் தரப்பு வளங்கள்: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_resources">மூன்றாம் தரப்பு வளங்கள்: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="groupsList">குழுக்கள்: <xliff:g>%s</xliff:g></string>
|
||||
<string name="sort_by_valid_from">இருந்து செல்லுபடியாகும்</string>
|
||||
<string name="setBarcodeWidth">பட்டைகுறி அகலம் அமை</string>
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="app_contributors">Katkıda bulunanlar: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="settings_brown_theme">Kahverengi</string>
|
||||
<string name="settings_green_theme">Yeşil</string>
|
||||
<string name="settings_sky_blue_theme">Gök mavisi</string>
|
||||
<string name="settings_blue_theme">Mavi</string>
|
||||
<string name="settings_violet_theme">Mor</string>
|
||||
<string name="settings_magenta_theme">Eflatun</string>
|
||||
<string name="settings_pink_theme">Pembe</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_theme_color">Tema rengi</string>
|
||||
<string name="settings_system_locale">Sistem</string>
|
||||
<string name="settings_locale">Dil</string>
|
||||
<string name="turn_flashlight_off">El fenerini kapat</string>
|
||||
@@ -305,4 +296,7 @@
|
||||
<string name="acra_crash_email_subject"><xliff:g id="app_name">%s</xliff:g> çökme raporu</string>
|
||||
<string name="pref_enable_acra_summary">Etkinleştirildiğinde, bir çökmeyi şikayet etmeniz istenecektir. Çökme raporları hiç bir zaman otomatik olarak gönderilmez.</string>
|
||||
<string name="pref_enable_acra">Çökme bildirimlerini göndermeyi iste</string>
|
||||
<string name="copy_value">Değeri kopyala</string>
|
||||
<string name="copied_to_clipboard">Panoya kopyalandı</string>
|
||||
<string name="nothing_to_copy">Değer bulunamadı</string>
|
||||
</resources>
|
||||
|
||||
@@ -150,17 +150,8 @@
|
||||
<item quantity="many">Видалити ці <xliff:g>%d</xliff:g> карток назавжди\?</item>
|
||||
<item quantity="other">Видалити ці <xliff:g>%d</xliff:g> карток назавжди\?</item>
|
||||
</plurals>
|
||||
<string name="settings_blue_theme">Синій</string>
|
||||
<string name="settings_violet_theme">Фіолетовий</string>
|
||||
<string name="settings_magenta_theme">Пурпуровий</string>
|
||||
<string name="settings_pink_theme">Рожевий</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_theme_color">Колір теми</string>
|
||||
<string name="settings_system_locale">Системна</string>
|
||||
<string name="settings_locale">Мова</string>
|
||||
<string name="settings_brown_theme">Коричневий</string>
|
||||
<string name="settings_green_theme">Зелений</string>
|
||||
<string name="settings_sky_blue_theme">Небесно-синій</string>
|
||||
<string name="app_contributors">Стало можливим завдяки: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="noGroupCards">Пуста група</string>
|
||||
<string name="barcodeImageDescriptionWithType">Зображення штрих-коду <xliff:g>%s</xliff:g></string>
|
||||
@@ -317,4 +308,7 @@
|
||||
<string name="acra_crash_email_subject">Звіт про збій <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="pref_enable_acra">Запит на надсилання звітів про збої</string>
|
||||
<string name="pref_enable_acra_summary">Якщо цю функцію ввімкнено, вам буде запропоновано повідомити про збій, коли він станеться. Звіти про збої ніколи не надсилаються автоматично.</string>
|
||||
<string name="copy_value">Копіювати значення</string>
|
||||
<string name="copied_to_clipboard">Скопійовано в буфер обміну</string>
|
||||
<string name="nothing_to_copy">Значення не знайдено</string>
|
||||
</resources>
|
||||
|
||||
@@ -72,10 +72,8 @@
|
||||
<string name="permissionReadCardsDescription">đọc thẻ Catima của bạn và mọi thông tin trong đó, bao gồm cả ghi chú và ảnh</string>
|
||||
<string name="anyDate">Bất cứ ngày nào</string>
|
||||
<string name="unsupportedBarcodeType">Loại mã vạch này chưa thể hiện thị được. Ửng dụng có thể hỗ trợ nó ở những phiên bản sau này.</string>
|
||||
<string name="settings_green_theme">Màu xanh lá</string>
|
||||
<string name="failedLaunchingPhotoPicker">Không tìm thấy ứng dụng thư viện ảnh được hỗ trợ</string>
|
||||
<string name="expiryStateSentenceExpired">Quá hạn: <xliff:g>%s</xliff:g></string>
|
||||
<string name="settings_pink_theme">Màu hồng</string>
|
||||
<string name="groupsList">Nhóm: <xliff:g>%s</xliff:g></string>
|
||||
<string name="yes">Có</string>
|
||||
<string name="barcodeType">Loại mã vạch</string>
|
||||
@@ -114,7 +112,6 @@
|
||||
<string name="star">Đánh dấu ưa thích</string>
|
||||
<string name="addFromImage">Chọn ảnh từ thư viện ảnh</string>
|
||||
<string name="reverse">...theo trật tự đảo ngược</string>
|
||||
<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">Nền đen tuyền cho chủ đề tối</string>
|
||||
@@ -123,7 +120,6 @@
|
||||
<string name="importOptionFilesystemExplanation">Chọn 1 tập tin cụ thể từ hệ thống (filesystem).</string>
|
||||
<string name="validFromSentence">Hợp lệ từ: <xliff:g>%s</xliff:g></string>
|
||||
<string name="exportSuccessful">Xuất dữ liệu xong</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="previousCard">Trước</string>
|
||||
<string name="settings_allow_content_provider_read_summary">Mọi ứng dụng vẫn phải cần phải xin cấp phép để được truy cập</string>
|
||||
<string name="license">Giấy phép</string>
|
||||
@@ -141,7 +137,6 @@
|
||||
<string name="options">Tùy chọn</string>
|
||||
<string name="sendLabel">Gửi…</string>
|
||||
<string name="importOptionFilesystemButton">Lấy từ hệ thống</string>
|
||||
<string name="settings_magenta_theme">Màu sắc tố tím và đỏ</string>
|
||||
<string name="failedGeneratingShareURL">Không tạo được URL chia sẻ. Xin hãy báo cáo sự cố này.</string>
|
||||
<string name="selectColor">Chọn màu</string>
|
||||
<string name="setBarcodeHeight">Đặt chiều cao cho mã vạch</string>
|
||||
@@ -155,8 +150,7 @@
|
||||
<string name="updateBalance">Cập nhật số dư</string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Bản quyền © 2019–<xliff:g>%d</xliff:g> Sylvia van Os và các cộng sự</string>
|
||||
<string name="sort_by_most_recently_used">Sửa dụng gần đây nhất</string>
|
||||
<string name="noGiftCards">Bấm nút dấu cộng + để thêm thẻ, hoặc nhập dữ liệu từ menu ⋮.</string>
|
||||
<string name="settings_theme_color">Chủ đề màu</string>
|
||||
<string name="noGiftCards">Bấm nút dấu cộng + để thêm thẻ, hoặc nhập dữ liệu từ ⋮ menu</string>
|
||||
<string name="importVoucherVault">Nhập dữ liệu từ Voucher Vault</string>
|
||||
<string name="barcodeId">Giá trị mã vạch</string>
|
||||
<string name="settings_locale">Ngôn ngữ</string>
|
||||
@@ -166,7 +160,6 @@
|
||||
<string name="errorReadingImage">Không thể xem được ảnh</string>
|
||||
<string name="setFrontImage">Đặt ảnh mặt trước</string>
|
||||
<string name="settings_theme">Chủ đề</string>
|
||||
<string name="settings_sky_blue_theme">Xanh da trời</string>
|
||||
<string name="balance">Số dư</string>
|
||||
<string name="cameraPermissionRequired">Tác vụ này cần được cấp quyền sử dụng camera…</string>
|
||||
<string name="settings_allow_content_provider_read_title">Cho phép ứng dụng khác truy cập vào dữ liệu của tôi</string>
|
||||
@@ -202,7 +195,6 @@
|
||||
<string name="group_name_already_in_use">Tên nhóm đã tạo rồi</string>
|
||||
<string name="exportFailedTitle">Xuất dữ liệu thất bại</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Bỏ không lưu chứ\?</string>
|
||||
<string name="settings_violet_theme">Màu tím</string>
|
||||
<string name="card">Thẻ</string>
|
||||
<string name="never">Không bao giờ</string>
|
||||
<string name="include_if_asking_support">Nếu bạn muốn yêu cầu hỗ trợ, hãy cung cấp những thông tin sau:</string>
|
||||
@@ -214,7 +206,6 @@
|
||||
<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>
|
||||
<string name="app_resources">Tài nguyên mở từ bên thứ 3: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="shortcutSelectCard">Chọn một thẻ</string>
|
||||
<string name="accept">Đồng ý</string>
|
||||
|
||||
@@ -147,10 +147,8 @@
|
||||
</plurals>
|
||||
<string name="settings_locale">语言</string>
|
||||
<string name="setIcon">设置缩略图</string>
|
||||
<string name="settings_pink_theme">粉色</string>
|
||||
<string name="settings_oled_dark">纯黑色背景的深色主题</string>
|
||||
<string name="translate_platform">在Weblate上</string>
|
||||
<string name="settings_sky_blue_theme">天蓝</string>
|
||||
<string name="showMoreInfo">显示信息</string>
|
||||
<string name="options">选项</string>
|
||||
<string name="source_repository">源码库</string>
|
||||
@@ -164,26 +162,19 @@
|
||||
<string name="shortcutSelectCard">选择一张卡片</string>
|
||||
<string name="group_name_already_in_use">组名已在使用中</string>
|
||||
<string name="group_name_is_empty">组名不可为空</string>
|
||||
<string name="settings_brown_theme">棕色</string>
|
||||
<string name="settings_green_theme">绿色</string>
|
||||
<string name="sort_by_most_recently_used">最近使用</string>
|
||||
<string name="sort_by_name">名称</string>
|
||||
<string name="help_translate_this_app">帮助翻译此应用</string>
|
||||
<string name="reverse">倒序</string>
|
||||
<string name="sort_by">排序方式</string>
|
||||
<string name="selectColor">选择颜色</string>
|
||||
<string name="settings_theme_color">主题色</string>
|
||||
<string name="settings_blue_theme">蓝色</string>
|
||||
<string name="sort_by_expiry">到期日</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="noGroupCards">该组是空的</string>
|
||||
<string name="on_github">在GitHub上</string>
|
||||
<string name="group_updated">群组已更新</string>
|
||||
<string name="editGroup">编辑组:<xliff:g>%s</xliff:g></string>
|
||||
<string name="settings_system_locale">系统</string>
|
||||
<string name="exportPassword">设置密码来保护导出的内容(可选)</string>
|
||||
<string name="settings_magenta_theme">紫红</string>
|
||||
<string name="settings_violet_theme">紫色</string>
|
||||
<string name="app_contributors">因他们而存在: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="and_data_usage">和数据使用方法</string>
|
||||
<string name="failedLaunchingPhotoPicker">找不到支持的图片选择应用</string>
|
||||
@@ -299,4 +290,7 @@
|
||||
<string name="acra_crash_email_subject"><xliff:g id="app_name">%s</xliff:g> 崩溃报告</string>
|
||||
<string name="pref_enable_acra">请求发送崩溃报告</string>
|
||||
<string name="pref_enable_acra_summary">开启后,会在发生崩溃时请求报告崩溃。应用永远不会自动发送崩溃报告。</string>
|
||||
<string name="copy_value">复制值</string>
|
||||
<string name="copied_to_clipboard">已复制到剪贴板</string>
|
||||
<string name="nothing_to_copy">没找到值</string>
|
||||
</resources>
|
||||
|
||||
@@ -77,14 +77,6 @@
|
||||
<string name="noCardExistsError">無法找到此卡片</string>
|
||||
<string name="noCardsMessage">請先新增卡片</string>
|
||||
<string name="sort">排列</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>
|
||||
<string name="settings_blue_theme">藍色</string>
|
||||
<string name="settings_sky_blue_theme">天空藍</string>
|
||||
<string name="settings_green_theme">綠色</string>
|
||||
<string name="settings_brown_theme">棕色</string>
|
||||
<string name="sort_by_name">名稱</string>
|
||||
<string name="sort_by_most_recently_used">最近使用</string>
|
||||
<string name="sort_by_expiry">逾期日期</string>
|
||||
@@ -111,7 +103,6 @@
|
||||
<string name="turn_flashlight_off">關閉手電筒</string>
|
||||
<string name="settings_locale">語言</string>
|
||||
<string name="settings_system_locale">系統語言</string>
|
||||
<string name="settings_theme_color">主題顏色</string>
|
||||
<string name="app_contributors">感謝以下貢獻者:<xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="privacy_policy">隱私權政策</string>
|
||||
<plurals name="selectedCardCount">
|
||||
@@ -298,4 +289,7 @@
|
||||
<string name="acra_crash_email_subject"><xliff:g id="app_name">%s</xliff:g> 當機報告</string>
|
||||
<string name="pref_enable_acra">詢問是否傳送當機報告</string>
|
||||
<string name="pref_enable_acra_summary">啟用後,當發生當機時系統會詢問您是否要回報。當機報告絕不會自動傳送。</string>
|
||||
<string name="copy_value">複製值</string>
|
||||
<string name="copied_to_clipboard">已複製到剪貼簿</string>
|
||||
<string name="nothing_to_copy">未找到值</string>
|
||||
</resources>
|
||||
|
||||
@@ -12,30 +12,6 @@
|
||||
<item>@string/settings_dark_theme</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="color_values">
|
||||
<item>@string/settings_key_system_theme</item>
|
||||
<item>@string/settings_key_catima_theme</item>
|
||||
<item>@string/settings_key_pink_theme</item>
|
||||
<item>@string/settings_key_magenta_theme</item>
|
||||
<item>@string/settings_key_violet_theme</item>
|
||||
<item>@string/settings_key_blue_theme</item>
|
||||
<item>@string/settings_key_sky_blue_theme</item>
|
||||
<item>@string/settings_key_green_theme</item>
|
||||
<item>@string/settings_key_brown_theme</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="color_value_strings">
|
||||
<item>@string/settings_system_theme</item>
|
||||
<item>@string/settings_catima_theme</item>
|
||||
<item>@string/settings_pink_theme</item>
|
||||
<item>@string/settings_magenta_theme</item>
|
||||
<item>@string/settings_violet_theme</item>
|
||||
<item>@string/settings_blue_theme</item>
|
||||
<item>@string/settings_sky_blue_theme</item>
|
||||
<item>@string/settings_green_theme</item>
|
||||
<item>@string/settings_brown_theme</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="column_count_portrait_values">
|
||||
<item>@string/settings_key_automatic_column_count</item>
|
||||
<item>1</item>
|
||||
@@ -70,28 +46,6 @@
|
||||
<item>@string/settings_column_count_7</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="color_values_no_dynamic">
|
||||
<item>@string/settings_key_system_theme</item>
|
||||
<item>@string/settings_key_pink_theme</item>
|
||||
<item>@string/settings_key_magenta_theme</item>
|
||||
<item>@string/settings_key_violet_theme</item>
|
||||
<item>@string/settings_key_blue_theme</item>
|
||||
<item>@string/settings_key_sky_blue_theme</item>
|
||||
<item>@string/settings_key_green_theme</item>
|
||||
<item>@string/settings_key_brown_theme</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="color_value_strings_no_dynamic">
|
||||
<item>@string/settings_catima_theme</item>
|
||||
<item>@string/settings_pink_theme</item>
|
||||
<item>@string/settings_magenta_theme</item>
|
||||
<item>@string/settings_violet_theme</item>
|
||||
<item>@string/settings_blue_theme</item>
|
||||
<item>@string/settings_sky_blue_theme</item>
|
||||
<item>@string/settings_green_theme</item>
|
||||
<item>@string/settings_brown_theme</item>
|
||||
</string-array>
|
||||
|
||||
<!--
|
||||
NB: this list needs to be updated manually for new/removed languages and
|
||||
is used to generate the locale lists in app/build.gradle and
|
||||
@@ -144,6 +98,7 @@
|
||||
<item>nb-rNO</item>
|
||||
<item>nl</item>
|
||||
<item>oc</item>
|
||||
<!-- <item>peo</item> -->
|
||||
<item>pl</item>
|
||||
<item>pt</item>
|
||||
<item>pt-rBR</item>
|
||||
|
||||
@@ -211,24 +211,6 @@
|
||||
<string name="settings_system_locale">System</string>
|
||||
<string name="selectColor">Select color</string>
|
||||
<string name="setIcon">Set thumbnail</string>
|
||||
<string name="setting_key_theme_color" translatable="false">pref_theme_color</string>
|
||||
<string name="settings_theme_color">Theme color</string>
|
||||
<string name="settings_catima_theme">Catima</string>
|
||||
<string name="settings_pink_theme">Pink</string>
|
||||
<string name="settings_magenta_theme">Magenta</string>
|
||||
<string name="settings_violet_theme">Violet</string>
|
||||
<string name="settings_blue_theme">Blue</string>
|
||||
<string name="settings_sky_blue_theme">Sky blue</string>
|
||||
<string name="settings_green_theme">Green</string>
|
||||
<string name="settings_brown_theme">Brown</string>
|
||||
<string name="settings_key_catima_theme" translatable="false">catima_theme</string>
|
||||
<string name="settings_key_pink_theme" translatable="false">pink_theme</string>
|
||||
<string name="settings_key_magenta_theme" translatable="false">magenta_theme</string>
|
||||
<string name="settings_key_violet_theme" translatable="false">violet_theme</string>
|
||||
<string name="settings_key_blue_theme" translatable="false">blue_theme</string>
|
||||
<string name="settings_key_sky_blue_theme" translatable="false">sky_blue_theme</string>
|
||||
<string name="settings_key_green_theme" translatable="false">green_theme</string>
|
||||
<string name="settings_key_brown_theme" translatable="false">brown_theme</string>
|
||||
<string name="app_contributors">Made possible by: <xliff:g id="app_contributors">%s</xliff:g></string>
|
||||
<string name="sort">Sort</string>
|
||||
<string name="showMoreInfo">Show info</string>
|
||||
@@ -358,4 +340,10 @@
|
||||
<string name="acra_crash_email_subject"><xliff:g id="app_name">%s</xliff:g> crash report</string>
|
||||
<string name="pref_enable_acra">Ask to send crash reports</string>
|
||||
<string name="pref_enable_acra_summary">When enabled, you will be asked to report a crash when it happens. Crash reports are never sent automatically.</string>
|
||||
<string name="copy_value">Copy value</string>
|
||||
<string name="copied_to_clipboard">Copied to clipboard</string>
|
||||
<string name="nothing_to_copy">No value found</string>
|
||||
<string name="barcodeEncoding">Barcode encoding</string>
|
||||
<string name="automatic">Automatic</string>
|
||||
<string name="back">Back</string>
|
||||
</resources>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user