Compare commits
189 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5325f1955e | ||
|
|
ee30180137 | ||
|
|
6bddeb2f75 | ||
|
|
3c69990b0d | ||
|
|
43d5478ae3 | ||
|
|
30a54ae22a | ||
|
|
9ff6b87092 | ||
|
|
9763d9fb73 | ||
|
|
0b92686dad | ||
|
|
cb1c834057 | ||
|
|
98a0487d0c | ||
|
|
2df165061d | ||
|
|
fdd7ca03cf | ||
|
|
29e996a5fe | ||
|
|
3c1c8baaa0 | ||
|
|
6c186c2abb | ||
|
|
9deb0b94af | ||
|
|
97d54e87f2 | ||
|
|
0e329b3c31 | ||
|
|
bd337d6da8 | ||
|
|
dc7f199e0c | ||
|
|
b54e14def2 | ||
|
|
f724e4c164 | ||
|
|
c389a02d69 | ||
|
|
b7db58e7d0 | ||
|
|
eefd26fa06 | ||
|
|
8d4a122cb5 | ||
|
|
13ea10d0b0 | ||
|
|
4366eab380 | ||
|
|
0c61d36cb3 | ||
|
|
6bc5e77bbd | ||
|
|
d8ddee0667 | ||
|
|
5e8312e816 | ||
|
|
8e10022158 | ||
|
|
b209b670a5 | ||
|
|
ecdec0f773 | ||
|
|
5c90107a7b | ||
|
|
6a8a9878d7 | ||
|
|
3400d10cc6 | ||
|
|
05e171170b | ||
|
|
cb967a8d8d | ||
|
|
5835da2931 | ||
|
|
2e9339b8aa | ||
|
|
bbba4b2e11 | ||
|
|
d9659ecc9d | ||
|
|
c558278962 | ||
|
|
c137cb9428 | ||
|
|
1d2f54c69b | ||
|
|
d4a377fe18 | ||
|
|
9844113568 | ||
|
|
c49f26db95 | ||
|
|
9744dfe6ff | ||
|
|
55dfd1fe09 | ||
|
|
0a3c81154c | ||
|
|
70a9689bb2 | ||
|
|
54f6d8d26f | ||
|
|
c0622ddaec | ||
|
|
12578eab3e | ||
|
|
5dd57577af | ||
|
|
d883c84b4e | ||
|
|
0ebe1b387d | ||
|
|
942aff2af5 | ||
|
|
c1606fef62 | ||
|
|
cc895353a9 | ||
|
|
73bac0ae8d | ||
|
|
158e424a47 | ||
|
|
133fa13d3b | ||
|
|
44ff4d0cc6 | ||
|
|
a7b280c08b | ||
|
|
5fe0429c98 | ||
|
|
bf391022fd | ||
|
|
a431bf8c30 | ||
|
|
a242944ee6 | ||
|
|
84a7e84486 | ||
|
|
d4988f1d4c | ||
|
|
04e52f0a8a | ||
|
|
370db97af1 | ||
|
|
84d7f4fbba | ||
|
|
afcbca251c | ||
|
|
aa9df04c9c | ||
|
|
a24452a962 | ||
|
|
e74176abb0 | ||
|
|
6f4cec4cf4 | ||
|
|
febd0cf463 | ||
|
|
a5f91486e9 | ||
|
|
d8300640af | ||
|
|
afef158169 | ||
|
|
a728d1d84d | ||
|
|
9f88b6348b | ||
|
|
6929ba1c0d | ||
|
|
49b296b983 | ||
|
|
f21a75b19a | ||
|
|
8946b0a9e1 | ||
|
|
eae470f13c | ||
|
|
5ce046b3f4 | ||
|
|
a51debb2e1 | ||
|
|
7312a4bd1a | ||
|
|
3c1a54e456 | ||
|
|
6d4babf944 | ||
|
|
7ecdf52f1a | ||
|
|
c6f28272d9 | ||
|
|
ba8c20f415 | ||
|
|
b41dcc7ba1 | ||
|
|
6a14b5706b | ||
|
|
5bde6796b9 | ||
|
|
3c797b5ec9 | ||
|
|
dec85d8fa9 | ||
|
|
979d88d2e6 | ||
|
|
67b961c672 | ||
|
|
ed62ad321b | ||
|
|
251bdcd500 | ||
|
|
16f9b8f3a5 | ||
|
|
6be52f9b31 | ||
|
|
d8b901c3a0 | ||
|
|
ed52d2d666 | ||
|
|
ff6b62c3f0 | ||
|
|
da8b15a985 | ||
|
|
eccf994379 | ||
|
|
66622817cc | ||
|
|
3fcfe8afe1 | ||
|
|
2c5dae37fd | ||
|
|
295e63981d | ||
|
|
9ac0ee53b5 | ||
|
|
7e1dbf905a | ||
|
|
63de6f50ed | ||
|
|
6b24f56c79 | ||
|
|
e601d1a659 | ||
|
|
1641631bdc | ||
|
|
91c2efbdfc | ||
|
|
462f77e26f | ||
|
|
0aa1f8b7dd | ||
|
|
0f9509c0e5 | ||
|
|
95d497c7bd | ||
|
|
d760fbd3cb | ||
|
|
ad82492f63 | ||
|
|
e84a23c58e | ||
|
|
67cbb34425 | ||
|
|
0c4fed5c50 | ||
|
|
e1a72a948d | ||
|
|
50d9205aef | ||
|
|
9093c88e23 | ||
|
|
3c793fe54f | ||
|
|
a8960eb506 | ||
|
|
7913e95abf | ||
|
|
fac7b76798 | ||
|
|
aa9c4b81b4 | ||
|
|
5b3fc845f9 | ||
|
|
c8c7498dc9 | ||
|
|
712763969c | ||
|
|
d3f1e0d80b | ||
|
|
e8ab92d8c1 | ||
|
|
e0e4ba0012 | ||
|
|
cb4cede2da | ||
|
|
7bfdb3a8c3 | ||
|
|
c4210da1a5 | ||
|
|
e082f45333 | ||
|
|
d10c8668b6 | ||
|
|
a766a25f6a | ||
|
|
daa2f4137c | ||
|
|
e61d29417c | ||
|
|
cc1be04cf7 | ||
|
|
e0ed5bd11c | ||
|
|
1bda5410d8 | ||
|
|
4bbeb27714 | ||
|
|
c04f2c6785 | ||
|
|
70fa8ff11c | ||
|
|
1637895866 | ||
|
|
6e0d48e42d | ||
|
|
9e71a0d86c | ||
|
|
20365e31be | ||
|
|
fb29adbb22 | ||
|
|
c4f0ab37a9 | ||
|
|
038def0114 | ||
|
|
1f962d88c0 | ||
|
|
d897f3b137 | ||
|
|
dba3692521 | ||
|
|
7ab6ec5f75 | ||
|
|
0d6e002324 | ||
|
|
9b2748cf61 | ||
|
|
e505bce0ba | ||
|
|
e25d8910c5 | ||
|
|
3e79001e84 | ||
|
|
4b432ea94c | ||
|
|
78752e1cf2 | ||
|
|
129608befd | ||
|
|
0c2bf8b8a5 | ||
|
|
6bc08a21e8 | ||
|
|
fa5d094197 | ||
|
|
7d5f79b7e1 |
2
.gitignore
vendored
@@ -6,3 +6,5 @@
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
/app/release
|
||||
/app/debug
|
||||
|
||||
10
.tx/config
@@ -1,10 +0,0 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
|
||||
[loyalty-card-locker.stringsxml]
|
||||
file_filter = app/src/main/res/values-<lang>/strings.xml
|
||||
minimum_perc = 0
|
||||
source_file = app/src/main/res/values/strings.xml
|
||||
source_lang = en
|
||||
type = ANDROID
|
||||
|
||||
296
CHANGELOG.md
@@ -1,6 +1,84 @@
|
||||
# Changelog
|
||||
|
||||
## v1.5.1 (2020-12-03)
|
||||
|
||||
Changes:
|
||||
|
||||
- Fix bottomsheet background being transparent
|
||||
|
||||
## v1.5.0 (2020-12-03)
|
||||
|
||||
Changes:
|
||||
|
||||
- Improve contrast by always using white text on red buttons
|
||||
- Draggable bottom sheet in loyalty card view
|
||||
|
||||
## v1.4.1 (2020-12-01)
|
||||
|
||||
Changes:
|
||||
|
||||
- Improved translations
|
||||
- Small UI fixes
|
||||
|
||||
## v1.4.0 (2020-11-28)
|
||||
|
||||
Changes:
|
||||
|
||||
- Move About screen into its own activity
|
||||
- Ask user if they want to use their camera or manually enter ID on add/edit card
|
||||
- Make group ordering manual instead of forced alphabetically
|
||||
|
||||
## v1.3.0 (2020-11-22)
|
||||
|
||||
Changes:
|
||||
|
||||
- Always show all import/export options and show a toast on actual issues (improves compat with XPrivacyLua)
|
||||
- Ask for confirmation when leaving edit view after making changes without saving
|
||||
|
||||
## v1.2.2 (2020-11-19)
|
||||
|
||||
Changes:
|
||||
|
||||
- Remember active group tab between screens and sessions
|
||||
|
||||
## v1.2.1 (2020-11-17)
|
||||
|
||||
Changes:
|
||||
|
||||
- Fix home screen swiping triggering during vertical swipes too
|
||||
|
||||
## v1.2.0 (2020-11-17)
|
||||
|
||||
Changes:
|
||||
|
||||
- Add swiping between groups on the home screen
|
||||
- Fix crash with cards lacking header colour
|
||||
|
||||
## v1.1.0 (2020-11-11)
|
||||
|
||||
Changes:
|
||||
|
||||
- Improved edit UI
|
||||
- Removed header text colour option (now automatically generated based on brightness)
|
||||
- Updated translations
|
||||
|
||||
## v1.0.1 (2020-11-07)
|
||||
|
||||
Changes:
|
||||
|
||||
- Fix crash in search with no groups
|
||||
|
||||
## v1.0 (2020-11-06)
|
||||
|
||||
Changes:
|
||||
|
||||
- Added rounded edges to card icons on main overview
|
||||
- Added support for grouping entries
|
||||
|
||||
## v0.29 (2020-10-29)
|
||||
|
||||
Changes:
|
||||
|
||||
- Rebrand to Catima
|
||||
- Removed intro
|
||||
- Add floating action buttons
|
||||
@@ -11,6 +89,7 @@ Changes:
|
||||
## v0.28 (2020-03-09)
|
||||
|
||||
Changes:
|
||||
|
||||
- Fix barcode centering when exiting full screen ([#351](https://github.com/brarcher/loyalty-card-locker/pull/351))
|
||||
- Allow backup export location to be selected ([#352](https://github.com/brarcher/loyalty-card-locker/pull/352))
|
||||
- Update translations ([#357](https://github.com/brarcher/loyalty-card-locker/pull/357)) & ([#362](https://github.com/brarcher/loyalty-card-locker/pull/362))
|
||||
@@ -18,6 +97,7 @@ Changes:
|
||||
## v0.27 (2020-01-26)
|
||||
|
||||
Changes:
|
||||
|
||||
- Tapping on a barcode now moves it to the top of the screen ([#348](https://github.com/brarcher/loyalty-card-locker/pull/348))
|
||||
- Add white space around barcodes to improve scanning in dark mode ([#328](https://github.com/brarcher/loyalty-card-locker/issues/328))
|
||||
- Fix swapped import buttons. ([#346](https://github.com/brarcher/loyalty-card-locker/pull/346))
|
||||
@@ -25,11 +105,13 @@ Changes:
|
||||
## v0.26.1 (2020-01-09)
|
||||
|
||||
Changes:
|
||||
|
||||
- Fix issue with sharing cards without background color ([#343](https://github.com/brarcher/loyalty-card-locker/pull/343))
|
||||
|
||||
## v0.26 (2020-01-05)
|
||||
|
||||
Changes:
|
||||
|
||||
- Add ability to search for a card ([#320](https://github.com/brarcher/loyalty-card-locker/pull/320))
|
||||
- Add ability to share and receive loyalty cards ([#321](https://github.com/brarcher/loyalty-card-locker/pull/321))
|
||||
- Dark mode support ([#322](https://github.com/brarcher/loyalty-card-locker/pull/322))
|
||||
@@ -39,178 +121,203 @@ Changes:
|
||||
- Improve notification and app icon visibility ([#330](https://github.com/brarcher/loyalty-card-locker/pull/330))
|
||||
- Update target SDK to Android 10
|
||||
- Improve the following translations:
|
||||
* German
|
||||
* Italian
|
||||
* Dutch
|
||||
* Polish
|
||||
* Russian
|
||||
- German
|
||||
- Italian
|
||||
- Dutch
|
||||
- Polish
|
||||
- Russian
|
||||
|
||||
## v0.25.4 (2019-10-04)
|
||||
|
||||
Changes
|
||||
Changes:
|
||||
|
||||
- Enable app backups
|
||||
- Update French and Slovenian translations
|
||||
|
||||
## v0.25.3 (2019-03-02)
|
||||
|
||||
Changes
|
||||
Changes:
|
||||
|
||||
- Update Russian translations
|
||||
|
||||
## v0.25.2 (2019-01-05)
|
||||
|
||||
Changes
|
||||
|
||||
Changes:
|
||||
|
||||
- Update and add translations
|
||||
|
||||
## v0.25.1 (2018-10-14)
|
||||
|
||||
Changes:
|
||||
- Fix creating new card by manually entering barcode (https://github.com/brarcher/loyalty-card-locker/issues/272)
|
||||
|
||||
- Fix creating new card by manually entering barcode ([issue #272](https://github.com/brarcher/loyalty-card-locker/issues/272))
|
||||
|
||||
## v0.25 (2018-10-07)
|
||||
|
||||
Changes:
|
||||
- Sort card list case insensitive (https://github.com/brarcher/loyalty-card-locker/pull/266)
|
||||
- Add setting to lock orientation for all cards (https://github.com/brarcher/loyalty-card-locker/pull/269)
|
||||
|
||||
- Sort card list case insensitive ([pull #266](https://github.com/brarcher/loyalty-card-locker/pull/266))
|
||||
- Add setting to lock orientation for all cards ([pull #269](https://github.com/brarcher/loyalty-card-locker/pull/269)
|
||||
|
||||
## v0.24 (2018-07-31)
|
||||
|
||||
Changes:
|
||||
- Add a setting to control screen brightness when displaying a barcode (https://github.com/brarcher/loyalty-card-locker/pull/259)
|
||||
- Add Greek translations (https://github.com/brarcher/loyalty-card-locker/pull/252)
|
||||
- Add Slovenian translations (https://github.com/brarcher/loyalty-card-locker/pull/260)
|
||||
- Update translations (https://github.com/brarcher/loyalty-card-locker/pull/260, https://github.com/brarcher/loyalty-card-locker/pull/254)
|
||||
|
||||
- Add a setting to control screen brightness when displaying a barcode ([pull #259](https://github.com/brarcher/loyalty-card-locker/pull/259))
|
||||
- Add Greek translations ([pull #252](https://github.com/brarcher/loyalty-card-locker/pull/252))
|
||||
- Add Slovenian translations ([pull #260](https://github.com/brarcher/loyalty-card-locker/pull/260))
|
||||
- Update translations ([pull #260](https://github.com/brarcher/loyalty-card-locker/pull/260), [pull #254](https://github.com/brarcher/loyalty-card-locker/pull/254))
|
||||
|
||||
## v0.23.4 (2018-05-12)
|
||||
|
||||
Changes:
|
||||
- Fix Spanish translations (https://github.com/brarcher/loyalty-card-locker/pull/244)
|
||||
- Update translations (https://github.com/brarcher/loyalty-card-locker/pull/244)
|
||||
Changes:
|
||||
|
||||
- Fix Spanish translations ([pull #244](https://github.com/brarcher/loyalty-card-locker/pull/244))
|
||||
- Update translations ([pull #244](https://github.com/brarcher/loyalty-card-locker/pull/244))
|
||||
|
||||
## v0.23.3 (2018-05-05)
|
||||
|
||||
Changes:
|
||||
|
||||
- Added translations
|
||||
* Polish (https://github.com/brarcher/loyalty-card-locker/pull/232)
|
||||
* Spanish (https://github.com/brarcher/loyalty-card-locker/pull/232)
|
||||
* Slovak (https://github.com/brarcher/loyalty-card-locker/pull/232)
|
||||
- Updated translations (https://github.com/brarcher/loyalty-card-locker/pull/239)
|
||||
- Polish ([pull #232](https://github.com/brarcher/loyalty-card-locker/pull/232))
|
||||
- Spanish ([pull #232](https://github.com/brarcher/loyalty-card-locker/pull/232))
|
||||
- Slovak ([pull #232](https://github.com/brarcher/loyalty-card-locker/pull/232))
|
||||
- Updated translations ([pull #239](https://github.com/brarcher/loyalty-card-locker/pull/239))
|
||||
|
||||
## v0.23.2 (2018-03-11)
|
||||
|
||||
Changes:
|
||||
- Reduce min SDK from 17 to 15. (https://github.com/brarcher/loyalty-card-locker/pull/226)
|
||||
- Remove usage of legacy apache library, used only in unit tests but no longer needed. (https://github.com/brarcher/loyalty-card-locker/pull/225)
|
||||
|
||||
- Reduce min SDK from 17 to 15. ([pull #226](https://github.com/brarcher/loyalty-card-locker/pull/226))
|
||||
- Remove usage of legacy apache library, used only in unit tests but no longer needed. ([pull #225](https://github.com/brarcher/loyalty-card-locker/pull/225))
|
||||
|
||||
## v0.23.1 (2018-03-07)
|
||||
|
||||
Changes:
|
||||
- Prevent crash when rendering a barcode exhausts the application's memory. (https://github.com/brarcher/loyalty-card-locker/pull/219)
|
||||
|
||||
- Prevent crash when rendering a barcode exhausts the application's memory. ([pull #219](https://github.com/brarcher/loyalty-card-locker/pull/219))
|
||||
|
||||
## v0.23 (2018-02-28)
|
||||
|
||||
Changes:
|
||||
- Reduce space in header when viewing a card. (https://github.com/brarcher/loyalty-card-locker/pull/213)
|
||||
- Disable beep when scanning a barcode. (https://github.com/brarcher/loyalty-card-locker/pull/216)
|
||||
|
||||
- Reduce space in header when viewing a card. ([pull #213](https://github.com/brarcher/loyalty-card-locker/pull/213))
|
||||
- Disable beep when scanning a barcode. ([pull #216](https://github.com/brarcher/loyalty-card-locker/pull/216))
|
||||
|
||||
## v0.22 (2018-02-19)
|
||||
|
||||
Changes:
|
||||
- Update translations. (https://github.com/brarcher/loyalty-card-locker/pull/208)
|
||||
- Barcode rendering updates: (https://github.com/brarcher/loyalty-card-locker/pull/209)
|
||||
* Reload card view activity when screen is rotated, so barcode image is correct size.
|
||||
* Render 1D barcodes in a larger space, allowing them to better fill the screen.
|
||||
|
||||
- Update translations. ([pull #208](https://github.com/brarcher/loyalty-card-locker/pull/208))
|
||||
- Barcode rendering updates: ([pull #209](https://github.com/brarcher/loyalty-card-locker/pull/209))
|
||||
- Reload card view activity when screen is rotated, so barcode image is correct size.
|
||||
- Render 1D barcodes in a larger space, allowing them to better fill the screen.
|
||||
|
||||
## v0.21 (2018-02-17)
|
||||
|
||||
Changes
|
||||
- Add quiet space at the start/end of barcodes. (https://github.com/brarcher/loyalty-card-locker/pull/200)
|
||||
- Add options to configure the colors used for the store name font and background. (https://github.com/brarcher/loyalty-card-locker/pull/203)
|
||||
- Add options to adjust font sizes on the card listing page and single card page. (https://github.com/brarcher/loyalty-card-locker/pull/204)
|
||||
Changes:
|
||||
|
||||
- Add quiet space at the start/end of barcodes. ([pull #200](https://github.com/brarcher/loyalty-card-locker/pull/200))
|
||||
- Add options to configure the colors used for the store name font and background. ([pull #203](https://github.com/brarcher/loyalty-card-locker/pull/203))
|
||||
- Add options to adjust font sizes on the card listing page and single card page. ([pull #204](https://github.com/brarcher/loyalty-card-locker/pull/204))
|
||||
|
||||
## v0.20 (2018-02-10)
|
||||
|
||||
Changes:
|
||||
- Changes to Card view to display the note, allow the card ID to take multiple lines, and show the store name. (https://github.com/brarcher/loyalty-card-locker/pull/197)
|
||||
|
||||
- Changes to Card view to display the note, allow the card ID to take multiple lines, and show the store name. ([pull #197](https://github.com/brarcher/loyalty-card-locker/pull/197))
|
||||
|
||||
## v0.19 (2018-02-01)
|
||||
|
||||
Changes:
|
||||
- Improved layout for card list. (https://github.com/brarcher/loyalty-card-locker/pull/188)
|
||||
- Improved layout when viewing a card. (https://github.com/brarcher/loyalty-card-locker/pull/190)
|
||||
|
||||
- Improved layout for card list. ([pull #188](https://github.com/brarcher/loyalty-card-locker/pull/188))
|
||||
- Improved layout when viewing a card. ([pull #190](https://github.com/brarcher/loyalty-card-locker/pull/190))
|
||||
|
||||
## v0.18.1 (2018-01-24)
|
||||
|
||||
Changes:
|
||||
- Workaround crash during install on some Android versions (likely Android 5 and below). (https://github.com/brarcher/loyalty-card-locker/pull/184)
|
||||
|
||||
- Workaround crash during install on some Android versions (likely Android 5 and below). ([pull #184](https://github.com/brarcher/loyalty-card-locker/pull/184))
|
||||
|
||||
## v0.18 (2018-01-19)
|
||||
|
||||
Changes:
|
||||
- Fix crash when importing certain types of corrupted CSV files. (https://github.com/brarcher/loyalty-card-locker/pull/177)
|
||||
- Fix importing backups directly from the file system. (https://github.com/brarcher/loyalty-card-locker/pull/180)
|
||||
- Fix importing backups from certain types of content providers. (https://github.com/brarcher/loyalty-card-locker/pull/179)
|
||||
|
||||
- Fix crash when importing certain types of corrupted CSV files. ([pull #177](https://github.com/brarcher/loyalty-card-locker/pull/177))
|
||||
- Fix importing backups directly from the file system. ([pull #180](https://github.com/brarcher/loyalty-card-locker/pull/180))
|
||||
- Fix importing backups from certain types of content providers. ([pull #179](https://github.com/brarcher/loyalty-card-locker/pull/179))
|
||||
|
||||
## v0.17 (2018-01-11)
|
||||
|
||||
Changes:
|
||||
- Fix issue on Android SDK 24+ where using the file chooser import option would cause a crash. (https://github.com/brarcher/loyalty-card-locker/pull/170)
|
||||
- New icon and color scheme. (https://github.com/brarcher/loyalty-card-locker/pull/171)
|
||||
|
||||
- Fix issue on Android SDK 24+ where using the file chooser import option would cause a crash. ([pull #170](https://github.com/brarcher/loyalty-card-locker/pull/170))
|
||||
- New icon and color scheme. ([pull #171](https://github.com/brarcher/loyalty-card-locker/pull/171))
|
||||
|
||||
## v0.16 (2017-11-29)
|
||||
|
||||
Changes:
|
||||
- Add support for adding loyalty card shortcuts from the launcher/homescreen. (https://github.com/brarcher/loyalty-card-locker/pull/161)
|
||||
- Remove support for adding loyalty card shortcuts from the app itself. This removes the need for the shortcut permission. (https://github.com/brarcher/loyalty-card-locker/pull/163)
|
||||
|
||||
- Add support for adding loyalty card shortcuts from the launcher/homescreen. ([pull #161](https://github.com/brarcher/loyalty-card-locker/pull/161))
|
||||
- Remove support for adding loyalty card shortcuts from the app itself. This removes the need for the shortcut permission. ([pull #163](https://github.com/brarcher/loyalty-card-locker/pull/163))
|
||||
|
||||
## v0.15 (2017-11-25)
|
||||
|
||||
Changes:
|
||||
- Add support for adding shortcuts to home screen when adding or editing a card. (https://github.com/brarcher/loyalty-card-locker/pull/155)
|
||||
- Remove widget, as it was a poor substitute for shortcuts. (https://github.com/brarcher/loyalty-card-locker/pull/155)
|
||||
- Fix exporting backups on Android 7+. (https://github.com/brarcher/loyalty-card-locker/pull/153)
|
||||
- Report more accurate mime type when exporting backup data. (https://github.com/brarcher/loyalty-card-locker/pull/156)
|
||||
- Fix bug where a card could not be edited. (https://github.com/brarcher/loyalty-card-locker/pull/155)
|
||||
|
||||
- Add support for adding shortcuts to home screen when adding or editing a card. ([pull #155](https://github.com/brarcher/loyalty-card-locker/pull/155))
|
||||
- Remove widget, as it was a poor substitute for shortcuts. ([pull #155](https://github.com/brarcher/loyalty-card-locker/pull/155))
|
||||
- Fix exporting backups on Android 7+. ([pull #153](https://github.com/brarcher/loyalty-card-locker/pull/153))
|
||||
- Report more accurate mime type when exporting backup data. ([pull #156](https://github.com/brarcher/loyalty-card-locker/pull/156))
|
||||
- Fix bug where a card could not be edited. ([pull #155](https://github.com/brarcher/loyalty-card-locker/pull/155))
|
||||
|
||||
## v0.14 (2017-10-26)
|
||||
|
||||
Changes:
|
||||
- Add support for app shortcuts (Android 7.1+), where the most recently used cards will appear as shortcuts. (https://github.com/brarcher/loyalty-card-locker/pull/145)
|
||||
- Add a widget which works like a pinned app shortcut, to support devices which run below Android 7.1. (https://github.com/brarcher/loyalty-card-locker/pull/142)
|
||||
|
||||
- Add support for app shortcuts (Android 7.1+), where the most recently used cards will appear as shortcuts. ([pull #145](https://github.com/brarcher/loyalty-card-locker/pull/145))
|
||||
- Add a widget which works like a pinned app shortcut, to support devices which run below Android 7.1. ([pull #142](https://github.com/brarcher/loyalty-card-locker/pull/142))
|
||||
|
||||
## v0.13 (2017-07-25)
|
||||
|
||||
Changes:
|
||||
- Add screen rotation lock menu option when displaying a card. If locked, the screen will transition to its "natural" orientation and further screen rotation will be blocked. (https://github.com/brarcher/loyalty-card-locker/pull/128)
|
||||
- If a card is selected from the main screen but cannot be loaded, the application fails gracefully and posts a message. (https://github.com/brarcher/loyalty-card-locker/pull/132)
|
||||
- Fix case where layout IDs for intro wizard could not be found. (https://github.com/brarcher/loyalty-card-locker/pull/128)
|
||||
|
||||
- Add screen rotation lock menu option when displaying a card. If locked, the screen will transition to its "natural" orientation and further screen rotation will be blocked. ([pull #128](https://github.com/brarcher/loyalty-card-locker/pull/128))
|
||||
- If a card is selected from the main screen but cannot be loaded, the application fails gracefully and posts a message. ([pull #132](https://github.com/brarcher/loyalty-card-locker/pull/132))
|
||||
- Fix case where layout IDs for intro wizard could not be found. ([pull #128](https://github.com/brarcher/loyalty-card-locker/pull/128))
|
||||
|
||||
## v0.12 (2017-07-16)
|
||||
|
||||
Changes:
|
||||
|
||||
- A change in v0.11 reduced the memory usage of barcode drawing, but affected the barcode dimensions. This is now changed to maintain the barcode dimensions while reducing memory usage. (https://github.com/brarcher/loyalty-card-locker/pull/126)
|
||||
- Update German and French translations. (https://github.com/brarcher/loyalty-card-locker/pull/122, https://github.com/brarcher/loyalty-card-locker/pull/124, https://github.com/brarcher/loyalty-card-locker/pull/125)
|
||||
- A change in v0.11 reduced the memory usage of barcode drawing, but affected the barcode dimensions. This is now changed to maintain the barcode dimensions while reducing memory usage. ([pull #126](https://github.com/brarcher/loyalty-card-locker/pull/126))
|
||||
- Update German and French translations. ([pull #122](https://github.com/brarcher/loyalty-card-locker/pull/122), [pull #124](https://github.com/brarcher/loyalty-card-locker/pull/124), [pull #125](https://github.com/brarcher/loyalty-card-locker/pull/125))
|
||||
|
||||
## v0.11.1 (2017-06-29)
|
||||
|
||||
Changes:
|
||||
|
||||
- Prevent a crash when rotation the screen in the first run intro wizard.
|
||||
|
||||
## v0.11 (2017-06-26)
|
||||
|
||||
Improvements:
|
||||
- When editing a card ID, pre-populate the existing ID to start. (https://github.com/brarcher/loyalty-card-locker/pull/94)
|
||||
- Limit the width of generated barcodes to reduce memory usage and out of memory errors. (https://github.com/brarcher/loyalty-card-locker/pull/103)
|
||||
- When editing a card, change the "Enter Card" button to say "Edit Card" if a card ID already exists. (https://github.com/brarcher/loyalty-card-locker/pull/104)
|
||||
- Change the color scheme to be softer and compatible with the app icon, and change the layout when viewing a card to be cleaner. (https://github.com/brarcher/loyalty-card-locker/pull/107)
|
||||
- Add an intro wizard which launches on the app's first launch. (https://github.com/brarcher/loyalty-card-locker/pull/108)
|
||||
|
||||
- When editing a card ID, pre-populate the existing ID to start. ([pull #94](https://github.com/brarcher/loyalty-card-locker/pull/94))
|
||||
- Limit the width of generated barcodes to reduce memory usage and out of memory errors. ([pull #103](https://github.com/brarcher/loyalty-card-locker/pull/103))
|
||||
- When editing a card, change the "Enter Card" button to say "Edit Card" if a card ID already exists. ([pull #104](https://github.com/brarcher/loyalty-card-locker/pull/104))
|
||||
- Change the color scheme to be softer and compatible with the app icon, and change the layout when viewing a card to be cleaner. ([pull #107](https://github.com/brarcher/loyalty-card-locker/pull/107))
|
||||
- Add an intro wizard which launches on the app's first launch. ([pull #108](https://github.com/brarcher/loyalty-card-locker/pull/108))
|
||||
|
||||
## v0.10 (2017-02-12)
|
||||
|
||||
Improvements:
|
||||
- Changed the default import/export filename. (https://github.com/brarcher/loyalty-card-locker/pull/84)
|
||||
- Correct string on the import/export page. (https://github.com/brarcher/loyalty-card-locker/pull/87)
|
||||
- Improve layout of card view page. The text should be easier to read, and is selectable with a long click. (https://github.com/brarcher/loyalty-card-locker/pull/91)
|
||||
|
||||
- Changed the default import/export filename. ([pull #84](https://github.com/brarcher/loyalty-card-locker/pull/84))
|
||||
- Correct string on the import/export page. ([pull #87](https://github.com/brarcher/loyalty-card-locker/pull/87))
|
||||
- Improve layout of card view page. The text should be easier to read, and is selectable with a long click. ([pull #91](https://github.com/brarcher/loyalty-card-locker/pull/91))
|
||||
|
||||
## v0.9 (2017-01-17)
|
||||
|
||||
@@ -218,43 +325,50 @@ The "Locker" part of the name was not intuitive. To help remedy this a new appli
|
||||
|
||||
Additional features/improvements:
|
||||
|
||||
- Importing/Exporting cards was changed to be more flexible. (https://github.com/brarcher/loyalty-card-locker/pull/76)
|
||||
- Translations for Lithuanian added. (https://github.com/brarcher/loyalty-card-locker/pull/62)
|
||||
- Translations for French added. (https://github.com/brarcher/loyalty-card-locker/pull/80)
|
||||
- Importing/Exporting cards was changed to be more flexible. ([pull #76](https://github.com/brarcher/loyalty-card-locker/pull/76))
|
||||
- Translations for Lithuanian added. ([pull #62](https://github.com/brarcher/loyalty-card-locker/pull/62))
|
||||
- Translations for French added. ([pull #80](https://github.com/brarcher/loyalty-card-locker/pull/80))
|
||||
|
||||
## v0.8 (2016-11-22)
|
||||
|
||||
New features/improvements:
|
||||
- Screen brightness increased to its maximum when displaying a card, to help barcode scanners successfully capture the barcode. (https://github.com/brarcher/loyalty-card-locker/pull/54)
|
||||
- Add a delete confirmation when deleting a card. (https://github.com/brarcher/loyalty-card-locker/pull/55)
|
||||
- Add translations for German (https://github.com/brarcher/loyalty-card-locker/pull/57) and Czech (https://github.com/brarcher/loyalty-card-locker/pull/58).
|
||||
- Clarification change for Italian translation. (https://github.com/brarcher/loyalty-card-locker/pull/66)
|
||||
|
||||
- Screen brightness increased to its maximum when displaying a card, to help barcode scanners successfully capture the barcode. ([pull #54](https://github.com/brarcher/loyalty-card-locker/pull/54))
|
||||
- Add a delete confirmation when deleting a card. ([pull #55](https://github.com/brarcher/loyalty-card-locker/pull/55))
|
||||
- Add translations for German ([pull #57](https://github.com/brarcher/loyalty-card-locker/pull/57)) and Czech ([pull #58](https://github.com/brarcher/loyalty-card-locker/pull/58)).
|
||||
- Clarification change for Italian translation. ([pull #66](https://github.com/brarcher/loyalty-card-locker/pull/66))
|
||||
|
||||
## v0.7 (2016-07-14)
|
||||
|
||||
New features/improvements:
|
||||
- Long-click of a card brings up option to copy card ID to the clipboard. (https://github.com/brarcher/loyalty-card-locker/issues/49)
|
||||
|
||||
- Long-click of a card brings up option to copy card ID to the clipboard. ([pull #49](https://github.com/brarcher/loyalty-card-locker/issues/49))
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Back button on Input/Export view now works, moving user to main view
|
||||
|
||||
## v0.6 (2016-05-23)
|
||||
|
||||
New features/improvements:
|
||||
- Allow user to enter barcode manually. If a user elects to enter a barcode manually, a list of all valid and supported barcode images is displayed. The user then may select the barcode image which matches what the user wants. https://github.com/brarcher/loyalty-card-locker/issues/33, https://github.com/brarcher/loyalty-card-locker/pull/44
|
||||
|
||||
- Allow user to enter barcode manually. If a user elects to enter a barcode manually, a list of all valid and supported barcode images is displayed. The user then may select the barcode image which matches what the user wants. [issue #33](https://github.com/brarcher/loyalty-card-locker/issues/33), [pull #44](https://github.com/brarcher/loyalty-card-locker/pull/44)
|
||||
|
||||
Bug fixes:
|
||||
- Resolve issue where some displayed barcodes were blurry. (https://github.com/brarcher/loyalty-card-locker/issues/37)
|
||||
|
||||
- Resolve issue where some displayed barcodes were blurry. ([issue #37](https://github.com/brarcher/loyalty-card-locker/issues/37))
|
||||
|
||||
## v0.5 (2016-05-16)
|
||||
|
||||
New features/improvements:
|
||||
- An about dialog can be opened from the main screen, which gives details about the application and project on GitHub (https://github.com/brarcher/loyalty-card-locker/issues/19)
|
||||
- Allow loyalty card information to be imported from/exported to a CSV file in external storage (https://github.com/brarcher/loyalty-card-locker/issues/36 https://github.com/brarcher/loyalty-card-locker/issues/20)
|
||||
|
||||
- An about dialog can be opened from the main screen, which gives details about the application and project on GitHub ([issue #19](https://github.com/brarcher/loyalty-card-locker/issues/19))
|
||||
- Allow loyalty card information to be imported from/exported to a CSV file in external storage ([issue #36](https://github.com/brarcher/loyalty-card-locker/issues/36), [issue #20](https://github.com/brarcher/loyalty-card-locker/issues/20))
|
||||
|
||||
## v0.4 (2016-04-09)
|
||||
|
||||
New features/improvements:
|
||||
|
||||
- Dutch translation
|
||||
- Allow name field to be editable after adding loyalty card
|
||||
- Add an optional note field
|
||||
@@ -266,17 +380,18 @@ Bug fixes:
|
||||
## v0.3 (2016-02-11)
|
||||
|
||||
- Now officially supports the following list of 1D and 2D barcodes:
|
||||
* AZTEC
|
||||
* CODABAR
|
||||
* CODE_39
|
||||
* CODE_128
|
||||
* DATA_MATRIX
|
||||
* EAN_8
|
||||
* EAN_13
|
||||
* ITF
|
||||
* PDF_417
|
||||
* QR_CODE
|
||||
* UPC_A
|
||||
- AZTEC
|
||||
- CODABAR
|
||||
- CODE_39
|
||||
- CODE_128
|
||||
- DATA_MATRIX
|
||||
- EAN_8
|
||||
- EAN_13
|
||||
- ITF
|
||||
- PDF_417
|
||||
- QR_CODE
|
||||
- UPC_A
|
||||
|
||||
- Generated barcodes are larger, easier to scan from a scanning device
|
||||
|
||||
## v0.2 (2016-02-07)
|
||||
@@ -285,7 +400,6 @@ Bug fixes:
|
||||
- Support for all 1D barcode types. (Originally only product 1D barcodes were supported)
|
||||
- Add required camera permission, which was initially missing.
|
||||
|
||||
|
||||
## v0.1 (2016-01-30)
|
||||
|
||||
- Ability to create/edit/delete loyalty cards
|
||||
|
||||
180
Gemfile.lock
Normal file
@@ -0,0 +1,180 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.2)
|
||||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.1.0)
|
||||
aws-partitions (1.388.0)
|
||||
aws-sdk-core (3.109.1)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.239.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
jmespath (~> 1.0)
|
||||
aws-sdk-kms (1.39.0)
|
||||
aws-sdk-core (~> 3, >= 3.109.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.83.1)
|
||||
aws-sdk-core (~> 3, >= 3.109.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sigv4 (1.2.2)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
babosa (1.0.4)
|
||||
claide (1.0.3)
|
||||
colored (1.2)
|
||||
colored2 (3.1.2)
|
||||
commander-fastlane (4.4.6)
|
||||
highline (~> 1.7.2)
|
||||
declarative (0.0.20)
|
||||
declarative-option (0.1.0)
|
||||
digest-crc (0.6.1)
|
||||
rake (~> 13.0)
|
||||
domain_name (0.5.20190701)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
dotenv (2.7.6)
|
||||
emoji_regex (3.2.0)
|
||||
excon (0.78.0)
|
||||
faraday (1.1.0)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ruby2_keywords
|
||||
faraday-cookie_jar (0.0.7)
|
||||
faraday (>= 0.8.0)
|
||||
http-cookie (~> 1.0.0)
|
||||
faraday_middleware (1.0.0)
|
||||
faraday (~> 1.0)
|
||||
fastimage (2.2.0)
|
||||
fastlane (2.165.0)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.3, < 3.0.0)
|
||||
aws-sdk-s3 (~> 1.0)
|
||||
babosa (>= 1.0.3, < 2.0.0)
|
||||
bundler (>= 1.12.0, < 3.0.0)
|
||||
colored
|
||||
commander-fastlane (>= 4.4.6, < 5.0.0)
|
||||
dotenv (>= 2.1.1, < 3.0.0)
|
||||
emoji_regex (>= 0.1, < 4.0)
|
||||
excon (>= 0.71.0, < 1.0.0)
|
||||
faraday (~> 1.0)
|
||||
faraday-cookie_jar (~> 0.0.6)
|
||||
faraday_middleware (~> 1.0)
|
||||
fastimage (>= 2.1.0, < 3.0.0)
|
||||
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||
google-api-client (>= 0.37.0, < 0.39.0)
|
||||
google-cloud-storage (>= 1.15.0, < 2.0.0)
|
||||
highline (>= 1.7.2, < 2.0.0)
|
||||
json (< 3.0.0)
|
||||
jwt (>= 2.1.0, < 3)
|
||||
mini_magick (>= 4.9.4, < 5.0.0)
|
||||
multipart-post (~> 2.0.0)
|
||||
plist (>= 3.1.0, < 4.0.0)
|
||||
rubyzip (>= 2.0.0, < 3.0.0)
|
||||
security (= 0.1.3)
|
||||
simctl (~> 1.6.3)
|
||||
slack-notifier (>= 2.0.0, < 3.0.0)
|
||||
terminal-notifier (>= 2.0.0, < 3.0.0)
|
||||
terminal-table (>= 1.4.5, < 2.0.0)
|
||||
tty-screen (>= 0.6.3, < 1.0.0)
|
||||
tty-spinner (>= 0.8.0, < 1.0.0)
|
||||
word_wrap (~> 1.0.0)
|
||||
xcodeproj (>= 1.13.0, < 2.0.0)
|
||||
xcpretty (~> 0.3.0)
|
||||
xcpretty-travis-formatter (>= 0.0.3)
|
||||
gh_inspector (1.1.3)
|
||||
google-api-client (0.38.0)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
googleauth (~> 0.9)
|
||||
httpclient (>= 2.8.1, < 3.0)
|
||||
mini_mime (~> 1.0)
|
||||
representable (~> 3.0)
|
||||
retriable (>= 2.0, < 4.0)
|
||||
signet (~> 0.12)
|
||||
google-cloud-core (1.5.0)
|
||||
google-cloud-env (~> 1.0)
|
||||
google-cloud-errors (~> 1.0)
|
||||
google-cloud-env (1.4.0)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
google-cloud-errors (1.0.1)
|
||||
google-cloud-storage (1.29.1)
|
||||
addressable (~> 2.5)
|
||||
digest-crc (~> 0.4)
|
||||
google-api-client (~> 0.33)
|
||||
google-cloud-core (~> 1.2)
|
||||
googleauth (~> 0.9)
|
||||
mini_mime (~> 1.0)
|
||||
googleauth (0.14.0)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
memoist (~> 0.16)
|
||||
multi_json (~> 1.11)
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (~> 0.14)
|
||||
highline (1.7.10)
|
||||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
httpclient (2.8.3)
|
||||
jmespath (1.4.0)
|
||||
json (2.3.1)
|
||||
jwt (2.2.2)
|
||||
memoist (0.16.2)
|
||||
mini_magick (4.10.1)
|
||||
mini_mime (1.0.2)
|
||||
multi_json (1.15.0)
|
||||
multipart-post (2.0.0)
|
||||
nanaimo (0.3.0)
|
||||
naturally (2.2.0)
|
||||
os (1.1.1)
|
||||
plist (3.5.0)
|
||||
public_suffix (4.0.6)
|
||||
rake (13.0.1)
|
||||
representable (3.0.4)
|
||||
declarative (< 0.1.0)
|
||||
declarative-option (< 0.2.0)
|
||||
uber (< 0.2.0)
|
||||
retriable (3.1.2)
|
||||
rouge (2.0.7)
|
||||
ruby2_keywords (0.0.2)
|
||||
rubyzip (2.3.0)
|
||||
security (0.1.3)
|
||||
signet (0.14.0)
|
||||
addressable (~> 2.3)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
jwt (>= 1.5, < 3.0)
|
||||
multi_json (~> 1.10)
|
||||
simctl (1.6.8)
|
||||
CFPropertyList
|
||||
naturally
|
||||
slack-notifier (2.3.2)
|
||||
terminal-notifier (2.0.0)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
tty-cursor (0.7.1)
|
||||
tty-screen (0.8.1)
|
||||
tty-spinner (0.9.3)
|
||||
tty-cursor (~> 0.7)
|
||||
uber (0.1.0)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.7)
|
||||
unicode-display_width (1.7.0)
|
||||
word_wrap (1.0.0)
|
||||
xcodeproj (1.19.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
xcpretty (0.3.0)
|
||||
rouge (~> 2.0.7)
|
||||
xcpretty-travis-formatter (1.0.0)
|
||||
xcpretty (~> 0.2, >= 0.0.7)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
fastlane
|
||||
|
||||
BUNDLED WITH
|
||||
2.1.4
|
||||
@@ -11,10 +11,11 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "me.hackerchick.catima"
|
||||
minSdkVersion 16
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 40
|
||||
versionName "0.29"
|
||||
versionCode 51
|
||||
versionName "1.5.1"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
@@ -43,23 +44,20 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'androidx.appcompat:appcompat:1.2.0'
|
||||
compile 'com.google.android.material:material:1.2.0-alpha03'
|
||||
compile 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
compile 'com.journeyapps:zxing-android-embedded:3.5.0@aar'
|
||||
compile 'com.google.zxing:core:3.3.0'
|
||||
compile 'org.apache.commons:commons-csv:1.5'
|
||||
compile 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
compile 'com.jaredrummler:colorpicker:1.0.2'
|
||||
compile group: 'com.google.guava', name: 'guava', version: '20.0'
|
||||
compile 'com.github.apl-devs:appintro:v4.2.0'
|
||||
compile "com.vanniktech:vntnumberpickerpreference:1.0.0"
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile "org.robolectric:robolectric:4.0.2"
|
||||
|
||||
|
||||
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'com.google.android.material:material:1.2.1'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'com.journeyapps:zxing-android-embedded:3.5.0@aar'
|
||||
implementation 'com.google.zxing:core:3.3.0'
|
||||
implementation 'org.apache.commons:commons-csv:1.5'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation 'com.jaredrummler:colorpicker:1.0.2'
|
||||
implementation group: 'com.google.guava', name: 'guava', version: '20.0'
|
||||
implementation "com.vanniktech:vntnumberpickerpreference:1.0.0"
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation "org.robolectric:robolectric:4.0.2"
|
||||
}
|
||||
|
||||
task findbugs(type: FindBugs, dependsOn: 'assembleDebug') {
|
||||
|
||||
@@ -33,6 +33,16 @@
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".AboutActivity"
|
||||
android:label="@string/about"
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ManageGroupsActivity"
|
||||
android:label="@string/groups"
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".LoyaltyCardViewActivity"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
|
||||
125
app/src/main/java/protect/card_locker/AboutActivity.java
Normal file
@@ -0,0 +1,125 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.util.Linkify;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import org.w3c.dom.Text;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
|
||||
public class AboutActivity extends AppCompatActivity
|
||||
{
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.about_activity);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if(actionBar != null)
|
||||
{
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
final Map<String, String> USED_LIBRARIES = new ImmutableMap.Builder<String, String>()
|
||||
.put("Commons CSV", "https://commons.apache.org/proper/commons-csv/")
|
||||
.put("Guava", "https://github.com/google/guava")
|
||||
.put("ZXing", "https://github.com/zxing/zxing")
|
||||
.put("ZXing Android Embedded", "https://github.com/journeyapps/zxing-android-embedded")
|
||||
.put("Color Picker", "https://github.com/jaredrummler/ColorPicker")
|
||||
.put("VNTNumberPickerPreference", "https://github.com/vanniktech/VNTNumberPickerPreference")
|
||||
.build();
|
||||
|
||||
final Map<String, String> USED_ASSETS = ImmutableMap.of
|
||||
(
|
||||
"Save by Bernar Novalyi", "https://thenounproject.com/term/save/716011"
|
||||
);
|
||||
|
||||
StringBuilder libs = new StringBuilder().append("<br/>");
|
||||
for (Map.Entry<String, String> entry : USED_LIBRARIES.entrySet())
|
||||
{
|
||||
libs.append("<br/><a href=\"").append(entry.getValue()).append("\">").append(entry.getKey()).append("</a><br/>");
|
||||
}
|
||||
|
||||
StringBuilder resources = new StringBuilder().append("<br/>");
|
||||
for (Map.Entry<String, String> entry : USED_ASSETS.entrySet())
|
||||
{
|
||||
resources.append("<br/><a href=\"").append(entry.getValue()).append("\">").append(entry.getKey()).append("</a><br/>");
|
||||
}
|
||||
|
||||
String appName = getString(R.string.app_name);
|
||||
int year = Calendar.getInstance().get(Calendar.YEAR);
|
||||
|
||||
String version = "?";
|
||||
try
|
||||
{
|
||||
PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0);
|
||||
version = pi.versionName;
|
||||
}
|
||||
catch (PackageManager.NameNotFoundException e)
|
||||
{
|
||||
Log.w(TAG, "Package name not found", e);
|
||||
}
|
||||
|
||||
setTitle(String.format(getString(R.string.about_title_fmt), appName));
|
||||
|
||||
TextView aboutTextView = findViewById(R.id.aboutText);
|
||||
aboutTextView.setText(HtmlCompat.fromHtml(String.format(getString(R.string.debug_version_fmt), version) +
|
||||
"<br/><br/>" +
|
||||
String.format(getString(R.string.app_revision_fmt),
|
||||
"<a href=\"" + getString(R.string.app_revision_url) + "\">" +
|
||||
"GitHub" +
|
||||
"</a>") +
|
||||
"<br/><br/>" +
|
||||
String.format(getString(R.string.app_copyright_fmt), year) +
|
||||
"<br/><br/>" +
|
||||
getString(R.string.app_copyright_old) +
|
||||
"<br/><br/>" +
|
||||
getString(R.string.app_license) +
|
||||
"<br/><br/>" +
|
||||
String.format(getString(R.string.app_libraries), appName, libs.toString()) +
|
||||
"<br/><br/>" +
|
||||
String.format(getString(R.string.app_resources), appName, resources.toString()), HtmlCompat.FROM_HTML_MODE_COMPACT));
|
||||
aboutTextView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
int id = item.getItemId();
|
||||
|
||||
if (id == android.R.id.home) {
|
||||
finish();
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
@@ -191,14 +191,7 @@ public class BarcodeSelectorActivity extends AppCompatActivity
|
||||
public void onGlobalLayout()
|
||||
{
|
||||
Log.d(TAG, "Global layout finished, type: + " + formatType + ", width: " + image.getWidth());
|
||||
if (Build.VERSION.SDK_INT < 16)
|
||||
{
|
||||
image.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
image.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
}
|
||||
image.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
|
||||
Log.d(TAG, "Generating barcode for type " + formatType);
|
||||
BarcodeImageWriterTask task = new BarcodeImageWriterTask(image, cardId, format, text);
|
||||
|
||||
23
app/src/main/java/protect/card_locker/BarcodeValues.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package protect.card_locker;
|
||||
|
||||
public class BarcodeValues {
|
||||
private final String mFormat;
|
||||
private final String mContent;
|
||||
|
||||
public BarcodeValues(String format, String content) {
|
||||
mFormat = format;
|
||||
mContent = content;
|
||||
}
|
||||
|
||||
public String format() {
|
||||
return mFormat;
|
||||
}
|
||||
|
||||
public String content() {
|
||||
return mContent;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return mFormat == null && mContent == null;
|
||||
}
|
||||
}
|
||||
@@ -18,28 +18,53 @@ public class CsvDatabaseExporter implements DatabaseExporter
|
||||
{
|
||||
CSVPrinter printer = new CSVPrinter(output, CSVFormat.RFC4180);
|
||||
|
||||
// Print the header
|
||||
// Print the version
|
||||
printer.printRecord("2");
|
||||
|
||||
printer.println();
|
||||
|
||||
// Print the header for groups
|
||||
printer.printRecord(DBHelper.LoyaltyCardDbGroups.ID);
|
||||
|
||||
Cursor groupCursor = db.getGroupCursor();
|
||||
|
||||
while(groupCursor.moveToNext())
|
||||
{
|
||||
Group group = Group.toGroup(groupCursor);
|
||||
|
||||
printer.printRecord(group._id);
|
||||
|
||||
if(Thread.currentThread().isInterrupted())
|
||||
{
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
groupCursor.close();
|
||||
|
||||
// Print an empty line
|
||||
printer.println();
|
||||
|
||||
// Print the header for cards
|
||||
printer.printRecord(DBHelper.LoyaltyCardDbIds.ID,
|
||||
DBHelper.LoyaltyCardDbIds.STORE,
|
||||
DBHelper.LoyaltyCardDbIds.NOTE,
|
||||
DBHelper.LoyaltyCardDbIds.CARD_ID,
|
||||
DBHelper.LoyaltyCardDbIds.HEADER_COLOR,
|
||||
DBHelper.LoyaltyCardDbIds.HEADER_TEXT_COLOR,
|
||||
DBHelper.LoyaltyCardDbIds.BARCODE_TYPE,
|
||||
DBHelper.LoyaltyCardDbIds.STAR_STATUS);
|
||||
|
||||
Cursor cursor = db.getLoyaltyCardCursor();
|
||||
Cursor cardCursor = db.getLoyaltyCardCursor();
|
||||
|
||||
while(cursor.moveToNext())
|
||||
while(cardCursor.moveToNext())
|
||||
{
|
||||
LoyaltyCard card = LoyaltyCard.toLoyaltyCard(cursor);
|
||||
LoyaltyCard card = LoyaltyCard.toLoyaltyCard(cardCursor);
|
||||
|
||||
printer.printRecord(card.id,
|
||||
card.store,
|
||||
card.note,
|
||||
card.cardId,
|
||||
card.headerColor,
|
||||
card.headerTextColor,
|
||||
card.barcodeType,
|
||||
card.starStatus);
|
||||
|
||||
@@ -49,7 +74,32 @@ public class CsvDatabaseExporter implements DatabaseExporter
|
||||
}
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
cardCursor.close();
|
||||
|
||||
// Print an empty line
|
||||
printer.println();
|
||||
|
||||
// Print the header for card group mappings
|
||||
printer.printRecord(DBHelper.LoyaltyCardDbIdsGroups.cardID,
|
||||
DBHelper.LoyaltyCardDbIdsGroups.groupID);
|
||||
|
||||
Cursor cardCursor2 = db.getLoyaltyCardCursor();
|
||||
|
||||
while(cardCursor2.moveToNext())
|
||||
{
|
||||
LoyaltyCard card = LoyaltyCard.toLoyaltyCard(cardCursor2);
|
||||
|
||||
for (Group group : db.getLoyaltyCardGroups(card.id)) {
|
||||
printer.printRecord(card.id, group._id);
|
||||
}
|
||||
|
||||
if(Thread.currentThread().isInterrupted())
|
||||
{
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
cardCursor2.close();
|
||||
|
||||
printer.close();
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVParser;
|
||||
import org.apache.commons.csv.CSVRecord;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringReader;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class for importing a database from CSV (Comma Separate Values)
|
||||
@@ -19,6 +22,34 @@ import java.io.InputStreamReader;
|
||||
public class CsvDatabaseImporter implements DatabaseImporter
|
||||
{
|
||||
public void importData(DBHelper db, InputStreamReader input) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
BufferedReader bufferedReader = new BufferedReader(input);
|
||||
|
||||
bufferedReader.mark(100);
|
||||
|
||||
Integer version = 1;
|
||||
|
||||
try {
|
||||
version = Integer.parseInt(bufferedReader.readLine());
|
||||
} catch (NumberFormatException _e) {
|
||||
// Assume version 1
|
||||
}
|
||||
|
||||
bufferedReader.reset();
|
||||
|
||||
switch (version) {
|
||||
case 1:
|
||||
parseV1(db, bufferedReader);
|
||||
break;
|
||||
case 2:
|
||||
parseV2(db, bufferedReader);
|
||||
break;
|
||||
default:
|
||||
throw new FormatException(String.format("No code to parse version %s", version));
|
||||
}
|
||||
}
|
||||
|
||||
public void parseV1(DBHelper db, BufferedReader input) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
final CSVParser parser = new CSVParser(input, CSVFormat.RFC4180.withHeader());
|
||||
|
||||
@@ -51,6 +82,116 @@ public class CsvDatabaseImporter implements DatabaseImporter
|
||||
}
|
||||
}
|
||||
|
||||
public void parseV2(DBHelper db, BufferedReader input) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
SQLiteDatabase database = db.getWritableDatabase();
|
||||
database.beginTransaction();
|
||||
|
||||
Integer part = 0;
|
||||
String stringPart = "";
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
String tmp = input.readLine();
|
||||
|
||||
if (tmp == null || tmp.isEmpty()) {
|
||||
switch (part) {
|
||||
case 0:
|
||||
// This is the version info, ignore
|
||||
break;
|
||||
case 1:
|
||||
parseV2Groups(db, database, stringPart);
|
||||
break;
|
||||
case 2:
|
||||
parseV2Cards(db, database, stringPart);
|
||||
break;
|
||||
case 3:
|
||||
parseV2CardGroups(db, database, stringPart);
|
||||
break;
|
||||
default:
|
||||
throw new FormatException("Issue parsing CSV data, too many parts for v2 parsing");
|
||||
}
|
||||
|
||||
if (tmp == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
part += 1;
|
||||
stringPart = "";
|
||||
} else {
|
||||
stringPart += tmp + "\n";
|
||||
}
|
||||
}
|
||||
database.setTransactionSuccessful();
|
||||
} catch (FormatException e) {
|
||||
throw new FormatException("Issue parsing CSV data", e);
|
||||
} finally {
|
||||
database.endTransaction();
|
||||
database.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void parseV2Groups(DBHelper db, SQLiteDatabase database, String data) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
// Parse groups
|
||||
final CSVParser groupParser = new CSVParser(new StringReader(data), CSVFormat.RFC4180.withHeader());
|
||||
|
||||
try {
|
||||
for (CSVRecord record : groupParser) {
|
||||
importGroup(database, db, record);
|
||||
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
groupParser.close();
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
throw new FormatException("Issue parsing CSV data", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void parseV2Cards(DBHelper db, SQLiteDatabase database, String data) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
// Parse cards
|
||||
final CSVParser cardParser = new CSVParser(new StringReader(data), CSVFormat.RFC4180.withHeader());
|
||||
|
||||
try {
|
||||
for (CSVRecord record : cardParser) {
|
||||
importLoyaltyCard(database, db, record);
|
||||
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
cardParser.close();
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
throw new FormatException("Issue parsing CSV data", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void parseV2CardGroups(DBHelper db, SQLiteDatabase database, String data) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
// Parse card group mappings
|
||||
final CSVParser cardGroupParser = new CSVParser(new StringReader(data), CSVFormat.RFC4180.withHeader());
|
||||
|
||||
try {
|
||||
for (CSVRecord record : cardGroupParser) {
|
||||
importCardGroupMapping(database, db, record);
|
||||
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
cardGroupParser.close();
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
throw new FormatException("Issue parsing CSV data", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a string from the items array. The index into the array
|
||||
* is determined by looking up the index in the fields map using the
|
||||
@@ -133,23 +274,47 @@ public class CsvDatabaseImporter implements DatabaseImporter
|
||||
String barcodeType = extractString(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE, record, "");
|
||||
|
||||
Integer headerColor = null;
|
||||
Integer headerTextColor = null;
|
||||
|
||||
if(record.isMapped(DBHelper.LoyaltyCardDbIds.HEADER_COLOR) &&
|
||||
record.isMapped(DBHelper.LoyaltyCardDbIds.HEADER_TEXT_COLOR))
|
||||
if(record.isMapped(DBHelper.LoyaltyCardDbIds.HEADER_COLOR))
|
||||
{
|
||||
headerColor = extractInt(DBHelper.LoyaltyCardDbIds.HEADER_COLOR, record, true);
|
||||
headerTextColor = extractInt(DBHelper.LoyaltyCardDbIds.HEADER_TEXT_COLOR, record, true);
|
||||
}
|
||||
|
||||
int starStatus = 0;
|
||||
try {
|
||||
starStatus = extractInt(DBHelper.LoyaltyCardDbIds.STAR_STATUS, record, false);
|
||||
} catch (FormatException _ ) {
|
||||
} catch (FormatException _e ) {
|
||||
// This field did not exist in versions 0.28 and before
|
||||
// We catch this exception so we can still import old backups
|
||||
}
|
||||
if (starStatus != 1) starStatus = 0;
|
||||
helper.insertLoyaltyCard(database, id, store, note, cardId, barcodeType, headerColor, headerTextColor, starStatus);
|
||||
helper.insertLoyaltyCard(database, id, store, note, cardId, barcodeType, headerColor, starStatus);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a single group into the database using the given
|
||||
* session.
|
||||
*/
|
||||
private void importGroup(SQLiteDatabase database, DBHelper helper, CSVRecord record)
|
||||
throws IOException, FormatException
|
||||
{
|
||||
String id = extractString(DBHelper.LoyaltyCardDbGroups.ID, record, null);
|
||||
|
||||
helper.insertGroup(database, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a single card to group mapping into the database using the given
|
||||
* session.
|
||||
*/
|
||||
private void importCardGroupMapping(SQLiteDatabase database, DBHelper helper, CSVRecord record)
|
||||
throws IOException, FormatException
|
||||
{
|
||||
Integer cardId = extractInt(DBHelper.LoyaltyCardDbIdsGroups.cardID, record, false);
|
||||
String groupId = extractString(DBHelper.LoyaltyCardDbIdsGroups.groupID, record, null);
|
||||
|
||||
List<Group> cardGroups = helper.getLoyaltyCardGroups(cardId);
|
||||
cardGroups.add(helper.getGroup(groupId));
|
||||
helper.setLoyaltyCardGroups(database, cardId, cardGroups);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,27 @@
|
||||
package protect.card_locker;
|
||||
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.graphics.Color;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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 = 4;
|
||||
public static final int DATABASE_VERSION = 6;
|
||||
|
||||
static class LoyaltyCardDbGroups
|
||||
{
|
||||
public static final String TABLE = "groups";
|
||||
public static final String ID = "_id";
|
||||
public static final String ORDER = "orderId";
|
||||
}
|
||||
|
||||
static class LoyaltyCardDbIds
|
||||
{
|
||||
@@ -26,6 +36,13 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
public static final String STAR_STATUS = "starstatus";
|
||||
}
|
||||
|
||||
static class LoyaltyCardDbIdsGroups
|
||||
{
|
||||
public static final String TABLE = "cardsGroups";
|
||||
public static final String cardID = "cardId";
|
||||
public static final String groupID = "groupId";
|
||||
}
|
||||
|
||||
public DBHelper(Context context)
|
||||
{
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
@@ -34,7 +51,12 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db)
|
||||
{
|
||||
// create table for gift cards
|
||||
// create table for card groups
|
||||
db.execSQL("create table " + LoyaltyCardDbGroups.TABLE + "(" +
|
||||
LoyaltyCardDbGroups.ID + " TEXT primary key not null," +
|
||||
LoyaltyCardDbGroups.ORDER + " INTEGER DEFAULT '0')");
|
||||
|
||||
// create table for cards
|
||||
db.execSQL("create table " + LoyaltyCardDbIds.TABLE + "(" +
|
||||
LoyaltyCardDbIds.ID + " INTEGER primary key autoincrement," +
|
||||
LoyaltyCardDbIds.STORE + " TEXT not null," +
|
||||
@@ -44,6 +66,12 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
LoyaltyCardDbIds.CARD_ID + " TEXT not null," +
|
||||
LoyaltyCardDbIds.BARCODE_TYPE + " TEXT not null," +
|
||||
LoyaltyCardDbIds.STAR_STATUS + " INTEGER DEFAULT '0' )");
|
||||
|
||||
// create associative table for cards in groups
|
||||
db.execSQL("create table " + LoyaltyCardDbIdsGroups.TABLE + "(" +
|
||||
LoyaltyCardDbIdsGroups.cardID + " INTEGER," +
|
||||
LoyaltyCardDbIdsGroups.groupID + " TEXT," +
|
||||
"primary key (" + LoyaltyCardDbIdsGroups.cardID + "," + LoyaltyCardDbIdsGroups.groupID +"))");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,18 +92,37 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
db.execSQL("ALTER TABLE " + LoyaltyCardDbIds.TABLE
|
||||
+ " ADD COLUMN " + LoyaltyCardDbIds.HEADER_TEXT_COLOR + " INTEGER");
|
||||
}
|
||||
|
||||
// Upgrade from version 3 to version 4
|
||||
if(oldVersion < 4 && newVersion >= 4)
|
||||
{
|
||||
db.execSQL("ALTER TABLE " + LoyaltyCardDbIds.TABLE
|
||||
+ " ADD COLUMN " + LoyaltyCardDbIds.STAR_STATUS + " INTEGER DEFAULT '0'");
|
||||
}
|
||||
|
||||
// Upgrade from version 4 to version 5
|
||||
if(oldVersion < 5 && newVersion >= 5)
|
||||
{
|
||||
db.execSQL("create table " + LoyaltyCardDbGroups.TABLE + "(" +
|
||||
LoyaltyCardDbGroups.ID + " TEXT primary key not null)");
|
||||
|
||||
db.execSQL("create table " + LoyaltyCardDbIdsGroups.TABLE + "(" +
|
||||
LoyaltyCardDbIdsGroups.cardID + " INTEGER," +
|
||||
LoyaltyCardDbIdsGroups.groupID + " TEXT," +
|
||||
"primary key (" + LoyaltyCardDbIdsGroups.cardID + "," + LoyaltyCardDbIdsGroups.groupID +"))");
|
||||
}
|
||||
|
||||
// Upgrade from version 5 to 6
|
||||
if(oldVersion < 6 && newVersion >= 6)
|
||||
{
|
||||
db.execSQL("ALTER TABLE " + LoyaltyCardDbGroups.TABLE
|
||||
+ " ADD COLUMN " + LoyaltyCardDbGroups.ORDER + " INTEGER DEFAULT '0'");
|
||||
}
|
||||
}
|
||||
|
||||
public long insertLoyaltyCard(final String store, final String note, final String cardId,
|
||||
final String barcodeType, final Integer headerColor,
|
||||
final Integer headerTextColor, final int starStatus)
|
||||
final int starStatus)
|
||||
{
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
@@ -84,16 +131,16 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_COLOR, headerColor);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_TEXT_COLOR, headerTextColor);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_TEXT_COLOR, Color.WHITE);
|
||||
contentValues.put(LoyaltyCardDbIds.STAR_STATUS, starStatus);
|
||||
final long newId = db.insert(LoyaltyCardDbIds.TABLE, null, contentValues);
|
||||
return newId;
|
||||
}
|
||||
|
||||
public boolean insertLoyaltyCard(final SQLiteDatabase db, final int id,
|
||||
final String store, final String note, final String cardId,
|
||||
public boolean insertLoyaltyCard(final SQLiteDatabase db, final int id, final String store,
|
||||
final String note, final String cardId,
|
||||
final String barcodeType, final Integer headerColor,
|
||||
final Integer headerTextColor, final int starStatus)
|
||||
final int starStatus)
|
||||
{
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbIds.ID, id);
|
||||
@@ -102,16 +149,15 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_COLOR, headerColor);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_TEXT_COLOR, headerTextColor);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_TEXT_COLOR, Color.WHITE);
|
||||
contentValues.put(LoyaltyCardDbIds.STAR_STATUS,starStatus);
|
||||
final long newId = db.insert(LoyaltyCardDbIds.TABLE, null, contentValues);
|
||||
return (newId != -1);
|
||||
}
|
||||
|
||||
|
||||
public boolean updateLoyaltyCard(final int id, final String store, final String note,
|
||||
final String cardId, final String barcodeType,
|
||||
final Integer headerColor, final Integer headerTextColor)
|
||||
final Integer headerColor)
|
||||
{
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
@@ -120,7 +166,7 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_COLOR, headerColor);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_TEXT_COLOR, headerTextColor);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_TEXT_COLOR, Color.WHITE);
|
||||
int rowsUpdated = db.update(LoyaltyCardDbIds.TABLE, contentValues,
|
||||
LoyaltyCardDbIds.ID + "=?",
|
||||
new String[]{Integer.toString(id)});
|
||||
@@ -149,6 +195,7 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
if(data.getCount() == 1)
|
||||
{
|
||||
data.moveToFirst();
|
||||
|
||||
card = LoyaltyCard.toLoyaltyCard(data);
|
||||
}
|
||||
|
||||
@@ -157,12 +204,76 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
return card;
|
||||
}
|
||||
|
||||
public List<Group> getLoyaltyCardGroups(final int id)
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
Cursor data = db.rawQuery("select * from " + LoyaltyCardDbGroups.TABLE + " g " +
|
||||
" LEFT JOIN " + LoyaltyCardDbIdsGroups.TABLE + " ig ON ig." + LoyaltyCardDbIdsGroups.groupID + " = g." + LoyaltyCardDbGroups.ID +
|
||||
" where " + LoyaltyCardDbIdsGroups.cardID + "=?" +
|
||||
" ORDER BY " + LoyaltyCardDbIdsGroups.groupID, new String[]{String.format("%d", id)});
|
||||
|
||||
List<Group> groups = new ArrayList<>();
|
||||
|
||||
if (!data.moveToFirst()) {
|
||||
return groups;
|
||||
}
|
||||
|
||||
groups.add(Group.toGroup(data));
|
||||
|
||||
while (data.moveToNext()) {
|
||||
groups.add(Group.toGroup(data));
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
public void setLoyaltyCardGroups(final int id, List<Group> groups)
|
||||
{
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
|
||||
// First delete lookup table entries associated with this card
|
||||
db.delete(LoyaltyCardDbIdsGroups.TABLE,
|
||||
LoyaltyCardDbIdsGroups.cardID + " = ? ",
|
||||
new String[]{String.format("%d", id)});
|
||||
|
||||
// Then create entries for selected values
|
||||
for (Group group : groups) {
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbIdsGroups.cardID, id);
|
||||
contentValues.put(LoyaltyCardDbIdsGroups.groupID, group._id);
|
||||
db.insert(LoyaltyCardDbIdsGroups.TABLE, null, contentValues);
|
||||
}
|
||||
}
|
||||
|
||||
public void setLoyaltyCardGroups(final SQLiteDatabase db, final int id, List<Group> groups)
|
||||
{
|
||||
// First delete lookup table entries associated with this card
|
||||
db.delete(LoyaltyCardDbIdsGroups.TABLE,
|
||||
LoyaltyCardDbIdsGroups.cardID + " = ? ",
|
||||
new String[]{String.format("%d", id)});
|
||||
|
||||
// Then create entries for selected values
|
||||
for (Group group : groups) {
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbIdsGroups.cardID, id);
|
||||
contentValues.put(LoyaltyCardDbIdsGroups.groupID, group._id);
|
||||
db.insert(LoyaltyCardDbIdsGroups.TABLE, null, contentValues);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean deleteLoyaltyCard (final int id)
|
||||
{
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
int rowsDeleted = db.delete(LoyaltyCardDbIds.TABLE,
|
||||
// Delete card
|
||||
int rowsDeleted = db.delete(LoyaltyCardDbIds.TABLE,
|
||||
LoyaltyCardDbIds.ID + " = ? ",
|
||||
new String[]{String.format("%d", id)});
|
||||
|
||||
// And delete lookup table entries associated with this card
|
||||
db.delete(LoyaltyCardDbIdsGroups.TABLE,
|
||||
LoyaltyCardDbIdsGroups.cardID + " = ? ",
|
||||
new String[]{String.format("%d", id)});
|
||||
|
||||
return (rowsDeleted == 1);
|
||||
}
|
||||
|
||||
@@ -179,16 +290,52 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
* @return Cursor
|
||||
*/
|
||||
public Cursor getLoyaltyCardCursor(final String filter)
|
||||
{
|
||||
return getLoyaltyCardCursor(filter, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cursor to all loyalty cards with the filter text in either the store or note in a certain group.
|
||||
*
|
||||
* @param filter
|
||||
* @param group
|
||||
* @return Cursor
|
||||
*/
|
||||
public Cursor getLoyaltyCardCursor(final String filter, Group group)
|
||||
{
|
||||
String actualFilter = String.format("%%%s%%", filter);
|
||||
String[] selectionArgs = { actualFilter, actualFilter };
|
||||
StringBuilder groupFilter = new StringBuilder();
|
||||
String limitString = "";
|
||||
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
|
||||
if (group != null) {
|
||||
List<Integer> allowedIds = getGroupCardIds(group._id);
|
||||
|
||||
// Empty group
|
||||
if (allowedIds.size() > 0) {
|
||||
groupFilter.append("AND (");
|
||||
|
||||
for (int i = 0; i < allowedIds.size(); i++) {
|
||||
groupFilter.append(LoyaltyCardDbIds.ID + " = " + allowedIds.get(i));
|
||||
if (i != allowedIds.size() - 1) {
|
||||
groupFilter.append(" OR ");
|
||||
}
|
||||
}
|
||||
groupFilter.append(") ");
|
||||
} else {
|
||||
limitString = "LIMIT 0";
|
||||
}
|
||||
}
|
||||
|
||||
Cursor res = db.rawQuery("select * from " + LoyaltyCardDbIds.TABLE +
|
||||
" WHERE " + LoyaltyCardDbIds.STORE + " LIKE ? " +
|
||||
" OR " + LoyaltyCardDbIds.NOTE + " LIKE ? " +
|
||||
" ORDER BY " + LoyaltyCardDbIds.STAR_STATUS + " DESC," + LoyaltyCardDbIds.STORE + " COLLATE NOCASE ASC", selectionArgs, null);
|
||||
" WHERE (" + LoyaltyCardDbIds.STORE + " LIKE ? " +
|
||||
" OR " + LoyaltyCardDbIds.NOTE + " LIKE ? )" +
|
||||
groupFilter.toString() +
|
||||
" ORDER BY " + LoyaltyCardDbIds.STAR_STATUS + " DESC," + LoyaltyCardDbIds.STORE + " COLLATE NOCASE ASC " +
|
||||
limitString, selectionArgs, null);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -227,5 +374,194 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
|
||||
return numItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cursor to all groups.
|
||||
*
|
||||
* @return Cursor
|
||||
*/
|
||||
public Cursor getGroupCursor()
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
|
||||
Cursor res = db.rawQuery("select * from " + LoyaltyCardDbGroups.TABLE +
|
||||
" ORDER BY " + LoyaltyCardDbGroups.ORDER + " ASC," + LoyaltyCardDbGroups.ID + " COLLATE NOCASE ASC", null, null);
|
||||
return res;
|
||||
}
|
||||
|
||||
public List<Group> getGroups() {
|
||||
Cursor data = getGroupCursor();
|
||||
|
||||
List<Group> groups = new ArrayList<>();
|
||||
|
||||
if (!data.moveToFirst()) {
|
||||
return groups;
|
||||
}
|
||||
|
||||
groups.add(Group.toGroup(data));
|
||||
|
||||
while (data.moveToNext()) {
|
||||
groups.add(Group.toGroup(data));
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
public void reorderGroups(final List<Group> groups)
|
||||
{
|
||||
Integer order = 0;
|
||||
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues contentValues;
|
||||
|
||||
for (Group group : groups)
|
||||
{
|
||||
contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbGroups.ORDER, order);
|
||||
|
||||
db.update(LoyaltyCardDbGroups.TABLE, contentValues,
|
||||
LoyaltyCardDbGroups.ID + "=?",
|
||||
new String[]{group._id});
|
||||
|
||||
order++;
|
||||
}
|
||||
}
|
||||
|
||||
public Group getGroup(final String groupName)
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
Cursor data = db.rawQuery("select * from " + LoyaltyCardDbGroups.TABLE +
|
||||
" where " + LoyaltyCardDbGroups.ID + "=?", new String[]{groupName});
|
||||
|
||||
Group group = null;
|
||||
|
||||
if(data.getCount() == 1)
|
||||
{
|
||||
data.moveToFirst();
|
||||
|
||||
group = Group.toGroup(data);
|
||||
}
|
||||
|
||||
data.close();
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
public int getGroupCount()
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
Cursor data = db.rawQuery("SELECT Count(*) FROM " + LoyaltyCardDbGroups.TABLE, null);
|
||||
|
||||
int numItems = 0;
|
||||
|
||||
if(data.getCount() == 1)
|
||||
{
|
||||
data.moveToFirst();
|
||||
numItems = data.getInt(0);
|
||||
}
|
||||
|
||||
data.close();
|
||||
|
||||
return numItems;
|
||||
}
|
||||
|
||||
public List<Integer> getGroupCardIds(final String groupName)
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
Cursor data = db.rawQuery("SELECT " + LoyaltyCardDbIdsGroups.cardID +
|
||||
" FROM " + LoyaltyCardDbIdsGroups.TABLE +
|
||||
" WHERE " + LoyaltyCardDbIdsGroups.groupID + " =? ", new String[]{groupName});
|
||||
|
||||
List<Integer> cardIds = new ArrayList<>();
|
||||
|
||||
if (!data.moveToFirst()) {
|
||||
return cardIds;
|
||||
}
|
||||
|
||||
cardIds.add(data.getInt(0));
|
||||
|
||||
while (data.moveToNext()) {
|
||||
cardIds.add(data.getInt(0));
|
||||
}
|
||||
|
||||
data.close();
|
||||
|
||||
return cardIds;
|
||||
}
|
||||
|
||||
public long insertGroup(final String name)
|
||||
{
|
||||
if (name.isEmpty()) return -1;
|
||||
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbGroups.ID, name);
|
||||
contentValues.put(LoyaltyCardDbGroups.ORDER, getGroupCount());
|
||||
final long newId = db.insert(LoyaltyCardDbGroups.TABLE, null, contentValues);
|
||||
return newId;
|
||||
}
|
||||
|
||||
public boolean insertGroup(final SQLiteDatabase db, final String name)
|
||||
{
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbGroups.ID, name);
|
||||
contentValues.put(LoyaltyCardDbGroups.ORDER, getGroupCount());
|
||||
final long newId = db.insert(LoyaltyCardDbGroups.TABLE, null, contentValues);
|
||||
return (newId != -1);
|
||||
}
|
||||
|
||||
public boolean updateGroup(final String groupName, final String newName)
|
||||
{
|
||||
if (newName.isEmpty()) return false;
|
||||
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbGroups.ID, newName);
|
||||
try {
|
||||
int rowsUpdated = db.update(LoyaltyCardDbGroups.TABLE, contentValues,
|
||||
LoyaltyCardDbGroups.ID + "=?",
|
||||
new String[]{groupName});
|
||||
return (rowsUpdated == 1);
|
||||
} catch (android.database.sqlite.SQLiteConstraintException _e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean deleteGroup(final String groupName)
|
||||
{
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
// Delete group
|
||||
int rowsDeleted = db.delete(LoyaltyCardDbGroups.TABLE,
|
||||
LoyaltyCardDbGroups.ID + " = ? ",
|
||||
new String[]{groupName});
|
||||
|
||||
// And delete lookup table entries associated with this group
|
||||
db.delete(LoyaltyCardDbIdsGroups.TABLE,
|
||||
LoyaltyCardDbIdsGroups.groupID + " = ? ",
|
||||
new String[]{groupName});
|
||||
|
||||
return (rowsDeleted == 1);
|
||||
}
|
||||
|
||||
public int getGroupCardCount(final String groupName)
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
|
||||
Cursor data = db.rawQuery("SELECT Count(*) FROM " + LoyaltyCardDbIdsGroups.TABLE +
|
||||
" where " + LoyaltyCardDbIdsGroups.groupID + "=?",
|
||||
new String[]{groupName});
|
||||
|
||||
int numItems = 0;
|
||||
|
||||
if(data.getCount() == 1)
|
||||
{
|
||||
data.moveToFirst();
|
||||
numItems = data.getInt(0);
|
||||
}
|
||||
|
||||
data.close();
|
||||
|
||||
return numItems;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
20
app/src/main/java/protect/card_locker/Group.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
public class Group
|
||||
{
|
||||
public final String _id;
|
||||
|
||||
public Group(final String _id)
|
||||
{
|
||||
this._id = _id;
|
||||
}
|
||||
|
||||
public static Group toGroup(Cursor cursor)
|
||||
{
|
||||
String _id = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbGroups.ID));
|
||||
|
||||
return new Group(_id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CursorAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import protect.card_locker.preferences.Settings;
|
||||
|
||||
class GroupCursorAdapter extends CursorAdapter
|
||||
{
|
||||
Settings settings;
|
||||
DBHelper db;
|
||||
|
||||
public GroupCursorAdapter(Context context, Cursor cursor)
|
||||
{
|
||||
super(context, cursor, 0);
|
||||
settings = new Settings(context);
|
||||
|
||||
db = new DBHelper(context);
|
||||
}
|
||||
|
||||
// The newView method is used to inflate a new view and return it,
|
||||
// you don't bind any data to the view at this point.
|
||||
@Override
|
||||
public View newView(Context context, Cursor cursor, ViewGroup parent)
|
||||
{
|
||||
return LayoutInflater.from(context).inflate(R.layout.group_layout, parent, false);
|
||||
}
|
||||
|
||||
// The bindView method is used to bind all data to a given view
|
||||
// such as setting the text on a TextView.
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor)
|
||||
{
|
||||
// Find fields to populate in inflated template
|
||||
TextView nameField = view.findViewById(R.id.name);
|
||||
TextView countField = view.findViewById(R.id.cardCount);
|
||||
|
||||
// Extract properties from cursor
|
||||
Group group = Group.toGroup(cursor);
|
||||
|
||||
Integer groupCardCount = db.getGroupCardCount(group._id);
|
||||
|
||||
// Populate fields with extracted properties
|
||||
nameField.setText(group._id);
|
||||
|
||||
countField.setText(context.getResources().getQuantityString(R.plurals.groupCardCount, groupCardCount, groupCardCount));
|
||||
|
||||
nameField.setTextSize(settings.getCardTitleListFontSize());
|
||||
countField.setTextSize(settings.getCardNoteListFontSize());
|
||||
}
|
||||
}
|
||||
@@ -100,14 +100,6 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
}
|
||||
});
|
||||
|
||||
if(isCallable(getApplicationContext(), intentGetContentAction) == false)
|
||||
{
|
||||
findViewById(R.id.dividerImportFilesystem).setVisibility(View.GONE);
|
||||
findViewById(R.id.importOptionFilesystemTitle).setVisibility(View.GONE);
|
||||
findViewById(R.id.importOptionFilesystemExplanation).setVisibility(View.GONE);
|
||||
importFilesystem.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// Check that there is an app that data can be imported from
|
||||
final Intent intentPickAction = new Intent(Intent.ACTION_PICK);
|
||||
|
||||
@@ -120,14 +112,6 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
chooseFileWithIntent(intentPickAction, CHOOSE_EXPORTED_FILE);
|
||||
}
|
||||
});
|
||||
|
||||
if(isCallable(getApplicationContext(), intentPickAction) == false)
|
||||
{
|
||||
findViewById(R.id.dividerImportApplication).setVisibility(View.GONE);
|
||||
findViewById(R.id.importOptionApplicationTitle).setVisibility(View.GONE);
|
||||
findViewById(R.id.importOptionApplicationExplanation).setVisibility(View.GONE);
|
||||
importApplication.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void startImport(final InputStream target, final Uri targetUri)
|
||||
@@ -295,31 +279,6 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if there is at least one activity that can perform the given intent
|
||||
*/
|
||||
private boolean isCallable(Context context, final Intent intent)
|
||||
{
|
||||
PackageManager manager = context.getPackageManager();
|
||||
if(manager == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
List<ResolveInfo> list = manager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
|
||||
for(ResolveInfo info : list)
|
||||
{
|
||||
if(info.activityInfo.exported)
|
||||
{
|
||||
// There is one activity which is available to be called
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void chooseFileWithIntent(Intent intent, int requestCode)
|
||||
{
|
||||
try
|
||||
@@ -328,6 +287,7 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
}
|
||||
catch (ActivityNotFoundException e)
|
||||
{
|
||||
Toast.makeText(getApplicationContext(), R.string.failedOpeningFileManager, Toast.LENGTH_LONG).show();
|
||||
Log.e(TAG, "No activity found to handle intent", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,6 @@ public class ImportURIHelper {
|
||||
private static final String BARCODE_TYPE = DBHelper.LoyaltyCardDbIds.BARCODE_TYPE;
|
||||
|
||||
private static final String HEADER_COLOR = DBHelper.LoyaltyCardDbIds.HEADER_COLOR;
|
||||
private static final String HEADER_TEXT_COLOR = DBHelper.LoyaltyCardDbIds.HEADER_TEXT_COLOR;
|
||||
|
||||
|
||||
|
||||
private final Context context;
|
||||
private final String host;
|
||||
@@ -57,11 +54,6 @@ public class ImportURIHelper {
|
||||
{
|
||||
headerColor = Integer.parseInt(unparsedHeaderColor);
|
||||
}
|
||||
String unparsedHeaderTextColor = uri.getQueryParameter(HEADER_TEXT_COLOR);
|
||||
if(unparsedHeaderTextColor != null)
|
||||
{
|
||||
headerTextColor = Integer.parseInt(unparsedHeaderTextColor);
|
||||
}
|
||||
|
||||
return new LoyaltyCard(-1, store, note, cardId, barcodeType, headerColor, headerTextColor, 0);
|
||||
} catch (NullPointerException | NumberFormatException ex) {
|
||||
@@ -83,10 +75,6 @@ public class ImportURIHelper {
|
||||
{
|
||||
uriBuilder.appendQueryParameter(HEADER_COLOR, loyaltyCard.headerColor.toString());
|
||||
}
|
||||
if(loyaltyCard.headerTextColor != null)
|
||||
{
|
||||
uriBuilder.appendQueryParameter(HEADER_TEXT_COLOR, loyaltyCard.headerTextColor.toString());
|
||||
}
|
||||
//StarStatus will not be exported
|
||||
return uriBuilder.build();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class LoyaltyCard
|
||||
@@ -20,7 +21,8 @@ public class LoyaltyCard
|
||||
public final int starStatus;
|
||||
|
||||
public LoyaltyCard(final int id, final String store, final String note, final String cardId,
|
||||
final String barcodeType, final Integer headerColor, final Integer headerTextColor,final int starStatus)
|
||||
final String barcodeType, final Integer headerColor, final Integer headerTextColor,
|
||||
final int starStatus)
|
||||
{
|
||||
this.id = id;
|
||||
this.store = store;
|
||||
|
||||
@@ -15,14 +15,11 @@ import protect.card_locker.preferences.Settings;
|
||||
class LoyaltyCardCursorAdapter extends CursorAdapter
|
||||
{
|
||||
Settings settings;
|
||||
boolean darkModeEnabled;
|
||||
|
||||
public LoyaltyCardCursorAdapter(Context context, Cursor cursor)
|
||||
{
|
||||
super(context, cursor, 0);
|
||||
settings = new Settings(context);
|
||||
darkModeEnabled= MainActivity.isDarkModeEnabled(context);
|
||||
|
||||
}
|
||||
|
||||
// The newView method is used to inflate a new view and return it,
|
||||
@@ -44,11 +41,6 @@ class LoyaltyCardCursorAdapter extends CursorAdapter
|
||||
TextView noteField = view.findViewById(R.id.note);
|
||||
ImageView star = view.findViewById(R.id.star);
|
||||
|
||||
if(darkModeEnabled)
|
||||
{
|
||||
star.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
|
||||
// Extract properties from cursor
|
||||
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(cursor);
|
||||
|
||||
@@ -71,13 +63,6 @@ class LoyaltyCardCursorAdapter extends CursorAdapter
|
||||
if (loyaltyCard.starStatus!=0) star.setVisibility(View.VISIBLE);
|
||||
else star.setVisibility(View.GONE);
|
||||
|
||||
int tileLetterFontSize = context.getResources().getDimensionPixelSize(R.dimen.tileLetterFontSize);
|
||||
int pixelSize = context.getResources().getDimensionPixelSize(R.dimen.cardThumbnailSize);
|
||||
|
||||
Integer letterBackgroundColor = loyaltyCard.headerColor;
|
||||
Integer letterTextColor = loyaltyCard.headerTextColor;
|
||||
LetterBitmap letterBitmap = new LetterBitmap(context, loyaltyCard.store, loyaltyCard.store,
|
||||
tileLetterFontSize, pixelSize, pixelSize, letterBackgroundColor, letterTextColor);
|
||||
thumbnail.setImageBitmap(letterBitmap.getLetterTile());
|
||||
thumbnail.setImageBitmap(Utils.generateIcon(context, loyaltyCard.store, loyaltyCard.headerColor).getLetterTile());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,17 +9,25 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.google.android.material.chip.Chip;
|
||||
import com.google.android.material.chip.ChipGroup;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
@@ -33,45 +41,51 @@ import com.jaredrummler.android.colorpicker.ColorPickerDialog;
|
||||
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener;
|
||||
|
||||
import java.io.InvalidObjectException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
{
|
||||
private static final String TAG = "Catima";
|
||||
protected static final String NO_BARCODE = "_NO_BARCODE_";
|
||||
|
||||
protected static final int SELECT_BARCODE_REQUEST = 1;
|
||||
|
||||
ImageView thumbnail;
|
||||
EditText storeFieldEdit;
|
||||
EditText noteFieldEdit;
|
||||
ImageView headingColorSample;
|
||||
Button headingColorSelectButton;
|
||||
ImageView headingStoreTextColorSample;
|
||||
Button headingStoreTextColorSelectButton;
|
||||
ChipGroup groupsChips;
|
||||
View cardAndBarcodeLayout;
|
||||
TextView cardIdFieldView;
|
||||
View cardIdDivider;
|
||||
View cardIdTableRow;
|
||||
TextView barcodeTypeField;
|
||||
View barcodeTypeView;
|
||||
AutoCompleteTextView barcodeTypeField;
|
||||
ImageView barcodeImage;
|
||||
View barcodeImageLayout;
|
||||
View barcodeCaptureLayout;
|
||||
|
||||
Button captureButton;
|
||||
Button enterButton;
|
||||
|
||||
int loyaltyCardId;
|
||||
boolean updateLoyaltyCard;
|
||||
String barcodeType;
|
||||
String cardId;
|
||||
|
||||
Uri importLoyaltyCardUri = null;
|
||||
Integer headingColorValue = null;
|
||||
Integer headingStoreTextColorValue = null;
|
||||
|
||||
DBHelper db;
|
||||
ImportURIHelper importUriHelper;
|
||||
|
||||
boolean hasChanged = false;
|
||||
boolean initDone = false;
|
||||
AlertDialog confirmExitDialog = null;
|
||||
|
||||
private void extractIntentFields(Intent intent)
|
||||
{
|
||||
final Bundle b = intent.getExtras();
|
||||
loyaltyCardId = b != null ? b.getInt("id") : 0;
|
||||
updateLoyaltyCard = b != null && b.getBoolean("update", false);
|
||||
|
||||
barcodeType = b != null ? b.getString("barcodeType") : null;
|
||||
cardId = b != null ? b.getString("cardId") : null;
|
||||
|
||||
importLoyaltyCardUri = intent.getData();
|
||||
|
||||
Log.d(TAG, "View activity: id=" + loyaltyCardId
|
||||
@@ -97,22 +111,78 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
db = new DBHelper(this);
|
||||
importUriHelper = new ImportURIHelper(this);
|
||||
|
||||
thumbnail = findViewById(R.id.thumbnail);
|
||||
storeFieldEdit = findViewById(R.id.storeNameEdit);
|
||||
noteFieldEdit = findViewById(R.id.noteEdit);
|
||||
headingColorSample = findViewById(R.id.headingColorSample);
|
||||
headingColorSelectButton = findViewById(R.id.headingColorSelectButton);
|
||||
headingStoreTextColorSample = findViewById(R.id.headingStoreTextColorSample);
|
||||
headingStoreTextColorSelectButton = findViewById(R.id.headingStoreTextColorSelectButton);
|
||||
groupsChips = findViewById(R.id.groupChips);
|
||||
cardAndBarcodeLayout = findViewById(R.id.cardAndBarcodeLayout);
|
||||
cardIdFieldView = findViewById(R.id.cardIdView);
|
||||
cardIdDivider = findViewById(R.id.cardIdDivider);
|
||||
cardIdTableRow = findViewById(R.id.cardIdTableRow);
|
||||
barcodeTypeField = findViewById(R.id.barcodeTypeView);
|
||||
barcodeTypeView = findViewById(R.id.barcodeTypeView);
|
||||
barcodeTypeField = findViewById(R.id.barcodeTypeField);
|
||||
barcodeImage = findViewById(R.id.barcode);
|
||||
barcodeImageLayout = findViewById(R.id.barcodeLayout);
|
||||
barcodeCaptureLayout = findViewById(R.id.barcodeCaptureLayout);
|
||||
|
||||
captureButton = findViewById(R.id.captureButton);
|
||||
enterButton = findViewById(R.id.enterButton);
|
||||
|
||||
storeFieldEdit.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
hasChanged = true;
|
||||
|
||||
generateIcon(s.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) { }
|
||||
});
|
||||
|
||||
cardIdFieldView.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
hasChanged = true;
|
||||
|
||||
String formatString = barcodeTypeField.getText().toString();
|
||||
|
||||
if (!formatString.isEmpty()) {
|
||||
if (formatString.equals(getString(R.string.noBarcode))) {
|
||||
hideBarcode();
|
||||
} else {
|
||||
generateBarcode(s.toString(), BarcodeFormat.valueOf(formatString));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) { }
|
||||
});
|
||||
|
||||
barcodeTypeField.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
hasChanged = true;
|
||||
|
||||
if (!s.toString().isEmpty()) {
|
||||
if (s.toString().equals(getString(R.string.noBarcode))) {
|
||||
hideBarcode();
|
||||
} else {
|
||||
generateBarcode(cardIdFieldView.getText().toString(), BarcodeFormat.valueOf(s.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) { }
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,7 +235,7 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
|
||||
if(barcodeTypeField.getText().length() == 0)
|
||||
{
|
||||
barcodeTypeField.setText(loyaltyCard.barcodeType.isEmpty() ? LoyaltyCardEditActivity.NO_BARCODE : loyaltyCard.barcodeType);
|
||||
barcodeTypeField.setText(loyaltyCard.barcodeType.isEmpty() ? getString(R.string.noBarcode) : loyaltyCard.barcodeType);
|
||||
}
|
||||
|
||||
if(headingColorValue == null)
|
||||
@@ -177,15 +247,6 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
if(headingStoreTextColorValue == null)
|
||||
{
|
||||
headingStoreTextColorValue = loyaltyCard.headerTextColor;
|
||||
if(headingStoreTextColorValue == null)
|
||||
{
|
||||
headingStoreTextColorValue = Color.WHITE;
|
||||
}
|
||||
}
|
||||
|
||||
setTitle(R.string.editCardTitle);
|
||||
}
|
||||
else if(importLoyaltyCardUri != null)
|
||||
@@ -205,7 +266,6 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
cardIdFieldView.setText(importCard.cardId);
|
||||
barcodeTypeField.setText(importCard.barcodeType);
|
||||
headingColorValue = importCard.headerColor;
|
||||
headingStoreTextColorValue = importCard.headerTextColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -213,6 +273,43 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
hideBarcode();
|
||||
}
|
||||
|
||||
if(groupsChips.getChildCount() == 0)
|
||||
{
|
||||
List<Group> existingGroups = db.getGroups();
|
||||
|
||||
List<Group> loyaltyCardGroups = db.getLoyaltyCardGroups(loyaltyCardId);
|
||||
|
||||
if (existingGroups.isEmpty()) {
|
||||
groupsChips.setVisibility(View.GONE);
|
||||
} else {
|
||||
groupsChips.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
for (Group group : db.getGroups()) {
|
||||
Chip chip = (Chip) getLayoutInflater().inflate(R.layout.layout_chip_choice, groupsChips, false);
|
||||
chip.setText(group._id);
|
||||
chip.setTag(group);
|
||||
|
||||
chip.setChecked(false);
|
||||
for (Group loyaltyCardGroup : loyaltyCardGroups) {
|
||||
if (loyaltyCardGroup._id.equals(group._id)) {
|
||||
chip.setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
chip.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
hasChanged = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
groupsChips.addView(chip);
|
||||
}
|
||||
}
|
||||
|
||||
if(headingColorValue == null)
|
||||
{
|
||||
// Select a random color to start out with.
|
||||
@@ -222,110 +319,47 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
colors.recycle();
|
||||
}
|
||||
|
||||
if(headingStoreTextColorValue == null) {
|
||||
headingStoreTextColorValue = Color.WHITE;
|
||||
thumbnail.setOnClickListener(new ColorSelectListener(headingColorValue));
|
||||
|
||||
if (!initDone) {
|
||||
hasChanged = false;
|
||||
initDone = true;
|
||||
}
|
||||
|
||||
headingColorSample.setBackgroundColor(headingColorValue);
|
||||
headingStoreTextColorSample.setBackgroundColor(headingStoreTextColorValue);
|
||||
headingColorSelectButton.setOnClickListener(new ColorSelectListener(headingColorValue, true));
|
||||
headingStoreTextColorSelectButton.setOnClickListener(new ColorSelectListener(headingStoreTextColorValue, false));
|
||||
// Update from intent
|
||||
if (barcodeType != null) {
|
||||
barcodeTypeField.setText(barcodeType.isEmpty() ? getString(R.string.noBarcode) : barcodeType);
|
||||
barcodeType = null;
|
||||
}
|
||||
if (cardId != null) {
|
||||
cardIdFieldView.setText(cardId);
|
||||
cardId = null;
|
||||
}
|
||||
|
||||
if(cardIdFieldView.getText().length() > 0 && barcodeTypeField.getText().length() > 0)
|
||||
{
|
||||
if(barcodeTypeField.getText().toString().equals(NO_BARCODE))
|
||||
String formatString = barcodeTypeField.getText().toString();
|
||||
|
||||
if(formatString.isEmpty() || formatString.equals(getString(R.string.noBarcode)))
|
||||
{
|
||||
hideBarcode();
|
||||
}
|
||||
else
|
||||
{
|
||||
String formatString = barcodeTypeField.getText().toString();
|
||||
final BarcodeFormat format = BarcodeFormat.valueOf(formatString);
|
||||
final String cardIdString = cardIdFieldView.getText().toString();
|
||||
|
||||
if(barcodeImage.getHeight() == 0)
|
||||
{
|
||||
Log.d(TAG, "ImageView size is not known known at start, waiting for load");
|
||||
// The size of the ImageView is not yet available as it has not
|
||||
// yet been drawn. Wait for it to be drawn so the size is available.
|
||||
barcodeImage.getViewTreeObserver().addOnGlobalLayoutListener(
|
||||
new ViewTreeObserver.OnGlobalLayoutListener()
|
||||
{
|
||||
@Override
|
||||
public void onGlobalLayout()
|
||||
{
|
||||
if (Build.VERSION.SDK_INT < 16)
|
||||
{
|
||||
barcodeImage.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
barcodeImage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
}
|
||||
|
||||
Log.d(TAG, "ImageView size now known");
|
||||
new BarcodeImageWriterTask(barcodeImage, cardIdString, format).execute();
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.d(TAG, "ImageView size known known, creating barcode");
|
||||
new BarcodeImageWriterTask(barcodeImage, cardIdString, format).execute();
|
||||
}
|
||||
|
||||
showBarcode();
|
||||
generateBarcode(cardIdString, format);
|
||||
}
|
||||
}
|
||||
|
||||
View.OnClickListener captureCallback = new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
IntentIntegrator integrator = new IntentIntegrator(LoyaltyCardEditActivity.this);
|
||||
integrator.setDesiredBarcodeFormats(BarcodeSelectorActivity.SUPPORTED_BARCODE_TYPES);
|
||||
enterButton.setOnClickListener(new EditCardIdAndBarcode());
|
||||
barcodeImage.setOnClickListener(new EditCardIdAndBarcode());
|
||||
|
||||
String prompt = getResources().getString(R.string.scanCardBarcode);
|
||||
integrator.setPrompt(prompt);
|
||||
integrator.setBeepEnabled(false);
|
||||
integrator.initiateScan();
|
||||
}
|
||||
};
|
||||
|
||||
captureButton.setOnClickListener(captureCallback);
|
||||
|
||||
enterButton.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent i = new Intent(getApplicationContext(), BarcodeSelectorActivity.class);
|
||||
|
||||
String cardId = cardIdFieldView.getText().toString();
|
||||
if(cardId.length() > 0)
|
||||
{
|
||||
final Bundle b = new Bundle();
|
||||
b.putString("initialCardId", cardId);
|
||||
i.putExtras(b);
|
||||
}
|
||||
|
||||
startActivityForResult(i, SELECT_BARCODE_REQUEST);
|
||||
}
|
||||
});
|
||||
|
||||
if(cardIdFieldView.getText().length() > 0)
|
||||
{
|
||||
cardIdDivider.setVisibility(View.VISIBLE);
|
||||
cardIdTableRow.setVisibility(View.VISIBLE);
|
||||
enterButton.setText(R.string.editCard);
|
||||
}
|
||||
else
|
||||
{
|
||||
cardIdDivider.setVisibility(View.GONE);
|
||||
cardIdTableRow.setVisibility(View.GONE);
|
||||
enterButton.setText(R.string.enterCard);
|
||||
}
|
||||
ArrayList<String> barcodeList = new ArrayList<>(BarcodeSelectorActivity.SUPPORTED_BARCODE_TYPES);
|
||||
barcodeList.add(0, getString(R.string.noBarcode));
|
||||
ArrayAdapter<String> barcodeAdapter = new ArrayAdapter<>(this, android.R.layout.select_dialog_item, barcodeList);
|
||||
barcodeTypeField.setAdapter(barcodeAdapter);
|
||||
|
||||
FloatingActionButton saveButton = findViewById(R.id.fabSave);
|
||||
saveButton.setOnClickListener(new View.OnClickListener() {
|
||||
@@ -334,17 +368,59 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
doSave();
|
||||
}
|
||||
});
|
||||
|
||||
generateIcon(storeFieldEdit.getText().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
askBeforeQuitIfChanged();
|
||||
}
|
||||
|
||||
private void askBeforeQuitIfChanged() {
|
||||
if (!hasChanged) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
if (confirmExitDialog == null) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.leaveWithoutSaveTitle);
|
||||
builder.setMessage(R.string.leaveWithoutSaveConfirmation);
|
||||
builder.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
finish();
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
confirmExitDialog = builder.create();
|
||||
}
|
||||
confirmExitDialog.show();
|
||||
}
|
||||
|
||||
class EditCardIdAndBarcode implements View.OnClickListener
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Utils.createSetBarcodeDialog(LoyaltyCardEditActivity.this, LoyaltyCardEditActivity.this, true, cardIdFieldView.getText().toString());
|
||||
}
|
||||
}
|
||||
|
||||
class ColorSelectListener implements View.OnClickListener
|
||||
{
|
||||
final int defaultColor;
|
||||
final boolean isBackgroundColor;
|
||||
|
||||
ColorSelectListener(int defaultColor, boolean isBackgroundColor)
|
||||
ColorSelectListener(int defaultColor)
|
||||
{
|
||||
this.defaultColor = defaultColor;
|
||||
this.isBackgroundColor = isBackgroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -356,16 +432,11 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
@Override
|
||||
public void onColorSelected(int dialogId, int color)
|
||||
{
|
||||
if(isBackgroundColor)
|
||||
{
|
||||
headingColorSample.setBackgroundColor(color);
|
||||
headingColorValue = color;
|
||||
}
|
||||
else
|
||||
{
|
||||
headingStoreTextColorSample.setBackgroundColor(color);
|
||||
headingStoreTextColorValue = color;
|
||||
}
|
||||
hasChanged = true;
|
||||
|
||||
headingColorValue = color;
|
||||
|
||||
generateIcon(storeFieldEdit.getText().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -387,7 +458,7 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
|
||||
// We do not want to save the no barcode string to the database
|
||||
// it is simply an empty there for no barcode
|
||||
if(barcodeType.equals(NO_BARCODE))
|
||||
if(barcodeType.equals(getString(R.string.noBarcode)))
|
||||
{
|
||||
barcodeType = "";
|
||||
}
|
||||
@@ -404,16 +475,25 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
return;
|
||||
}
|
||||
|
||||
List<Group> selectedGroups = new ArrayList<>();
|
||||
|
||||
for (Integer chipId : groupsChips.getCheckedChipIds()) {
|
||||
Chip chip = groupsChips.findViewById(chipId);
|
||||
selectedGroups.add((Group) chip.getTag());
|
||||
}
|
||||
|
||||
if(updateLoyaltyCard)
|
||||
{ //update of "starStatus" not necessary, since it cannot be changed in this activity (only in ViewActivity)
|
||||
db.updateLoyaltyCard(loyaltyCardId, store, note, cardId, barcodeType, headingColorValue, headingStoreTextColorValue);
|
||||
db.updateLoyaltyCard(loyaltyCardId, store, note, cardId, barcodeType, headingColorValue);
|
||||
Log.i(TAG, "Updated " + loyaltyCardId + " to " + cardId);
|
||||
}
|
||||
else
|
||||
{
|
||||
loyaltyCardId = (int)db.insertLoyaltyCard(store, note, cardId, barcodeType, headingColorValue, headingStoreTextColorValue, 0);
|
||||
loyaltyCardId = (int)db.insertLoyaltyCard(store, note, cardId, barcodeType, headingColorValue, 0);
|
||||
}
|
||||
|
||||
db.setLoyaltyCardGroups(loyaltyCardId, selectedGroups);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
@@ -440,7 +520,7 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
switch(id)
|
||||
{
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
askBeforeQuitIfChanged();
|
||||
break;
|
||||
|
||||
case R.id.action_delete:
|
||||
@@ -485,50 +565,60 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
{
|
||||
super.onActivityResult(requestCode, resultCode, intent);
|
||||
|
||||
String contents = null;
|
||||
String format = null;
|
||||
BarcodeValues barcodeValues = Utils.parseSetBarcodeActivityResult(requestCode, resultCode, intent);
|
||||
|
||||
IntentResult result =
|
||||
IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
|
||||
if (result != null)
|
||||
{
|
||||
Log.i(TAG, "Received barcode information from capture");
|
||||
contents = result.getContents();
|
||||
format = result.getFormatName();
|
||||
}
|
||||
barcodeType = barcodeValues.format();
|
||||
cardId = barcodeValues.content();
|
||||
|
||||
if(requestCode == SELECT_BARCODE_REQUEST && resultCode == Activity.RESULT_OK)
|
||||
{
|
||||
Log.i(TAG, "Received barcode information from typing it");
|
||||
|
||||
contents = intent.getStringExtra(BarcodeSelectorActivity.BARCODE_CONTENTS);
|
||||
format = intent.getStringExtra(BarcodeSelectorActivity.BARCODE_FORMAT);
|
||||
}
|
||||
|
||||
if(contents != null && contents.isEmpty() == false &&
|
||||
format != null)
|
||||
{
|
||||
Log.i(TAG, "Read barcode id: " + contents);
|
||||
Log.i(TAG, "Read format: " + format);
|
||||
|
||||
TextView cardIdView = findViewById(R.id.cardIdView);
|
||||
cardIdView.setText(contents);
|
||||
|
||||
// Set special NO_BARCODE value to prevent onResume from overwriting it
|
||||
barcodeTypeField.setText(format.isEmpty() ? LoyaltyCardEditActivity.NO_BARCODE : format);
|
||||
onResume();
|
||||
}
|
||||
onResume();
|
||||
}
|
||||
|
||||
private void showBarcode() {
|
||||
barcodeImageLayout.setVisibility(View.VISIBLE);
|
||||
findViewById(R.id.barcodeTypeDivider).setVisibility(View.VISIBLE);
|
||||
findViewById(R.id.barcodeTypeTableRow).setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void hideBarcode() {
|
||||
barcodeImageLayout.setVisibility(View.GONE);
|
||||
findViewById(R.id.barcodeTypeDivider).setVisibility(View.GONE);
|
||||
findViewById(R.id.barcodeTypeTableRow).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void generateBarcode(final String cardId, final BarcodeFormat barcodeFormat) {
|
||||
if (barcodeImage.getHeight() == 0) {
|
||||
Log.d(TAG, "ImageView size is not known known at start, waiting for load");
|
||||
// The size of the ImageView is not yet available as it has not
|
||||
// yet been drawn. Wait for it to be drawn so the size is available.
|
||||
barcodeImage.getViewTreeObserver().addOnGlobalLayoutListener(
|
||||
new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
barcodeImage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
|
||||
Log.d(TAG, "ImageView size now known");
|
||||
new BarcodeImageWriterTask(barcodeImage, cardId, barcodeFormat).execute();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.d(TAG, "ImageView size known known, creating barcode");
|
||||
new BarcodeImageWriterTask(barcodeImage, cardId, barcodeFormat).execute();
|
||||
}
|
||||
|
||||
showBarcode();
|
||||
}
|
||||
|
||||
private void generateIcon(String store) {
|
||||
if (headingColorValue == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
thumbnail.setBackgroundColor(headingColorValue);
|
||||
|
||||
LetterBitmap letterBitmap = Utils.generateIcon(this, store, headingColorValue);
|
||||
|
||||
if (letterBitmap != null) {
|
||||
thumbnail.setImageBitmap(letterBitmap.getLetterTile());
|
||||
} else {
|
||||
thumbnail.setImageBitmap(null);
|
||||
}
|
||||
|
||||
thumbnail.setMinimumWidth(thumbnail.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package protect.card_locker;
|
||||
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.graphics.Color;
|
||||
@@ -8,8 +7,8 @@ import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
import androidx.core.widget.TextViewCompat;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
@@ -29,20 +28,23 @@ import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import protect.card_locker.preferences.Settings;
|
||||
import java.util.List;
|
||||
|
||||
import protect.card_locker.preferences.Settings;
|
||||
|
||||
public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
{
|
||||
private static final String TAG = "Catima";
|
||||
private static final double LUMINANCE_MIDPOINT = 0.5;
|
||||
|
||||
TextView cardIdFieldView;
|
||||
View bottomSheet;
|
||||
ImageView bottomSheetButton;
|
||||
TextView noteView;
|
||||
View noteViewDivider;
|
||||
TextView groupsView;
|
||||
TextView storeName;
|
||||
ImageView barcodeImage;
|
||||
View collapsingToolbarLayout;
|
||||
@@ -107,8 +109,10 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
importURIHelper = new ImportURIHelper(this);
|
||||
|
||||
cardIdFieldView = findViewById(R.id.cardIdView);
|
||||
bottomSheet = findViewById(R.id.bottom_sheet);
|
||||
bottomSheetButton = findViewById(R.id.bottomSheetButton);
|
||||
noteView = findViewById(R.id.noteView);
|
||||
noteViewDivider = findViewById(R.id.noteViewDivider);
|
||||
groupsView = findViewById(R.id.groupsView);
|
||||
storeName = findViewById(R.id.storeName);
|
||||
barcodeImage = findViewById(R.id.barcode);
|
||||
collapsingToolbarLayout = findViewById(R.id.collapsingToolbarLayout);
|
||||
@@ -129,6 +133,50 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final FloatingActionButton editButton = findViewById(R.id.fabEdit);
|
||||
editButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("id", loyaltyCardId);
|
||||
bundle.putBoolean("update", true);
|
||||
intent.putExtras(bundle);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
final BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
|
||||
behavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
|
||||
@Override
|
||||
public void onStateChanged(@NonNull View bottomSheet, int newState) {
|
||||
if (newState == BottomSheetBehavior.STATE_DRAGGING) {
|
||||
editButton.hide();
|
||||
} else if (newState == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
bottomSheetButton.setImageResource(R.drawable.ic_baseline_arrow_drop_down_24);
|
||||
editButton.hide();
|
||||
} else if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||
bottomSheetButton.setImageResource(R.drawable.ic_baseline_arrow_drop_up_24);
|
||||
editButton.show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSlide(@NonNull View bottomSheet, float slideOffset) { }
|
||||
});
|
||||
|
||||
bottomSheetButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (behavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
|
||||
} else {
|
||||
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -187,31 +235,42 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
|
||||
if(loyaltyCard.note.length() > 0)
|
||||
{
|
||||
noteView.setVisibility(View.VISIBLE);
|
||||
noteView.setText(loyaltyCard.note);
|
||||
TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(noteView,
|
||||
getResources().getInteger(R.integer.settings_card_note_min_font_size_sp)-1,
|
||||
settings.getCardNoteFontSize(), 1, TypedValue.COMPLEX_UNIT_SP);
|
||||
}
|
||||
else
|
||||
{
|
||||
noteView.setVisibility(View.GONE);
|
||||
noteViewDivider.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
List<Group> loyaltyCardGroups = db.getLoyaltyCardGroups(loyaltyCardId);
|
||||
|
||||
if(loyaltyCardGroups.size() > 0) {
|
||||
StringBuilder groupsString = new StringBuilder();
|
||||
for (Group group : loyaltyCardGroups) {
|
||||
groupsString.append(group._id);
|
||||
groupsString.append(" ");
|
||||
}
|
||||
|
||||
groupsView.setVisibility(View.VISIBLE);
|
||||
groupsView.setText(getString(R.string.groupsList, groupsString.toString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
groupsView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (noteView.getVisibility() == View.VISIBLE || groupsView.getVisibility() == View.VISIBLE) {
|
||||
bottomSheet.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
bottomSheet.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
storeName.setText(loyaltyCard.store);
|
||||
storeName.setTextSize(settings.getCardTitleFontSize());
|
||||
|
||||
int textColor;
|
||||
if(loyaltyCard.headerTextColor != null)
|
||||
{
|
||||
textColor = loyaltyCard.headerTextColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
textColor = Color.WHITE;
|
||||
}
|
||||
storeName.setTextColor(textColor);
|
||||
|
||||
int backgroundHeaderColor;
|
||||
if(loyaltyCard.headerColor != null)
|
||||
{
|
||||
@@ -224,8 +283,19 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
|
||||
collapsingToolbarLayout.setBackgroundColor(backgroundHeaderColor);
|
||||
|
||||
int textColor;
|
||||
if(Utils.needsDarkForeground(backgroundHeaderColor))
|
||||
{
|
||||
textColor = Color.BLACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
textColor = Color.WHITE;
|
||||
}
|
||||
storeName.setTextColor(textColor);
|
||||
|
||||
// If the background is very bright, we should use dark icons
|
||||
backgroundNeedsDarkIcons = (ColorUtils.calculateLuminance(backgroundHeaderColor) > LUMINANCE_MIDPOINT);
|
||||
backgroundNeedsDarkIcons = Utils.needsDarkForeground(backgroundHeaderColor);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if(actionBar != null)
|
||||
{
|
||||
@@ -276,20 +346,6 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
{
|
||||
findViewById(R.id.barcode).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
FloatingActionButton editButton = findViewById(R.id.fabEdit);
|
||||
editButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("id", loyaltyCardId);
|
||||
bundle.putBoolean("update", true);
|
||||
intent.putExtras(bundle);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,44 +1,48 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.SearchManager;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.zxing.integration.android.IntentIntegrator;
|
||||
import com.google.zxing.integration.android.IntentResult;
|
||||
|
||||
import java.util.List;
|
||||
import protect.card_locker.preferences.SettingsActivity;
|
||||
|
||||
public class MainActivity extends AppCompatActivity
|
||||
public class MainActivity extends AppCompatActivity implements GestureDetector.OnGestureListener
|
||||
{
|
||||
private static final String TAG = "Catima";
|
||||
private static final int MAIN_REQUEST_CODE = 1;
|
||||
|
||||
private Menu menu;
|
||||
private GestureDetector gestureDetector;
|
||||
protected String filter = "";
|
||||
protected int selectedTab = 0;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
@@ -48,7 +52,51 @@ public class MainActivity extends AppCompatActivity
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
updateLoyaltyCardList("");
|
||||
updateLoyaltyCardList(filter, null);
|
||||
|
||||
TabLayout groupsTabLayout = findViewById(R.id.groups);
|
||||
groupsTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||
@Override
|
||||
public void onTabSelected(TabLayout.Tab tab) {
|
||||
selectedTab = tab.getPosition();
|
||||
updateLoyaltyCardList(filter, tab.getTag());
|
||||
|
||||
// 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), selectedTab);
|
||||
activeTabPrefEditor.apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(TabLayout.Tab tab) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(TabLayout.Tab tab) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
gestureDetector = new GestureDetector(this, this);
|
||||
|
||||
View.OnTouchListener gestureTouchListener = new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(final View v, final MotionEvent event){
|
||||
return gestureDetector.onTouchEvent(event);
|
||||
}
|
||||
};
|
||||
|
||||
final View helpText = findViewById(R.id.helpText);
|
||||
final View noMatchingCardsText = findViewById(R.id.noMatchingCardsText);
|
||||
final View list = findViewById(R.id.list);
|
||||
|
||||
helpText.setOnTouchListener(gestureTouchListener);
|
||||
noMatchingCardsText.setOnTouchListener(gestureTouchListener);
|
||||
list.setOnTouchListener(gestureTouchListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,24 +112,45 @@ public class MainActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
updateLoyaltyCardList(filter);
|
||||
// Start of active tab logic
|
||||
TabLayout groupsTabLayout = findViewById(R.id.groups);
|
||||
updateTabGroups(groupsTabLayout);
|
||||
|
||||
// Restore active 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);
|
||||
|
||||
Object group = null;
|
||||
|
||||
if (groupsTabLayout.getTabCount() != 0) {
|
||||
TabLayout.Tab tab = groupsTabLayout.getTabAt(0);
|
||||
|
||||
if (selectedTab < groupsTabLayout.getTabCount()) {
|
||||
tab = groupsTabLayout.getTabAt(selectedTab);
|
||||
}
|
||||
|
||||
groupsTabLayout.selectTab(tab);
|
||||
group = tab.getTag();
|
||||
}
|
||||
updateLoyaltyCardList(filter, group);
|
||||
// End of active tab logic
|
||||
|
||||
FloatingActionButton addButton = findViewById(R.id.fabAdd);
|
||||
addButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent i = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
|
||||
startActivityForResult(i, MAIN_REQUEST_CODE);
|
||||
Utils.createSetBarcodeDialog(MainActivity.this, MainActivity.this, false, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
super.onActivityResult(requestCode, resultCode, intent);
|
||||
|
||||
if (requestCode == MAIN_REQUEST_CODE)
|
||||
{
|
||||
if (requestCode == Utils.MAIN_REQUEST) {
|
||||
// We're coming back from another view so clear the search
|
||||
// We only do this now to prevent a flash of all entries right after picking one
|
||||
filter = "";
|
||||
@@ -93,6 +162,19 @@ public class MainActivity extends AppCompatActivity
|
||||
|
||||
// In case the theme changed
|
||||
recreate();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BarcodeValues barcodeValues = Utils.parseSetBarcodeActivityResult(requestCode, resultCode, intent);
|
||||
|
||||
if(!barcodeValues.isEmpty()) {
|
||||
Intent newIntent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
|
||||
Bundle newBundle = new Bundle();
|
||||
newBundle.putString("barcodeType", barcodeValues.format());
|
||||
newBundle.putString("cardId", barcodeValues.content());
|
||||
newIntent.putExtras(newBundle);
|
||||
startActivity(newIntent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,17 +191,31 @@ public class MainActivity extends AppCompatActivity
|
||||
if (!searchView.isIconified()) {
|
||||
searchView.setIconified(true);
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
TabLayout groupsTabLayout = findViewById(R.id.groups);
|
||||
|
||||
if (groupsTabLayout.getVisibility() == View.VISIBLE && selectedTab != 0) {
|
||||
selectedTab = 0;
|
||||
groupsTabLayout.selectTab(groupsTabLayout.getTabAt(0));
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLoyaltyCardList(String filterText)
|
||||
private void updateLoyaltyCardList(String filterText, Object tag)
|
||||
{
|
||||
Group group = null;
|
||||
if (tag != null) {
|
||||
group = (Group) tag;
|
||||
}
|
||||
|
||||
final ListView cardList = findViewById(R.id.list);
|
||||
final TextView helpText = findViewById(R.id.helpText);
|
||||
final TextView noMatchingCardsText = findViewById(R.id.noMatchingCardsText);
|
||||
final DBHelper db = new DBHelper(this);
|
||||
|
||||
Cursor cardCursor = db.getLoyaltyCardCursor(filterText, group);
|
||||
|
||||
if(db.getLoyaltyCardCount() > 0)
|
||||
{
|
||||
// We want the cardList to be visible regardless of the filtered match count
|
||||
@@ -127,7 +223,7 @@ public class MainActivity extends AppCompatActivity
|
||||
// the keyboard
|
||||
cardList.setVisibility(View.VISIBLE);
|
||||
helpText.setVisibility(View.GONE);
|
||||
if(db.getLoyaltyCardCount(filterText) > 0)
|
||||
if(cardCursor.getCount() > 0)
|
||||
{
|
||||
noMatchingCardsText.setVisibility(View.GONE);
|
||||
}
|
||||
@@ -143,8 +239,6 @@ public class MainActivity extends AppCompatActivity
|
||||
noMatchingCardsText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
Cursor cardCursor = db.getLoyaltyCardCursor(filterText);
|
||||
|
||||
final LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(this, cardCursor);
|
||||
cardList.setAdapter(adapter);
|
||||
|
||||
@@ -166,11 +260,40 @@ public class MainActivity extends AppCompatActivity
|
||||
|
||||
ShortcutHelper.updateShortcuts(MainActivity.this, loyaltyCard, i);
|
||||
|
||||
startActivityForResult(i, MAIN_REQUEST_CODE);
|
||||
startActivityForResult(i, Utils.MAIN_REQUEST);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void updateTabGroups(TabLayout groupsTabLayout)
|
||||
{
|
||||
final DBHelper db = new DBHelper(this);
|
||||
|
||||
List<Group> newGroups = db.getGroups();
|
||||
|
||||
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
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)
|
||||
{
|
||||
@@ -240,7 +363,10 @@ public class MainActivity extends AppCompatActivity
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
filter = newText;
|
||||
updateLoyaltyCardList(newText);
|
||||
|
||||
TabLayout groupsTabLayout = findViewById(R.id.groups);
|
||||
|
||||
updateLoyaltyCardList(newText, groupsTabLayout.getTabCount() > 0 ? groupsTabLayout.getTabAt(groupsTabLayout.getSelectedTabPosition()).getTag() : null);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -254,125 +380,37 @@ public class MainActivity extends AppCompatActivity
|
||||
{
|
||||
int id = item.getItemId();
|
||||
|
||||
if (id == R.id.action_manage_groups)
|
||||
{
|
||||
Intent i = new Intent(getApplicationContext(), ManageGroupsActivity.class);
|
||||
startActivityForResult(i, Utils.MAIN_REQUEST);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(id == R.id.action_import_export)
|
||||
{
|
||||
Intent i = new Intent(getApplicationContext(), ImportExportActivity.class);
|
||||
startActivityForResult(i, MAIN_REQUEST_CODE);
|
||||
startActivityForResult(i, Utils.MAIN_REQUEST);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(id == R.id.action_settings)
|
||||
{
|
||||
Intent i = new Intent(getApplicationContext(), SettingsActivity.class);
|
||||
startActivityForResult(i, MAIN_REQUEST_CODE);
|
||||
startActivityForResult(i, Utils.MAIN_REQUEST);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(id == R.id.action_about)
|
||||
{
|
||||
displayAboutDialog();
|
||||
Intent i = new Intent(getApplicationContext(), AboutActivity.class);
|
||||
startActivityForResult(i, Utils.MAIN_REQUEST);
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void displayAboutDialog()
|
||||
{
|
||||
final Map<String, String> USED_LIBRARIES = new ImmutableMap.Builder<String, String>()
|
||||
.put("Commons CSV", "https://commons.apache.org/proper/commons-csv/")
|
||||
.put("Guava", "https://github.com/google/guava")
|
||||
.put("ZXing", "https://github.com/zxing/zxing")
|
||||
.put("ZXing Android Embedded", "https://github.com/journeyapps/zxing-android-embedded")
|
||||
.put("AppIntro", "https://github.com/apl-devs/AppIntro")
|
||||
.put("Color Picker", "https://github.com/jaredrummler/ColorPicker")
|
||||
.put("VNTNumberPickerPreference", "https://github.com/vanniktech/VNTNumberPickerPreference")
|
||||
.build();
|
||||
|
||||
final Map<String, String> USED_ASSETS = ImmutableMap.of
|
||||
(
|
||||
"Save by Bernar Novalyi", "https://thenounproject.com/term/save/716011"
|
||||
);
|
||||
|
||||
StringBuilder libs = new StringBuilder().append("<ul>");
|
||||
for (Map.Entry<String, String> entry : USED_LIBRARIES.entrySet())
|
||||
{
|
||||
libs.append("<li><a href=\"").append(entry.getValue()).append("\">").append(entry.getKey()).append("</a></li>");
|
||||
}
|
||||
libs.append("</ul>");
|
||||
|
||||
StringBuilder resources = new StringBuilder().append("<ul>");
|
||||
for (Map.Entry<String, String> entry : USED_ASSETS.entrySet())
|
||||
{
|
||||
resources.append("<li><a href=\"").append(entry.getValue()).append("\">").append(entry.getKey()).append("</a></li>");
|
||||
}
|
||||
resources.append("</ul>");
|
||||
|
||||
String appName = getString(R.string.app_name);
|
||||
int year = Calendar.getInstance().get(Calendar.YEAR);
|
||||
|
||||
String version = "?";
|
||||
try
|
||||
{
|
||||
PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0);
|
||||
version = pi.versionName;
|
||||
}
|
||||
catch (PackageManager.NameNotFoundException e)
|
||||
{
|
||||
Log.w(TAG, "Package name not found", e);
|
||||
}
|
||||
|
||||
WebView wv = new WebView(this);
|
||||
|
||||
// Set CSS for dark mode if dark mode
|
||||
String css = "";
|
||||
if(isDarkModeEnabled(this))
|
||||
{
|
||||
css = "<style>body {color:white; background-color:black;}</style>";
|
||||
}
|
||||
|
||||
String html =
|
||||
"<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />" +
|
||||
css +
|
||||
"<h1>" +
|
||||
String.format(getString(R.string.about_title_fmt),
|
||||
"<a href=\"" + getString(R.string.app_webpage_url)) + "\">" +
|
||||
appName +
|
||||
"</a>" +
|
||||
"</h1><p>" +
|
||||
appName +
|
||||
" " +
|
||||
String.format(getString(R.string.debug_version_fmt), version) +
|
||||
"</p><p>" +
|
||||
String.format(getString(R.string.app_revision_fmt),
|
||||
"<a href=\"" + getString(R.string.app_revision_url) + "\">" +
|
||||
"GitHub" +
|
||||
"</a>") +
|
||||
"</p><hr/><p>" +
|
||||
String.format(getString(R.string.app_copyright_fmt), year) +
|
||||
"</p><p>" +
|
||||
getString(R.string.app_copyright_old) +
|
||||
"</p><hr/><p>" +
|
||||
getString(R.string.app_license) +
|
||||
"</p><hr/><p>" +
|
||||
String.format(getString(R.string.app_libraries), appName, libs.toString()) +
|
||||
"</p><hr/><p>" +
|
||||
String.format(getString(R.string.app_resources), appName, resources.toString());
|
||||
|
||||
wv.loadDataWithBaseURL("file:///android_res/drawable/", html, "text/html", "utf-8", null);
|
||||
new AlertDialog.Builder(this)
|
||||
.setView(wv)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
dialog.dismiss();
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
protected static boolean isDarkModeEnabled(Context inputContext)
|
||||
{
|
||||
Configuration config = inputContext.getResources().getConfiguration();
|
||||
@@ -380,4 +418,73 @@ public class MainActivity extends AppCompatActivity
|
||||
return (currentNightMode == Configuration.UI_MODE_NIGHT_YES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDown(MotionEvent e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShowPress(MotionEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapUp(MotionEvent e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(MotionEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
Log.d(TAG, "On fling");
|
||||
|
||||
// Don't swipe if we have too much vertical movement
|
||||
if (Math.abs(velocityY) > (0.75 * Math.abs(velocityX))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TabLayout groupsTabLayout = findViewById(R.id.groups);
|
||||
if (groupsTabLayout.getTabCount() < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Integer currentTab = groupsTabLayout.getSelectedTabPosition();
|
||||
|
||||
// Swipe right
|
||||
if (velocityX < -150) {
|
||||
Integer nextTab = currentTab + 1;
|
||||
|
||||
if (nextTab == groupsTabLayout.getTabCount()) {
|
||||
groupsTabLayout.selectTab(groupsTabLayout.getTabAt(0));
|
||||
} else {
|
||||
groupsTabLayout.selectTab(groupsTabLayout.getTabAt(nextTab));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Swipe left
|
||||
if (velocityX > 150) {
|
||||
Integer nextTab = currentTab - 1;
|
||||
|
||||
if (nextTab < 0) {
|
||||
groupsTabLayout.selectTab(groupsTabLayout.getTabAt(groupsTabLayout.getTabCount() - 1));
|
||||
} else {
|
||||
groupsTabLayout.selectTab(groupsTabLayout.getTabAt(nextTab));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
254
app/src/main/java/protect/card_locker/ManageGroupsActivity.java
Normal file
@@ -0,0 +1,254 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
public class ManageGroupsActivity extends AppCompatActivity
|
||||
{
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
private AlertDialog newGroupDialog;
|
||||
private final DBHelper db = new DBHelper(this);
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.manage_groups_activity);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if(actionBar != null)
|
||||
{
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
newGroupDialog = createNewGroupDialog();
|
||||
|
||||
updateGroupList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
updateGroupList();
|
||||
|
||||
FloatingActionButton addButton = findViewById(R.id.fabAdd);
|
||||
addButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
newGroupDialog.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
private void updateGroupList()
|
||||
{
|
||||
final ListView groupList = findViewById(R.id.list);
|
||||
final TextView helpText = findViewById(R.id.helpText);
|
||||
final DBHelper db = new DBHelper(this);
|
||||
|
||||
if(db.getGroupCount() > 0)
|
||||
{
|
||||
groupList.setVisibility(View.VISIBLE);
|
||||
helpText.setVisibility(View.GONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
groupList.setVisibility(View.GONE);
|
||||
helpText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
Cursor groupCursor = db.getGroupCursor();
|
||||
|
||||
final GroupCursorAdapter adapter = new GroupCursorAdapter(this, groupCursor);
|
||||
groupList.setAdapter(adapter);
|
||||
|
||||
registerForContextMenu(groupList);
|
||||
}
|
||||
|
||||
private void invalidateHomescreenActiveTab()
|
||||
{
|
||||
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), 0);
|
||||
activeTabPrefEditor.apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
int id = item.getItemId();
|
||||
|
||||
if (id == android.R.id.home) {
|
||||
finish();
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
public void moveGroupUp(View view) {
|
||||
moveGroup(view, true);
|
||||
}
|
||||
|
||||
public void moveGroupDown(View view) {
|
||||
moveGroup(view, false);
|
||||
}
|
||||
|
||||
public void editGroup(View view) {
|
||||
final String groupName = getGroupname(view);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.enter_group_name);
|
||||
final EditText input = new EditText(this);
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
input.setText(groupName);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
db.updateGroup(groupName, input.getText().toString());
|
||||
updateGroupList();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.cancel();
|
||||
}
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public void deleteGroup(View view) {
|
||||
final String groupName = getGroupname(view);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.deleteConfirmationGroup);
|
||||
builder.setMessage(groupName);
|
||||
|
||||
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
db.deleteGroup(groupName);
|
||||
updateGroupList();
|
||||
// Delete may change ordering, so invalidate
|
||||
invalidateHomescreenActiveTab();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.cancel();
|
||||
}
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private AlertDialog createNewGroupDialog() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.enter_group_name);
|
||||
final EditText input = new EditText(this);
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
db.insertGroup(input.getText().toString());
|
||||
updateGroupList();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.cancel();
|
||||
}
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private String getGroupname(View view) {
|
||||
LinearLayout parentRow = (LinearLayout) view.getParent().getParent();
|
||||
TextView groupNameTextView = parentRow.findViewById(R.id.name);
|
||||
return (String) groupNameTextView.getText();
|
||||
}
|
||||
|
||||
private void moveGroup(View view, boolean up) {
|
||||
final String groupName = getGroupname(view);
|
||||
|
||||
List<Group> groups = db.getGroups();
|
||||
|
||||
int currentIndex = -1;
|
||||
Integer newIndex;
|
||||
|
||||
// Get current index in group list
|
||||
for (int i = 0; i < groups.size(); i++) {
|
||||
if (groups.get(i)._id.equals(groupName)) {
|
||||
currentIndex = i;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentIndex == -1) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
// Reinsert group in correct position
|
||||
if (up) {
|
||||
newIndex = currentIndex - 1;
|
||||
} else {
|
||||
newIndex = currentIndex + 1;
|
||||
}
|
||||
|
||||
// Don't try to move out of bounds
|
||||
if (newIndex < 0 || newIndex >= groups.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Group group = groups.remove(currentIndex);
|
||||
groups.add(newIndex, group);
|
||||
|
||||
// Update database
|
||||
db.reorderGroups(groups);
|
||||
|
||||
// Update UI
|
||||
updateGroupList();
|
||||
|
||||
// Ordering may have changed, so invalidate
|
||||
invalidateHomescreenActiveTab();
|
||||
}
|
||||
}
|
||||
138
app/src/main/java/protect/card_locker/Utils.java
Normal file
@@ -0,0 +1,138 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
import com.google.zxing.integration.android.IntentIntegrator;
|
||||
import com.google.zxing.integration.android.IntentResult;
|
||||
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
|
||||
public class Utils {
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
// Barcode config dialog
|
||||
private static AlertDialog setBarcodeDialog;
|
||||
|
||||
// Activity request codes
|
||||
public static final int MAIN_REQUEST = 1;
|
||||
public static final int SELECT_BARCODE_REQUEST = 2;
|
||||
|
||||
static final double LUMINANCE_MIDPOINT = 0.5;
|
||||
|
||||
static public LetterBitmap generateIcon(Context context, String store, Integer backgroundColor) {
|
||||
if (store.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int tileLetterFontSize = context.getResources().getDimensionPixelSize(R.dimen.tileLetterFontSize);
|
||||
int pixelSize = context.getResources().getDimensionPixelSize(R.dimen.cardThumbnailSize);
|
||||
|
||||
if (backgroundColor == null) {
|
||||
backgroundColor = LetterBitmap.getDefaultColor(context, store);
|
||||
}
|
||||
|
||||
return new LetterBitmap(context, store, store,
|
||||
tileLetterFontSize, pixelSize, pixelSize, backgroundColor, needsDarkForeground(backgroundColor) ? Color.BLACK : Color.WHITE);
|
||||
}
|
||||
|
||||
static public boolean needsDarkForeground(Integer backgroundColor) {
|
||||
return ColorUtils.calculateLuminance(backgroundColor) > LUMINANCE_MIDPOINT;
|
||||
}
|
||||
|
||||
static public void startCameraBarcodeScan(Context context, Activity activity) {
|
||||
IntentIntegrator integrator = new IntentIntegrator(activity);
|
||||
integrator.setDesiredBarcodeFormats(BarcodeSelectorActivity.SUPPORTED_BARCODE_TYPES);
|
||||
|
||||
String prompt = context.getResources().getString(R.string.scanCardBarcode);
|
||||
integrator.setPrompt(prompt);
|
||||
integrator.setBeepEnabled(false);
|
||||
integrator.initiateScan();
|
||||
}
|
||||
|
||||
static public void createSetBarcodeDialog(final Context context, final Activity activity, boolean isUpdate, final String initialCardId) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
// Get the layout inflater
|
||||
LayoutInflater inflater = activity.getLayoutInflater();
|
||||
|
||||
// Inflate and set the layout for the dialog
|
||||
// Pass null as the parent view because its going in the dialog layout
|
||||
builder.setView(inflater.inflate(R.layout.dialog_create, null));
|
||||
|
||||
if (isUpdate) {
|
||||
builder.setTitle(context.getString(R.string.editCardTitle));
|
||||
} else {
|
||||
builder.setTitle(context.getString(R.string.addCardTitle));
|
||||
}
|
||||
|
||||
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
setBarcodeDialog.cancel();
|
||||
}
|
||||
});
|
||||
setBarcodeDialog = builder.create();
|
||||
setBarcodeDialog.show();
|
||||
|
||||
View addFromCamera = setBarcodeDialog.getWindow().findViewById(R.id.add_from_camera);
|
||||
View addManually = setBarcodeDialog.getWindow().findViewById(R.id.add_manually);
|
||||
|
||||
addFromCamera.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Utils.startCameraBarcodeScan(context, activity);
|
||||
|
||||
setBarcodeDialog.hide();
|
||||
}
|
||||
});
|
||||
|
||||
addManually.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent i = new Intent(context, BarcodeSelectorActivity.class);
|
||||
if (initialCardId != null) {
|
||||
final Bundle b = new Bundle();
|
||||
b.putString("initialCardId", initialCardId);
|
||||
i.putExtras(b);
|
||||
}
|
||||
activity.startActivityForResult(i, Utils.SELECT_BARCODE_REQUEST);
|
||||
|
||||
setBarcodeDialog.hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static public BarcodeValues parseSetBarcodeActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
String contents = null;
|
||||
String format = null;
|
||||
|
||||
IntentResult result =
|
||||
IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
|
||||
if (result != null)
|
||||
{
|
||||
Log.i(TAG, "Received barcode information from capture");
|
||||
contents = result.getContents();
|
||||
format = result.getFormatName();
|
||||
}
|
||||
|
||||
if(requestCode == Utils.SELECT_BARCODE_REQUEST && resultCode == Activity.RESULT_OK)
|
||||
{
|
||||
Log.i(TAG, "Received barcode information from typing it");
|
||||
|
||||
contents = intent.getStringExtra(BarcodeSelectorActivity.BARCODE_CONTENTS);
|
||||
format = intent.getStringExtra(BarcodeSelectorActivity.BARCODE_FORMAT);
|
||||
}
|
||||
|
||||
Log.i(TAG, "Read barcode id: " + contents);
|
||||
Log.i(TAG, "Read format: " + format);
|
||||
|
||||
return new BarcodeValues(format, contents);
|
||||
}
|
||||
}
|
||||
@@ -81,11 +81,6 @@ public class Settings
|
||||
return getInt(R.string.settings_key_card_id_font_size, R.integer.settings_card_id_font_size_sp);
|
||||
}
|
||||
|
||||
public int getCardNoteFontSize()
|
||||
{
|
||||
return getInt(R.string.settings_key_card_note_font_size, R.integer.settings_card_note_font_size_sp);
|
||||
}
|
||||
|
||||
public boolean useMaxBrightnessDisplayingBarcode()
|
||||
{
|
||||
return getBoolean(R.string.settings_key_display_barcode_max_brightness, true);
|
||||
|
||||
|
After Width: | Height: | Size: 139 B |
BIN
app/src/main/res/drawable-hdpi/ic_baseline_arrow_drop_up_24.png
Normal file
|
After Width: | Height: | Size: 140 B |
BIN
app/src/main/res/drawable-hdpi/ic_camera_white.png
Normal file
|
After Width: | Height: | Size: 327 B |
BIN
app/src/main/res/drawable-hdpi/ic_folder_white.png
Normal file
|
After Width: | Height: | Size: 163 B |
|
After Width: | Height: | Size: 107 B |
BIN
app/src/main/res/drawable-mdpi/ic_baseline_arrow_drop_up_24.png
Normal file
|
After Width: | Height: | Size: 110 B |
BIN
app/src/main/res/drawable-mdpi/ic_camera_white.png
Normal file
|
After Width: | Height: | Size: 217 B |
BIN
app/src/main/res/drawable-mdpi/ic_folder_white.png
Normal file
|
After Width: | Height: | Size: 135 B |
|
After Width: | Height: | Size: 139 B |
BIN
app/src/main/res/drawable-xhdpi/ic_baseline_arrow_drop_up_24.png
Normal file
|
After Width: | Height: | Size: 147 B |
BIN
app/src/main/res/drawable-xhdpi/ic_camera_white.png
Normal file
|
After Width: | Height: | Size: 375 B |
BIN
app/src/main/res/drawable-xhdpi/ic_folder_white.png
Normal file
|
After Width: | Height: | Size: 207 B |
|
After Width: | Height: | Size: 169 B |
|
After Width: | Height: | Size: 176 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_camera_white.png
Normal file
|
After Width: | Height: | Size: 523 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_folder_white.png
Normal file
|
After Width: | Height: | Size: 252 B |
41
app/src/main/res/layout/about_activity.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?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:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="?attr/actionBarSize"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/aboutText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:linksClickable="true"
|
||||
android:singleLine="false"
|
||||
android:focusable="true" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@@ -55,6 +55,7 @@
|
||||
android:labelFor="@+id/cardId"
|
||||
android:text="@string/cardId" />
|
||||
<EditText android:id="@+id/cardId"
|
||||
android:importantForAutofill="no"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text"/>
|
||||
@@ -69,6 +70,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/barcodeNoBarcode"
|
||||
android:textColor="#FFFFFF"
|
||||
android:enabled="false" />
|
||||
<LinearLayout android:orientation="vertical"
|
||||
android:padding="10.0dp"
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
style="@style/AppTheme.TextView.NoData"
|
||||
android:id="@+id/helpText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/noGiftCards"
|
||||
android:visibility="gone"/>
|
||||
|
||||
@@ -21,13 +22,14 @@
|
||||
style="@style/AppTheme.TextView.NoData"
|
||||
android:id="@+id/noMatchingCardsText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/noMatchingGiftCards"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ListView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/list"
|
||||
android:visibility="gone"/>
|
||||
</RelativeLayout>
|
||||
|
||||
29
app/src/main/res/layout/dialog_create.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:id="@+id/add_from_camera"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/addWithCamera"
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:drawablePadding="@dimen/inputPadding"
|
||||
app:drawableStartCompat="@drawable/ic_camera_white"
|
||||
app:drawableTint="@color/iconColor" />
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@android:color/darker_gray"/>
|
||||
<TextView
|
||||
android:id="@+id/add_manually"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/addManually"
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:drawablePadding="@dimen/inputPadding"
|
||||
app:drawableStartCompat="@drawable/ic_mode_edit_white_24dp"
|
||||
app:drawableTint="@color/iconColor" />
|
||||
</LinearLayout>
|
||||
82
app/src/main/res/layout/group_layout.xml
Normal file
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:baselineAligned="false"
|
||||
android:padding="@dimen/activity_margin">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:textSize="@dimen/storeNameTextSize"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cardCount"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:textSize="@dimen/noteTextSize"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/moveUp"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/ic_baseline_arrow_drop_up_24"
|
||||
android:contentDescription="@string/moveUp"
|
||||
app:tint="@color/iconColor"
|
||||
android:onClick="moveGroupUp"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/moveDown"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/ic_baseline_arrow_drop_down_24"
|
||||
android:contentDescription="@string/moveDown"
|
||||
app:tint="@color/iconColor"
|
||||
android:onClick="moveGroupDown"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/edit"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/ic_mode_edit_white_24dp"
|
||||
android:contentDescription="@string/edit"
|
||||
app:tint="@color/iconColor"
|
||||
android:onClick="editGroup" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/delete"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/ic_delete_white_24dp"
|
||||
android:contentDescription="@string/delete"
|
||||
app:tint="@color/iconColor"
|
||||
android:onClick="deleteGroup"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
25
app/src/main/res/layout/group_main.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
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"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
tools:context="protect.card_locker.MainActivity"
|
||||
tools:showIn="@layout/main_activity">
|
||||
|
||||
<TextView
|
||||
style="@style/AppTheme.TextView.NoData"
|
||||
android:id="@+id/helpText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/noGroups"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ListView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/list"
|
||||
android:visibility="gone"/>
|
||||
</RelativeLayout>
|
||||
9
app/src/main/res/layout/layout_chip_choice.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<com.google.android.material.chip.Chip xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
style="@style/Widget.MaterialComponents.Chip.Choice"
|
||||
app:checkedIconVisible="true"
|
||||
android:textAppearance="?android:attr/textAppearance" />
|
||||
@@ -32,420 +32,175 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/inputContrastBackground"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
||||
<LinearLayout
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<TableLayout android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:shrinkColumns="1"
|
||||
android:background="@color/inputContrastBackground">
|
||||
|
||||
<!-- Store Name -->
|
||||
<View
|
||||
android:layout_height="@dimen/inputBorderThickness"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@color/inputBorder" />
|
||||
<TableRow
|
||||
android:background="@color/inputBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<View
|
||||
android:gravity="start"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="@dimen/inputBorderThickness"
|
||||
android:background="@color/inputBorder" />
|
||||
<!-- Store -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="@dimen/inputPadding"
|
||||
android:paddingTop="@dimen/inputPadding"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_weight="1"
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:layout_marginEnd="@dimen/activity_margin"
|
||||
android:layout_gravity="center_vertical"
|
||||
app:cardCornerRadius="4dp"
|
||||
android:paddingHorizontal="@dimen/inputPadding"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/thumbnail"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:contentDescription="@string/thumbnailDescription"
|
||||
android:src="@mipmap/ic_launcher"/>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/storeNameField"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/storeName">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/storeNameEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="@dimen/inputPadding"
|
||||
android:paddingEnd="@dimen/inputPadding">
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/storeNameField"
|
||||
android:text="@string/storeName"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="@dimen/inputSize"
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentLeft="true"/>
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/storeNameEdit"
|
||||
android:inputType="textCapWords"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:textSize="@dimen/inputSize"
|
||||
android:layout_toEndOf="@id/storeNameField"
|
||||
android:layout_toRightOf="@id/storeNameField"
|
||||
/>
|
||||
<!-- Note -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="@dimen/inputPadding"
|
||||
android:paddingTop="@dimen/inputPadding"
|
||||
android:orientation="horizontal">
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:gravity="end"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="@dimen/inputBorderThickness"
|
||||
android:background="@color/inputBorder" />
|
||||
</TableRow>
|
||||
|
||||
<!-- Note -->
|
||||
<View
|
||||
android:layout_height="@dimen/inputBorderThickness"
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/noteField"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@color/inputBorder" />
|
||||
<TableRow
|
||||
android:background="@color/inputBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<View
|
||||
android:gravity="start"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="@dimen/inputBorderThickness"
|
||||
android:background="@color/inputBorder" />
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/note">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_weight="1"
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/noteEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="@dimen/inputPadding"
|
||||
android:paddingEnd="@dimen/inputPadding">
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/noteField"
|
||||
android:text="@string/note"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="@dimen/inputSize"
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
/>
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/noteEdit"
|
||||
android:inputType="textMultiLine"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:textSize="@dimen/inputSize"
|
||||
android:layout_toEndOf="@id/noteField"
|
||||
android:layout_toRightOf="@id/noteField"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
<!-- Group -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="@dimen/inputPadding"
|
||||
android:paddingTop="@dimen/inputPadding"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<View
|
||||
android:gravity="end"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="@dimen/inputBorderThickness"
|
||||
android:background="@color/inputBorder" />
|
||||
</TableRow>
|
||||
|
||||
<!-- Store Header Background Color -->
|
||||
<View
|
||||
android:layout_height="@dimen/inputBorderThickness"
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/groupChips"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@color/inputBorder" />
|
||||
<TableRow
|
||||
android:background="@color/inputBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<View
|
||||
android:gravity="start"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="@dimen/inputBorderThickness"
|
||||
android:background="@color/inputBorder" />
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:textSize="@dimen/inputSize" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_weight="1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="@dimen/inputPadding"
|
||||
android:paddingEnd="@dimen/inputPadding">
|
||||
<!-- Buttons -->
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:padding="10.0dip"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/barcodeCaptureLayout">
|
||||
<Button android:id="@+id/enterButton"
|
||||
android:layout_margin="@dimen/inputMargin"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/editCard"
|
||||
android:textColor="#FFFFFF"
|
||||
android:layout_weight="1.0"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/headingField"
|
||||
android:text="@string/storeTextBackgroundColorTitle"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="@dimen/inputSize"
|
||||
android:padding="@dimen/inputPadding"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/headingColorSampleBorder"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="@dimen/colorSamplePadding"
|
||||
app:layout_constraintStart_toEndOf="@id/headingField"
|
||||
app:layout_constraintEnd_toStartOf="@+id/headingColorSelectButton"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:background="@android:color/black">
|
||||
<ImageView
|
||||
android:id="@+id/headingColorSample"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="1dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:background="@android:color/white"
|
||||
android:contentDescription="@string/storeNameBackgroundColorDescription"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/headingColorSelectButton"
|
||||
android:text="@string/change"
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toEndOf="@id/headingColorSampleBorder"
|
||||
android:layout_toRightOf="@id/headingColorSampleBorder"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<View
|
||||
android:gravity="end"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="@dimen/inputBorderThickness"
|
||||
android:background="@color/inputBorder" />
|
||||
</TableRow>
|
||||
|
||||
<!-- Store Text Color -->
|
||||
<View
|
||||
android:layout_height="@dimen/inputBorderThickness"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@color/inputBorder" />
|
||||
<TableRow
|
||||
android:background="@color/inputBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<View
|
||||
android:gravity="start"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="@dimen/inputBorderThickness"
|
||||
android:background="@color/inputBorder" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_weight="1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="@dimen/inputPadding"
|
||||
android:paddingEnd="@dimen/inputPadding">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/storeTextField"
|
||||
android:text="@string/storeTextColorTitle"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="@dimen/inputSize"
|
||||
android:padding="@dimen/inputPadding"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/headingStoreTextColorSampleBorder"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="@dimen/colorSamplePadding"
|
||||
app:layout_constraintStart_toEndOf="@id/storeTextField"
|
||||
app:layout_constraintEnd_toStartOf="@+id/headingStoreTextColorSelectButton"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:background="@android:color/black">
|
||||
<ImageView
|
||||
android:id="@+id/headingStoreTextColorSample"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="1dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:background="@android:color/white"
|
||||
android:contentDescription="@string/storeNameColorDescription"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/headingStoreTextColorSelectButton"
|
||||
android:text="@string/change"
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toEndOf="@id/headingStoreTextColorSampleBorder"
|
||||
android:layout_toRightOf="@id/headingStoreTextColorSampleBorder"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<View
|
||||
android:gravity="end"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="@dimen/inputBorderThickness"
|
||||
android:background="@color/inputBorder" />
|
||||
</TableRow>
|
||||
<!-- Card ID and Barcode type -->
|
||||
<LinearLayout
|
||||
android:id="@+id/cardAndBarcodeLayout"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="@dimen/inputPadding"
|
||||
android:paddingTop="@dimen/inputPadding"
|
||||
android:orientation="horizontal"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<!-- Card ID -->
|
||||
<View
|
||||
android:id="@+id/cardIdDivider"
|
||||
android:layout_height="@dimen/inputBorderThickness"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@color/inputBorder" />
|
||||
<TableRow
|
||||
android:id="@+id/cardIdTableRow"
|
||||
android:background="@color/inputBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<View
|
||||
android:gravity="start"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="@dimen/inputBorderThickness"
|
||||
android:background="@color/inputBorder" />
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/cardIdField"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0"
|
||||
android:hint="@string/cardId">
|
||||
|
||||
<RelativeLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_weight="1"
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/cardIdView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="@dimen/inputPadding"
|
||||
android:paddingEnd="@dimen/inputPadding">
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cardIdField"
|
||||
android:text="@string/cardId"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="@dimen/inputSize"
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
/>
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cardIdView"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:textSize="@dimen/inputSize"
|
||||
android:textIsSelectable="true"
|
||||
android:layout_toEndOf="@id/cardIdField"
|
||||
android:layout_toRightOf="@id/cardIdField"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
<!-- Barcode type -->
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/barcodeTypeView"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0"
|
||||
android:hint="@string/barcodeType"
|
||||
android:labelFor="@+id/barcodeTypeField">
|
||||
|
||||
<View
|
||||
android:gravity="end"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="@dimen/inputBorderThickness"
|
||||
android:background="@color/inputBorder" />
|
||||
</TableRow>
|
||||
|
||||
<!-- Barcode Type -->
|
||||
<View
|
||||
android:id="@+id/barcodeTypeDivider"
|
||||
android:layout_height="@dimen/inputBorderThickness"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@color/inputBorder" />
|
||||
<TableRow
|
||||
android:id="@+id/barcodeTypeTableRow"
|
||||
android:background="@color/inputBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<View
|
||||
android:gravity="start"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="@dimen/inputBorderThickness"
|
||||
android:background="@color/inputBorder" />
|
||||
|
||||
<RelativeLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_weight="1"
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/barcodeTypeField"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="@dimen/inputPadding"
|
||||
android:paddingEnd="@dimen/inputPadding">
|
||||
android:inputType="none"/>
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/barcodeTypeField"
|
||||
android:text="@string/barcodeType"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="@dimen/inputSize"
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
/>
|
||||
<!-- Barcode -->
|
||||
<View
|
||||
android:layout_height="@dimen/inputBorderThickness"
|
||||
android:layout_width="match_parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/barcodeTypeView"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:textSize="@dimen/inputSize"
|
||||
android:textIsSelectable="true"
|
||||
android:layout_toEndOf="@id/barcodeTypeField"
|
||||
android:layout_toRightOf="@id/barcodeTypeField"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:gravity="end"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="@dimen/inputBorderThickness"
|
||||
android:background="@color/inputBorder" />
|
||||
</TableRow>
|
||||
|
||||
<View
|
||||
android:layout_height="@dimen/inputBorderThickness"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@color/inputBorder" />
|
||||
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:padding="10.0dip"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/barcodeLayout">
|
||||
<ImageView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/barcode_disp_height"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:padding="10.0dp"
|
||||
android:background="#ffffff"
|
||||
android:id="@+id/barcode"
|
||||
android:contentDescription="@string/barcodeImageDescription"
|
||||
android:layout_weight="1.0"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/inputBackground">
|
||||
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:padding="10.0dip"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/barcodeCaptureLayout">
|
||||
<Button android:id="@+id/captureButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/capture"
|
||||
android:layout_weight="1.0"/>
|
||||
<Button android:id="@+id/enterButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/enterCard"
|
||||
android:layout_weight="1.0"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</TableLayout>
|
||||
</LinearLayout>
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:padding="10.0dip"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/barcodeLayout">
|
||||
<ImageView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/barcode_disp_height"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:padding="10.0dp"
|
||||
android:background="#ffffff"
|
||||
android:id="@+id/barcode"
|
||||
android:contentDescription="@string/barcodeImageDescription"
|
||||
android:layout_weight="1.0"/>
|
||||
</LinearLayout>
|
||||
</TableLayout>
|
||||
</ScrollView>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
@@ -8,14 +8,21 @@
|
||||
android:baselineAligned="false"
|
||||
android:padding="@dimen/activity_margin">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/thumbnail"
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:layout_marginEnd="@dimen/activity_margin"
|
||||
android:layout_marginRight="@dimen/activity_margin"
|
||||
android:src="@mipmap/ic_launcher"
|
||||
android:contentDescription="@string/thumbnailDescription"/>
|
||||
app:cardCornerRadius="4dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/thumbnail"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:contentDescription="@string/thumbnailDescription"
|
||||
android:src="@mipmap/ic_launcher"/>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
@@ -24,23 +31,17 @@
|
||||
android:layout_weight="1">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/valueLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" >
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="visible" >
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/valueLayout"
|
||||
<TextView
|
||||
android:id="@+id/store"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="visible">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/store"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/storeNameTextSize"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
</LinearLayout>
|
||||
android:textSize="@dimen/storeNameTextSize"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -56,8 +57,8 @@
|
||||
android:id="@+id/star"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:layout_marginLeft="@dimen/activity_margin"
|
||||
android:layout_marginStart="@dimen/activity_margin"
|
||||
android:src="@drawable/ic_starred_white"
|
||||
android:tint="#000000"
|
||||
app:tint="@color/iconColor"
|
||||
android:contentDescription="@string/starImage"/>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -59,44 +59,14 @@
|
||||
android:layout_marginLeft="10.0dip"
|
||||
android:layout_marginRight="10.0dip"
|
||||
app:layout_constraintTop_toBottomOf="@+id/barcode"
|
||||
app:layout_constraintBottom_toTopOf="@+id/noteViewDivider"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:textAlignment="center"
|
||||
app:autoSizeTextType="uniform"
|
||||
app:autoSizeMinTextSize="@dimen/singleCardCardIdTextSizeMin"
|
||||
app:autoSizeMaxTextSize="@dimen/singleCardCardIdTextSizeMax"
|
||||
android:ellipsize="end"
|
||||
android:textIsSelectable="true"/>
|
||||
|
||||
<View
|
||||
android:id="@id/noteViewDivider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@android:color/black"
|
||||
app:layout_constraintTop_toBottomOf="@id/cardIdView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/noteView"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@id/noteView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="10.0dip"
|
||||
android:layout_gravity="bottom"
|
||||
app:layout_constraintTop_toBottomOf="@id/noteViewDivider"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:autoSizeTextType="uniform"
|
||||
app:autoSizeMinTextSize="@dimen/singleCardNoteTextSizeMin"
|
||||
app:autoSizeMaxTextSize="@dimen/singleCardNoteTextSizeMax"
|
||||
android:textIsSelectable="true"
|
||||
android:scrollbars="vertical"/>
|
||||
android:ellipsize="end"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -107,6 +77,50 @@
|
||||
android:layout_gravity="top"/>
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bottom_sheet"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:behavior_hideable="false"
|
||||
app:behavior_peekHeight="80dp"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/bottomSheetButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="80dp"
|
||||
android:background="@color/colorPrimary"
|
||||
android:gravity="center"
|
||||
android:src="@drawable/ic_baseline_arrow_drop_up_24"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="fitCenter"
|
||||
android:tint="@android:color/white" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/noteView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/inputBackground"
|
||||
android:gravity="center"
|
||||
android:padding="20dp"
|
||||
app:autoSizeTextType="uniform"
|
||||
app:autoSizeMinTextSize="@dimen/singleCardNoteTextSizeMin"
|
||||
app:autoSizeMaxTextSize="@dimen/singleCardNoteTextSizeMax" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/groupsView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/inputBackground"
|
||||
android:gravity="center"
|
||||
android:padding="20dp"
|
||||
app:autoSizeTextType="uniform"
|
||||
app:autoSizeMinTextSize="@dimen/singleCardNoteTextSizeMin"
|
||||
app:autoSizeMaxTextSize="@dimen/singleCardNoteTextSizeMax" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar_layout"
|
||||
android:background="@android:color/transparent"
|
||||
|
||||
@@ -29,6 +29,13 @@
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/groups"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:tabMode="scrollable"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<include layout="@layout/content_main"/>
|
||||
|
||||
36
app/src/main/res/layout/manage_groups_activity.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?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.ManageGroupsActivity">
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fabAdd"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|bottom"
|
||||
android:src="@drawable/ic_add_white_24dp"
|
||||
android:contentDescription="@string/action_add"
|
||||
android:layout_margin="16dp" />
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<include layout="@layout/group_main"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@@ -8,6 +8,11 @@
|
||||
android:icon="@drawable/ic_search_white"
|
||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||
app:showAsAction="always|collapseActionView"/>
|
||||
<item
|
||||
android:id="@+id/action_manage_groups"
|
||||
android:icon="@drawable/ic_folder_white"
|
||||
android:title="@string/groups"
|
||||
app:showAsAction="always"/>
|
||||
<item
|
||||
android:id="@+id/action_import_export"
|
||||
android:icon="@drawable/ic_import_export_white_24dp"
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<string name="cancel">Zrušit</string>
|
||||
<string name="save">Uložit</string>
|
||||
<string name="capture">Naskenovat kartu</string>
|
||||
<string name="enterCard">Vložit vlastnoručně</string>
|
||||
<string name="edit">Editovat</string>
|
||||
<string name="delete">Smazat</string>
|
||||
<string name="confirm">Potvrdit</string>
|
||||
@@ -26,7 +25,6 @@
|
||||
|
||||
<string name="noStoreError">Nebyl zadán Obchod</string>
|
||||
<string name="noCardIdError">Nebylo zadáno ID karty</string>
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
<string name="importExport">Import/Export</string>
|
||||
<string name="exportName">Export</string>
|
||||
<string name="importExportHelp">Zálohování dat vám umožní přesunout vaše uložené karty na jiné zařízení.</string>
|
||||
|
||||
@@ -2,15 +2,16 @@
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="action_search">Suche</string>
|
||||
<string name="action_add">Neu</string>
|
||||
<string name="noGiftCards">Sie haben noch keine Kundenkarte angelegt. Über den \"+\"-Button oben rechts können welche angelegt werden.\n\nDiese App ermöglicht es, Kundenkarten immer mit zu führen.</string>
|
||||
<string name="noMatchingGiftCards">Es passen keine Kundenkarten zum Suchfilter. Bitte probiere verschiedene Begriffe aus.</string>
|
||||
<string name="noGiftCards">Klicken Sie auf die Schaltfläche + (plus), um zuerst eine Karte hinzuzufügen.
|
||||
\n
|
||||
\nCatima trägt Ihre Karten auf dem Gerät, so dass sie immer in Reichweite sind.</string>
|
||||
<string name="noMatchingGiftCards">Nichts gefunden. Versuchen Sie, Ihre Suche zu ändern.</string>
|
||||
<string name="storeName">Geschäft</string>
|
||||
<string name="note">Notiz</string>
|
||||
<string name="cardId">Kartennummer</string>
|
||||
<string name="cancel">Abbrechen</string>
|
||||
<string name="save">Speichern</string>
|
||||
<string name="capture">Karte scannen</string>
|
||||
<string name="enterCard">Manuell eingeben</string>
|
||||
<string name="editCard">Karte bearbeiten</string>
|
||||
<string name="edit">Bearbeiten</string>
|
||||
<string name="delete">Löschen</string>
|
||||
@@ -28,32 +29,31 @@
|
||||
<string name="addCardTitle">Neue Kundenkarte</string>
|
||||
<string name="scanCardBarcode">Strichcode scannen</string>
|
||||
<string name="cardShortcut">Shortcut zu einer Karte</string>
|
||||
<string name="noCardsMessage">Es ist noch keine Karte vorhanden, bitte zuerst eine hinzufügen</string>
|
||||
<string name="noCardsMessage">Fügen Sie zuerst eine Karte hinzu</string>
|
||||
<string name="barcodeImageDescription">Bild des Strichcodes</string>
|
||||
<string name="noStoreError">Kein Geschäft angegeben</string>
|
||||
<string name="noCardIdError">Keine Kartennummer angegeben</string>
|
||||
<string name="noCardExistsError">Karte konnte nicht gefunden werden</string>
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
<string name="importExport">Import/Export</string>
|
||||
<string name="exportName">Exportieren</string>
|
||||
<string name="importExportHelp">Gesicherte Daten ermöglichen das Verschieben der Kundenkarten auf ein anderes Gerät.</string>
|
||||
<string name="importSuccessfulTitle">Import erfolgreich</string>
|
||||
<string name="importExportHelp">Durch das Sichern Ihrer Karten können Sie sie auf ein anderes Gerät verschieben.</string>
|
||||
<string name="importSuccessfulTitle">Importiert</string>
|
||||
<string name="importFailedTitle">Import fehlgeschlagen</string>
|
||||
<string name="importFailed">Import fehlgeschlagen</string>
|
||||
<string name="exportSuccessfulTitle">Export erfolgreich</string>
|
||||
<string name="importFailed">Karten konnten nicht importiert werden</string>
|
||||
<string name="exportSuccessfulTitle">Exportiert</string>
|
||||
<string name="exportFailedTitle">Export fehlgeschlagen</string>
|
||||
<string name="exportFailed">Export fehlgeschlagen</string>
|
||||
<string name="exportFailed">Karten konnten nicht exportiert werden</string>
|
||||
<string name="importing">Importiere…</string>
|
||||
<string name="exporting">Exportiere…</string>
|
||||
<string name="noExternalStoragePermissionError">Ohne die Berechtigung für den externen Speicher kann kein Import oder Export erfolgen</string>
|
||||
<string name="noExternalStoragePermissionError">Erteilen Sie zuerst die Erlaubnis zur externen Speicherung, um Karten zu importieren oder zu exportieren</string>
|
||||
<string name="importOptionFilesystemTitle">Importiere aus Dateisystem</string>
|
||||
<string name="importOptionFilesystemExplanation">Wähle eine Datei aus dem Speicher aus.</string>
|
||||
<string name="importOptionFilesystemButton">Aus Dateisystem</string>
|
||||
<string name="importOptionApplicationTitle">Externe App verwenden</string>
|
||||
<string name="importOptionApplicationExplanation">Wählen Sie eine Datei aus einer App wie Dropbox, Google Drive, oder Ihrem bevorzugten Dateisystem aus.</string>
|
||||
<string name="importOptionApplicationButton">Nutze eine externe App</string>
|
||||
<string name="importOptionApplicationTitle">Externe Anwendung verwenden</string>
|
||||
<string name="importOptionApplicationExplanation">Verwenden Sie eine beliebige Anwendung oder Ihren bevorzugten Dateiverwaltungsprogramm, um eine Datei zu öffnen.</string>
|
||||
<string name="importOptionApplicationButton">Externe Anwendung nutzen</string>
|
||||
<string name="about">Über</string>
|
||||
<string name="app_license">Lizensiert unter der GPLv3.</string>
|
||||
<string name="app_license">Freie Software, lizensiert unter der GPLv3+.</string>
|
||||
<string name="about_title_fmt">Über <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Version: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Informationen zu dieser Version: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
@@ -63,32 +63,47 @@
|
||||
<string name="copy_to_clipboard_toast">Nummer in die Zwischenablage kopiert</string>
|
||||
<string name="thumbnailDescription">Vorschaubild für die Karte</string>
|
||||
<string name="change">Anpassen</string>
|
||||
<string name="storeTextColorTitle">Textfarbe</string>
|
||||
<string name="storeTextBackgroundColorTitle">Hintergrundfarbe</string>
|
||||
<string name="storeNameBackgroundColorDescription">Hintergrundfarbe für den Geschäftsnamen</string>
|
||||
<string name="storeNameColorDescription">Farbe für den Geschäftsnamen</string>
|
||||
<string name="settings">Einstellungen</string>
|
||||
<string name="settings_category_title_ui">Benutzeroberfläche</string>
|
||||
<string name="settings_card_title_list_font_size">Schriftgröße des Titels in der Listenansicht</string>
|
||||
<string name="settings_card_note_list_font_size">Schriftgröße der Notiz in der Listenansicht</string>
|
||||
<string name="settings_card_title_font_size">Schriftgröße des Titels</string>
|
||||
<string name="settings_card_title_list_font_size">Schriftgröße des Kartentitels (Listenmodus)</string>
|
||||
<string name="settings_card_note_list_font_size">Schriftgröße der Kartennotiz (Listenmodus)</string>
|
||||
<string name="settings_card_title_font_size">Schriftgröße des Kartentitels (Vorschau)</string>
|
||||
<string name="settings_card_id_font_size">Schriftgröße der Kartennummer</string>
|
||||
<string name="settings_card_note_font_size">Schriftgröße der Notiz</string>
|
||||
<string name="settings_card_note_font_size">Schriftgröße der Kartennotiz (Vorschau)</string>
|
||||
<string name="settings_display_barcode_max_brightness">Helligkeit bei Strichcode Ansicht erhöhen</string>
|
||||
<string name="settings_lock_barcode_orientation">Strichcodeausrichtung sperren</string>
|
||||
<string name="exportSuccessful">Kundenkartendaten erflogreich exportiert</string>
|
||||
<string name="importSuccessful">Kundenkartendaten erflogreich importiert</string>
|
||||
<string name="exportSuccessful">Kartendaten exportiert</string>
|
||||
<string name="importSuccessful">Kartendaten importiert</string>
|
||||
<string name="intent_import_card_from_url_share_text">Ich will eine Karte mit Ihnen teilen</string>
|
||||
<string name="settings_dark_theme">Dunkel</string>
|
||||
<string name="settings_light_theme">Hell</string>
|
||||
<string name="settings_system_theme">Systemvorgabe</string>
|
||||
<string name="settings_system_theme">System</string>
|
||||
<string name="settings_theme">Design</string>
|
||||
<string name="enterBarcodeInstructions">Geben Sie die Karten-ID ein und wählen Sie das Bild aus, das den Strichcode darstellt, den Sie verwenden möchten, oder wählen Sie „Diese Karte hat keinen Strichcode“, um keinen Strichcode zu verwenden.</string>
|
||||
<string name="app_copyright_old">Basiert auf Loyalty Card Keychain, Copyright 2016-2020 Branden Archer.</string>
|
||||
<string name="app_copyright_old">Basiert auf Loyalty Card Keychain, Copyright 2016–2020 Branden Archer.</string>
|
||||
<string name="exportOptionExplanation">Die Daten werden an einen Ort Ihrer Wahl geschrieben.</string>
|
||||
<string name="failedParsingImportUriError">Der Import-URI konnte nicht analysiert werden</string>
|
||||
<string name="addedShortcut">Verknüpfung hinzugefügt</string>
|
||||
<string name="share">Teilen</string>
|
||||
<string name="barcodeNoBarcode">Diese Karte hat keinen Strichcode</string>
|
||||
<string name="barcodeType">Strichcode-Typ</string>
|
||||
</resources>
|
||||
<string name="starImage">Favoritenstern</string>
|
||||
<string name="deleteConfirmationGroup">Bitte bestätigen Sie, dass Sie diese Gruppe löschen möchten</string>
|
||||
<string name="all">Alle</string>
|
||||
<string name="noGroups">Klicken Sie auf die Schaltfläche + (plus), um zuerst Gruppen hinzuzufügen.
|
||||
\n
|
||||
\nGruppen machen es einfacher, Dinge zu finden.</string>
|
||||
<string name="groups">Gruppen</string>
|
||||
<string name="enter_group_name">Geben Sie den Gruppennamen ein</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Sind Sie sicher, dass Sie diesen Bildschirm verlassen wollen\? Vorgenommene Änderungen werden nicht gespeichert.</string>
|
||||
<string name="leaveWithoutSaveTitle">Beenden ohne zu speichern</string>
|
||||
<string name="failedOpeningFileManager">Fehler beim Öffnen eines Dateiverwaltungsprogrammes. Stellen Sie sicher, dass eine installiert ist.</string>
|
||||
<string name="noBarcode">Kein Strichcode</string>
|
||||
<string name="addManually">Die Karten-ID manuell eingeben</string>
|
||||
<string name="addWithCamera">Scannen Sie den Strichcode mit Ihrer Kamera</string>
|
||||
<string name="moveDown">In der Liste nach unten verschieben</string>
|
||||
<string name="moveUp">In der Liste nach oben verschieben</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> Karte</item>
|
||||
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> Karten</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
@@ -10,7 +10,6 @@
|
||||
<string name="cancel">Άκυρο</string>
|
||||
<string name="save">Αποθήκευση</string>
|
||||
<string name="capture">Φωτογράφιση Κάρτας</string>
|
||||
<string name="enterCard">Εισάγετε Κάρτα</string>
|
||||
<string name="editCard">Επεξεργασία Κάρτας</string>
|
||||
<string name="edit">Επεξεργασία</string>
|
||||
<string name="delete">Διαγραφή</string>
|
||||
@@ -33,7 +32,6 @@
|
||||
<string name="noStoreError">Δεν δώσατε κατάστημα</string>
|
||||
<string name="noCardIdError">Δεν δώσατε κωδικό κάρτας</string>
|
||||
<string name="noCardExistsError">Δεν ήταν δυνατό να εντοπιστεί κάρτα</string>
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
<string name="importExport">Εισαγωγή/Εξαγωγή</string>
|
||||
<string name="exportName">Εξαγωγή</string>
|
||||
<string name="importExportHelp">Τα εφεδρικά δεδομένα σας δίνουν την δυνατότητα να μεταφέρετε τις κάρτες σας σε μία άλλη συσκευή.</string>
|
||||
@@ -67,10 +65,6 @@
|
||||
<string name="thumbnailDescription">Μικρογραφία κάρτας</string>
|
||||
|
||||
<string name="change">Αλλαγή</string>
|
||||
<string name="storeTextColorTitle">Χρώμα Κειμένου Καταστήματος</string>
|
||||
<string name="storeTextBackgroundColorTitle">Χρώμα Κεφαλίδας</string>
|
||||
<string name="storeNameBackgroundColorDescription">Χρώμα για το υπόβαθρο του καταστήματος</string>
|
||||
<string name="storeNameColorDescription">Χρώμα για το κείμενο του καταστήματος</string>
|
||||
|
||||
<string name="settings">Ρυθμίσεις</string>
|
||||
<string name="settings_category_title_ui">Διεπαφή χρήστη</string>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<string name="cancel">Cancelar</string>
|
||||
<string name="save">Guardar</string>
|
||||
<string name="capture">Capturar tarjeta</string>
|
||||
<string name="enterCard">Introducir tarjeta</string>
|
||||
<string name="editCard">Editar tarjeta</string>
|
||||
<string name="edit">Editar</string>
|
||||
<string name="delete">Eliminar</string>
|
||||
@@ -31,7 +30,6 @@
|
||||
<string name="noStoreError">Establecimiento no especificado</string>
|
||||
<string name="noCardIdError">Id. de tarjeta no especificado</string>
|
||||
<string name="noCardExistsError">No se ha podido encontrar la tarjeta de fidelización</string>
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
<string name="importExport">Importar/exportar</string>
|
||||
<string name="exportName">Exportar</string>
|
||||
<string name="importExportHelp">La copia de respaldo le permite transferir sus tarjetas a otro dispositivo.</string>
|
||||
@@ -55,10 +53,6 @@
|
||||
<string name="about_title_fmt">Acerca de <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Versión: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="change">Cambiar</string>
|
||||
<string name="storeTextColorTitle">Color de texto de establecimiento</string>
|
||||
<string name="storeTextBackgroundColorTitle">Color principal</string>
|
||||
<string name="storeNameBackgroundColorDescription">Color de fondo para el texto de la tienda</string>
|
||||
<string name="storeNameColorDescription">Color del texto de la tienda</string>
|
||||
<string name="settings">Configuración</string>
|
||||
<string name="settings_category_title_ui">Interfaz de usuario</string>
|
||||
<string name="settings_card_title_list_font_size">Tamaño de la letra para el título (lista)</string>
|
||||
@@ -76,13 +70,12 @@
|
||||
<string name="settings_system_theme">Tema del sistema</string>
|
||||
<string name="settings_theme">Tema</string>
|
||||
<string name="enterBarcodeInstructions">Introduzca el identificador de tarjeta y seleccione la imagen que represente el código de barras que se utilizará, o bien, elija «Esta tarjeta no tiene código de barras» para no utilizar ninguno.</string>
|
||||
<string name="app_copyright_old">Basado en Loyalty Card Keychain, derechos de autor 2016-2020 de Branden Archer.</string>
|
||||
<string name="app_copyright_old">Basado en Loyalty Card Keychain, derechos de autor 2016–2020 de Branden Archer.</string>
|
||||
<string name="exportOptionExplanation">Los datos se guardarán en la ubicación que elija.</string>
|
||||
<string name="failedParsingImportUriError">No se pudo procesar el URI de importación</string>
|
||||
<string name="addedShortcut">Atajo añadido</string>
|
||||
<string name="share">Compartir</string>
|
||||
<string name="barcodeNoBarcode">Esta tarjeta no tiene código de barras</string>
|
||||
<string name="barcodeType">Tipo de código de barras</string>
|
||||
<string name="noMatchingGiftCards">Ninguna tarjeta coincide con el filtro de búsqueda. Pruebe con términos distintos.</string>
|
||||
<string name="action_search">Buscar</string>
|
||||
</resources>
|
||||
</resources>
|
||||
@@ -1,14 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="action_add">Ajouter</string>
|
||||
<string name="noGiftCards">Aucune carte de fidélité enregistrée. Appuyez sur le bouton \"+\" (plus) pour commencer.\n\nLoyalty Card Locker vous permet d\'enregistrer vos cartes de fidélité sur votre téléphone pour toujours les avoir à portée de main.</string>
|
||||
<string name="storeName">Nom</string>
|
||||
<string name="note">Note</string>
|
||||
<string name="noGiftCards">Appuyez d\'abord sur le bouton \"+\" (plus) pour ajouter une carte.
|
||||
\n
|
||||
\nCatima enregistre vos cartes sur votre appareil, pour toujours les avoir à portée de main.</string>
|
||||
<string name="storeName">Nom du Magasin</string>
|
||||
<string name="note">Notes</string>
|
||||
<string name="cardId">Numéro</string>
|
||||
<string name="cancel">Annuler</string>
|
||||
<string name="save">Enregistrer</string>
|
||||
<string name="capture">Mode capture</string>
|
||||
<string name="enterCard">Mode manuel</string>
|
||||
<string name="editCard">Modifier</string>
|
||||
<string name="edit">Modifier</string>
|
||||
<string name="delete">Supprimer</string>
|
||||
@@ -16,7 +17,7 @@
|
||||
<string name="lockScreen">Désactiver la rotation</string>
|
||||
<string name="unlockScreen">Activer la rotation</string>
|
||||
<string name="deleteTitle">Supprimer la carte de fidélité</string>
|
||||
<string name="deleteConfirmation">Confirmez que vous souhaitez supprimer cette carte.</string>
|
||||
<string name="deleteConfirmation">Confirmez la suppression de cette carte.</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="copy_to_clipboard">Copier le numéro dans le presse-papier</string>
|
||||
<string name="sendLabel">Envoyer…</string>
|
||||
@@ -24,69 +25,85 @@
|
||||
<string name="addCardTitle">Ajouter une carte de fidélité</string>
|
||||
<string name="scanCardBarcode">Scanner le code-barres</string>
|
||||
<string name="cardShortcut">Raccourci de carte</string>
|
||||
<string name="noCardsMessage">Il n\'y a aucune carte. Ajoutez-en une d\'abord</string>
|
||||
<string name="barcodeImageDescription">Image du code-barres de la carte</string>
|
||||
<string name="noStoreError">Aucun nom n\'a été saisi</string>
|
||||
<string name="noCardIdError">Aucun numéro n\'a été saisi</string>
|
||||
<string name="noCardExistsError">N\'a pas pu retrouver la carte de fidélité</string>
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
<string name="noCardsMessage">Ajoutez d\'abord une carte</string>
|
||||
<string name="barcodeImageDescription">Image du code-barres</string>
|
||||
<string name="noStoreError">Aucun nom de magasin saisi</string>
|
||||
<string name="noCardIdError">Aucun numéro de carte saisi</string>
|
||||
<string name="noCardExistsError">Aucune carte trouvée</string>
|
||||
<string name="importExport">Importer/Exporter</string>
|
||||
<string name="exportName">Exporter</string>
|
||||
<string name="importExportHelp">Exporter vos données vous permet de récupérer vos cartes sur un autre appareil.</string>
|
||||
<string name="importSuccessfulTitle">Importé avec succès</string>
|
||||
<string name="importExportHelp">Exporter vos cartes vous permet de les récupérer sur un autre appareil.</string>
|
||||
<string name="importSuccessfulTitle">Importé</string>
|
||||
<string name="importFailedTitle">Échec de l\'import</string>
|
||||
<string name="importFailed">Échec de l\'import </string>
|
||||
<string name="exportSuccessfulTitle">Exporté avec succès</string>
|
||||
<string name="importFailed">Impossible d\'importer les cartes</string>
|
||||
<string name="exportSuccessfulTitle">Exporté</string>
|
||||
<string name="exportFailedTitle">Échec de l\'export</string>
|
||||
<string name="exportFailed">Échec de l\'export </string>
|
||||
<string name="exportFailed">Impossible d\'exporter les cartes</string>
|
||||
<string name="importing">Import …</string>
|
||||
<string name="exporting">Export …</string>
|
||||
<string name="noExternalStoragePermissionError">Impossible d\'importer ou d\'exporter les données sans l\'autorisation d\'accès au stockage externe</string>
|
||||
<string name="noExternalStoragePermissionError">Veuillez autoriser l\'accès au stockage externe avant d\'importer/exporter les données</string>
|
||||
<string name="importOptionFilesystemTitle">Importer depuis le système de fichiers</string>
|
||||
<string name="importOptionFilesystemExplanation">Choisissez le fichier à importer.</string>
|
||||
<string name="importOptionFilesystemButton">Système de fichiers</string>
|
||||
<string name="importOptionApplicationTitle">Application externe</string>
|
||||
<string name="importOptionApplicationExplanation">Utilisez une application externe comme Dropbox, Google Drive, ou votre gestionnaire de fichiers favori pour ouvrir un fichier.</string>
|
||||
<string name="importOptionApplicationButton">Application externe</string>
|
||||
<string name="importOptionApplicationTitle">Utiliser une application externe</string>
|
||||
<string name="importOptionApplicationExplanation">Utilisez le gestionnaire de fichiers de votre choix pour importer un fichier.</string>
|
||||
<string name="importOptionApplicationButton">Utiliser une application externe</string>
|
||||
<string name="about">À propos</string>
|
||||
<string name="app_license">Licence GPLv3.</string>
|
||||
<string name="app_license">Logiciel libre à copyleft, sous licence GPLv3+.</string>
|
||||
<string name="about_title_fmt">À propos de <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Version : <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Notes sur les versions : <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Notes de version : <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> utilise les bibliothèques-tierces suivantes : <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> utilise les ressources-tierces suivantes : <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g> utilise les ressources tierces suivantes : <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="selectBarcodeTitle">Choisissez le code-barres</string>
|
||||
<string name="copy_to_clipboard_toast">Numéro de carte copié dans le presse-papier</string>
|
||||
<string name="thumbnailDescription">Miniature pour la carte</string>
|
||||
<string name="thumbnailDescription">Miniature de la carte</string>
|
||||
<string name="change">Modifier</string>
|
||||
<string name="storeTextColorTitle">Couleur du texte du magasin</string>
|
||||
<string name="storeTextBackgroundColorTitle">Couleur du titre</string>
|
||||
<string name="storeNameBackgroundColorDescription">Couleur de fond du texte du magasin</string>
|
||||
<string name="storeNameColorDescription">Couleur pour le nom du magasin</string>
|
||||
<string name="settings">Paramètres</string>
|
||||
<string name="settings_category_title_ui">Interface utilisateur</string>
|
||||
<string name="settings_card_title_list_font_size">Taille de police pour les titres de carte en liste</string>
|
||||
<string name="settings_card_note_list_font_size">Taille de police pour les notes de carte en liste</string>
|
||||
<string name="settings_card_title_font_size">Taille de police pour les titres de carte</string>
|
||||
<string name="settings_card_id_font_size">Taille de police pour les numéros de carte</string>
|
||||
<string name="settings_card_note_font_size">Taille de police pour les notes de carte</string>
|
||||
<string name="settings_card_title_list_font_size">Taille du nom des cartes (mode liste)</string>
|
||||
<string name="settings_card_note_list_font_size">Taille de la description (mode liste)</string>
|
||||
<string name="settings_card_title_font_size">Taille du nom de la carte (aperçu)</string>
|
||||
<string name="settings_card_id_font_size">Taille des numéros de carte</string>
|
||||
<string name="settings_card_note_font_size">Taille de la description (aperçu)</string>
|
||||
<string name="settings_display_barcode_max_brightness">Augmenter la luminosité du code-barres</string>
|
||||
<string name="settings_lock_barcode_orientation">Verrouiller l\'orientation du code-barres</string>
|
||||
<string name="exportSuccessful">Carte de fidélité exportée avec succès</string>
|
||||
<string name="importSuccessful">Carte de fidélité importée avec succès</string>
|
||||
<string name="exportSuccessful">Carte exportée avec succès</string>
|
||||
<string name="importSuccessful">Carte de fidélité importée</string>
|
||||
<string name="intent_import_card_from_url_share_text">Je veux partager une carte avec toi</string>
|
||||
<string name="settings_dark_theme">Thème sombre</string>
|
||||
<string name="settings_light_theme">Thème clair</string>
|
||||
<string name="settings_system_theme">Thème du système</string>
|
||||
<string name="settings_dark_theme">Sombre</string>
|
||||
<string name="settings_light_theme">Clair</string>
|
||||
<string name="settings_system_theme">Système</string>
|
||||
<string name="settings_theme">Thème</string>
|
||||
<string name="enterBarcodeInstructions">Entrez l\'identifiant de la carte puis sélectionnez l\'image qui représente le code-barres que vous souhaitez utiliser, ou sélectionnez « Cette carte n\'a pas de code-barres » pour ne pas utiliser de code-barres.</string>
|
||||
<string name="app_copyright_old">Basé sur Loyalty Card Keychain, copyright 2016-2020 Branden Archer.</string>
|
||||
<string name="exportOptionExplanation">Les données seront écrites à un emplacement de votre choix.</string>
|
||||
<string name="app_copyright_old">Basé sur Loyalty Card Keychain, copyright 2016–2020 Branden Archer.</string>
|
||||
<string name="exportOptionExplanation">Les données seront eportées vers l\'emplacement de votre choix.</string>
|
||||
<string name="failedParsingImportUriError">Impossible d\'analyser l\'URI d\'importation</string>
|
||||
<string name="addedShortcut">Raccourci ajouté</string>
|
||||
<string name="share">Partager</string>
|
||||
<string name="barcodeNoBarcode">Cette carte n\'a pas de code-barres</string>
|
||||
<string name="barcodeType">Type de code-barres</string>
|
||||
<string name="noMatchingGiftCards">Aucune carte ne correspond au filtre de recherche. Veuillez essayer d\'autres termes.</string>
|
||||
<string name="noMatchingGiftCards">Aucun résultat. Essayez de modifier votre recherche.</string>
|
||||
<string name="action_search">Rechercher</string>
|
||||
</resources>
|
||||
<string name="unstar">Retirer des favoris</string>
|
||||
<string name="star">Ajouter aux favoris</string>
|
||||
<string name="starImage">Étoile favorite</string>
|
||||
<string name="deleteConfirmationGroup">Confirmez que vous voulez supprimer cette carte</string>
|
||||
<string name="all">Tous</string>
|
||||
<string name="noGroups">Cliquez d\'abord sur le bouton \"+\" (plus) pour ajouter un groupe.
|
||||
\n
|
||||
\nLes groupes permettent de facilement retrouver vos cartes.</string>
|
||||
<string name="groups">Groupes</string>
|
||||
<string name="enter_group_name">Entrez le nom du groupe</string>
|
||||
<string name="noBarcode">Aucun code-barres</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Voulez-vous quitter la page \? Toutes vos modifications seront perdues.</string>
|
||||
<string name="leaveWithoutSaveTitle">Quitter sans enregistrer</string>
|
||||
<string name="failedOpeningFileManager">Gestionnaire de fichiers introuvable. Installez-en un si nécessaire.</string>
|
||||
<string name="addManually">Entrer manuellement l\'identifiant de la carte</string>
|
||||
<string name="addWithCamera">Scannez le code-barres avec votre appareil photo</string>
|
||||
<string name="moveDown">Descendre dans la liste</string>
|
||||
<string name="moveUp">Monter dans la liste</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> carte</item>
|
||||
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> cartes</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
@@ -7,6 +7,5 @@
|
||||
<string name="cancel">ביטול</string>
|
||||
<string name="save">שמור</string>
|
||||
<string name="capture">צלם כרטיס</string>
|
||||
<string name="enterCard">הכנס כרטיס</string>
|
||||
<string name="editCard">עריכת כרטיס</string>
|
||||
</resources>
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
<string name="cancel">Annulla</string>
|
||||
<string name="save">Salva</string>
|
||||
<string name="capture">Scansione carta</string>
|
||||
<string name="enterCard">Inserisci carta</string>
|
||||
<string name="editCard">Modifica carta</string>
|
||||
<string name="edit">Modifica</string>
|
||||
<string name="delete">Elimina</string>
|
||||
@@ -34,7 +33,6 @@
|
||||
<string name="noCardIdError">Nessun codice carta inserito</string>
|
||||
<string name="noCardExistsError">Impossibile trovare la carta</string>
|
||||
<string name="failedParsingImportUriError">Impossibile analizzare l\'URI</string>
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
<string name="importExport">Importa/Esporta</string>
|
||||
<string name="exportName">Esporta</string>
|
||||
<string name="importExportHelp">Fare il backup dei dati ti permette di spostare le tue carte da un dispositivo ad un altro.</string>
|
||||
@@ -65,10 +63,6 @@
|
||||
<string name="copy_to_clipboard_toast">ID della carta copiato negli appunti</string>
|
||||
<string name="thumbnailDescription">Miniatura carta</string>
|
||||
<string name="change">Cambia</string>
|
||||
<string name="storeTextColorTitle">Colore titolo</string>
|
||||
<string name="storeTextBackgroundColorTitle">Colore scheda</string>
|
||||
<string name="storeNameBackgroundColorDescription">Colore di sfondo del titolo carta</string>
|
||||
<string name="storeNameColorDescription">Colore del titolo carta</string>
|
||||
<string name="settings">Impostazioni</string>
|
||||
<string name="settings_category_title_ui">Interfaccia utente</string>
|
||||
<string name="settings_theme">Tema</string>
|
||||
@@ -85,8 +79,17 @@
|
||||
<string name="intent_import_card_from_url_share_text">Voglio condividere una carta fedeltà con te</string>
|
||||
<string name="exportSuccessful">Dati della carta fedeltà esportati correttamente</string>
|
||||
<string name="importSuccessful">Dati della carta fedeltà importati correttamente</string>
|
||||
<string name="app_copyright_old">Basato su Loyalty Card Keychain, copyright 2016-2020 Branden Archer.</string>
|
||||
<string name="app_copyright_old">Basato su Loyalty Card Keychain, copyright 2016–2020 Branden Archer.</string>
|
||||
<string name="exportOptionExplanation">I dati verranno scritti in una posizione a tua scelta.</string>
|
||||
<string name="addedShortcut">Scorciatoia aggiunta</string>
|
||||
<string name="barcodeType">Tipo di codice a barre</string>
|
||||
<string name="unstar">Rimuovi dai preferiti</string>
|
||||
<string name="star">Aggiungi ai preferiti</string>
|
||||
<string name="starImage">Stella preferita</string>
|
||||
<string name="deleteConfirmationGroup">Conferma di voler eliminare questo gruppo</string>
|
||||
<string name="all">Tutti</string>
|
||||
<string name="noGroups">Al momento non hai gruppi. Fai clic sul pulsante + (più) per iniziare.
|
||||
\n
|
||||
\nLe carte possono essere assegnate a gruppi per renderle più facili da trovare.</string>
|
||||
<string name="groups">Gruppi</string>
|
||||
<string name="enter_group_name">Inserisci il nome del gruppo</string>
|
||||
</resources>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<string name="cancel">Atšaukti</string>
|
||||
<string name="save">Išsaugoti</string>
|
||||
<string name="capture">Nufotografuoti kortelę</string>
|
||||
<string name="enterCard">Įvesti kortelę</string>
|
||||
<string name="edit">Redaguoti</string>
|
||||
<string name="delete">Ištrinti</string>
|
||||
<string name="confirm">Patvirtinti</string>
|
||||
@@ -25,7 +24,6 @@
|
||||
|
||||
<string name="noStoreError">Parduotuvė neįvesta</string>
|
||||
<string name="noCardIdError">Neįvestas kortelės ID</string>
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
<string name="importExport">Importuoti/Exportuoti</string>
|
||||
<string name="exportName">Exportuoti</string>
|
||||
<string name="importFailed">Nepavyko importuoti</string>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="action_add">Legg til</string>
|
||||
<string name="noGiftCards">Du har ingen kundekort for øyeblikket. Klikk på \"+\" (pluss)-knappen øverst for å komme igang.\n\nDa har du dem alltid hendig.</string>
|
||||
<string name="noGiftCards">Klikk på \"+\" (pluss)-knappen for å legge til et kort først.
|
||||
\n
|
||||
\nDa har du dem alltid hendig.</string>
|
||||
<string name="storeName">Butikk</string>
|
||||
<string name="note">Merknad</string>
|
||||
<string name="cardId">Kort-ID</string>
|
||||
@@ -9,7 +11,6 @@
|
||||
<string name="cancel">Avbryt</string>
|
||||
<string name="save">Lagre</string>
|
||||
<string name="capture">Les inn kort</string>
|
||||
<string name="enterCard">Skriv inn kort</string>
|
||||
<string name="editCard">Rediger kort</string>
|
||||
<string name="edit">Rediger</string>
|
||||
<string name="delete">Slett</string>
|
||||
@@ -21,7 +22,6 @@
|
||||
<string name="ok">OK</string>
|
||||
<string name="copy_to_clipboard">Kopier ID til utklippstavle</string>
|
||||
<string name="sendLabel">Send…</string>
|
||||
<string name="addedShortcut">Lagt til på hjemmeskjerm</string>
|
||||
<string name="editCardTitle">Rediger kundekort</string>
|
||||
<string name="addCardTitle">Legg til kundekort</string>
|
||||
<string name="scanCardBarcode">Skann kortets strekkode</string>
|
||||
@@ -30,49 +30,38 @@
|
||||
<string name="barcodeImageDescription">Bilde av kortets strekkode</string>
|
||||
<string name="noStoreError">Ingen butikk angitt</string>
|
||||
<string name="noCardIdError">Ingen kort-ID innskrevet</string>
|
||||
<string name="noCardExistsError">Kunne ikke finne kundekort</string>
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
<string name="noCardExistsError">Kunne ikke finne kort</string>
|
||||
<string name="importExport">Import/eksport</string>
|
||||
<string name="exportName">Eksporter</string>
|
||||
<string name="importExportHelp">Sikkerhetskopiering av data lar deg flytte kortene til en annen enhet.</string>
|
||||
<string name="importExportHelp">Sikkerhetskopiering av kort lar deg flytte dem til en annen enhet.</string>
|
||||
<string name="importSuccessfulTitle">Importert</string>
|
||||
<string name="importFailedTitle">Kunne ikke importere</string>
|
||||
<string name="importFailed">Klarte ikke å importere</string>
|
||||
<string name="importFailed">Klarte ikke å importere kort</string>
|
||||
<string name="exportSuccessfulTitle">Eksportert</string>
|
||||
<string name="exportFailedTitle">Kunne ikke eksportere</string>
|
||||
<string name="exportFailed">Klarte ikke å eksportere</string>
|
||||
<string name="exportFailed">Kunne ikke eksportere kort</string>
|
||||
<string name="importing">Importerer…</string>
|
||||
<string name="exporting">Exporterer…</string>
|
||||
<string name="noExternalStoragePermissionError">Kan ikke importere eller eksportere kort uten tilgang til ekstern lagring</string>
|
||||
<string name="exportOptionExplanation">Data skrives til rotmappen i eksternt lagringsområde.</string>
|
||||
<string name="noExternalStoragePermissionError">Innvilg lagringstilgang til eksternlager for å importere eller eksportere kort først</string>
|
||||
<string name="exportOptionExplanation">Data skrives dit du ønsker det.</string>
|
||||
<string name="importOptionFilesystemTitle">Importer fra filsystem</string>
|
||||
<string name="importOptionFilesystemExplanation">Velg spesifikk fil fra filsystemet.</string>
|
||||
<string name="importOptionFilesystemButton">Fra filsystem</string>
|
||||
<string name="importOptionApplicationTitle">Brukt eksternt program</string>
|
||||
<string name="importOptionApplicationExplanation">Bruk eksternt program som Nextcloud, eller din favorittfilbehandler til å åpne ei fil.</string>
|
||||
<string name="importOptionApplicationTitle">Bruk eksternt program</string>
|
||||
<string name="importOptionApplicationExplanation">Bruk hvilket som helst program, eller din favoritt-filutforsker for å åpne en fil.</string>
|
||||
<string name="importOptionApplicationButton">Bruk eksternt program</string>
|
||||
<string name="about">Om</string>
|
||||
<string name="app_license">Lisensiert GPLv3+.</string>
|
||||
<string name="about_title_fmt">Om <xliff:g id="app_name">%s</xliff:g>
|
||||
</string>
|
||||
<string name="debug_version_fmt">Versjon: <xliff:g id="version">%s</xliff:g>
|
||||
</string>
|
||||
<string name="app_license">Gemenhetslig fri programvare, lisensiert GPLv3+.</string>
|
||||
<string name="about_title_fmt">Om <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Versjon: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Utgivelsesinfo: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries">
|
||||
<xliff:g id="app_name">%s</xliff:g> brukfer følgende tredjepartsbibliotek: <xliff:g id="app_libraries_list">%s</xliff:g>
|
||||
</string>
|
||||
<string name="app_resources">
|
||||
<xliff:g id="app_name">%s</xliff:g> bruker følgende tredjepartsressurser: <xliff:g id="app_resources_list">%s</xliff:g>
|
||||
</string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> brukfer følgende tredjepartsbibliotek: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> bruker følgende tredjepartsressurser: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="selectBarcodeTitle">Velg strekkode</string>
|
||||
<string name="enterBarcodeInstructions">Skriv inn strekkodeverdien og velg så bildet som representerer strekkoden du ønsker å bruke.</string>
|
||||
<string name="copy_to_clipboard_toast">Kort-ID kopiert til utklippstavle</string>
|
||||
<string name="thumbnailDescription">Miniatyrbilde for kort</string>
|
||||
<string name="change">Endre</string>
|
||||
<string name="storeTextColorTitle">Skriftstørrelse for butikktekst</string>
|
||||
<string name="storeTextBackgroundColorTitle">Overskriftsfarge</string>
|
||||
<string name="storeNameBackgroundColorDescription">Farge for butikktekstbakgrunn</string>
|
||||
<string name="storeNameColorDescription">Butikktekstfarge</string>
|
||||
<string name="settings">Innstillinger</string>
|
||||
<string name="settings_category_title_ui">Brukergrensesnitt</string>
|
||||
<string name="settings_card_title_list_font_size">Korttittelskriftstørrelse</string>
|
||||
@@ -82,17 +71,35 @@
|
||||
<string name="settings_card_note_font_size">Skriftstørrelse for kortmerknad</string>
|
||||
<string name="settings_display_barcode_max_brightness">Lysere strekkodevisning</string>
|
||||
<string name="settings_lock_barcode_orientation">Lås strekkodesideretning</string>
|
||||
<string name="exportSuccessful">Eksporterte stamkundekortdata</string>
|
||||
<string name="importSuccessful">Importerte stamkundekortdata</string>
|
||||
<string name="exportSuccessful">Kortdata eksportert</string>
|
||||
<string name="importSuccessful">Kortdata importert</string>
|
||||
<string name="intent_import_card_from_url_share_text">Jeg ønsker å dele et kort med deg</string>
|
||||
<string name="settings_dark_theme">Mørk</string>
|
||||
<string name="settings_light_theme">Lys</string>
|
||||
<string name="settings_system_theme">Systemdrakt</string>
|
||||
<string name="settings_system_theme">System</string>
|
||||
<string name="settings_theme">Drakt</string>
|
||||
<string name="app_copyright_old">Basert på Kundekortknippe, opphavsrett 2016-2020 Branden Archer.</string>
|
||||
<string name="app_copyright_old">Basert på Kundekortknippe, opphavsrett 2016–2020 Branden Archer.</string>
|
||||
<string name="failedParsingImportUriError">Kunne ikke tolke importerings-URI</string>
|
||||
<string name="share">Del</string>
|
||||
<string name="barcodeNoBarcode">Dette kortet har ingen strekkode</string>
|
||||
<string name="noMatchingGiftCards">Fant ingen slike kort. Prøv å endre søket.</string>
|
||||
<string name="noMatchingGiftCards">Fant ikke noe. Prøv å endre søket.</string>
|
||||
<string name="action_search">Søk</string>
|
||||
</resources>
|
||||
<string name="starImage">Favorittstjerne</string>
|
||||
<string name="unstar">Fjern fra favoritter</string>
|
||||
<string name="star">Legg til i favoritter</string>
|
||||
<string name="noGroups">Klikk på «+»-tegnet for å legge til grupper først.
|
||||
\n
|
||||
\nGrupper gjør ting enklere å finne.</string>
|
||||
<string name="deleteConfirmationGroup">Bekreft at du ønsker å slette denne gruppen</string>
|
||||
<string name="all">Alle</string>
|
||||
<string name="groups">Grupper</string>
|
||||
<string name="enter_group_name">Skriv inn gruppenavn</string>
|
||||
<string name="noBarcode">Ingen strekkode</string>
|
||||
<string name="failedOpeningFileManager">Klarte ikke å åpne noen filbehandler. Forsikre deg om at du har installert en.</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Er du sikker på at du vil forlate denne skjermen\? Endringer vil ikke bli lagret.</string>
|
||||
<string name="leaveWithoutSaveTitle">Forlat uten å lagre</string>
|
||||
<string name="addManually">Skriv inn kort-ID manuelt</string>
|
||||
<string name="addWithCamera">Skann strekkoden med kameraet ditt</string>
|
||||
<string name="moveDown">Flytt nedover i listen</string>
|
||||
<string name="moveUp">Flytt oppover i listen</string>
|
||||
</resources>
|
||||
|
||||
@@ -15,4 +15,6 @@
|
||||
<color name="inputBackground">#000000</color>
|
||||
<color name="inputBorder">#222222</color>
|
||||
<color name="inputDividerBorder">#666666</color>
|
||||
|
||||
<color name="iconColor">#ffffff</color>
|
||||
</resources>
|
||||
@@ -1,22 +1,19 @@
|
||||
<resources
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="action_search">Zoeken</string>
|
||||
<string name="action_add">Toevoegen</string>
|
||||
|
||||
<string name="noGiftCards">Je hebt nog geen klantenkaarten toegevoegd. Druk op de knop \'+\' (plus) om te beginnen.\n\nMet Klantenkaartkluis beheer je je klantenkaarten op je smartphone of tablet zodat ze altijd binnen handbereik zijn.</string>
|
||||
<string name="noMatchingGiftCards">Er zijn geen kaarten die overeenkomen met je zoekopdracht. Probeer het opnieuw.</string>
|
||||
|
||||
<string name="noGiftCards">Druk op de knop \'+\' (plus) om een kaart toe te voegen.
|
||||
\n
|
||||
\nMet Catima heb je je klantenkaarten altijd binnen handbereik, gewoon op je apparaat.</string>
|
||||
<string name="noMatchingGiftCards">Geen zoekresultaten. Probeer een andere zoekopdracht.</string>
|
||||
<string name="storeName">Winkel</string>
|
||||
<string name="note">Aantekening</string>
|
||||
<string name="cardId">Kaartnummer</string>
|
||||
<string name="barcodeType">Soort barcode</string>
|
||||
<string name="barcodeNoBarcode">Deze kaart heeft geen barcode</string>
|
||||
|
||||
<string name="cancel">Annuleren</string>
|
||||
<string name="save">Opslaan</string>
|
||||
<string name="capture">Scan een kaart</string>
|
||||
<string name="enterCard">Voer een kaartnummer in</string>
|
||||
<string name="editCard">Kaart bewerken</string>
|
||||
<string name="edit">Bewerken</string>
|
||||
<string name="delete">Verwijderen</string>
|
||||
@@ -28,74 +25,86 @@
|
||||
<string name="ok">Oké</string>
|
||||
<string name="copy_to_clipboard">Kaartnummer kopiëren naar klembord</string>
|
||||
<string name="share">Delen</string>
|
||||
<string name="sendLabel">Versturen…</string>
|
||||
<string name="addedShortcut">Snelkoppeling is toegevoegd</string>
|
||||
<string name="editCardTitle">Klantenkaart bewerken</string>
|
||||
<string name="addCardTitle">Klantenkaart toevoegen</string>
|
||||
<string name="sendLabel">Versturen…</string>
|
||||
<string name="editCardTitle">Kaart bewerken</string>
|
||||
<string name="addCardTitle">Kaart toevoegen</string>
|
||||
<string name="scanCardBarcode">Scan de barcode van de kaart</string>
|
||||
<string name="cardShortcut">Kaartsnelkoppeling</string>
|
||||
<string name="noCardsMessage">Je hebt nog geen kaarten toegevoegd.</string>
|
||||
|
||||
<string name="noCardsMessage">Voeg eerst een kaart toe</string>
|
||||
<string name="barcodeImageDescription">Afbeelding van barcode</string>
|
||||
|
||||
<string name="noStoreError">Geen winkelnaam ingevoerd</string>
|
||||
<string name="noCardIdError">Geen kaartnummer ingevoerd</string>
|
||||
<string name="noCardExistsError">De klantenkaart kan niet worden opgevraagd</string>
|
||||
<string name="noCardExistsError">De kaart is niet aangetroffen</string>
|
||||
<string name="failedParsingImportUriError">Kan de import-uri niet verwerken</string>
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
<string name="importExport">Importeren/Exporteren</string>
|
||||
<string name="exportName">Exporteren</string>
|
||||
<string name="importExportHelp">Door de gegevens te back-uppen kun je je kaarten overzetten naar een ander apparaat.</string>
|
||||
<string name="importExportHelp">Door je kaarten te back-uppen, kun je ze overzetten naar een ander apparaat.</string>
|
||||
<string name="importSuccessfulTitle">Importeren voltooid</string>
|
||||
<string name="importFailedTitle">Importeren mislukt</string>
|
||||
<string name="importFailed">Het importeren is mislukt</string>
|
||||
<string name="exportSuccessfulTitle">Exporteren voltooid</string>
|
||||
<string name="exportFailedTitle">Exporteren mislukt</string>
|
||||
<string name="exportFailed">Het exporteren is mislukt</string>
|
||||
<string name="importing">Bezig met importeren…...</string>
|
||||
<string name="exporting">Bezig met exporteren…...</string>
|
||||
<string name="noExternalStoragePermissionError">Het importeren of exporteren van kaarten is niet mogelijk zonder de machtiging \'externe opslag\'.</string>
|
||||
<string name="importing">Bezig met importeren…</string>
|
||||
<string name="exporting">Bezig met exporteren…</string>
|
||||
<string name="noExternalStoragePermissionError">Verleen het recht \'externe opslag\' om kaarten te kunnen im- of exporteren</string>
|
||||
<string name="exportOptionExplanation">De gegevens worden weggeschreven op een locatie naar keuze.</string>
|
||||
<string name="importOptionFilesystemTitle">Importeren uit bestandssysteem</string>
|
||||
<string name="importOptionFilesystemExplanation">Kies een specifiek bestand uit het bestandssysteem.</string>
|
||||
<string name="importOptionFilesystemButton">Uit bestandssysteem</string>
|
||||
<string name="importOptionFilesystemExplanation">Kies een specifiek bestand vanop het bestandssysteem.</string>
|
||||
<string name="importOptionFilesystemButton">Van bestandssysteem</string>
|
||||
<string name="importOptionApplicationTitle">Externe app gebruiken</string>
|
||||
<string name="importOptionApplicationExplanation">Open een bestand middels een externe app, zoals Dropbox, Google Drive of je favoriete bestandsbeheerder.</string>
|
||||
<string name="importOptionApplicationExplanation">Open een bestand middels een app of je favoriete bestandsbeheerder.</string>
|
||||
<string name="importOptionApplicationButton">Externe app gebruiken</string>
|
||||
|
||||
<string name="about">Over</string>
|
||||
<string name="app_license">Uitgebracht onder de GPLv3-licentie.</string>
|
||||
<string name="app_license">Vrije software, uitgebracht onder de GPLv3-licentie.</string>
|
||||
<string name="about_title_fmt">Over <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Versie: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Versie-informatie: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> gebruikt de volgende bibliotheken van externe partijen: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> gebruikt de volgende bronnen van externe partijen: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
|
||||
<string name="selectBarcodeTitle">Barcode toevoegen</string>
|
||||
<string name="enterBarcodeInstructions">Voer de barcode in en kies daarna de afbeelding van de barcode die je wilt gebruiken., of druk op “Deze kaart heeft geen barcode” om geen barcode te gebruiken.</string>
|
||||
|
||||
<string name="enterBarcodeInstructions">Voer de barcode in en kies daarna de afbeelding van de barcode die je wilt gebruiken of druk op “Deze kaart heeft geen barcode” om geen barcode te gebruiken.</string>
|
||||
<string name="copy_to_clipboard_toast">Kaartnummer is gekopieerd naar het klembord</string>
|
||||
|
||||
<string name="thumbnailDescription">Miniatuurvoorbeeld van kaart</string>
|
||||
|
||||
<string name="change">Aanpassen</string>
|
||||
<string name="storeTextColorTitle">Tekstkleur van winkelnaam</string>
|
||||
<string name="storeTextBackgroundColorTitle">Kopkleur</string>
|
||||
<string name="storeNameBackgroundColorDescription">Achtergrondkleur van winkeltekst</string>
|
||||
<string name="storeNameColorDescription">Kleur van winkeltekst</string>
|
||||
|
||||
<string name="settings">Instellingen</string>
|
||||
<string name="settings_category_title_ui">Uiterlijk en bediening</string>
|
||||
<string name="settings_category_title_ui">Vormgeving</string>
|
||||
<string name="settings_theme">Thema</string>
|
||||
<string name="settings_system_theme">Systeemthema</string>
|
||||
<string name="settings_system_theme">Systeem</string>
|
||||
<string name="settings_light_theme">Licht</string>
|
||||
<string name="settings_dark_theme">Donker</string>
|
||||
<string name="settings_card_title_list_font_size">Lettergrootte van kaartnamen op de lijst</string>
|
||||
<string name="settings_card_note_list_font_size">Lettergrootte van aantekeningen op de lijst</string>
|
||||
<string name="settings_card_title_font_size">Lettergrootte van kaartnamen</string>
|
||||
<string name="settings_card_title_list_font_size">Lettergrootte van kaartnamen (lijstmodus)</string>
|
||||
<string name="settings_card_note_list_font_size">Lettergrootte van aantekeningen (lijstmodus)</string>
|
||||
<string name="settings_card_title_font_size">Lettergrootte van kaartnamen (voorvertoning)</string>
|
||||
<string name="settings_card_id_font_size">Lettergrootte van kaartnummer</string>
|
||||
<string name="settings_card_note_font_size">Lettergrootte van aantekeningen</string>
|
||||
<string name="settings_card_note_font_size">Lettergrootte van aantekeningen (voorvertoning)</string>
|
||||
<string name="settings_display_barcode_max_brightness">Scherm helderder maken bij tonen van barcode</string>
|
||||
<string name="settings_lock_barcode_orientation">Barcode-oriëntatie vergrendelen</string>
|
||||
<string name="intent_import_card_from_url_share_text">Ik wil een klantenkaart met je delen</string>
|
||||
</resources>
|
||||
<string name="all">Alles</string>
|
||||
<string name="importSuccessful">De kaartgegevens zijn geïmporteerd</string>
|
||||
<string name="deleteConfirmationGroup">Bevestig dat je deze groep wilt verwijderen</string>
|
||||
<string name="noGroups">Druk op de knop \'+\' (plus) om een groep toe te voegen.
|
||||
\n
|
||||
\nDoor kaarten te groeperen vind je ze makkelijker terug.</string>
|
||||
<string name="exportSuccessful">De kaartgegevens zijn geëxporteerd</string>
|
||||
<string name="groups">Groepen</string>
|
||||
<string name="enter_group_name">Voer een groepsnaam in</string>
|
||||
<string name="starImage">Favoriete ster</string>
|
||||
<string name="app_copyright_old">Gebaseerd op Loyalty Card Keychain, copyright 2016–2020 Branden Archer.</string>
|
||||
<string name="unstar">Verwijderen uit favorieten</string>
|
||||
<string name="star">Toevoegen aan favorieten</string>
|
||||
<string name="addManually">Kaartnummer handmatig invoeren</string>
|
||||
<string name="addWithCamera">Barcode scannen met camera</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Weet je zeker dat je dit wilt\? Hierdoor worden je aanpassingen niet opgeslagen.</string>
|
||||
<string name="leaveWithoutSaveTitle">Afbreken zonder opslaan</string>
|
||||
<string name="moveDown">Omlaag verplaatsen</string>
|
||||
<string name="moveUp">Omhoog verplaatsen</string>
|
||||
<string name="failedOpeningFileManager">Kan de bestandsbeheerder niet openen - zorg dat je er een hebt geïnstalleerd.</string>
|
||||
<string name="noBarcode">Geen barcode</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> kaart</item>
|
||||
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> kaarten</item>
|
||||
</plurals>
|
||||
<string name="groupsList">Groepen: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
</resources>
|
||||
@@ -1,21 +1,16 @@
|
||||
<resources
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="action_search">Szukaj</string>
|
||||
<string name="action_add">Dodaj</string>
|
||||
|
||||
<string name="noGiftCards">W tej chwili nie masz żadnych kart lojalnościowych. Kliknij przycisk \"+\" (plus) u góry, aby rozpocząć. \n\nLoyalty Locker Card pozwala nosić karty lojalnościowe w telefonie, dzięki czemu są zawsze w zasięgu ręki.</string>
|
||||
<string name="noMatchingGiftCards">Żadne karty lojalnościowe nie pasują do filtra wyszukiwania. Spróbuj użyć innych warunków.</string>
|
||||
|
||||
<string name="noMatchingGiftCards">Nic nie znaleziono. Spróbuj zmienić wyszukiwanie.</string>
|
||||
<string name="storeName">Sklep</string>
|
||||
<string name="note">Notatka</string>
|
||||
<string name="cardId">Identyfikator karty</string>
|
||||
<string name="barcodeNoBarcode">Ta karta nie ma kodu kreskowego</string>
|
||||
|
||||
<string name="cancel">Anuluj</string>
|
||||
<string name="save">Zapisz</string>
|
||||
<string name="capture">Zeskanuj kod</string>
|
||||
<string name="enterCard">Wprowadź ręcznie</string>
|
||||
<string name="editCard">Edytuj kartę</string>
|
||||
<string name="edit">Edytuj</string>
|
||||
<string name="delete">Usuń</string>
|
||||
@@ -27,60 +22,47 @@
|
||||
<string name="ok">OK</string>
|
||||
<string name="copy_to_clipboard">Skopiuj identyfikator do schowka</string>
|
||||
<string name="share">Udostępnij</string>
|
||||
<string name="sendLabel">Wyślij…</string>
|
||||
<string name="sendLabel">Wyślij…</string>
|
||||
<string name="editCardTitle">Edytuj kartę lojalnościową</string>
|
||||
<string name="addCardTitle">Dodaj kartę lojalnościową</string>
|
||||
<string name="scanCardBarcode">Zeskanuj kod kreskowy karty lojalnościowej</string>
|
||||
<string name="cardShortcut">Skrót karty</string>
|
||||
<string name="noCardsMessage">Nie ma kart, należy dodać pierwszą</string>
|
||||
|
||||
<string name="noCardsMessage">Najpierw dodaj kartę</string>
|
||||
<string name="barcodeImageDescription">Obraz kodu kreskowego karty</string>
|
||||
|
||||
<string name="noStoreError">Nie wprowadzono nazwy sklepu</string>
|
||||
<string name="noCardIdError">Nie wprowadzono identyfikatora karty</string>
|
||||
<string name="noCardExistsError">Nie można wyszukać karty lojalnościowej</string>
|
||||
<string name="failedParsingImportUriError">Nie można przeanalizować identyfikatora importu URI</string>
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
<string name="importExport">Importuj/Eksportuj</string>
|
||||
<string name="exportName">Eksportuj</string>
|
||||
<string name="importExportHelp">Zarchiwizowane dane umożliwiają przeniesienie kart na inne urządzenie.</string>
|
||||
<string name="importSuccessfulTitle">Zaimportowano pomyślnie</string>
|
||||
<string name="importSuccessfulTitle">Zaimportowano</string>
|
||||
<string name="importFailedTitle">Import nie powiódł się</string>
|
||||
<string name="importFailed">Nie udało się zaimportować</string>
|
||||
<string name="exportSuccessfulTitle">Wyeksportowano pomyślnie</string>
|
||||
<string name="exportSuccessfulTitle">Wyeksportowano</string>
|
||||
<string name="exportFailedTitle">Eksport nie powiódł się</string>
|
||||
<string name="exportFailed">Nie udało się wyeksportować</string>
|
||||
<string name="importing">Importowanie…</string>
|
||||
<string name="exporting">Eksportowanie…</string>
|
||||
<string name="noExternalStoragePermissionError">Nie można importować ani eksportować kart bez uprawnień do pamięci zewnętrznej</string>
|
||||
<string name="importing">Importowanie…</string>
|
||||
<string name="exporting">Eksportowanie…</string>
|
||||
<string name="noExternalStoragePermissionError">Najpierw przyznaj uprawnienia pamięci zewnętrznej do importowania lub eksportowania kart</string>
|
||||
<string name="importOptionFilesystemTitle">Importuj z systemu plików</string>
|
||||
<string name="importOptionFilesystemExplanation">Wybierz określony plik z systemu plików.</string>
|
||||
<string name="importOptionFilesystemButton">Z systemu plików</string>
|
||||
<string name="importOptionApplicationTitle">Użyj zewnętrznej aplikacji</string>
|
||||
<string name="importOptionApplicationExplanation">Użyj zewnętrznej aplikacji jak Dropbox, Google Drive, bądź ulubiony menedżer plików, aby otworzyć plik.</string>
|
||||
<string name="importOptionApplicationExplanation">Użyj dowolnej aplikacji lub ulubionego menedżera plików, aby otworzyć plik.</string>
|
||||
<string name="importOptionApplicationButton">Użyj zewnętrznej aplikacji</string>
|
||||
|
||||
<string name="about">O aplikacji</string>
|
||||
<string name="app_license">Licencjonowane na podstawie GNU General Public License, wersji 3.0.</string>
|
||||
<string name="app_license">Wolne oprogramowanie copylefted, licencjonowane GPLv3 +.</string>
|
||||
<string name="about_title_fmt">O <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Wersja: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Informacje o wersji: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Info o wydaniu: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> wykorzystuje następujące biblioteki osób trzecich: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> wykorzystuje następujące zasoby osób trzecich: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
|
||||
<string name="selectBarcodeTitle">Wybierz kod kreskowy</string>
|
||||
<string name="enterBarcodeInstructions">Wprowadź identyfikator karty, a następnie wybierz obraz reprezentujący kod kreskowy, którego chcesz użyć, lub wybierz “Ta karta nie ma kodu kreskowego”, aby nie używać kodu kreskowego.</string>
|
||||
|
||||
<string name="enterBarcodeInstructions">Wprowadź identyfikator karty, a następnie wybierz obraz reprezentujący kod kreskowy, którego chcesz użyć, lub wybierz “Ta karta nie ma kodu kreskowego”, aby nie używać kodu kreskowego.</string>
|
||||
<string name="copy_to_clipboard_toast">Skopiowano identyfikator karty do schowka</string>
|
||||
|
||||
<string name="thumbnailDescription">Miniaturka karty</string>
|
||||
|
||||
<string name="change">Zmień</string>
|
||||
<string name="storeTextColorTitle">Kolor tekstu nazwy sklepu</string>
|
||||
<string name="storeTextBackgroundColorTitle">Kolor nagłówka</string>
|
||||
<string name="storeNameBackgroundColorDescription">Kolor tła tekstu nazwy sklepu</string>
|
||||
<string name="storeNameColorDescription">Kolor dla tekstu sklepu</string>
|
||||
|
||||
<string name="settings">Ustawienia</string>
|
||||
<string name="settings_category_title_ui">Interfejs użytkownika</string>
|
||||
<string name="settings_theme">Motyw</string>
|
||||
@@ -95,4 +77,20 @@
|
||||
<string name="settings_display_barcode_max_brightness">Rozjaśnij widok kodu kreskowego</string>
|
||||
<string name="settings_lock_barcode_orientation">Zablokuj autoobracanie kodów kreskowych</string>
|
||||
<string name="intent_import_card_from_url_share_text">Chcę udostępnić Ci kartę lojalnościową</string>
|
||||
</resources>
|
||||
<string name="deleteConfirmationGroup">Potwierdź, że chcesz usunąć tę grupę</string>
|
||||
<string name="all">Wszystko</string>
|
||||
<string name="noGroups">Kliknij przycisk + (plus), aby najpierw dodać grupy.
|
||||
\n
|
||||
\nGrupy ułatwiają wyszukiwanie.</string>
|
||||
<string name="groups">Grupy</string>
|
||||
<string name="enter_group_name">Wpisz nazwę grupy</string>
|
||||
<string name="exportSuccessful">Dane karty zostały wyeksportowane</string>
|
||||
<string name="importSuccessful">Zaimportowano dane karty</string>
|
||||
<string name="starImage">Ulubiona gwiazda</string>
|
||||
<string name="app_copyright_old">Na podstawie Loyalty Card Keychain, prawa autorskie 2016–2020 Branden Archer.</string>
|
||||
<string name="exportOptionExplanation">Dane zostaną zapisane w wybranym przez Ciebie miejscu.</string>
|
||||
<string name="unstar">Usuń z ulubionych</string>
|
||||
<string name="star">Dodaj do ulubionych</string>
|
||||
<string name="noBarcode">Brak kodu kreskowego</string>
|
||||
<string name="barcodeType">Typ kodu kreskowego</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
<resources
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="action_search">Поиск</string>
|
||||
<string name="action_add">Добавить карту</string>
|
||||
|
||||
<string name="noGiftCards">Пока нет ни одной карты. Нажмите на кнопку «+» (плюс) сверху для добавления.\n\n«Карты лояльности» позволяют хранить карты скидок в телефоне, так что они всегда будут под рукой.</string>
|
||||
<string name="noMatchingGiftCards">Карт не найдено, попробуйте поискать по-другому.</string>
|
||||
|
||||
<string name="noGiftCards">Нажмите кнопку + (плюс), чтобы сначала добавить карту.
|
||||
\n
|
||||
\nCatima хранит ваши карты на устройстве, поэтому они всегда под рукой.</string>
|
||||
<string name="noMatchingGiftCards">"Ничего не найдено. Попробуйте изменить свой поиск."</string>
|
||||
<string name="storeName">Магазин</string>
|
||||
<string name="note">Примечание</string>
|
||||
<string name="cardId">Номер карты</string>
|
||||
<string name="barcodeType">Тип штрихкода</string>
|
||||
<string name="barcodeNoBarcode">Эта карта без штрихкода</string>
|
||||
|
||||
<string name="cancel">Отменить</string>
|
||||
<string name="save">Сохранить</string>
|
||||
<string name="capture">Сканировать карту</string>
|
||||
<string name="enterCard">Ввести номер</string>
|
||||
<string name="editCard">Редактировать штрих-код</string>
|
||||
<string name="edit">Редактировать</string>
|
||||
<string name="delete">Удалить карту</string>
|
||||
@@ -28,69 +25,55 @@
|
||||
<string name="ok">ОК</string>
|
||||
<string name="copy_to_clipboard">Скопировать номер карты в буфер обмена</string>
|
||||
<string name="share">Переслать</string>
|
||||
<string name="sendLabel">Отправить…</string>
|
||||
<string name="addedShortcut">Добавленный ярлык</string>
|
||||
<string name="sendLabel">Отправить…</string>
|
||||
<string name="editCardTitle">Редактировать карту</string>
|
||||
<string name="addCardTitle">Добавить карту</string>
|
||||
<string name="scanCardBarcode">Отсканируйте штрих-код</string>
|
||||
<string name="cardShortcut">Ярлык карты</string>
|
||||
<string name="noCardsMessage">Карт нет, добавьте одну для начала</string>
|
||||
|
||||
<string name="barcodeImageDescription">Изображение штрих-кода</string>
|
||||
|
||||
<string name="noCardsMessage">Сначала добавьте карту</string>
|
||||
<string name="barcodeImageDescription">Изображение штрих-кода карты</string>
|
||||
<string name="noStoreError">Название магазина не указано</string>
|
||||
<string name="noCardIdError">Номер карты не указан</string>
|
||||
<string name="noCardExistsError">Карта не найдена</string>
|
||||
<string name="failedParsingImportUriError">Не удалось разобрать импортируемый URI</string>
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
<string name="importExport">Импорт/Экспорт</string>
|
||||
<string name="exportName">Экспорт</string>
|
||||
<string name="importExportHelp">Сохранение карт позволяет перенести их на другое устройство.</string>
|
||||
<string name="importSuccessfulTitle">Успешный импорт</string>
|
||||
<string name="importExportHelp">Резервное копирование карт позволяет переместить их на другое устройство.</string>
|
||||
<string name="importSuccessfulTitle">Импортировано</string>
|
||||
<string name="importFailedTitle">Импорт не удался</string>
|
||||
<string name="importFailed">Не удалось импортировать</string>
|
||||
<string name="exportSuccessfulTitle">Успешный экспорт</string>
|
||||
<string name="importFailed">Не удалось импортировать карты</string>
|
||||
<string name="exportSuccessfulTitle">Экспортировано</string>
|
||||
<string name="exportFailedTitle">Экспорт не удался</string>
|
||||
<string name="exportFailed">Не удалось экспортировать</string>
|
||||
<string name="importing">Импорт…</string>
|
||||
<string name="exporting">Экспорт…</string>
|
||||
<string name="importing">Импорт…</string>
|
||||
<string name="exporting">Экспорт…</string>
|
||||
<string name="noExternalStoragePermissionError">Импорт или экспорт невозможен без разрешения на доступ к хранилищу</string>
|
||||
<string name="exportOptionExplanation">Данные будут записаны в выбранное место.</string>
|
||||
<string name="importOptionFilesystemTitle">Импорт из файловой системы</string>
|
||||
<string name="importOptionFilesystemExplanation">Выберете файл на файловой системе.</string>
|
||||
<string name="importOptionFilesystemButton">Выбрать файл</string>
|
||||
<string name="importOptionApplicationTitle">Использование другого приложения</string>
|
||||
<string name="importOptionApplicationExplanation">Использовать другое приложение такое как Dropbox, Google Drive, или ваш любимый файловый менеджер чтобы открыть файл.</string>
|
||||
<string name="importOptionApplicationExplanation">Используйте любое приложение или ваш любимый файловый менеджер, чтобы открыть файл.</string>
|
||||
<string name="importOptionApplicationButton">Использовать другое приложение</string>
|
||||
|
||||
<string name="about">О программе</string>
|
||||
<string name="app_license">Лицензия GPLv3.</string>
|
||||
<string name="app_license">Авторское лево свободного программного обеспечения, лицензия GPLv3+.</string>
|
||||
<string name="about_title_fmt">О программе <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Версия: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Информация о версиях: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> использует следующие сторонние библиотеки: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> использует следующие сторонние ресурсы: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
|
||||
<string name="selectBarcodeTitle">Выбор штрих-кода</string>
|
||||
<string name="enterBarcodeInstructions">Введите ID карты и выберите тип штрих-кода.</string>
|
||||
|
||||
<string name="copy_to_clipboard_toast">Номер карты скопирован в буфер обмена</string>
|
||||
|
||||
<string name="thumbnailDescription">Логотип карты</string>
|
||||
|
||||
<string name="change">Изменить</string>
|
||||
<string name="storeTextColorTitle">Цвет текста</string>
|
||||
<string name="storeTextBackgroundColorTitle">Цвет фона</string>
|
||||
<string name="storeNameBackgroundColorDescription">Цвет фона названия магазина</string>
|
||||
<string name="storeNameColorDescription">Цвет текста названия магазина</string>
|
||||
|
||||
<string name="settings">Настройки</string>
|
||||
<string name="settings_category_title_ui">Внешний вид</string>
|
||||
<string name="settings_theme">Тема</string>
|
||||
<string name="settings_system_theme">Системная тема</string>
|
||||
<string name="settings_light_theme">Светлая тема</string>
|
||||
<string name="settings_dark_theme">Тёмная тема</string>
|
||||
<string name="settings_card_title_list_font_size">Размер шрифта названия карты для списка</string>
|
||||
<string name="settings_system_theme">Системная</string>
|
||||
<string name="settings_light_theme">Светлая</string>
|
||||
<string name="settings_dark_theme">Тёмная</string>
|
||||
<string name="settings_card_title_list_font_size">Размер шрифта для названий карт</string>
|
||||
<string name="settings_card_note_list_font_size">Размер шрифта примечания для списка</string>
|
||||
<string name="settings_card_title_font_size">Размер шрифта названия карты</string>
|
||||
<string name="settings_card_id_font_size">Размер шрифта номера карты</string>
|
||||
@@ -98,4 +81,21 @@
|
||||
<string name="settings_display_barcode_max_brightness">Максимальная яркость при показе карты</string>
|
||||
<string name="settings_lock_barcode_orientation">Портретная ориентация экрана при показе карты</string>
|
||||
<string name="intent_import_card_from_url_share_text">Я хочу поделиться картой с вами</string>
|
||||
</resources>
|
||||
<string name="exportSuccessful">Данные карты экспортированы</string>
|
||||
<string name="all">Все</string>
|
||||
<string name="noGroups">Нажмите кнопку + (плюс), чтобы сначала добавить группы.
|
||||
\n
|
||||
\nГруппы упрощают поиск.</string>
|
||||
<string name="groups">Группы</string>
|
||||
<string name="enter_group_name">Введите название группы</string>
|
||||
<string name="importSuccessful">Данные карты лояльности успешно импортированы</string>
|
||||
<string name="starImage">Любимая звезда</string>
|
||||
<string name="app_copyright_old">На основе Loyalty Card Keychain, авторские права 2016–2020 Branden Archer.</string>
|
||||
<string name="unstar">Удалить из избранного</string>
|
||||
<string name="star">Добавить в избранное</string>
|
||||
<string name="noBarcode">Нет штрих-кода</string>
|
||||
<string name="deleteConfirmationGroup">Подтвердите, что хотите удалить эту группу</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Вы уверены, что хотите покинуть этот экран\? Изменения не будут сохранены.</string>
|
||||
<string name="leaveWithoutSaveTitle">Выйти без сохранения</string>
|
||||
<string name="failedOpeningFileManager">Не удалось открыть файловый менеджер. Пожалуйста, убедитись, что он установлен.</string>
|
||||
</resources>
|
||||
@@ -10,7 +10,6 @@
|
||||
<string name="cancel">Zrušiť</string>
|
||||
<string name="save">Uložiť</string>
|
||||
<string name="capture">Zosnímať kartu</string>
|
||||
<string name="enterCard">Zadať kód</string>
|
||||
<string name="editCard">Úprava karty</string>
|
||||
<string name="edit">Upraviť</string>
|
||||
<string name="delete">Vymazať</string>
|
||||
@@ -33,7 +32,6 @@
|
||||
<string name="noStoreError">Nebol zadaný obchod</string>
|
||||
<string name="noCardIdError">Nebolo zadané ID karty</string>
|
||||
<string name="noCardExistsError">Nie je možné vyhľadať vernostnú kartu</string>
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
<string name="importExport">Import/Export</string>
|
||||
<string name="exportName">Export</string>
|
||||
<string name="importExportHelp">Zálohovanie dát Vám umožní presunúť Vaše uložené karty na iné zariadenie.</string>
|
||||
@@ -67,10 +65,6 @@
|
||||
<string name="thumbnailDescription">Náhľad karty</string>
|
||||
|
||||
<string name="change">Upraviť</string>
|
||||
<string name="storeTextColorTitle">Farba textu</string>
|
||||
<string name="storeTextBackgroundColorTitle">Farba hlavičky</string>
|
||||
<string name="storeNameBackgroundColorDescription">Farba hlavičky</string>
|
||||
<string name="storeNameColorDescription">Farba textu</string>
|
||||
|
||||
<string name="settings">Nastavenia</string>
|
||||
<string name="settings_category_title_ui">Používateľské prostredie</string>
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<resources
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
</resources>
|
||||
@@ -10,7 +10,6 @@
|
||||
<string name="cancel">Prekliči</string>
|
||||
<string name="save">Shrani</string>
|
||||
<string name="capture">Slikaj kartico</string>
|
||||
<string name="enterCard">Vnesi kartico</string>
|
||||
<string name="editCard">Uredi kartico</string>
|
||||
<string name="edit">Uredi</string>
|
||||
<string name="delete">Izbriši</string>
|
||||
@@ -33,7 +32,6 @@
|
||||
<string name="noStoreError">Ime trgovine ni bilo vnešeno</string>
|
||||
<string name="noCardIdError">Številka kartice ni bila vnešena</string>
|
||||
<string name="noCardExistsError">Te kartice zvestobe ni bilo moč najti</string>
|
||||
<string name="cardIdFormat">%1$s:%2$s</string>
|
||||
<string name="importExport">Uvozi/izvozi</string>
|
||||
<string name="exportName">Izvozi</string>
|
||||
<string name="importExportHelp">Varnostna kopija omogoča varen prenos kartic na druge telefonske naprave.</string>
|
||||
@@ -67,10 +65,6 @@
|
||||
<string name="thumbnailDescription">Ikona kartice</string>
|
||||
|
||||
<string name="change">Spremeni</string>
|
||||
<string name="storeTextColorTitle">Barva besedila trgovine</string>
|
||||
<string name="storeTextBackgroundColorTitle">Barva naslova</string>
|
||||
<string name="storeNameBackgroundColorDescription">Barva ozadja za imenom trgovine</string>
|
||||
<string name="storeNameColorDescription">Barva trgovine</string>
|
||||
|
||||
<string name="settings">Nastavitve</string>
|
||||
<string name="settings_category_title_ui">Uporabniški vmesnik</string>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<resources>>
|
||||
|
||||
<style name="AppTheme.NoActionBar">
|
||||
<style name="AppTheme.NoActionBar" parent="AppTheme">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
|
||||
@@ -14,4 +14,6 @@
|
||||
<color name="inputBackground">#FFFFFF</color>
|
||||
<color name="inputBorder">#DDDDDD</color>
|
||||
<color name="inputDividerBorder">#AAAAAA</color>
|
||||
|
||||
<color name="iconColor">#000000</color>
|
||||
</resources>
|
||||
@@ -21,7 +21,8 @@
|
||||
|
||||
<dimen name="inputBorderThickness">2dip</dimen>
|
||||
<dimen name="inputBorderDividerThickness">4dip</dimen>
|
||||
<dimen name="inputPadding">20dip</dimen>
|
||||
<dimen name="inputMargin">2dip</dimen>
|
||||
<dimen name="inputPadding">10dip</dimen>
|
||||
<dimen name="colorSamplePadding">10dip</dimen>
|
||||
<dimen name="inputSize">18sp</dimen>
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
<integer name="settings_card_note_list_font_size_sp">14</integer>
|
||||
<integer name="settings_card_title_font_size_sp">40</integer>
|
||||
<integer name="settings_card_id_font_size_sp">50</integer>
|
||||
<integer name="settings_card_note_font_size_sp">50</integer>
|
||||
|
||||
<!-- Constraints -->
|
||||
<integer name="settings_card_title_list_max_font_size_sp">40</integer>
|
||||
@@ -39,6 +38,4 @@
|
||||
<integer name="settings_card_title_min_font_size_sp">16</integer>
|
||||
<integer name="settings_card_id_max_font_size_sp">50</integer>
|
||||
<integer name="settings_card_id_min_font_size_sp">16</integer>
|
||||
<integer name="settings_card_note_max_font_size_sp">50</integer>
|
||||
<integer name="settings_card_note_min_font_size_sp">26</integer>
|
||||
</resources>
|
||||
@@ -1,18 +1,20 @@
|
||||
<resources
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<string name="app_name" translatable="false">Catima</string>
|
||||
<string name="action_search">Search</string>
|
||||
<string name="action_add">Add</string>
|
||||
|
||||
<string name="noGiftCards">You don\'t have any cards at the moment. Click the "+" (plus) button to get started.\n\nCatima lets you carry your cards on your phone, so they are always within reach.</string>
|
||||
<string name="noMatchingGiftCards">No cards match the search filter. Please try some different terms.</string>
|
||||
<string name="noGiftCards">Click the "+" (plus) button to add a card first.\n\nCatima carries your cards on the device, so they are always within reach.</string>
|
||||
<string name="noMatchingGiftCards">Didn\'t find anything. Try changing your search.</string>
|
||||
|
||||
<string name="storeName">Store</string>
|
||||
<string name="note">Note</string>
|
||||
<string name="cardId">Card ID</string>
|
||||
<string name="barcodeType">Barcode type</string>
|
||||
<string name="barcodeNoBarcode">This card has no barcode</string>
|
||||
<string name="noBarcode">No barcode</string>
|
||||
|
||||
<string name="star">Add to favorites</string>
|
||||
<string name="unstar">Remove from favorites</string>
|
||||
@@ -20,7 +22,6 @@
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="save">Save</string>
|
||||
<string name="capture">Capture Card</string>
|
||||
<string name="enterCard">Enter Card</string>
|
||||
<string name="editCard">Edit Card</string>
|
||||
<string name="edit">Edit</string>
|
||||
<string name="delete">Delete</string>
|
||||
@@ -28,52 +29,50 @@
|
||||
<string name="lockScreen">Block Rotation</string>
|
||||
<string name="unlockScreen">Unblock Rotation</string>
|
||||
<string name="deleteTitle">Remove Card</string>
|
||||
<string name="deleteConfirmation">Please confirm that you want to delete this card.</string>
|
||||
<string name="deleteConfirmation">Please confirm you want to delete this card.</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="copy_to_clipboard">Copy ID to clipboard</string>
|
||||
<string name="share">Share</string>
|
||||
<string name="sendLabel">Send…</string>
|
||||
<string name="addedShortcut">Added shortcut</string>
|
||||
<string name="editCardTitle">Edit Card</string>
|
||||
<string name="addCardTitle">Add Card</string>
|
||||
<string name="scanCardBarcode">Scan Card\'s Barcode</string>
|
||||
<string name="scanCardBarcode">Scan Card Barcode</string>
|
||||
<string name="cardShortcut">Card Shortcut</string>
|
||||
<string name="noCardsMessage">There are no cards, add one first</string>
|
||||
<string name="noCardsMessage">Add a card first</string>
|
||||
|
||||
<string name="barcodeImageDescription">Image of card\'s barcode</string>
|
||||
<string name="barcodeImageDescription">Image of card barcode</string>
|
||||
|
||||
<string name="noStoreError">No Store entered</string>
|
||||
<string name="noCardIdError">No Card ID entered</string>
|
||||
<string name="noCardExistsError">Could not lookup loyalty card</string>
|
||||
<string name="noStoreError">No store entered</string>
|
||||
<string name="noCardIdError">No card ID entered</string>
|
||||
<string name="noCardExistsError">Could not find card</string>
|
||||
<string name="failedParsingImportUriError">Could not parse the import URI</string>
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
<string name="importExport">Import/Export</string>
|
||||
<string name="exportName">Export</string>
|
||||
<string name="importExportHelp">Backed up data can allow you to move your cards to another device.</string>
|
||||
<string name="importSuccessfulTitle">Import successful</string>
|
||||
<string name="importExportHelp">Backing up your cards allows you to move them to another device.</string>
|
||||
<string name="importSuccessfulTitle">Imported</string>
|
||||
<string name="importFailedTitle">Import failed</string>
|
||||
<string name="importFailed">Failed to import</string>
|
||||
<string name="exportSuccessfulTitle">Export successful</string>
|
||||
<string name="importFailed">Could not import cards</string>
|
||||
<string name="exportSuccessfulTitle">Exported</string>
|
||||
<string name="exportFailedTitle">Export failed</string>
|
||||
<string name="exportFailed">Failed to export</string>
|
||||
<string name="exportFailed">Could not export cards</string>
|
||||
<string name="importing">Importing…</string>
|
||||
<string name="exporting">Exporting…</string>
|
||||
<string name="noExternalStoragePermissionError">Unable to import or export cards without the external storage permission</string>
|
||||
<string name="exportOptionExplanation">Data will be written to a location of your choice.</string>
|
||||
<string name="noExternalStoragePermissionError">Grant external storage permission to import or export cards first</string>
|
||||
<string name="exportOptionExplanation">The data will be written to a location of your choice.</string>
|
||||
<string name="importOptionFilesystemTitle">Import from filesystem</string>
|
||||
<string name="importOptionFilesystemExplanation">Choose a specific file from the filesystem.</string>
|
||||
<string name="importOptionFilesystemButton">From filesystem</string>
|
||||
<string name="importOptionApplicationTitle">Use external ap1plication</string>
|
||||
<string name="importOptionApplicationExplanation">Use an external application like Dropbox, Google Drive, or your favorite file manager to open a file.</string>
|
||||
<string name="importOptionApplicationButton">Use external application</string>
|
||||
<string name="importOptionApplicationTitle">Use external app</string>
|
||||
<string name="importOptionApplicationExplanation">Use any app or your favorite file manager to open a file.</string>
|
||||
<string name="importOptionApplicationButton">Use external app</string>
|
||||
|
||||
<string name="about">About</string>
|
||||
<string name="app_copyright_fmt" translatable="false">Copyright 2019-<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="app_copyright_old">Based on Loyalty Card Keychain, copyright 2016-2020 Branden Archer.</string>
|
||||
<string name="app_license">Licensed under the GPLv3.</string>
|
||||
<string name="app_copyright_fmt" translatable="false" tools:ignore="PluralsCandidate">Copyright 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="app_copyright_old">Based on Loyalty Card Keychain, copyright 2016–2020 Branden Archer.</string>
|
||||
<string name="app_license">Copylefted libre software, licensed GPLv3+.</string>
|
||||
<string name="about_title_fmt">About <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Version: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Revision Information: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Revision Info: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> uses the following third-party libraries: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> uses the following third-party resources: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
|
||||
@@ -86,41 +85,58 @@
|
||||
<string name="starImage">Favorite star</string>
|
||||
|
||||
<string name="change">Change</string>
|
||||
<string name="storeTextColorTitle">Store Text Color</string>
|
||||
<string name="storeTextBackgroundColorTitle">Heading Color</string>
|
||||
<string name="storeNameBackgroundColorDescription">Color for store text background</string>
|
||||
<string name="storeNameColorDescription">Color for store text</string>
|
||||
|
||||
<string name="settings">Settings</string>
|
||||
<string name="settings_category_title_ui">User interface</string>
|
||||
<string name="settings_theme">Theme</string>
|
||||
<string name="settings_key_theme" translatable="false">pref_theme</string>
|
||||
<string name="settings_system_theme">System theme</string>
|
||||
<string name="settings_system_theme">System</string>
|
||||
<string name="settings_key_system_theme" translatable="false">system</string>
|
||||
<string name="settings_light_theme">Light theme</string>
|
||||
<string name="settings_light_theme">Light</string>
|
||||
<string name="settings_key_light_theme" translatable="false">light</string>
|
||||
<string name="settings_dark_theme">Dark theme</string>
|
||||
<string name="settings_dark_theme">Dark</string>
|
||||
<string name="settings_key_dark_theme" translatable="false">dark</string>
|
||||
<string name="settings_card_title_list_font_size">Card title list font size</string>
|
||||
<string name="settings_card_title_list_font_size">Card title font size (list mode)</string>
|
||||
<string name="settings_key_card_title_list_font_size" translatable="false">pref_card_title_list_font_size_sp</string>
|
||||
<string name="settings_card_note_list_font_size">Card note list font size</string>
|
||||
<string name="settings_card_note_list_font_size">Card note font size (list mode)</string>
|
||||
<string name="settings_key_card_note_list_font_size" translatable="false">pref_card_note_list_font_size_sp</string>
|
||||
<string name="settings_card_title_font_size">Card title font size</string>
|
||||
<string name="settings_card_title_font_size">Card title font size (preview)</string>
|
||||
<string name="settings_key_card_title_font_size" translatable="false">pref_card_title_font_size_sp</string>
|
||||
<string name="settings_card_id_font_size">Card ID font size</string>
|
||||
<string name="settings_key_card_id_font_size" translatable="false">pref_card_id_font_size_sp</string>
|
||||
<string name="settings_card_note_font_size">Card note font size</string>
|
||||
<string name="settings_card_note_font_size">Card note font size (preview)</string>
|
||||
<string name="settings_key_card_note_font_size" translatable="false">pref_card_note_font_size_sp</string>
|
||||
<string name="settings_display_barcode_max_brightness">Brighten barcode view</string>
|
||||
<string name="settings_key_display_barcode_max_brightness" translatable="false">pref_display_card_max_brightness</string>
|
||||
<string name="settings_lock_barcode_orientation">Lock barcode orientation</string>
|
||||
<string name="settings_key_lock_barcode_orientation" translatable="false">pref_lock_barcode_orientation</string>
|
||||
|
||||
<string name="sharedpreference_active_tab" translatable="false">sharedpreference_active_tab</string>
|
||||
|
||||
<string name="intent_import_card_from_url_share_text">I want to share a card with you</string>
|
||||
<string name="intent_import_card_from_url_host" translatable="false">thelastproject.github.io</string>
|
||||
<string name="intent_import_card_from_url_path_prefix" translatable="false">/Catima/share</string>
|
||||
<string name="intent_import_card_from_url_host_old" translatable="false">brarcher.github.io</string>
|
||||
<string name="intent_import_card_from_url_path_prefix_old" translatable="false">/loyalty-card-locker/share</string>
|
||||
<string name="importSuccessful">Successfully imported loyalty card data</string>
|
||||
<string name="exportSuccessful">Successfully exported loyalty card data</string>
|
||||
<string name="importSuccessful">Card data imported</string>
|
||||
<string name="exportSuccessful">Card data exported</string>
|
||||
|
||||
<string name="enter_group_name">Enter group name</string>
|
||||
<string name="groups">Groups</string>
|
||||
<string name="noGroups">Click the "+" (plus) button to add groups first.\n\nGroups make things easier to find.</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> card</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> cards</item>
|
||||
</plurals>
|
||||
|
||||
<string name="all">All</string>
|
||||
<string name="deleteConfirmationGroup">Please confirm you want to delete this group</string>
|
||||
<string name="failedOpeningFileManager">Failed opening a file manager. Please make sure one is installed.</string>
|
||||
<string name="moveUp">Move up in list</string>
|
||||
<string name="moveDown">Move down in list</string>
|
||||
<string name="leaveWithoutSaveTitle">Leave without saving</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Are you sure you want to leave this screen? Changed made will not be saved.</string>
|
||||
<string name="addWithCamera">Scan the barcode with your camera</string>
|
||||
<string name="addManually">Manually enter card ID</string>
|
||||
<string name="groupsList">Groups: <xliff:g>%s</xliff:g></string>
|
||||
</resources>
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.DayNight.DarkActionBar">
|
||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorSecondary">@color/colorSecondary</item>
|
||||
<item name="colorAccent">@color/colorSecondary</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionBar">
|
||||
<style name="AppTheme.NoActionBar" parent="AppTheme">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>
|
||||
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.MaterialComponents.Dark.ActionBar"/>
|
||||
|
||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
|
||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.MaterialComponents.Light"/>
|
||||
|
||||
<style name="CardView.ActionBarTheme" parent="@style/ThemeOverlay.AppCompat.ActionBar">
|
||||
<style name="CardView.ActionBarTheme" parent="@style/ThemeOverlay.MaterialComponents.ActionBar">
|
||||
<!-- THIS is where you can color the arrow! -->
|
||||
<item name="colorControlNormal">@android:color/white</item>
|
||||
</style>
|
||||
@@ -28,5 +29,4 @@
|
||||
<item name="android:padding">@dimen/no_data_padding</item>
|
||||
<item name="android:textSize">@dimen/no_data_textSize</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -41,13 +41,6 @@
|
||||
app:vnt_maxValue="@integer/settings_card_id_max_font_size_sp"
|
||||
app:vnt_minValue="@integer/settings_card_id_min_font_size_sp" />
|
||||
|
||||
<com.vanniktech.vntnumberpickerpreference.VNTNumberPickerPreference
|
||||
android:key="@string/settings_key_card_note_font_size"
|
||||
android:title="@string/settings_card_note_font_size"
|
||||
android:defaultValue="@integer/settings_card_note_font_size_sp"
|
||||
app:vnt_maxValue="@integer/settings_card_note_max_font_size_sp"
|
||||
app:vnt_minValue="@integer/settings_card_note_min_font_size_sp" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/settings_key_display_barcode_max_brightness"
|
||||
|
||||
@@ -15,7 +15,11 @@ import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@@ -40,7 +44,7 @@ public class DatabaseTest
|
||||
public void addRemoveOneGiftCard()
|
||||
{
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
long id = db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR, DEFAULT_HEADER_TEXT_COLOR, 0);
|
||||
long id = db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
@@ -62,12 +66,12 @@ public class DatabaseTest
|
||||
@Test
|
||||
public void updateGiftCard()
|
||||
{
|
||||
long id = db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR, DEFAULT_HEADER_TEXT_COLOR,0);
|
||||
long id = db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
|
||||
result = db.updateLoyaltyCard(1, "store1", "note1", "cardId1", BarcodeFormat.AZTEC.toString(), DEFAULT_HEADER_COLOR, DEFAULT_HEADER_TEXT_COLOR);
|
||||
result = db.updateLoyaltyCard(1, "store1", "note1", "cardId1", BarcodeFormat.AZTEC.toString(), DEFAULT_HEADER_COLOR);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
|
||||
@@ -83,7 +87,7 @@ public class DatabaseTest
|
||||
@Test
|
||||
public void updateGiftCardOnlyStar()
|
||||
{
|
||||
long id = db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR, DEFAULT_HEADER_TEXT_COLOR,0);
|
||||
long id = db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
@@ -101,15 +105,13 @@ public class DatabaseTest
|
||||
assertEquals(BarcodeFormat.UPC_A.toString(), loyaltyCard.barcodeType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void updateMissingGiftCard()
|
||||
{
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
|
||||
boolean result = db.updateLoyaltyCard(1, "store1", "note1", "cardId1",
|
||||
BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR, DEFAULT_HEADER_TEXT_COLOR);
|
||||
BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR);
|
||||
assertEquals(false, result);
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
}
|
||||
@@ -117,7 +119,7 @@ public class DatabaseTest
|
||||
@Test
|
||||
public void emptyGiftCardValues()
|
||||
{
|
||||
long id = db.insertLoyaltyCard("", "", "", "", null, null, 0);
|
||||
long id = db.insertLoyaltyCard("", "", "", "", null, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
@@ -140,7 +142,7 @@ public class DatabaseTest
|
||||
for(int index = CARDS_TO_ADD-1; index >= 0; index--)
|
||||
{
|
||||
long id = db.insertLoyaltyCard("store" + index, "note" + index, "cardId" + index,
|
||||
BarcodeFormat.UPC_A.toString(), index, index*2, 0);
|
||||
BarcodeFormat.UPC_A.toString(), index, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
}
|
||||
@@ -163,7 +165,6 @@ public class DatabaseTest
|
||||
assertEquals(BarcodeFormat.UPC_A.toString(), cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE)));
|
||||
assertEquals(0, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STAR_STATUS)));
|
||||
assertEquals(index, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_COLOR)));
|
||||
assertEquals(index*2, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_TEXT_COLOR)));
|
||||
|
||||
cursor.moveToNext();
|
||||
}
|
||||
@@ -182,12 +183,12 @@ public class DatabaseTest
|
||||
{
|
||||
if (index == CARDS_TO_ADD-1) {
|
||||
id = db.insertLoyaltyCard("store" + index, "note" + index, "cardId" + index,
|
||||
BarcodeFormat.UPC_A.toString(), index, index*2, 1);
|
||||
BarcodeFormat.UPC_A.toString(), index, 1);
|
||||
}
|
||||
|
||||
else {
|
||||
id = db.insertLoyaltyCard("store" + index, "note" + index, "cardId" + index,
|
||||
BarcodeFormat.UPC_A.toString(), index, index*2, 0);
|
||||
BarcodeFormat.UPC_A.toString(), index, 0);
|
||||
}
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
@@ -209,7 +210,6 @@ public class DatabaseTest
|
||||
assertEquals(BarcodeFormat.UPC_A.toString(), cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE)));
|
||||
assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STAR_STATUS)));
|
||||
assertEquals(index, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_COLOR)));
|
||||
assertEquals(index*2, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_TEXT_COLOR)));
|
||||
|
||||
cursor.moveToNext();
|
||||
|
||||
@@ -222,7 +222,6 @@ public class DatabaseTest
|
||||
assertEquals(BarcodeFormat.UPC_A.toString(), cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE)));
|
||||
assertEquals(0, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STAR_STATUS)));
|
||||
assertEquals(index, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_COLOR)));
|
||||
assertEquals(index*2, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_TEXT_COLOR)));
|
||||
|
||||
cursor.moveToNext();
|
||||
}
|
||||
@@ -234,6 +233,8 @@ public class DatabaseTest
|
||||
{
|
||||
// Delete the tables as they exist now
|
||||
database.execSQL("drop table " + DBHelper.LoyaltyCardDbIds.TABLE);
|
||||
database.execSQL("drop table " + DBHelper.LoyaltyCardDbGroups.TABLE);
|
||||
database.execSQL("drop table " + DBHelper.LoyaltyCardDbIdsGroups.TABLE);
|
||||
|
||||
// Create the table as it existed in revision 1
|
||||
database.execSQL("create table " + DBHelper.LoyaltyCardDbIds.TABLE + "(" +
|
||||
@@ -256,6 +257,161 @@ public class DatabaseTest
|
||||
return (int)newId;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addRemoveOneGroup()
|
||||
{
|
||||
assertEquals(0, db.getGroupCount());
|
||||
long id = db.insertGroup("group one");
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getGroupCount());
|
||||
|
||||
Group group = db.getGroup("group one");
|
||||
assertNotNull(group);
|
||||
assertEquals("group one", group._id);
|
||||
|
||||
result = db.deleteGroup("group one");
|
||||
assertTrue(result);
|
||||
assertEquals(0, db.getGroupCount());
|
||||
assertNull(db.getGroup("group one"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateGroup()
|
||||
{
|
||||
long id = db.insertGroup("group one");
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getGroupCount());
|
||||
|
||||
result = db.updateGroup("group one", "group one renamed");
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getGroupCount());
|
||||
|
||||
// Group one no longer exists
|
||||
Group group = db.getGroup("group one");
|
||||
assertNull(group);
|
||||
|
||||
// But group one renamed does
|
||||
Group group2 = db.getGroup("group one renamed");
|
||||
assertNotNull(group2);
|
||||
assertEquals("group one renamed", group2._id);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateMissingGroup()
|
||||
{
|
||||
assertEquals(0, db.getGroupCount());
|
||||
|
||||
boolean result = db.updateGroup("group one", "new name");
|
||||
assertEquals(false, result);
|
||||
assertEquals(0, db.getGroupCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyGroupValues()
|
||||
{
|
||||
long id = db.insertGroup("");
|
||||
boolean result = (id != -1);
|
||||
assertFalse(result);
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void duplicateGroupName()
|
||||
{
|
||||
assertEquals(0, db.getGroupCount());
|
||||
long id = db.insertGroup("group one");
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getGroupCount());
|
||||
|
||||
Group group = db.getGroup("group one");
|
||||
assertNotNull(group);
|
||||
assertEquals("group one", group._id);
|
||||
|
||||
// Should fail on duplicate
|
||||
long id2 = db.insertGroup("group one");
|
||||
boolean result2 = (id2 != -1);
|
||||
assertFalse(result2);
|
||||
assertEquals(1, db.getGroupCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateGroupDuplicate()
|
||||
{
|
||||
long id = db.insertGroup("group one");
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getGroupCount());
|
||||
|
||||
long id2 = db.insertGroup("group two");
|
||||
boolean result2 = (id2 != -1);
|
||||
assertTrue(result2);
|
||||
assertEquals(2, db.getGroupCount());
|
||||
|
||||
// Should fail when trying to rename group two to one
|
||||
boolean result3 = db.updateGroup("group two", "group one");
|
||||
assertFalse(result3);
|
||||
assertEquals(2, db.getGroupCount());
|
||||
|
||||
// Rename failed so both should still be the same
|
||||
Group group = db.getGroup("group one");
|
||||
assertNotNull(group);
|
||||
assertEquals("group one", group._id);
|
||||
|
||||
Group group2 = db.getGroup("group two");
|
||||
assertNotNull(group2);
|
||||
assertEquals("group two", group2._id);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cardAddAndRemoveGroups()
|
||||
{
|
||||
// Create card
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
long id = db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
|
||||
// Create two groups to only one card
|
||||
assertEquals(0, db.getGroupCount());
|
||||
long gid = db.insertGroup("one");
|
||||
boolean gresult = (gid != -1);
|
||||
assertTrue(gresult);
|
||||
|
||||
long gid2 = db.insertGroup("two");
|
||||
boolean gresult2 = (gid2 != -1);
|
||||
assertTrue(gresult2);
|
||||
|
||||
assertEquals(2, db.getGroupCount());
|
||||
|
||||
Group group1 = db.getGroup("one");
|
||||
|
||||
// Card has no groups by default
|
||||
List<Group> cardGroups = db.getLoyaltyCardGroups(1);
|
||||
assertEquals(0, cardGroups.size());
|
||||
|
||||
// Add one groups to card
|
||||
List<Group> groupList1 = new ArrayList<>();
|
||||
groupList1.add(group1);
|
||||
db.setLoyaltyCardGroups(1, groupList1);
|
||||
|
||||
List<Group> cardGroups1 = db.getLoyaltyCardGroups(1);
|
||||
assertEquals(1, cardGroups1.size());
|
||||
assertEquals(cardGroups1.get(0)._id, group1._id);
|
||||
assertEquals(1, db.getGroupCardCount("one"));
|
||||
assertEquals(0, db.getGroupCardCount("two"));
|
||||
|
||||
// Remove groups
|
||||
db.setLoyaltyCardGroups(1, new ArrayList<Group>());
|
||||
List<Group> cardGroups2 = db.getLoyaltyCardGroups(1);
|
||||
assertEquals(0, cardGroups2.size());
|
||||
assertEquals(0, db.getGroupCardCount("one"));
|
||||
assertEquals(0, db.getGroupCardCount("two"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void databaseUpgradeFromVersion1()
|
||||
{
|
||||
|
||||
@@ -9,7 +9,6 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.view.View;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -17,7 +16,6 @@ import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowPackageManager;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(sdk = 23)
|
||||
@@ -62,56 +60,6 @@ public class ImportExportActivityTest
|
||||
assertEquals(state, buttonView.getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImportFilesystemOption()
|
||||
{
|
||||
for(boolean isInstalled : new Boolean[]{false, true})
|
||||
{
|
||||
int visibility = isInstalled ? View.VISIBLE : View.GONE;
|
||||
|
||||
if(isInstalled)
|
||||
{
|
||||
registerIntentHandler(Intent.ACTION_GET_CONTENT);
|
||||
}
|
||||
|
||||
Activity activity = Robolectric.setupActivity(ImportExportActivity.class);
|
||||
|
||||
checkVisibility(activity, visibility, R.id.dividerImportFilesystem,
|
||||
R.id.importOptionFilesystemTitle, R.id.importOptionFilesystemExplanation,
|
||||
R.id.importOptionFilesystemButton);
|
||||
|
||||
// Should always be gone, as its provider is never installed
|
||||
checkVisibility(activity, View.GONE, R.id.dividerImportApplication,
|
||||
R.id.importOptionApplicationTitle, R.id.importOptionApplicationExplanation,
|
||||
R.id.importOptionApplicationButton);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImportApplicationOption()
|
||||
{
|
||||
for(boolean isInstalled : new Boolean[]{false, true})
|
||||
{
|
||||
int visibility = isInstalled ? View.VISIBLE : View.GONE;
|
||||
|
||||
if(isInstalled)
|
||||
{
|
||||
registerIntentHandler(Intent.ACTION_PICK);
|
||||
}
|
||||
|
||||
Activity activity = Robolectric.setupActivity(ImportExportActivity.class);
|
||||
|
||||
checkVisibility(activity, visibility, R.id.dividerImportApplication,
|
||||
R.id.importOptionApplicationTitle, R.id.importOptionApplicationExplanation,
|
||||
R.id.importOptionApplicationButton);
|
||||
|
||||
// Should always be gone, as its provider is never installed
|
||||
checkVisibility(activity, View.GONE, R.id.dividerImportFilesystem,
|
||||
R.id.importOptionFilesystemTitle, R.id.importOptionFilesystemExplanation,
|
||||
R.id.importOptionFilesystemButton);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllOptionsAvailable()
|
||||
{
|
||||
|
||||
@@ -24,7 +24,9 @@ import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@@ -68,7 +70,7 @@ public class ImportExportTest
|
||||
{
|
||||
String storeName = String.format("store, \"%4d", index);
|
||||
String note = String.format("note, \"%4d", index);
|
||||
long id = db.insertLoyaltyCard(storeName, note, BARCODE_DATA, BARCODE_TYPE, index, index*2, 0);
|
||||
long id = db.insertLoyaltyCard(storeName, note, BARCODE_DATA, BARCODE_TYPE, index, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
}
|
||||
@@ -84,7 +86,7 @@ public class ImportExportTest
|
||||
{
|
||||
String storeName = String.format("store, \"%4d", index);
|
||||
String note = String.format("note, \"%4d", index);
|
||||
long id = db.insertLoyaltyCard(storeName, note, BARCODE_DATA, BARCODE_TYPE, index, index*2, 1);
|
||||
long id = db.insertLoyaltyCard(storeName, note, BARCODE_DATA, BARCODE_TYPE, index, 1);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
}
|
||||
@@ -93,13 +95,27 @@ public class ImportExportTest
|
||||
String storeName = String.format("store, \"%4d", index);
|
||||
String note = String.format("note, \"%4d", index);
|
||||
//if index is even
|
||||
long id = db.insertLoyaltyCard(storeName, note, BARCODE_DATA, BARCODE_TYPE, index, index*2, 0);
|
||||
long id = db.insertLoyaltyCard(storeName, note, BARCODE_DATA, BARCODE_TYPE, index, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
}
|
||||
assertEquals(cardsToAdd, db.getLoyaltyCardCount());
|
||||
}
|
||||
|
||||
private void addGroups(int groupsToAdd)
|
||||
{
|
||||
// Add in reverse order to test sorting
|
||||
for(int index = groupsToAdd; index > 0; index--)
|
||||
{
|
||||
String groupName = String.format("group, \"%4d", index);
|
||||
long id = db.insertGroup(groupName);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
assertEquals(groupsToAdd, db.getGroupCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that all of the cards follow the pattern
|
||||
* specified in addLoyaltyCards(), and are in sequential order
|
||||
@@ -122,7 +138,6 @@ public class ImportExportTest
|
||||
assertEquals(BARCODE_DATA, card.cardId);
|
||||
assertEquals(BARCODE_TYPE, card.barcodeType);
|
||||
assertEquals(Integer.valueOf(index), card.headerColor);
|
||||
assertEquals(Integer.valueOf(index*2), card.headerTextColor);
|
||||
assertEquals(0, card.starStatus);
|
||||
|
||||
index++;
|
||||
@@ -153,7 +168,6 @@ public class ImportExportTest
|
||||
assertEquals(BARCODE_DATA, card.cardId);
|
||||
assertEquals(BARCODE_TYPE, card.barcodeType);
|
||||
assertEquals(Integer.valueOf(index), card.headerColor);
|
||||
assertEquals(Integer.valueOf(index*2), card.headerTextColor);
|
||||
assertEquals(1, card.starStatus);
|
||||
|
||||
index++;
|
||||
@@ -172,7 +186,6 @@ public class ImportExportTest
|
||||
assertEquals(BARCODE_DATA, card.cardId);
|
||||
assertEquals(BARCODE_TYPE, card.barcodeType);
|
||||
assertEquals(Integer.valueOf(index), card.headerColor);
|
||||
assertEquals(Integer.valueOf(index*2), card.headerTextColor);
|
||||
assertEquals(0, card.starStatus);
|
||||
|
||||
index++;
|
||||
@@ -181,6 +194,29 @@ public class ImportExportTest
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that all of the groups follow the pattern
|
||||
* specified in addGroups(), and are in sequential order
|
||||
* where the smallest group's index is 1
|
||||
*/
|
||||
private void checkGroups()
|
||||
{
|
||||
Cursor cursor = db.getGroupCursor();
|
||||
int index = db.getGroupCount();
|
||||
|
||||
while(cursor.moveToNext())
|
||||
{
|
||||
Group group = Group.toGroup(cursor);
|
||||
|
||||
String expectedGroupName = String.format("group, \"%4d", index);
|
||||
|
||||
assertEquals(expectedGroupName, group._id);
|
||||
|
||||
index--;
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the contents of the database
|
||||
*/
|
||||
@@ -263,6 +299,96 @@ public class ImportExportTest
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> groupsToGroupNames(List<Group> groups)
|
||||
{
|
||||
List<String> groupNames = new ArrayList<>();
|
||||
|
||||
for (Group group : groups) {
|
||||
groupNames.add(group._id);
|
||||
}
|
||||
|
||||
return groupNames;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleCardsExportImportWithGroups() throws IOException
|
||||
{
|
||||
final int NUM_CARDS = 10;
|
||||
final int NUM_GROUPS = 3;
|
||||
|
||||
for(DataFormat format : DataFormat.values())
|
||||
{
|
||||
addLoyaltyCards(NUM_CARDS);
|
||||
addGroups(NUM_GROUPS);
|
||||
|
||||
List<Group> emptyGroup = new ArrayList<>();
|
||||
|
||||
List<Group> groupsForOne = new ArrayList<>();
|
||||
groupsForOne.add(db.getGroup("group, \" 1"));
|
||||
|
||||
List<Group> groupsForTwo = new ArrayList<>();
|
||||
groupsForTwo.add(db.getGroup("group, \" 1"));
|
||||
groupsForTwo.add(db.getGroup("group, \" 2"));
|
||||
|
||||
List<Group> groupsForThree = new ArrayList<>();
|
||||
groupsForThree.add(db.getGroup("group, \" 1"));
|
||||
groupsForThree.add(db.getGroup("group, \" 2"));
|
||||
groupsForThree.add(db.getGroup("group, \" 3"));
|
||||
|
||||
List<Group> groupsForFour = new ArrayList<>();
|
||||
groupsForFour.add(db.getGroup("group, \" 1"));
|
||||
groupsForFour.add(db.getGroup("group, \" 2"));
|
||||
groupsForFour.add(db.getGroup("group, \" 3"));
|
||||
|
||||
List<Group> groupsForFive = new ArrayList<>();
|
||||
groupsForFive.add(db.getGroup("group, \" 1"));
|
||||
groupsForFive.add(db.getGroup("group, \" 3"));
|
||||
|
||||
db.setLoyaltyCardGroups(1, groupsForOne);
|
||||
db.setLoyaltyCardGroups(2, groupsForTwo);
|
||||
db.setLoyaltyCardGroups(3, groupsForThree);
|
||||
db.setLoyaltyCardGroups(4, groupsForFour);
|
||||
db.setLoyaltyCardGroups(5, groupsForFive);
|
||||
|
||||
ByteArrayOutputStream outData = new ByteArrayOutputStream();
|
||||
OutputStreamWriter outStream = new OutputStreamWriter(outData);
|
||||
|
||||
// Export data to CSV format
|
||||
boolean result = MultiFormatExporter.exportData(db, outStream, format);
|
||||
assertTrue(result);
|
||||
outStream.close();
|
||||
|
||||
clearDatabase();
|
||||
|
||||
ByteArrayInputStream inData = new ByteArrayInputStream(outData.toByteArray());
|
||||
InputStreamReader inStream = new InputStreamReader(inData);
|
||||
|
||||
// Import the CSV data
|
||||
result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
|
||||
assertTrue(result);
|
||||
|
||||
assertEquals(NUM_CARDS, db.getLoyaltyCardCount());
|
||||
assertEquals(NUM_GROUPS, db.getGroupCount());
|
||||
|
||||
checkLoyaltyCards();
|
||||
checkGroups();
|
||||
|
||||
assertEquals(groupsToGroupNames(groupsForOne), groupsToGroupNames(db.getLoyaltyCardGroups(1)));
|
||||
assertEquals(groupsToGroupNames(groupsForTwo), groupsToGroupNames(db.getLoyaltyCardGroups(2)));
|
||||
assertEquals(groupsToGroupNames(groupsForThree), groupsToGroupNames(db.getLoyaltyCardGroups(3)));
|
||||
assertEquals(groupsToGroupNames(groupsForFour), groupsToGroupNames(db.getLoyaltyCardGroups(4)));
|
||||
assertEquals(groupsToGroupNames(groupsForFive), groupsToGroupNames(db.getLoyaltyCardGroups(5)));
|
||||
assertEquals(emptyGroup, db.getLoyaltyCardGroups(6));
|
||||
assertEquals(emptyGroup, db.getLoyaltyCardGroups(7));
|
||||
assertEquals(emptyGroup, db.getLoyaltyCardGroups(8));
|
||||
assertEquals(emptyGroup, db.getLoyaltyCardGroups(9));
|
||||
assertEquals(emptyGroup, db.getLoyaltyCardGroups(10));
|
||||
|
||||
// Clear the database for the next format under test
|
||||
clearDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importExistingCardsNotReplace() throws IOException
|
||||
{
|
||||
@@ -347,7 +473,7 @@ public class ImportExportTest
|
||||
final int NUM_CARDS = 10;
|
||||
|
||||
final File sdcardDir = Environment.getExternalStorageDirectory();
|
||||
final File exportFile = new File(sdcardDir, "LoyaltyCardLocker.csv");
|
||||
final File exportFile = new File(sdcardDir, "Catima.csv");
|
||||
|
||||
for(DataFormat format : DataFormat.values())
|
||||
{
|
||||
@@ -395,7 +521,7 @@ public class ImportExportTest
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importWithoutColors() throws IOException
|
||||
public void importWithoutColorsV1() throws IOException
|
||||
{
|
||||
String csvText = "";
|
||||
csvText += DBHelper.LoyaltyCardDbIds.ID + "," +
|
||||
@@ -423,11 +549,10 @@ public class ImportExportTest
|
||||
assertEquals("type", card.barcodeType);
|
||||
assertEquals(0, card.starStatus);
|
||||
assertNull(card.headerColor);
|
||||
assertNull(card.headerTextColor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importWithoutNullColors() throws IOException
|
||||
public void importWithoutNullColorsV1() throws IOException
|
||||
{
|
||||
String csvText = "";
|
||||
csvText += DBHelper.LoyaltyCardDbIds.ID + "," +
|
||||
@@ -457,11 +582,10 @@ public class ImportExportTest
|
||||
assertEquals("type", card.barcodeType);
|
||||
assertEquals(0, card.starStatus);
|
||||
assertNull(card.headerColor);
|
||||
assertNull(card.headerTextColor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importWithoutInvalidColors() throws IOException
|
||||
public void importWithoutInvalidColorsV1() throws IOException
|
||||
{
|
||||
String csvText = "";
|
||||
csvText += DBHelper.LoyaltyCardDbIds.ID + "," +
|
||||
@@ -485,7 +609,7 @@ public class ImportExportTest
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importWithNoBarcodeType() throws IOException
|
||||
public void importWithNoBarcodeTypeV1() throws IOException
|
||||
{
|
||||
String csvText = "";
|
||||
csvText += DBHelper.LoyaltyCardDbIds.ID + "," +
|
||||
@@ -515,11 +639,10 @@ public class ImportExportTest
|
||||
assertEquals("", card.barcodeType);
|
||||
assertEquals(0, card.starStatus);
|
||||
assertEquals(1, (long) card.headerColor);
|
||||
assertEquals(1, (long) card.headerTextColor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importWithStarredField() throws IOException
|
||||
public void importWithStarredFieldV1() throws IOException
|
||||
{
|
||||
String csvText = "";
|
||||
csvText += DBHelper.LoyaltyCardDbIds.ID + "," +
|
||||
@@ -549,13 +672,12 @@ public class ImportExportTest
|
||||
assertEquals("type", card.barcodeType);
|
||||
assertEquals(1, card.starStatus);
|
||||
assertEquals(1, (long) card.headerColor);
|
||||
assertEquals(1, (long) card.headerTextColor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void importWithNoStarredField() throws IOException
|
||||
public void importWithNoStarredFieldV1() throws IOException
|
||||
{
|
||||
String csvText = "";
|
||||
csvText += DBHelper.LoyaltyCardDbIds.ID + "," +
|
||||
@@ -585,11 +707,10 @@ public class ImportExportTest
|
||||
assertEquals("type", card.barcodeType);
|
||||
assertEquals(0, card.starStatus);
|
||||
assertEquals(1, (long) card.headerColor);
|
||||
assertEquals(1, (long) card.headerTextColor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importWithInvalidStarField() throws IOException
|
||||
public void importWithInvalidStarFieldV1() throws IOException
|
||||
{
|
||||
String csvText = "";
|
||||
csvText += DBHelper.LoyaltyCardDbIds.ID + "," +
|
||||
@@ -639,6 +760,5 @@ public class ImportExportTest
|
||||
assertEquals("type", card.barcodeType);
|
||||
assertEquals(0, card.starStatus);
|
||||
assertEquals(1, (long) card.headerColor);
|
||||
assertEquals(1, (long) card.headerTextColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ImportURITest {
|
||||
public void ensureNoDataLoss() throws InvalidObjectException
|
||||
{
|
||||
// Generate card
|
||||
db.insertLoyaltyCard("store", "note", BarcodeFormat.UPC_A.toString(), LoyaltyCardDbIds.BARCODE_TYPE, Color.BLACK, Color.WHITE, 1);
|
||||
db.insertLoyaltyCard("store", "note", BarcodeFormat.UPC_A.toString(), LoyaltyCardDbIds.BARCODE_TYPE, Color.BLACK, 1);
|
||||
|
||||
// Get card
|
||||
LoyaltyCard card = db.getLoyaltyCard(1);
|
||||
@@ -50,7 +50,6 @@ public class ImportURITest {
|
||||
assertEquals(card.barcodeType, parsedCard.barcodeType);
|
||||
assertEquals(card.cardId, parsedCard.cardId);
|
||||
assertEquals(card.headerColor, parsedCard.headerColor);
|
||||
assertEquals(card.headerTextColor, parsedCard.headerTextColor);
|
||||
assertEquals(card.note, parsedCard.note);
|
||||
assertEquals(card.store, parsedCard.store);
|
||||
// No export of starStatus for single cards foreseen therefore 0 will be imported
|
||||
@@ -61,7 +60,7 @@ public class ImportURITest {
|
||||
public void ensureNoCrashOnMissingHeaderFields() throws InvalidObjectException
|
||||
{
|
||||
// Generate card
|
||||
db.insertLoyaltyCard("store", "note", BarcodeFormat.UPC_A.toString(), LoyaltyCardDbIds.BARCODE_TYPE, null, null, 0);
|
||||
db.insertLoyaltyCard("store", "note", BarcodeFormat.UPC_A.toString(), LoyaltyCardDbIds.BARCODE_TYPE, null, 0);
|
||||
|
||||
// Get card
|
||||
LoyaltyCard card = db.getLoyaltyCard(1);
|
||||
@@ -97,7 +96,7 @@ public class ImportURITest {
|
||||
{
|
||||
try {
|
||||
//"stare" instead of store
|
||||
importURIHelper.parse(Uri.parse("https://brarcher.github.io/loyalty-card-locker/share?stare=store¬e=note&cardid=12345&barcodetype=ITF&headercolor=-416706&headertextcolor=-1"));
|
||||
importURIHelper.parse(Uri.parse("https://brarcher.github.io/loyalty-card-locker/share?stare=store¬e=note&cardid=12345&barcodetype=ITF&headercolor=-416706"));
|
||||
assertTrue(false); // Shouldn't get here
|
||||
} catch(InvalidObjectException ex) {
|
||||
// Desired behaviour
|
||||
@@ -120,7 +119,6 @@ public class ImportURITest {
|
||||
assertEquals("note", parsedCard.note);
|
||||
assertEquals("store", parsedCard.store);
|
||||
assertEquals(Integer.valueOf(-416706), parsedCard.headerColor);
|
||||
assertEquals(Integer.valueOf(-1), parsedCard.headerTextColor);
|
||||
assertEquals(0, parsedCard.starStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public class LoyaltyCardCursorAdapterTest
|
||||
@Test
|
||||
public void TestCursorAdapterEmptyNote()
|
||||
{
|
||||
db.insertLoyaltyCard("store", "", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, 0);
|
||||
LoyaltyCard card = db.getLoyaltyCard(1);
|
||||
|
||||
Cursor cursor = db.getLoyaltyCardCursor();
|
||||
@@ -98,7 +98,7 @@ public class LoyaltyCardCursorAdapterTest
|
||||
@Test
|
||||
public void TestCursorAdapterWithNote()
|
||||
{
|
||||
db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, 0);
|
||||
LoyaltyCard card = db.getLoyaltyCard(1);
|
||||
|
||||
Cursor cursor = db.getLoyaltyCardCursor();
|
||||
@@ -112,7 +112,7 @@ public class LoyaltyCardCursorAdapterTest
|
||||
@Test
|
||||
public void TestCursorAdapterFontSizes()
|
||||
{
|
||||
db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, 0);
|
||||
LoyaltyCard card = db.getLoyaltyCard(1);
|
||||
|
||||
Cursor cursor = db.getLoyaltyCardCursor();
|
||||
@@ -130,9 +130,9 @@ public class LoyaltyCardCursorAdapterTest
|
||||
@Test
|
||||
public void TestCursorAdapterStarring()
|
||||
{
|
||||
db.insertLoyaltyCard("storeA", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("storeB", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 1);
|
||||
db.insertLoyaltyCard("storeC", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 1);
|
||||
db.insertLoyaltyCard("storeA", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, 0);
|
||||
db.insertLoyaltyCard("storeB", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, 1);
|
||||
db.insertLoyaltyCard("storeC", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, 1);
|
||||
|
||||
|
||||
Cursor cursor = db.getLoyaltyCardCursor();
|
||||
|
||||
@@ -5,9 +5,9 @@ import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
import static protect.card_locker.LoyaltyCardEditActivity.NO_BARCODE;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ActivityInfo;
|
||||
@@ -39,6 +39,7 @@ import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.android.controller.ActivityController;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowActivity;
|
||||
import org.robolectric.shadows.ShadowDialog;
|
||||
import org.robolectric.shadows.ShadowLog;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -111,7 +112,7 @@ public class LoyaltyCardViewActivityTest
|
||||
final EditText storeField = activity.findViewById(R.id.storeNameEdit);
|
||||
final EditText noteField = activity.findViewById(R.id.noteEdit);
|
||||
final TextView cardIdField = activity.findViewById(R.id.cardIdView);
|
||||
final TextView barcodeTypeField = activity.findViewById(R.id.barcodeTypeView);
|
||||
final TextView barcodeTypeField = activity.findViewById(R.id.barcodeTypeField);
|
||||
|
||||
storeField.setText(store);
|
||||
noteField.setText(note);
|
||||
@@ -130,7 +131,7 @@ public class LoyaltyCardViewActivityTest
|
||||
assertEquals(cardId, card.cardId);
|
||||
|
||||
// The special "No barcode" string shouldn't actually be written to the loyalty card
|
||||
if(barcodeType.equals(NO_BARCODE))
|
||||
if(barcodeType.equals(activity.getApplicationContext().getString(R.string.noBarcode)))
|
||||
{
|
||||
assertEquals("", card.barcodeType);
|
||||
}
|
||||
@@ -146,11 +147,15 @@ public class LoyaltyCardViewActivityTest
|
||||
* Initiate and complete a barcode capture, either in success
|
||||
* or in failure
|
||||
*/
|
||||
private void captureBarcodeWithResult(final Activity activity, final int buttonId, final boolean success) throws IOException
|
||||
private void captureBarcodeWithResult(final Activity activity, final boolean success) throws IOException
|
||||
{
|
||||
// Start image capture
|
||||
final Button captureButton = activity.findViewById(buttonId);
|
||||
captureButton.performClick();
|
||||
final Button startButton = activity.findViewById(R.id.enterButton);
|
||||
startButton.performClick();
|
||||
|
||||
Dialog dialog = ShadowDialog.getLatestDialog();
|
||||
ShadowDialog shadowDialog = shadowOf(dialog);
|
||||
shadowDialog.clickOn(R.id.add_from_camera);
|
||||
|
||||
ShadowActivity.IntentForResult intentForResult = shadowOf(activity).peekNextStartedActivityForResult();
|
||||
assertNotNull(intentForResult);
|
||||
@@ -182,11 +187,15 @@ public class LoyaltyCardViewActivityTest
|
||||
* Initiate and complete a barcode selection, either in success
|
||||
* or in failure
|
||||
*/
|
||||
private void selectBarcodeWithResult(final Activity activity, final int buttonId, final String barcodeData, final String barcodeType, final boolean success) throws IOException
|
||||
private void selectBarcodeWithResult(final Activity activity, final String barcodeData, final String barcodeType, final boolean success) throws IOException
|
||||
{
|
||||
// Start image capture
|
||||
final Button captureButton = activity.findViewById(buttonId);
|
||||
captureButton.performClick();
|
||||
// Start barcode selector
|
||||
final Button startButton = activity.findViewById(R.id.enterButton);
|
||||
startButton.performClick();
|
||||
|
||||
Dialog dialog = ShadowDialog.getLatestDialog();
|
||||
ShadowDialog shadowDialog = shadowOf(dialog);
|
||||
shadowDialog.clickOn(R.id.add_manually);
|
||||
|
||||
ShadowActivity.IntentForResult intentForResult = shadowOf(activity).peekNextStartedActivityForResult();
|
||||
assertNotNull(intentForResult);
|
||||
@@ -232,17 +241,12 @@ public class LoyaltyCardViewActivityTest
|
||||
}
|
||||
else
|
||||
{
|
||||
int captureVisibility = (mode == ViewMode.UPDATE_CARD || mode == ViewMode.ADD_CARD) ? View.VISIBLE : View.GONE;
|
||||
|
||||
int editVisibility = View.VISIBLE;
|
||||
|
||||
checkFieldProperties(activity, R.id.storeNameEdit, editVisibility, store);
|
||||
checkFieldProperties(activity, R.id.noteEdit, editVisibility, note);
|
||||
checkFieldProperties(activity, R.id.cardIdView, View.VISIBLE, cardId);
|
||||
checkFieldProperties(activity, R.id.cardIdDivider, cardId.isEmpty() ? View.GONE : View.VISIBLE, null);
|
||||
checkFieldProperties(activity, R.id.cardIdTableRow, cardId.isEmpty() ? View.GONE : View.VISIBLE, null);
|
||||
checkFieldProperties(activity, R.id.barcodeTypeView, View.VISIBLE, barcodeType);
|
||||
checkFieldProperties(activity, R.id.captureButton, captureVisibility, null);
|
||||
checkFieldProperties(activity, R.id.barcodeTypeField, View.VISIBLE, barcodeType);
|
||||
checkFieldProperties(activity, R.id.barcode, View.VISIBLE, null);
|
||||
}
|
||||
}
|
||||
@@ -258,7 +262,6 @@ public class LoyaltyCardViewActivityTest
|
||||
Activity activity = (Activity)activityController.get();
|
||||
|
||||
checkAllFields(activity, ViewMode.ADD_CARD, "", "", "", "");
|
||||
assertEquals(View.GONE, activity.findViewById(R.id.barcodeTypeTableRow).getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -320,7 +323,7 @@ public class LoyaltyCardViewActivityTest
|
||||
checkAllFields(activity, ViewMode.ADD_CARD, "", "", "", "");
|
||||
|
||||
// Complete barcode capture successfully
|
||||
captureBarcodeWithResult(activity, R.id.captureButton, true);
|
||||
captureBarcodeWithResult(activity, true);
|
||||
|
||||
checkAllFields(activity, ViewMode.ADD_CARD, "", "", BARCODE_DATA, BARCODE_TYPE);
|
||||
|
||||
@@ -341,7 +344,7 @@ public class LoyaltyCardViewActivityTest
|
||||
checkAllFields(activity, ViewMode.ADD_CARD, "", "", "", "");
|
||||
|
||||
// Complete barcode capture in failure
|
||||
captureBarcodeWithResult(activity, R.id.captureButton, false);
|
||||
captureBarcodeWithResult(activity, false);
|
||||
|
||||
checkAllFields(activity, ViewMode.ADD_CARD, "", "", "", "");
|
||||
}
|
||||
@@ -354,18 +357,28 @@ public class LoyaltyCardViewActivityTest
|
||||
activityController.visible();
|
||||
activityController.resume();
|
||||
|
||||
Activity activity = (Activity)activityController.get();
|
||||
LoyaltyCardEditActivity activity = (LoyaltyCardEditActivity) activityController.get();
|
||||
|
||||
checkAllFields(activity, ViewMode.ADD_CARD, "", "", "", "");
|
||||
|
||||
// Complete barcode capture successfully
|
||||
captureBarcodeWithResult(activity, R.id.captureButton, true);
|
||||
captureBarcodeWithResult(activity, true);
|
||||
|
||||
checkAllFields(activity, ViewMode.ADD_CARD, "", "", BARCODE_DATA, BARCODE_TYPE);
|
||||
|
||||
// Cancel the loyalty card creation
|
||||
assertEquals(false, activity.isFinishing());
|
||||
|
||||
// A change was made
|
||||
shadowOf(activity).clickMenuItem(android.R.id.home);
|
||||
assertEquals(true, activity.confirmExitDialog.isShowing());
|
||||
assertEquals(true, activity.hasChanged);
|
||||
assertEquals(false, activity.isFinishing());
|
||||
|
||||
// Exit after setting hasChanged to false
|
||||
activity.hasChanged = false;
|
||||
shadowOf(activity).clickMenuItem(android.R.id.home);
|
||||
assertEquals(false, activity.hasChanged);
|
||||
assertEquals(true, activity.isFinishing());
|
||||
}
|
||||
|
||||
@@ -400,7 +413,7 @@ public class LoyaltyCardViewActivityTest
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, 0);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
@@ -416,7 +429,7 @@ public class LoyaltyCardViewActivityTest
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, 0);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
@@ -432,7 +445,7 @@ public class LoyaltyCardViewActivityTest
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
|
||||
db.insertLoyaltyCard("store", "note", EAN_BARCODE_DATA, EAN_BARCODE_TYPE, Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "note", EAN_BARCODE_DATA, EAN_BARCODE_TYPE, Color.BLACK, 0);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
@@ -441,7 +454,7 @@ public class LoyaltyCardViewActivityTest
|
||||
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", EAN_BARCODE_DATA, EAN_BARCODE_TYPE);
|
||||
|
||||
// Complete barcode capture successfully
|
||||
captureBarcodeWithResult(activity, R.id.captureButton, true);
|
||||
captureBarcodeWithResult(activity, true);
|
||||
|
||||
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", BARCODE_DATA, BARCODE_TYPE);
|
||||
}
|
||||
@@ -450,10 +463,10 @@ public class LoyaltyCardViewActivityTest
|
||||
public void startWithLoyaltyCardWithReceiptUpdateReceiptCancel() throws IOException
|
||||
{
|
||||
ActivityController activityController = createActivityWithLoyaltyCard(true);
|
||||
Activity activity = (Activity)activityController.get();
|
||||
LoyaltyCardEditActivity activity = (LoyaltyCardEditActivity) activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
|
||||
db.insertLoyaltyCard("store", "note", EAN_BARCODE_DATA, EAN_BARCODE_TYPE, Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "note", EAN_BARCODE_DATA, EAN_BARCODE_TYPE, Color.BLACK, 0);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
@@ -462,13 +475,22 @@ public class LoyaltyCardViewActivityTest
|
||||
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", EAN_BARCODE_DATA, EAN_BARCODE_TYPE);
|
||||
|
||||
// Complete barcode capture successfully
|
||||
captureBarcodeWithResult(activity, R.id.captureButton, true);
|
||||
captureBarcodeWithResult(activity, true);
|
||||
|
||||
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", BARCODE_DATA, BARCODE_TYPE);
|
||||
|
||||
// Cancel the loyalty card creation
|
||||
assertEquals(false, activity.isFinishing());
|
||||
// A change was made
|
||||
shadowOf(activity).clickMenuItem(android.R.id.home);
|
||||
assertEquals(true, activity.confirmExitDialog.isShowing());
|
||||
assertEquals(true, activity.hasChanged);
|
||||
assertEquals(false, activity.isFinishing());
|
||||
|
||||
// Exit after setting hasChanged to false
|
||||
activity.hasChanged = false;
|
||||
shadowOf(activity).clickMenuItem(android.R.id.home);
|
||||
assertEquals(false, activity.hasChanged);
|
||||
assertEquals(true, activity.isFinishing());
|
||||
}
|
||||
|
||||
@@ -479,7 +501,7 @@ public class LoyaltyCardViewActivityTest
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, 0);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
@@ -523,7 +545,7 @@ public class LoyaltyCardViewActivityTest
|
||||
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, 0);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
@@ -541,7 +563,7 @@ public class LoyaltyCardViewActivityTest
|
||||
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, null, null, 0);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, null, 0);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
@@ -559,7 +581,7 @@ public class LoyaltyCardViewActivityTest
|
||||
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, null, null, 0);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, null, 0);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
@@ -576,14 +598,14 @@ public class LoyaltyCardViewActivityTest
|
||||
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, "", Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, "", Color.BLACK, 0);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
activityController.resume();
|
||||
|
||||
// Save and check the loyalty card
|
||||
saveLoyaltyCardWithArguments(activity, "store", "note", BARCODE_DATA, NO_BARCODE, false);
|
||||
saveLoyaltyCardWithArguments(activity, "store", "note", BARCODE_DATA, activity.getApplicationContext().getString(R.string.noBarcode), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -593,7 +615,7 @@ public class LoyaltyCardViewActivityTest
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, 0);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
@@ -603,14 +625,14 @@ public class LoyaltyCardViewActivityTest
|
||||
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", BARCODE_DATA, BARCODE_TYPE);
|
||||
|
||||
// Complete empty barcode selection successfully
|
||||
selectBarcodeWithResult(activity, R.id.enterButton, BARCODE_DATA, "", true);
|
||||
selectBarcodeWithResult(activity, BARCODE_DATA, "", true);
|
||||
|
||||
// Check if the barcode type is NO_BARCODE as expected
|
||||
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", BARCODE_DATA, NO_BARCODE);
|
||||
assertEquals(View.GONE, activity.findViewById(R.id.barcodeTypeTableRow).getVisibility());
|
||||
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", BARCODE_DATA, activity.getApplicationContext().getString(R.string.noBarcode));
|
||||
assertEquals(View.GONE, activity.findViewById(R.id.barcodeLayout).getVisibility());
|
||||
|
||||
// Check if the special NO_BARCODE string doesn't get saved
|
||||
saveLoyaltyCardWithArguments(activity, "store", "note", BARCODE_DATA, NO_BARCODE, false);
|
||||
saveLoyaltyCardWithArguments(activity, "store", "note", BARCODE_DATA, activity.getApplicationContext().getString(R.string.noBarcode), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -620,17 +642,15 @@ public class LoyaltyCardViewActivityTest
|
||||
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, 0);
|
||||
|
||||
final int STORE_FONT_SIZE = 50;
|
||||
final int CARD_FONT_SIZE = 40;
|
||||
final int NOTE_FONT_SIZE = 30;
|
||||
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
settings.edit()
|
||||
.putInt(activity.getResources().getString(R.string.settings_key_card_title_font_size), STORE_FONT_SIZE)
|
||||
.putInt(activity.getResources().getString(R.string.settings_key_card_id_font_size), CARD_FONT_SIZE)
|
||||
.putInt(activity.getResources().getString(R.string.settings_key_card_note_font_size), NOTE_FONT_SIZE)
|
||||
.apply();
|
||||
|
||||
activityController.start();
|
||||
@@ -641,13 +661,11 @@ public class LoyaltyCardViewActivityTest
|
||||
|
||||
TextView storeName = activity.findViewById(R.id.storeName);
|
||||
TextView cardIdFieldView = activity.findViewById(R.id.cardIdView);
|
||||
TextView noteView = activity.findViewById(R.id.noteView);
|
||||
|
||||
TextViewCompat.getAutoSizeMaxTextSize(storeName);
|
||||
TextViewCompat.getAutoSizeMaxTextSize(storeName);
|
||||
assertEquals(STORE_FONT_SIZE, (int)storeName.getTextSize());
|
||||
assertEquals(CARD_FONT_SIZE, TextViewCompat.getAutoSizeMaxTextSize(cardIdFieldView));
|
||||
assertEquals(NOTE_FONT_SIZE, TextViewCompat.getAutoSizeMaxTextSize(noteView));
|
||||
|
||||
shadowOf(activity).clickMenuItem(android.R.id.home);
|
||||
assertEquals(true, activity.isFinishing());
|
||||
@@ -662,7 +680,7 @@ public class LoyaltyCardViewActivityTest
|
||||
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, 0);
|
||||
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
settings.edit()
|
||||
@@ -697,7 +715,7 @@ public class LoyaltyCardViewActivityTest
|
||||
|
||||
Activity activity = (Activity) activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, Color.WHITE,0);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK,0);
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
activityController.resume();
|
||||
@@ -726,7 +744,7 @@ public class LoyaltyCardViewActivityTest
|
||||
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, 0);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
@@ -799,8 +817,7 @@ public class LoyaltyCardViewActivityTest
|
||||
Activity activity = (Activity)activityController.get();
|
||||
|
||||
checkAllFields(activity, ViewMode.ADD_CARD, "Example Store", "", "123456", "AZTEC");
|
||||
assertEquals(-416706, ((ColorDrawable) activity.findViewById(R.id.headingColorSample).getBackground()).getColor());
|
||||
assertEquals(-1, ((ColorDrawable) activity.findViewById(R.id.headingStoreTextColorSample).getBackground()).getColor());
|
||||
assertEquals(-416706, ((ColorDrawable) activity.findViewById(R.id.thumbnail).getBackground()).getColor());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -820,7 +837,6 @@ public class LoyaltyCardViewActivityTest
|
||||
Activity activity = (Activity)activityController.get();
|
||||
|
||||
checkAllFields(activity, ViewMode.ADD_CARD, "Example Store", "", "123456", "AZTEC");
|
||||
assertEquals(-416706, ((ColorDrawable) activity.findViewById(R.id.headingColorSample).getBackground()).getColor());
|
||||
assertEquals(-1, ((ColorDrawable) activity.findViewById(R.id.headingStoreTextColorSample).getBackground()).getColor());
|
||||
assertEquals(-416706, ((ColorDrawable) activity.findViewById(R.id.thumbnail).getBackground()).getColor());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,31 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.android.controller.ActivityController;
|
||||
import org.robolectric.shadows.ShadowAlertDialog;
|
||||
import org.robolectric.shadows.ShadowDialog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@@ -60,25 +63,26 @@ public class MainActivityTest
|
||||
final Menu menu = shadowOf(activity).getOptionsMenu();
|
||||
assertTrue(menu != null);
|
||||
|
||||
// The settings, search and add button should be present
|
||||
assertEquals(menu.size(), 4);
|
||||
// The settings, import/export, groups, search and add button should be present
|
||||
assertEquals(menu.size(), 5);
|
||||
assertEquals("Search", menu.findItem(R.id.action_search).getTitle().toString());
|
||||
assertEquals("Groups", menu.findItem(R.id.action_manage_groups).getTitle().toString());
|
||||
assertEquals("Import/Export", menu.findItem(R.id.action_import_export).getTitle().toString());
|
||||
assertEquals("About", menu.findItem(R.id.action_about).getTitle().toString());
|
||||
assertEquals("Settings", menu.findItem(R.id.action_settings).getTitle().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickAddLaunchesLoyaltyCardEditActivity()
|
||||
public void clickAddLaunchesAddDialog()
|
||||
{
|
||||
final MainActivity activity = Robolectric.setupActivity(MainActivity.class);
|
||||
|
||||
activity.findViewById(R.id.fabAdd).performClick();
|
||||
|
||||
Intent intent = shadowOf(activity).peekNextStartedActivityForResult().intent;
|
||||
Dialog dialog = ShadowDialog.getLatestDialog();
|
||||
ShadowDialog shadowDialog = shadowOf(dialog);
|
||||
|
||||
assertEquals(new ComponentName(activity, LoyaltyCardEditActivity.class), intent.getComponent());
|
||||
assertNull(intent.getExtras());
|
||||
assertEquals("Add Card", shadowDialog.getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -97,7 +101,7 @@ public class MainActivityTest
|
||||
assertEquals(0, list.getCount());
|
||||
|
||||
DBHelper db = new DBHelper(mainActivity);
|
||||
db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, 0);
|
||||
|
||||
assertEquals(View.VISIBLE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
@@ -131,10 +135,10 @@ public class MainActivityTest
|
||||
assertEquals(0, list.getCount());
|
||||
|
||||
DBHelper db = new DBHelper(mainActivity);
|
||||
db.insertLoyaltyCard("storeB", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("storeA", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("storeD", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 1);
|
||||
db.insertLoyaltyCard("storeC", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 1);
|
||||
db.insertLoyaltyCard("storeB", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, 0);
|
||||
db.insertLoyaltyCard("storeA", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, 0);
|
||||
db.insertLoyaltyCard("storeD", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, 1);
|
||||
db.insertLoyaltyCard("storeC", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, 1);
|
||||
|
||||
assertEquals(View.VISIBLE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
@@ -165,6 +169,54 @@ public class MainActivityTest
|
||||
assertEquals("storeB",cursor.getString(cursor.getColumnIndex("store")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGroups()
|
||||
{
|
||||
ActivityController activityController = Robolectric.buildActivity(MainActivity.class).create();
|
||||
|
||||
Activity mainActivity = (Activity)activityController.get();
|
||||
activityController.start();
|
||||
activityController.resume();
|
||||
|
||||
DBHelper db = new DBHelper(mainActivity);
|
||||
|
||||
TabLayout groupTabs = mainActivity.findViewById(R.id.groups);
|
||||
|
||||
// No group tabs by default
|
||||
assertEquals(0, groupTabs.getTabCount());
|
||||
|
||||
// Having at least one group should create two tabs: One all and one for each group
|
||||
db.insertGroup("One");
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
assertEquals(2, groupTabs.getTabCount());
|
||||
assertEquals("All", groupTabs.getTabAt(0).getText().toString());
|
||||
assertEquals("One", groupTabs.getTabAt(1).getText().toString());
|
||||
|
||||
// Adding another group should have it added to the end
|
||||
db.insertGroup("Alphabetical two");
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
assertEquals(3, groupTabs.getTabCount());
|
||||
assertEquals("All", groupTabs.getTabAt(0).getText().toString());
|
||||
assertEquals("One", groupTabs.getTabAt(1).getText().toString());
|
||||
assertEquals("Alphabetical two", groupTabs.getTabAt(2).getText().toString());
|
||||
|
||||
// Removing a group should also change the list
|
||||
db.deleteGroup("Alphabetical two");
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
assertEquals(2, groupTabs.getTabCount());
|
||||
assertEquals("All", groupTabs.getTabAt(0).getText().toString());
|
||||
assertEquals("One", groupTabs.getTabAt(1).getText().toString());
|
||||
|
||||
// Removing the last group should make the tabs disappear
|
||||
db.deleteGroup("One");
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
assertEquals(0, groupTabs.getTabCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFiltering()
|
||||
{
|
||||
@@ -177,10 +229,16 @@ public class MainActivityTest
|
||||
TextView helpText = mainActivity.findViewById(R.id.helpText);
|
||||
TextView noMatchingCardsText = mainActivity.findViewById(R.id.noMatchingCardsText);
|
||||
ListView list = mainActivity.findViewById(R.id.list);
|
||||
TabLayout groupTabs = mainActivity.findViewById(R.id.groups);
|
||||
|
||||
DBHelper db = new DBHelper(mainActivity);
|
||||
db.insertLoyaltyCard("The First Store", "Initial note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("The Second Store", "Secondary note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("The First Store", "Initial note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, 0);
|
||||
db.insertLoyaltyCard("The Second Store", "Secondary note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, 0);
|
||||
|
||||
db.insertGroup("Group one");
|
||||
List<Group> groups = new ArrayList<>();
|
||||
groups.add(db.getGroup("Group one"));
|
||||
db.setLoyaltyCardGroups(1, groups);
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
@@ -202,6 +260,27 @@ public class MainActivityTest
|
||||
|
||||
assertEquals(2, list.getCount());
|
||||
|
||||
// Switch to Group one
|
||||
groupTabs.selectTab(groupTabs.getTabAt(1));
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
// Switch back to all groups
|
||||
groupTabs.selectTab(groupTabs.getTabAt(0));
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(2, list.getCount());
|
||||
|
||||
mainActivity.filter = "first";
|
||||
|
||||
activityController.pause();
|
||||
@@ -213,6 +292,27 @@ public class MainActivityTest
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
// Switch to Group one
|
||||
groupTabs.selectTab(groupTabs.getTabAt(1));
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
// Switch back to all groups
|
||||
groupTabs.selectTab(groupTabs.getTabAt(0));
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
mainActivity.filter = "initial";
|
||||
|
||||
activityController.pause();
|
||||
@@ -224,6 +324,27 @@ public class MainActivityTest
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
// Switch to Group one
|
||||
groupTabs.selectTab(groupTabs.getTabAt(1));
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
// Switch back to all groups
|
||||
groupTabs.selectTab(groupTabs.getTabAt(0));
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
mainActivity.filter = "second";
|
||||
|
||||
activityController.pause();
|
||||
@@ -235,6 +356,27 @@ public class MainActivityTest
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
// Switch to Group one
|
||||
groupTabs.selectTab(groupTabs.getTabAt(1));
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.VISIBLE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(0, list.getCount());
|
||||
|
||||
// Switch back to all groups
|
||||
groupTabs.selectTab(groupTabs.getTabAt(0));
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
mainActivity.filter = "company";
|
||||
|
||||
activityController.pause();
|
||||
@@ -246,6 +388,27 @@ public class MainActivityTest
|
||||
|
||||
assertEquals(0, list.getCount());
|
||||
|
||||
// Switch to Group one
|
||||
groupTabs.selectTab(groupTabs.getTabAt(1));
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.VISIBLE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(0, list.getCount());
|
||||
|
||||
// Switch back to all groups
|
||||
groupTabs.selectTab(groupTabs.getTabAt(0));
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.VISIBLE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(0, list.getCount());
|
||||
|
||||
mainActivity.filter = "";
|
||||
|
||||
activityController.pause();
|
||||
@@ -256,5 +419,26 @@ public class MainActivityTest
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(2, list.getCount());
|
||||
|
||||
// Switch to Group one
|
||||
groupTabs.selectTab(groupTabs.getTabAt(1));
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
// Switch back to all groups
|
||||
groupTabs.selectTab(groupTabs.getTabAt(0));
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(2, list.getCount());
|
||||
}
|
||||
}
|
||||
BIN
banner.png
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 9.8 KiB |
@@ -1,10 +1,13 @@
|
||||
# Catima
|
||||

|
||||
[](https://hosted.weblate.org/engage/catima/)
|
||||
|
||||
<a href="https://f-droid.org/repository/browse/?fdid=me.hackerchick.catima" target="_blank">
|
||||
<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="90"/></a>
|
||||
<a href="https://play.google.com/store/apps/details?id=me.hackerchick.catima" target="_blank">
|
||||
<img src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" alt="Get it on Google Play" height="90"/></a>
|
||||
<a href="https://apt.izzysoft.de/fdroid/index/apk/me.hackerchick.catima" target="_blank">
|
||||
<img src="https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png" alt="Get it on IzzyOnDroid" height="90"/></a>
|
||||
|
||||

|
||||
|
||||
@@ -26,16 +29,14 @@ Stores all of your store loyalty cards on your phone, removing the need to carry
|
||||
|
||||
# Screenshots
|
||||
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-01.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-01.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-02.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-02.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-03.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-03.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-04.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-04.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-05.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-05.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-06.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-06.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-07.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-07.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-08.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-08.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-09.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-09.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-10.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/metadata/en-US/images/phoneScreenshots/screenshot-10.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-01.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-01.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-02.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-02.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-03.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-03.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-04.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-04.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-05.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-05.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-06.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-06.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-07.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-07.png)
|
||||
[<img src="https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-08.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-08.png)
|
||||
|
||||
# Migrating from other apps
|
||||
|
||||
@@ -58,7 +59,7 @@ Windows:
|
||||
|
||||
# Translating
|
||||
|
||||
We are going to set up a translation platform soon, please check back later.
|
||||
Please contribute through [our Weblate page](https://hosted.weblate.org/projects/catima/).
|
||||
|
||||
# Thanks
|
||||
|
||||
|
||||
@@ -21,15 +21,18 @@ As Catima is based on Loyalty Card Keychain, importing your data from it is very
|
||||

|
||||
|
||||
## 7. Open Catima
|
||||
TODO: Logo
|
||||

|
||||
|
||||
## 8. Press the Import/Export button in the top right
|
||||
## 8. Press the More Options button in the top right
|
||||

|
||||
|
||||
## 9. Press From Filesystem
|
||||
## 9. Press Import/Export
|
||||

|
||||
|
||||
## 10. Choose the file you saved in step 5
|
||||
## 10. Press From Filesystem
|
||||

|
||||
|
||||
## 11. Choose the file you saved in step 5
|
||||

|
||||
|
||||
## That's it, you've succesfully imported your Loyalty Card Keychain database into Catima
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 106 KiB |
BIN
docs/migrate/protect_card_locker/step_11.png
Normal file
|
After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 68 KiB |
BIN
docs/migrate/protect_card_locker/step_7.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 69 KiB |
2
fastlane/Appfile
Normal file
@@ -0,0 +1,2 @@
|
||||
json_key_file("~/.config/google_play_service_account.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
|
||||
package_name("me.hackerchick.catima") # e.g. com.krausefx.app
|
||||
38
fastlane/Fastfile
Normal file
@@ -0,0 +1,38 @@
|
||||
# This file contains the fastlane.tools configuration
|
||||
# You can find the documentation at https://docs.fastlane.tools
|
||||
#
|
||||
# For a list of all available actions, check out
|
||||
#
|
||||
# https://docs.fastlane.tools/actions
|
||||
#
|
||||
# For a list of all available plugins, check out
|
||||
#
|
||||
# https://docs.fastlane.tools/plugins/available-plugins
|
||||
#
|
||||
|
||||
# Uncomment the line if you want fastlane to automatically update itself
|
||||
# update_fastlane
|
||||
|
||||
default_platform(:android)
|
||||
|
||||
platform :android do
|
||||
desc "Runs all the tests"
|
||||
lane :test do
|
||||
gradle(task: "test")
|
||||
end
|
||||
|
||||
desc "Submit a new Beta Build to Crashlytics Beta"
|
||||
lane :beta do
|
||||
gradle(task: "clean assembleRelease")
|
||||
crashlytics
|
||||
|
||||
# sh "your_script.sh"
|
||||
# You can also use other beta testing services here
|
||||
end
|
||||
|
||||
desc "Deploy a new version to the Google Play"
|
||||
lane :deploy do
|
||||
gradle(task: "clean assembleRelease")
|
||||
upload_to_play_store
|
||||
end
|
||||
end
|
||||