Compare commits

...

224 Commits

Author SHA1 Message Date
29d1e38340 Fixes #223. Fixes internal reader issue on 4.2.2 2018-09-30 09:37:22 +02:00
2be872e61e Fixed version update. 2018-09-25 20:56:25 +02:00
377c5518f7 Minimal versions updates. 2018-09-25 20:47:38 +02:00
21be7357b5 Revert "Updated to androidx."
This reverts commit d47ba2c820.
2018-09-25 20:27:27 +02:00
d47ba2c820 Updated to androidx. 2018-09-25 20:08:51 +02:00
a64b14614a New Crowdin translations (#222)
* New translations strings.xml (Italian)

* New translations strings.xml (Italian)

* New translations strings.xml (Italian)
2018-09-24 08:06:00 +02:00
6a88192e77 Fixes #221 2018-09-21 21:39:37 +02:00
aa7c630818 erge branch 'master' of github.com:aminecmi/ReaderforSelfoss 2018-09-15 16:26:22 +02:00
7fb54f14c7 Fixed bug 2018-09-15 16:24:29 +02:00
3d709c02b7 New Crowdin translations (#219)
* New translations strings.xml (French)

* New translations strings.xml (French)

* New translations strings.xml (Spanish)

* New translations strings.xml (Galician)
2018-09-12 13:16:07 +02:00
339d384561 Changelog. 2018-09-10 20:29:22 +02:00
50338d51af New Crowdin translations (#218)
* New translations strings.xml (French)

* New translations strings.xml (French)
2018-09-10 15:17:16 +02:00
92dbabf899 New Crowdin translations (#217)
* New translations strings.xml (Catalan)

* New translations strings.xml (Japanese)

* New translations strings.xml (Vietnamese)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Korean)

* New translations strings.xml (Italian)

* New translations strings.xml (Afrikaans)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Arabic)

* New translations strings.xml (Galician)
2018-09-09 20:59:34 +02:00
0043021390 Merge branch 'master' of github.com:aminecmi/ReaderforSelfoss 2018-09-09 20:40:13 +02:00
70ba9b20da Items marked as read on open. Closes #208. 2018-09-09 20:39:27 +02:00
7fda0a04a1 Fixes #215. 2018-09-09 19:45:49 +02:00
3db3157dc9 Trying to fix a strange issue with the loading when hiding items.. 2018-09-09 19:44:01 +02:00
2089fe60ca New Crowdin translations (#214)
* New translations strings.xml (Galician)

* New translations strings.xml (French)

* New translations strings.xml (Spanish)
2018-08-06 15:49:50 +02:00
9606d36670 Hiding hidden tags from the "normal" tags section. 2018-08-03 09:49:49 +02:00
869cf64c54 New Crowdin translations (#213)
* New translations strings.xml (Catalan)

* New translations strings.xml (Japanese)

* New translations strings.xml (Vietnamese)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Korean)

* New translations strings.xml (Italian)

* New translations strings.xml (Afrikaans)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Arabic)

* New translations strings.xml (Galician)
2018-08-02 22:33:58 +02:00
f57ec1f6c0 Add hidden tags option (#212)
* Add filter for hidden tags. (#207)

This commit adds the option to configure hidden tags. Articles tagged
with these hidden tags won't appear in the list of articles by default.
To see these articles the user must explicitly filter by those tags.

* Closes #211. Handling hidden tags in the lateral panel.

* Changelog.
2018-08-02 22:04:15 +02:00
361eea9a06 New Crowdin translations (#209)
* New translations strings.xml (Galician)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese, Brazilian)
2018-08-01 20:34:39 +02:00
838b4056ac Add store logos, put badges on the same line (#210)
* Add store logos, put badges on the same line

* fix link

* Changed Jenkins url.
2018-08-01 20:32:21 +02:00
0c0a98510b New translations strings.xml (Galician) (#206) 2018-07-17 19:21:42 +02:00
be642ed06f New Crowdin translations (#205)
* New translations strings.xml (Galician)

* New translations strings.xml (Galician)

* New translations strings.xml (Galician)
2018-07-17 17:47:45 +02:00
fd77f38e95 New Crowdin translations (#204)
* New translations strings.xml (Spanish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Galician)

* New translations strings.xml (Galician)
2018-07-17 17:12:01 +02:00
c9baab7267 New Crowdin translations (#203)
* New translations strings.xml (Spanish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Spanish)
2018-07-17 11:01:54 +02:00
86985cfd5b Update README.md 2018-07-16 11:24:56 +02:00
1327a4e069 Merge branch 'master' of github.com:aminecmi/ReaderforSelfoss 2018-07-07 13:52:53 +02:00
c46acbc579 Dependencies update to solve fdroid issues. 2018-07-07 13:50:32 +02:00
4c6a403fae New Crowdin translations (#202)
* New translations strings.xml (Catalan)

* New translations strings.xml (Catalan)
2018-06-15 13:45:01 +02:00
78920022bd Update 2018-06-04 19:22:40 +02:00
7b16c41e82 Added the alpha steps. 2018-06-04 19:22:05 +02:00
3389f8bd09 New Crowdin translations (#200)
* New translations strings.xml (Catalan)

* New translations strings.xml (Catalan)

* New translations strings.xml (Catalan)

* New translations strings.xml (Catalan)
2018-06-03 17:20:36 +02:00
8dc25c527d Trying to fix issues with Glide, fragment, and destroyed activity. 2018-05-31 22:41:23 +02:00
46d6bd57c1 Changelog. 2018-05-31 12:46:45 +02:00
db014fe13d Fixed issue on pre lolipop devices. 2018-05-31 12:42:06 +02:00
6c293f4cac Changing the tag handling. 2018-05-26 10:51:11 +02:00
91e5d3736f Cleaning build script. 2018-05-25 22:47:36 +02:00
e11dee220f Adde dHTTP version check for fdroid. 2018-05-25 22:22:32 +02:00
fcebf916d2 New translations strings.xml (French) (#199) 2018-05-25 20:28:15 +02:00
73cc1a7297 Remove any email from the reports, as there seems to be no way to secure the data. 2018-05-25 20:20:47 +02:00
798f112498 Added the ability to force push and force tag creation. 2018-05-24 22:36:20 +02:00
38b5e7dc65 New (new, new, new, new) way for handling versions. Will work with jenkins and fdroid. 2018-05-24 22:32:34 +02:00
2799a48f2b Fixed build issue. 2018-05-24 21:43:27 +02:00
ad5edae6cd Fixed jenkins build issue. 2018-05-23 20:56:30 +02:00
9cb02f0272 Changelog. 2018-05-23 20:44:47 +02:00
6d24fd9336 Removed every config string added at build time. 2018-05-23 20:39:50 +02:00
a3a7b78c96 Removed direct call to mercury api. 2018-05-23 20:00:46 +02:00
e995286068 New Crowdin translations (#196)
* New translations strings.xml (Catalan)

* New translations strings.xml (Japanese)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Korean)

* New translations strings.xml (Italian)

* New translations strings.xml (Afrikaans)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Arabic)

* New translations strings.xml (Vietnamese)

* New translations strings.xml (French)

* New translations strings.xml (French)
2018-05-22 21:20:27 +02:00
65fb6d9b7e Fixes #59. 2018-05-22 21:14:10 +02:00
eb02d1efad Settings for silent debug. 2018-05-22 20:21:31 +02:00
f8d3e1eefb New Crowdin translations (#195)
* New translations strings.xml (Catalan)

* New translations strings.xml (Japanese)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Korean)

* New translations strings.xml (Italian)

* New translations strings.xml (Afrikaans)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Arabic)

* New translations strings.xml (Vietnamese)
2018-05-22 13:21:03 +02:00
218b8fa843 Replace with ACRA bug reporter. 2018-05-21 21:39:23 +02:00
9f94af6239 Removed firebase and crashlytics 2018-05-20 10:19:46 +02:00
d3584ac40e New Crowdin translations (#194)
* New translations strings.xml (Catalan)

* New translations strings.xml (Catalan)

* New translations strings.xml (Catalan)

* New translations strings.xml (Catalan)

* New translations strings.xml (Catalan)

* New translations strings.xml (Catalan)

* New translations strings.xml (Japanese)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Korean)

* New translations strings.xml (Italian)

* New translations strings.xml (Afrikaans)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Arabic)

* New translations strings.xml (Vietnamese)
2018-05-14 22:36:36 +02:00
90bdb289d0 Fixed build and version issue. 2018-05-14 22:36:12 +02:00
78a08750a2 CHANGELOG. 2018-05-14 22:07:50 +02:00
baba851e97 Strings cleaning and versions updates. 2018-05-14 22:02:57 +02:00
2a03783623 Trying to fix some swipe and reload items issues. 2018-05-10 12:57:57 +02:00
9f2a4438b1 Trying to debug and fix a swipe to hide issue. 2018-05-08 10:23:12 +02:00
5ee5287ffa changelog. 2018-05-07 11:28:24 +02:00
29547c2c94 Changed the email subject. 2018-05-07 11:27:16 +02:00
4846c870fa Fixed dark theme issue. 2018-05-07 10:16:02 +02:00
c17980a032 Versionning changes. 2018-04-15 21:32:34 +02:00
a929e419d9 Version names. 2018-04-15 15:46:42 +02:00
487d484bae More styling. 2018-04-15 11:33:37 +02:00
0ca4c04c61 Add to sources. 2018-04-11 22:25:51 +02:00
c857cf2d67 No theme handling for the login page. 2018-04-11 22:25:51 +02:00
acb502028b Article fragment color. 2018-04-11 22:25:51 +02:00
533636f3a1 Link colors in cards and list items. 2018-04-11 22:25:51 +02:00
eb5672901b AS update. 2018-04-11 22:25:51 +02:00
53a8716b51 New translations strings.xml (Spanish) (#190) 2018-04-09 11:06:40 +02:00
3aaff612af WIP. All activities dynamic themes. 2018-04-08 14:16:16 +02:00
fdcd8c6c6a Dynamic theme handling. Works only on the homeactivity for now. 2018-04-08 13:08:42 +02:00
bafd478604 Keeping the source even when fetching details from mercury. 2018-04-07 19:55:55 +02:00
987513a88b Version for alpha deploy. 2018-04-07 19:31:50 +02:00
a450ab2a3b Handling items with multiple tags. 2018-04-07 18:51:39 +02:00
db89fe5aad Updating lateral panel tags without network call. 2018-04-07 18:19:24 +02:00
67a30b92f6 Cleaning. 2018-04-07 17:19:41 +02:00
c397de8c3e New Crowdin translations (#189)
* New translations strings.xml (German)

* New translations strings.xml (Japanese)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Korean)

* New translations strings.xml (Italian)

* New translations strings.xml (Afrikaans)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Catalan)

* New translations strings.xml (Arabic)

* New translations strings.xml (Vietnamese)

* New translations strings.xml (French)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Spanish)

* New translations strings.xml (Chinese Simplified)
2018-04-07 10:56:13 +02:00
b4db532c45 Fixes #184. Needs translations. 2018-04-07 10:40:27 +02:00
ebecc9c80a Fixes #188. 2018-04-02 09:08:58 +02:00
4f8556fca8 Change version code generation. 2018-03-31 18:25:14 +02:00
68892fb41b Fixed play store update. 2018-03-31 08:22:57 +02:00
6d6f6c72ac Fixes #187. 2018-03-31 07:40:11 +02:00
df5556b945 Build. 2018-03-30 22:17:47 +02:00
d6c74049c3 Fixes #185. 2018-03-30 22:14:49 +02:00
18946464a2 Do nothing if ids are empty. More logging. 2018-03-30 19:54:42 +02:00
edb5eabee7 Fixing NPE. And obfuscation. 2018-03-29 19:59:07 +02:00
99a305f3e2 Cache url as parameter. 2018-03-28 21:11:25 +02:00
68dc5a6acf Debugging read all items. WILL ONLY WORK IF THE OPTION IS ENABLED IN SETTINGS. 2018-03-28 19:26:59 +02:00
6816461502 D8 enabling and gradle cache debug. 2018-03-28 19:13:47 +02:00
15b93bbd9e Updated AS. Enabled build cache. 2018-03-27 20:00:02 +02:00
cd61e140f6 New Crowdin translations (#182)
* New translations strings.xml (German)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Portuguese, Brazilian)
2018-03-26 16:08:18 +02:00
4d861a84e6 Fixing permissions added by firebase update
See https://www.reddit.com/r/androiddev/comments/86c02l/google_play_services_1200_released/dw4ehln/?context=0 for more details.
2018-03-26 12:00:57 +02:00
f24de68618 Code cleaning and versions updates. 2018-03-25 21:11:47 +02:00
3bcffff444 Fixing crashlytics issues. 2018-03-25 20:54:33 +02:00
75e9031fa5 Changelog. 2018-03-19 07:53:46 +01:00
3b77e24399 Removed english indonesian translation. 2018-03-19 07:48:08 +01:00
0a738e895f Version updates. 2018-03-03 16:18:29 +01:00
242e5ba035 New Crowdin translations (#181)
* New translations strings.xml (Spanish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Korean)

* New translations strings.xml (Japanese)

* New translations strings.xml (Italian)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Afrikaans)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (English, Indonesia)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Catalan)

* New translations strings.xml (Arabic)

* New translations strings.xml (Vietnamese)
2018-03-03 16:10:02 +01:00
c94612106c Changelog. 2018-03-03 16:03:07 +01:00
320924b4ed Fixes #180. 2018-03-03 16:00:56 +01:00
403ecc4521 Trying to understand #83. 2018-02-07 21:30:39 +01:00
6a50b37364 Added a padding to the recyclerview. 2018-02-07 21:22:08 +01:00
d9d341ac5d Versions updates. 2018-02-07 21:16:51 +01:00
e9805b731e New translations strings.xml (Portuguese, Brazilian) (#177) 2018-02-06 11:35:31 +01:00
c6d4337cd1 New Crowdin translations (#176)
* New translations strings.xml (English, Indonesia)

* New translations strings.xml (English, Indonesia)

* New translations strings.xml (English, Indonesia)

* New translations strings.xml (English, Indonesia)

* New translations strings.xml (English, Indonesia)
2018-02-01 17:55:54 +01:00
173f4b2ff7 Build. 2018-01-27 17:23:31 +01:00
3b9436264c Still fixing small fonts issues. 2018-01-27 17:17:43 +01:00
35fe87d79d New Crowdin translations (#175)
* New translations strings.xml (Afrikaans)

* New translations strings.xml (Italian)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Korean)

* New translations strings.xml (Japanese)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Arabic)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (English, Indonesia)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Catalan)

* New translations strings.xml (Vietnamese)

* New translations strings.xml (French)
2018-01-27 12:39:55 +01:00
f1bb7ba9ad Should fix #174. Added the ability to set the font size of the content of the article reader. 2018-01-27 12:29:14 +01:00
279f229166 Trying jekkyl. 2018-01-21 18:53:00 +01:00
be1794e27b Github page. 2018-01-21 18:23:47 +01:00
4d4a2039c8 Reformated code according to official kotling style. 2018-01-21 18:08:39 +01:00
3013ae4f35 Set theme jekyll-theme-cayman 2018-01-21 17:56:58 +01:00
bb3f7d3786 Page. 2018-01-21 17:54:24 +01:00
f7cc305e44 Changed suffix back to normal. 2018-01-16 22:13:00 +01:00
da17f89148 Building. 2018-01-12 06:26:39 +01:00
ec71ab3c6f Fix issue with list adapter. 2018-01-12 06:24:06 +01:00
0d007f1492 Added logging for StringIndexOutOfBound. 2018-01-12 05:19:49 +01:00
96f8663b8f Simpler (kind of) way to have multiple builds a day) 2018-01-12 05:15:28 +01:00
1a4bc1b301 Refactoring to use #158. 2018-01-12 04:58:43 +01:00
b51ae58a97 A lot of logs to clean after solving an issue. 2018-01-11 21:21:40 +01:00
b126fc32da Fixing the same issue as #158. 2018-01-11 21:10:53 +01:00
b8d234c415 Removed sonar. 2018-01-11 20:53:17 +01:00
2c8902d404 Working on #169.
List isn't reloaded each time.
When new articles arrive, the list is still updated, but the list stays at the same (old) position.
Not sure if I keep this behavior, or try to keep the old position and scroll to it.
2018-01-06 15:37:12 +01:00
80ad65b196 New Crowdin translations (#171)
* New translations strings.xml (French)

* New translations strings.xml (French)
2018-01-06 03:52:23 +01:00
744d9ba72b Contributing to translations. 2018-01-06 03:38:08 +01:00
0c1d708588 Merge pull request #170 from aancel/fix/values-fr-rFR
Update values-fr-rFR/strings.xml
2018-01-06 03:14:21 +01:00
95e79e7c5d Update values-fr-rFR/strings.xml
Fix typos
2018-01-06 01:49:07 +01:00
3ce3260d20 Fixes #165. 2018-01-05 10:51:19 +01:00
641f4f34d3 Fixes #168. 2018-01-04 20:45:25 +01:00
99620cb1c5 Update README.md 2018-01-04 13:32:21 +01:00
8f5f33f5d2 Crowdin fixing Android Studio indentation issue.
* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Italian)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Japanese)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Afrikaans)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (English, Indonesia)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Arabic)

* New translations strings.xml (Vietnamese)
2018-01-03 19:19:56 +01:00
78e9230b82 Fixes #161. 2018-01-03 19:07:27 +01:00
78aa44c007 Changed from gitter to slack. 2018-01-01 15:04:52 +01:00
53fd944f00 Update README.md 2018-01-01 15:00:04 +01:00
9e6cb4ee3d Fixes #164. Page indicator position. 2018-01-01 07:55:57 +01:00
87ad6f2826 (Again) fixed auto version number. 2018-01-01 07:27:10 +01:00
9050f5a56f Changelog. 2018-01-01 07:03:11 +01:00
3437004082 Multiple crash fixes. 2018-01-01 07:02:19 +01:00
dcf620af87 New translations strings.xml (Chinese Simplified) (#163) 2017-12-27 05:44:58 +01:00
128085a02e New Crowdin translations (#159)
* New translations strings.xml (Afrikaans)

* New translations strings.xml (Korean)

* New translations strings.xml (English, Indonesia)

* New translations strings.xml (Vietnamese)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Japanese)

* New translations strings.xml (Arabic)

* New translations strings.xml (Italian)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Catalan)

* New translations strings.xml (Indonesian)

* New translations strings.xml (French)
2017-12-20 06:39:27 +01:00
302040ec25 Fixed #160. 2017-12-20 06:33:10 +01:00
e177c22032 Fixes #157. 2017-12-17 21:30:42 +01:00
a11007113a Maybe fixing IllegalStateException. 2017-12-17 20:59:16 +01:00
5e7897bcf4 Fixes #152. 2017-12-17 20:40:14 +01:00
9559af3637 Closes #154. 2017-12-17 19:51:20 +01:00
4c499abcdb Issue 155 - fix StringIndexOutOfBoundException 2017-12-17 17:12:54 +01:00
0055a503b3 New Crowdin translations (#156)
* New translations strings.xml (Afrikaans)

* New translations strings.xml (Korean)

* New translations strings.xml (English, Indonesia)

* New translations strings.xml (Vietnamese)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Japanese)

* New translations strings.xml (Arabic)

* New translations strings.xml (Italian)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Catalan)

* New translations strings.xml (Indonesian)
2017-12-13 10:48:56 +01:00
3a189ee4b6 Fixed changelog version. 2017-12-10 20:01:24 +01:00
e25dc49271 Changelog. 2017-12-10 20:00:09 +01:00
4208a80db8 Fixes #151. 2017-12-10 19:42:20 +01:00
ddb75e0d93 Fixed a NPE. 2017-12-10 19:16:27 +01:00
8b37e992a2 Removed log. 2017-12-10 18:51:21 +01:00
bac59036cd Removed text as it wasn't displaying well. 2017-12-10 17:48:05 +01:00
6c89a3b77c Closes #149. 2017-12-10 17:45:34 +01:00
dc2ef39fc6 Versions update. 2017-12-10 17:42:43 +01:00
a4806da2c5 Update CHANGELOG.md 2017-12-09 09:55:10 +01:00
ee30edb214 Changelog. 2017-12-09 09:54:26 +01:00
e4ed663fb3 New Crowdin translations (#148)
* New translations strings.xml (Afrikaans)

* New translations strings.xml (Korean)

* New translations strings.xml (English, Indonesia)

* New translations strings.xml (Vietnamese)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Japanese)

* New translations strings.xml (Arabic)

* New translations strings.xml (Italian)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Catalan)

* New translations strings.xml (Indonesian)

* New translations strings.xml (French)

* New translations strings.xml (Portuguese)
2017-12-09 09:53:20 +01:00
01629309b0 Fixed #147. Waiting for translations. 2017-12-08 09:35:14 +01:00
059c2991fb This should fix #144. 2017-12-07 06:20:15 +01:00
686ec5dd90 Changelog 2017-12-06 20:25:35 +01:00
eab9df8ed9 Fixes #144. Added some logs as I'm not sure if it's a good solution. 2017-12-06 20:24:21 +01:00
0107c3d7e2 New Crowdin translations (#145)
* New translations strings.xml (Afrikaans)

* New translations strings.xml (Korean)

* New translations strings.xml (English, Indonesia)

* New translations strings.xml (Vietnamese)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Japanese)

* New translations strings.xml (Arabic)

* New translations strings.xml (Italian)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Catalan)

* New translations strings.xml (Indonesian)
2017-12-06 13:35:15 +01:00
2def2f2e2c This should fix it. 2017-12-05 22:57:03 +01:00
44c79892a0 Still trying to fix the auto version code messe. 2017-12-05 22:35:14 +01:00
bc96b314c2 Moved to version 1.5.6.X due to an automatic versioncode problem. 2017-12-05 22:13:12 +01:00
8dcf749b4e Changelog; 2017-12-05 22:00:19 +01:00
6a56ec6442 Swapped the title and subtitle in the article viewer. 2017-12-05 21:59:22 +01:00
30e46d7eae Remaining translations. 2017-12-05 21:52:01 +01:00
9458b1834b Added setting to enable/disable the mark on swipe. 2017-12-05 21:40:54 +01:00
297f797b97 Reading items on page adapter swipe. 2017-12-05 21:32:20 +01:00
c70e80758c Fixed an issue with the version code generation. 2017-12-05 20:34:00 +01:00
3bf1d7c4f9 Added toolbar to reader activity. 2017-12-05 20:33:32 +01:00
173247041a Added an animation to the viewpager. 2017-12-05 20:09:14 +01:00
3a28772096 Reader actovoty thele set right. Fixes #142. 2017-12-05 20:00:39 +01:00
bd08b8aba3 Build changes. 2017-12-04 20:07:30 +01:00
2ceb0f988b New Crowdin translations (#141)
* New translations strings.xml (Dutch)

* New translations strings.xml (Dutch)

* New translations strings.xml (Dutch)

* New translations strings.xml (Dutch)

* New translations strings.xml (Dutch)

* New translations strings.xml (Dutch)

* New translations strings.xml (Dutch)

* New translations strings.xml (Dutch)

* New translations strings.xml (Dutch)
2017-12-04 19:17:46 +01:00
4ef3b155b8 New translations strings.xml (Indonesian) (#139) 2017-12-04 13:27:48 +01:00
350e24cded Changelog. 2017-12-03 22:19:48 +01:00
1bf8a578bc Simple view pager. Closes #50. 2017-12-03 22:09:58 +01:00
4818a101cc Trying to solve #120. 2017-12-03 18:00:52 +01:00
baebf938ef Changelog. 2017-12-03 14:20:11 +01:00
fea57c7b1e New Crowdin translations (#136)
* New translations strings.xml (Indonesian)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Spanish)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Spanish)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Spanish)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Spanish)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Indonesian)
2017-12-03 14:18:15 +01:00
113dfa68be Changelog. 2017-11-30 19:40:03 +01:00
60c6514fa1 New translations strings.xml (Turkish) 2017-11-30 19:38:40 +01:00
114485afc3 Missing changelog. 2017-11-29 20:28:27 +01:00
d6a51381b9 New Crowdin translations (#133)
* New translations strings.xml (Afrikaans)

* New translations strings.xml (Korean)

* New translations strings.xml (English, Indonesia)

* New translations strings.xml (Vietnamese)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Japanese)

* New translations strings.xml (Arabic)

* New translations strings.xml (Italian)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Catalan)

* New translations strings.xml (Indonesian)
2017-11-29 19:10:47 +01:00
620f13fd7c Closes #132. 2017-11-29 19:09:16 +01:00
6577b2c3d7 Update Crowdin configuration file 2017-11-29 13:27:00 +01:00
caef522c8b Changelog. 2017-11-28 20:16:09 +01:00
40ea07de2e Last fix for the endless scroll. 2017-11-28 20:10:32 +01:00
7905e4aa12 Fixes #127. 2017-11-28 19:18:43 +01:00
64f4fd708a Merge pull request #126 from aminecmi/translate_master
New Crowdin translations
2017-11-28 19:17:01 +01:00
b46e4a018f New translations strings.xml (Chinese Simplified) 2017-11-28 06:21:12 +01:00
3e999a9be2 New translations strings.xml (Chinese Simplified) 2017-11-28 06:11:20 +01:00
f656d621e6 New translations strings.xml (Chinese Simplified) 2017-11-28 06:01:37 +01:00
951cc1e6bd New translations strings.xml (Chinese Simplified) 2017-11-27 10:42:33 +01:00
d8d4264f1b New translations strings.xml (Chinese Simplified) 2017-11-27 10:33:30 +01:00
014eeec2b9 New translations strings.xml (Chinese Simplified) 2017-11-27 08:10:29 +01:00
83837bddc3 New translations strings.xml (Chinese Simplified) 2017-11-27 07:51:23 +01:00
f97666db92 New translations strings.xml (Chinese Simplified) 2017-11-27 07:00:51 +01:00
ee08ea41a1 New translations strings.xml (Chinese Simplified) 2017-11-27 06:50:49 +01:00
4ca64610cb New translations strings.xml (Chinese Simplified) 2017-11-27 06:40:37 +01:00
4980145e46 New translations strings.xml (Chinese Simplified) 2017-11-27 05:50:32 +01:00
10cbc19a0c New translations strings.xml (Chinese Simplified) 2017-11-27 05:40:32 +01:00
15fba2b29b New translations strings.xml (Chinese Simplified) 2017-11-27 05:20:28 +01:00
096952f88c New translations strings.xml (Chinese Simplified) 2017-11-27 05:10:31 +01:00
0ea70c1922 New translations strings.xml (Chinese Simplified) 2017-11-27 05:00:30 +01:00
69ac2e2b44 Kotlin style guide. (#125) 2017-11-25 13:12:12 +01:00
68098f4d84 Fixes #124. 2017-11-24 19:49:03 +01:00
080d52893e Changelog. 2017-11-23 21:57:10 +01:00
b02334a8d4 New Crowdin translations (#123)
* New translations strings.xml (Afrikaans)

* New translations strings.xml (Japanese)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Korean)

* New translations strings.xml (Italian)

* New translations strings.xml (Arabic)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Catalan)

* New translations strings.xml (Vietnamese)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Portuguese, Brazilian)
2017-11-23 21:55:57 +01:00
27118add22 Closes #118. 2017-11-23 21:29:45 +01:00
2a6f98a1e8 Should fix #119. 2017-11-23 21:27:01 +01:00
1f67f2fdee Fixes #121. 2017-11-21 19:05:14 +01:00
ebf4d294a8 Fixing infinite scroll trying to load more items when there are no more. 2017-11-20 21:08:13 +01:00
4a4dbacc95 Changelog. 2017-11-18 15:19:57 +01:00
687839b5f8 Infinite scroll should be working as expected. Fixes #116. 2017-11-18 15:09:44 +01:00
8fb339034f Fixed #117. 2017-11-16 19:37:19 +01:00
152 changed files with 7814 additions and 5292 deletions

View File

@ -8,7 +8,7 @@ Please read the guidelines before contributing, and follow them (or try to) when
### What you can do to help.
There are many ways to contribute to this project, you could report bugs, request missing features, suggest enhancements and changes to existing ones. You also can improve the README with useful tips that could help the other users.
There are many ways to contribute to this project, you could [translate the app](https://crowdin.com/project/readerforselfoss), report bugs, request missing features, suggest enhancements and changes to existing ones. You also can improve the README with useful tips that could help the other users.
You can fork the repository, and [help me solve some issues](https://github.com/aminecmi/ReaderforSelfoss/issues?q=is%3Aissue+is%3Aopen+label%3A%22Up+For+Grabs%22) or [develop new things](https://github.com/aminecmi/ReaderforSelfoss/issues)
@ -28,6 +28,7 @@ Always check if the web version of your instance is working.
### Pull requests
* Don't create a PR for translations. See [here](https://github.com/aminecmi/ReaderforSelfoss/pull/170#issuecomment-355715654) for an explanation why.
* Please ask before starting to work on an issue. I may be working on it, or someone else could be doing so.
* Each pull request should implement **ONE** feature or bugfix. Keep in mind that you can submit as many PR as you want.
* Your code must be simple and clear enough to avoid using comments to explain what it does.
@ -46,15 +47,8 @@ You can directly import this project into IntellIJ/Android Studio.
You'll have to:
- Configure fabric and add your `apiKey` and `apiSecret` in the `fabric.properties` file.
- Create a firebase project and add the `google-services.json` to the `app/` folder.
- Define some parameters either in `~/.gradle/gradle.properties` or as gradle parameters (see the examples)
- mercuryApiKey: A [Mercury](https://mercury.postlight.com/web-parser/) web parser api key for the internal browser
- feedbackEmail: An email to receive users feedback.
- sourceUrl: an url to the source code, used in the settings. **It can be empty.**
- trackerUrl: an url to the tracker, used in the settings. **It can be empty.**
- githubToken: a github token used to report issues from within the app. [Details here](https://github.com/heinrichreimer/android-issue-reporter#how-to-create-a-bot-key). **It can be empty.**
- appLoginUrl, appLoginUsername and appLoginPassword: url, username and password of a selfoss instance. **These are only used for tests. They can be empty if you don't test API calls.**
### Examples:
@ -64,15 +58,10 @@ You'll have to:
appLoginUrl="URL" # It can be empty.
appLoginUsername="LOGIN" # It can be empty.
appLoginPassword="PASS" # It can be empty.
mercuryApiKey="LONGAPIKEY"
feedbackEmail="EMAIL"
sourceUrl="URLSOURCE" # It can be empty.
trackerUrl="URLTRACKER" # It can be empty.
githubToken="GITHUBTOKEN" # It can be empty or use https://github.com/heinrichreimer/android-issue-reporter#how-to-create-a-bot-key to generate one
```
#### As gradle parameters
```
./gradlew .... -P appLoginUrl="URL" -P appLoginUsername="LOGIN" -P appLoginPassword="PASS" -P mercuryApiKey="LONGAPIKEY" -P feedbackEmail="EMAIL" -P sourceUrl="URLSOURCE" -P trackerUrl="URLTRACKER" -P githubToken="GITHUBTOKEN"
./gradlew .... -P appLoginUrl="URL" -P appLoginUsername="LOGIN" -P appLoginPassword="PASS"
```

View File

@ -5,6 +5,7 @@
- [ ] I have updated the documentation accordingly.
- [ ] I have added tests to cover my changes.
- [ ] All new and existing tests passed.
- [ ] This is **NOT** translation related. (See [here](https://github.com/aminecmi/ReaderforSelfoss/pull/170#issuecomment-355715654))
This closes issue #XXX

4
.gitignore vendored
View File

@ -216,4 +216,6 @@ gradle-app.setting
release/
crowdin.properties
crowdin.properties
publish-version.sh

View File

@ -1,3 +1,119 @@
**1.6.x**
- Handling hidden tags.
- Fixed pre-lolipop issue with automatic theme changes.
- Removed all Build config things.
- Removed firebase and fabric.
- Added Acra for optional crash reporting and error logging.
- Dynamic themes !
- Strings cleaning.
- Versions updates.
- Fixes #215, #208.
**1.5.7.x**
- Added confirmation to the mark as read and update menues.
- Add to favorites from article viewer.
- Added an option to use a webview in the article viewer (see #149)
- Fixes (#151 #152 #155 #157 #160 #174) and more.
- New year fixes !!!
- Changed page indicator position as it was overlaping content.
- Now using slack instead of gitter.
- Moved completely to a webview to fix #161.
- Fixed typos in French ( Thanks @aancel )
- Updated the Contribution guide about translations.
- Better handling for articles update. (See #169)
- Ability to change the article viewer content font size (see #153)
- Versions updates * 2.
- Added padding to the recyclerview.
**1.5.5.x (didn't last long) AND 1.5.6.x**
- Toolbar in reader activity.
- Marking items as read on scroll (with settings to enable/disable).
- Swapped the title and subtitle in the article viewer.
- Added an animation to the viewpager.
- Completed Dutch, Indonesian and Portuguese translations !
- Fixed #142, #144, #147.
- Changed versions handling.
- Removed indonesian english as it was causing issues with the english version of the app.
**1.5.4.22**
- You can now scroll through the loaded articles !
**1.5.4.21**
- Spanish translation and some Indonesian !
**1.5.4.20**
- Turkish translation !
**1.5.4.19**
- Fixed an issue with crowdin configuration (and its translations)
**1.5.4.18**
- Typo fix.
- The real last infinite scroll bug fix.
- Simplified Chinese translation !
**1.5.4.17**
- Fixed the last bug with infinite scroll.
**1.5.4.16**
- Fixing list view displaying issues.
- Endless scroll is not in beta anymore.
**1.5.4.15**
- Fixed an issue with the sources list.
**1.5.4.14**
- Fixing infinite scroll trying to load more items when there are no more.
**1.5.4.13**
- Displaying the right number of items.
- Fixing infinite scroll remaining issues. Should be stable enough.
**1.5.4.12**
- Fixed fab and toolbar issue (#113)

View File

@ -1,17 +1,20 @@
# ReaderForSelfoss
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/readerforselfoss/localized.svg)](https://crowdin.com/project/readerforselfoss) [![Gitter chat](https://badges.gitter.im/amine-bou/ReaderForSelfoss.png)](https://gitter.im/amine-bou/ReaderForSelfoss)
[![Build Status](http://jenkins.amine-bou.fr/job/ReaderForSelfoss/badge/icon)](http://jenkins.amine-bou.fr/job/ReaderForSelfoss/)
[![Code Triagers Badge](https://www.codetriage.com/aminecmi/readerforselfoss/badges/users.svg)](https://www.codetriage.com/aminecmi/readerforselfoss)
This is the repo of [Reader For Selfoss](https://play.google.com/store/apps/details?id=apps.amine.bou.readerforselfoss&hl=en).
[![Slack Channel](https://img.shields.io/badge/chat-slack-green.svg)](https://join.slack.com/t/readerforselfoss/shared_invite/enQtMjkyNzc3NjM2Mjc1LTUzZTZhOGM5YjQ1MTI5MWZiODRjMjE1ZDBmMzQxZmQ3NWZhYTNhMTBjNGEwNmE2ZGFjODU5NjUxZjBkMWJmMDQ) [![Build Status](https://jenkins.amine-bou.fr/job/ReaderForSelfoss/badge/icon)](https://jenkins.amine-bou.fr/job/ReaderForSelfoss/) [![Code Triagers Badge](https://www.codetriage.com/aminecmi/readerforselfoss/badges/users.svg)](https://www.codetriage.com/aminecmi/readerforselfoss) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/readerforselfoss/localized.svg)](https://crowdin.com/project/readerforselfoss)
It's an RSS Reader for Android, that **only** works with [Selfoss](https://selfoss.aditu.de/)
The last APK built from source is available [here](https://jenkins.amine-bou.fr/job/ReaderForSelfoss/lastSuccessfulBuild/artifact/SignApksBuilder-out/selfoss-key/selfoss/app-githubConfig-release-unsigned.apk/app-githubConfig-release.apk).
<a href='https://play.google.com/store/apps/details?id=apps.amine.bou.readerforselfoss'><img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png' height="100"/></a> <a href="https://f-droid.org/packages/apps.amine.bou.readerforselfoss"><img src="https://f-droid.org/badge/get-it-on.png" alt="Get it on F-Droid" height="100"></a>
Also, the last APK built from source is available [here](https://jenkins.amine-bou.fr/job/ReaderForSelfoss/lastSuccessfulBuild/artifact/SignApksBuilder-out/selfoss-key/selfoss/app-githubConfig-release-unsigned.apk/app-githubConfig-release.apk).
## Join the alpha channel
**Keep in mind, it could be instable, but you'll have the new updates faster**
- First, join the google [group](https://groups.google.com/d/forum/reader-for-selfoss-alpha-testing).
- Then, join the [alpha channel](https://play.google.com/apps/testing/apps.amine.bou.readerforselfoss) of the app.
- You'll be able to update the app for the current alpha version.
## Want to help ?
@ -23,4 +26,4 @@ Check the [Contribution guide](https://github.com/aminecmi/ReaderforSelfoss/blob
- [See what I'm doing](https://github.com/aminecmi/ReaderforSelfoss/projects/1)
- [Create an issue, or request a new feature](https://github.com/aminecmi/ReaderforSelfoss/issues)
- [Help translation the app](https://crowdin.com/project/readerforselfoss)
- [Ask for help](https://gitter.im/amine-bou/ReaderForSelfoss)
- [Ask for help](https://join.slack.com/t/readerforselfoss/shared_invite/enQtMjkyNzc3NjM2Mjc1LTUzZTZhOGM5YjQ1MTI5MWZiODRjMjE1ZDBmMzQxZmQ3NWZhYTNhMTBjNGEwNmE2ZGFjODU5NjUxZjBkMWJmMDQ)

View File

@ -1,51 +1,46 @@
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
}
dependencies {
classpath 'io.fabric.tools:gradle:1.+'
}
ext {
configuration = [
buildDate: new Date()
]
// This will make me able to build multiple times a day. May break thinks. I may forget it.
todaysBuilds = "1"
}
def gitVersion() {
def process = "git describe --abbrev=0 --tags".execute()
return process.text.substring(1).replaceAll("\\.", "")
return process.text.substring(1).replaceAll("\\.", "").trim()
}
def versionCodeFromGit() {
println "version code " + gitVersion().toInteger()
println "version code " + gitVersion()
return gitVersion().toInteger()
}
def versionNameFromGit() {
println "version code " + gitVersion().trim()
return gitVersion().trim()
println "version name " + gitVersion()
return gitVersion()
}
apply plugin: 'org.sonarqube'
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
repositories {
maven {
url 'https://maven.fabric.io/public'
}
}
android {
compileSdkVersion 27
buildToolsVersion '27.0.0'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
compileSdkVersion 28
buildToolsVersion '28.0.2'
defaultConfig {
applicationId "apps.amine.bou.readerforselfoss"
minSdkVersion 16
targetSdkVersion 27
targetSdkVersion 28
versionCode versionCodeFromGit()
versionName versionNameFromGit()
@ -59,13 +54,6 @@ android {
// tests
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
buildConfigField "String", "MERCURY_KEY", mercuryApiKey
buildConfigField "String", "FEEDBACK_EMAIL", feedbackEmail
buildConfigField "String", "SOURCE_URL", sourceUrl
buildConfigField "String", "TRACKER_URL", trackerUrl
buildConfigField "String", "TRANSLATION_URL", translationUrl
buildConfigField "String", "GITHUB_TOKEN", githubToken
}
buildTypes {
release {
@ -78,6 +66,7 @@ android {
buildConfigField "String", "LOGIN_URL", appLoginUrl
buildConfigField "String", "LOGIN_USERNAME", appLoginUsername
buildConfigField "String", "LOGIN_PASSWORD", appLoginPassword
applicationIdSuffix ".dev"
}
}
flavorDimensions "build"
@ -85,111 +74,86 @@ android {
githubConfig {
versionNameSuffix '-github'
dimension "build"
buildConfigField "boolean", "GITHUB_VERSION", "true"
}
storeConfig {
// As jenkins publishes to alpha first, this is the default suffix now.
versionNameSuffix '-store'
dimension "build"
buildConfigField "boolean", "GITHUB_VERSION", "false"
}
}
}
dependencies {
// Testing
androidTestCompile 'com.android.support.test.espresso:espresso-core:3.0.1'
androidTestCompile 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
// Espresso-contrib for DatePicker, RecyclerView, Drawer actions, Accessibility checks, CountingIdlingResource
androidTestCompile 'com.android.support.test.espresso:espresso-contrib:3.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:3.0.1'
// Espresso-intents for validation and stubbing of Intents
androidTestCompile 'com.android.support.test.espresso:espresso-intents:3.0.1'
compile fileTree(dir: 'libs', include: ['*.jar'])
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
androidTestImplementation 'com.android.support.test.espresso:espresso-intents:3.0.1'
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// Android Support
compile 'com.android.support:appcompat-v7:27.0.0'
compile 'com.android.support:design:27.0.0'
compile 'com.android.support:recyclerview-v7:27.0.0'
compile 'com.android.support:support-v4:27.0.0'
compile 'com.android.support:support-vector-drawable:27.0.0'
compile 'com.android.support:customtabs:27.0.0'
compile 'com.android.support:cardview-v7:27.0.0'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
// Firebase + crashlytics
compile 'com.google.firebase:firebase-core:11.4.2'
compile 'com.google.firebase:firebase-config:11.4.2'
compile 'com.google.firebase:firebase-invites:11.4.2'
compile('com.crashlytics.sdk.android:crashlytics:2.7.1@aar') {
transitive = true;
}
implementation "com.android.support:appcompat-v7:$android_version"
implementation "com.android.support:design:$android_version"
implementation "com.android.support:recyclerview-v7:$android_version"
implementation "com.android.support:support-v4:$android_version"
implementation "com.android.support:support-vector-drawable:$android_version"
implementation "com.android.support:customtabs:$android_version"
implementation "com.android.support:cardview-v7:$android_version"
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
//multidex
compile 'com.android.support:multidex:1.0.2'
implementation 'com.android.support:multidex:1.0.3'
// Intro
compile 'agency.tango.android:material-intro-screen:0.0.5'
implementation 'agency.tango.android:material-intro-screen:0.0.5'
// About
compile('com.mikepenz:aboutlibraries:6.0.0@aar') {
implementation('com.mikepenz:aboutlibraries:6.0.0@aar') {
transitive = true
}
// Retrofit + http logging + okhttp
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.9.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.burgstaller:okhttp-digest:1.12'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.burgstaller:okhttp-digest:1.12'
// Material-ish things
compile 'com.ashokvarma.android:bottom-navigation-bar:2.0.3'
compile 'com.github.jd-alexander:LikeButton:0.2.1'
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
compile 'org.sufficientlysecure:html-textview:3.5'
implementation 'com.ashokvarma.android:bottom-navigation-bar:2.0.3'
implementation 'com.github.jd-alexander:LikeButton:0.2.1'
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
// glide
compile 'com.github.bumptech.glide:glide:4.1.1'
compile 'com.github.bumptech.glide:okhttp3-integration:4.1.1'
implementation 'com.github.bumptech.glide:glide:4.1.1'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.1.1'
// Asking politely users to rate the app
compile 'com.github.stkent:amplify:2.1.0'
// For the article reader
compile 'com.klinkerapps:drag-dismiss-activity:1.5.0'
implementation 'com.github.stkent:amplify:2.1.0'
// Drawer
implementation 'co.zsmb:materialdrawer-kt:1.2.1'
compile 'com.anupcowkur:reservoir:3.1.0'
implementation 'co.zsmb:materialdrawer-kt:1.3.7'
implementation 'com.anupcowkur:reservoir:3.1.0'
// Themes
compile 'com.52inc:scoops:1.0.0'
implementation 'com.52inc:scoops:1.0.0'
implementation 'com.jrummyapps:colorpicker:2.1.7'
implementation 'com.github.rubensousa:floatingtoolbar:1.5.1'
// Github issues reporter
compile 'com.heinrichreimersoftware:android-issue-reporter:1.3.1'
// Pager
implementation 'me.relex:circleindicator:1.2.2@aar'
compile 'com.github.rubensousa:floatingtoolbar:1.5.1'
implementation 'androidx.core:core-ktx:0.3'
// Crash
implementation 'ch.acra:acra-http:5.1.3'
implementation 'ch.acra:acra-dialog:5.1.3'
}
apply plugin: 'com.google.gms.google-services'
afterEvaluate {
initFabricPropertiesIfNeeded()
initAppLoginPropertiesIfNeeded()
initAppForSecretPropertiesIfNeeded()
}
def initFabricPropertiesIfNeeded() {
def propertiesFile = file('fabric.properties')
if (!propertiesFile.exists()) {
def commentMessage = "This is autogenerated fabric property from system environment to prevent key to be committed to source control."
ant.propertyfile(file: "fabric.properties", comment: commentMessage) {
entry(key: "apiSecret", value: crashlyticsdemoApisecret)
entry(key: "apiKey", value: crashlyticsdemoApikey)
}
}
}
def initAppLoginPropertiesIfNeeded() {
@ -202,19 +166,4 @@ def initAppLoginPropertiesIfNeeded() {
entry(key: "appLoginPassword", value: System.getProperty("appLoginPassword"))
}
}
}
def initAppForSecretPropertiesIfNeeded() {
def propertiesFile = file(System.getProperty("user.home") + '/.gradle/gradle.properties')
if (!propertiesFile.exists()) {
def commentMessage = "This is autogenerated local property from system environment to prevent key to be committed to source control."
ant.propertyfile(file: System.getProperty("user.home") + "/.gradle/gradle.properties", comment: commentMessage) {
entry(key: "mercuryApiKey", value: System.getProperty("mercuryApiKey"))
entry(key: "feedbackEmail", value: System.getProperty("feedbackEmail"))
entry(key: "sourceUrl", value: System.getProperty("sourceUrl"))
entry(key: "trackerUrl", value: System.getProperty("trackerUrl"))
entry(key: "translationUrl", value: System.getProperty("translationUrl"))
entry(key: "githubToken", value: System.getProperty("githubToken"))
}
}
}
}

View File

@ -48,7 +48,11 @@
#}
-dontwarn okio.**
-dontwarn retrofit2.Platform$Java8
-keepattributes Signature
-keep class retrofit.** { *; }
-keepclasseswithmembers class * {
@retrofit.http.* <methods>;
}
-keepattributes *Annotation*,Signature
-keepattributes Exceptions
-dontwarn okio.**
-dontwarn javax.annotation.Nullable
@ -69,4 +73,6 @@
-dontwarn com.anupcowkur.reservoir.**
-dontwarn javax.annotation.**
-dontwarn javax.annotation.**
-keep class android.support.v7.widget.SearchView { *; }

View File

@ -1,4 +1,3 @@
package apps.amine.bou.readerforselfoss
// TODO: test source adding

View File

@ -5,29 +5,32 @@ import android.content.Intent
import android.support.test.InstrumentationRegistry
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
import android.support.test.espresso.action.ViewActions.*
import android.support.test.espresso.action.ViewActions.click
import android.support.test.espresso.action.ViewActions.closeSoftKeyboard
import android.support.test.espresso.action.ViewActions.pressBack
import android.support.test.espresso.action.ViewActions.pressKey
import android.support.test.espresso.action.ViewActions.typeText
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.contrib.DrawerActions
import android.support.test.espresso.intent.Intents
import android.support.test.espresso.intent.Intents.intended
import android.support.test.espresso.intent.Intents.times
import android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent
import android.support.test.espresso.matcher.ViewMatchers.*
import android.support.test.espresso.matcher.ViewMatchers.isDisplayed
import android.support.test.espresso.matcher.ViewMatchers.isRoot
import android.support.test.espresso.matcher.ViewMatchers.withContentDescription
import android.support.test.espresso.matcher.ViewMatchers.withId
import android.support.test.espresso.matcher.ViewMatchers.withText
import android.support.test.rule.ActivityTestRule
import android.support.test.runner.AndroidJUnit4
import android.view.KeyEvent
import com.mikepenz.aboutlibraries.ui.LibsActivity
import apps.amine.bou.readerforselfoss.utils.Config
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import apps.amine.bou.readerforselfoss.utils.Config
import com.heinrichreimersoftware.androidissuereporter.IssueReporterLauncher
import org.junit.After
@RunWith(AndroidJUnit4::class)
class HomeActivityEspressoTest {
lateinit var context: Context
@ -40,9 +43,9 @@ class HomeActivityEspressoTest {
context = InstrumentationRegistry.getInstrumentation().targetContext
val editor =
context
.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
.edit()
context
.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
.edit()
editor.clear()
editor.putString("url", BuildConfig.LOGIN_URL)
@ -60,49 +63,32 @@ class HomeActivityEspressoTest {
rule.launchActivity(Intent())
onView(
withMenu(
id = R.id.action_search,
titleId = R.string.menu_home_search
)
withMenu(
id = R.id.action_search,
titleId = R.string.menu_home_search
)
).perform(click())
onView(withId(R.id.search_bar)).check(matches(isDisplayed()))
onView(withId(R.id.search_src_text)).perform(typeText("android"), pressKey(KeyEvent.KEYCODE_SEARCH), closeSoftKeyboard())
onView(withId(R.id.search_src_text)).perform(
typeText("android"),
pressKey(KeyEvent.KEYCODE_SEARCH),
closeSoftKeyboard()
)
onView(withContentDescription(R.string.abc_toolbar_collapse_description)).perform(click())
openActionBarOverflowOrOptionsMenu(context)
onView(withMenu(id = R.id.refresh, titleId = R.string.menu_home_refresh))
.perform(click())
.perform(click())
openActionBarOverflowOrOptionsMenu(context)
onView(withText(R.string.action_disconnect)).perform(click())
intended(hasComponent(LoginActivity::class.java.name), times(1))
}
@Test
fun drawerTesting() {
rule.launchActivity(Intent())
onView(withId(R.id.material_drawer_layout)).perform(DrawerActions.open())
onView(withText(R.string.drawer_report_bug)).perform(click())
intended(hasComponent(IssueReporterLauncher.Activity::class.java.name))
onView(isRoot()).perform(pressBack())
onView(isRoot()).perform(pressBack())
intended(hasComponent(HomeActivity::class.java.name))
onView(withId(R.id.material_drawer_layout)).perform(DrawerActions.open())
onView(withId(R.id.material_drawer_layout)).perform(DrawerActions.open())
onView(withText(R.string.drawer_action_clear)).perform(click())
}
// TODO: test articles opening and actions for cards and lists

View File

@ -1,7 +1,5 @@
package apps.amine.bou.readerforselfoss
import java.util.*
import android.content.Context
import android.content.Intent
import android.support.test.InstrumentationRegistry.getInstrumentation
@ -11,22 +9,19 @@ import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.intent.Intents
import android.support.test.espresso.intent.Intents.intended
import android.support.test.espresso.intent.Intents.times
import android.support.test.espresso.intent.matcher.IntentMatchers.*
import android.support.test.espresso.intent.matcher.UriMatchers.hasHost
import android.support.test.espresso.matcher.ViewMatchers.*
import android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent
import android.support.test.espresso.matcher.ViewMatchers.isDisplayed
import android.support.test.espresso.matcher.ViewMatchers.withId
import android.support.test.espresso.matcher.ViewMatchers.withText
import android.support.test.rule.ActivityTestRule
import android.support.test.runner.AndroidJUnit4
import org.hamcrest.Matchers.allOf
import org.hamcrest.Matchers.equalTo
import apps.amine.bou.readerforselfoss.utils.Config
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import apps.amine.bou.readerforselfoss.utils.Config
import org.junit.After
import java.util.*
@RunWith(AndroidJUnit4::class)
class IntroActivityEspressoTest {
@ -37,9 +32,9 @@ class IntroActivityEspressoTest {
@Before
fun clearData() {
val editor =
getInstrumentation().targetContext
.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
.edit()
getInstrumentation().targetContext
.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
.edit()
editor.clear()
editor.commit()
@ -60,7 +55,6 @@ class IntroActivityEspressoTest {
intended(hasComponent(IntroActivity::class.java.name), times(1))
intended(hasComponent(LoginActivity::class.java.name), times(1))
}
@Test
@ -75,7 +69,7 @@ class IntroActivityEspressoTest {
onView(withText(R.string.intro_hello_title)).check(matches(isDisplayed()))
onView(withId(R.id.button_next)).perform(click())
repeat(random) {_ ->
repeat(random) { _ ->
onView(withText(R.string.intro_needs_selfoss_message)).check(matches(isDisplayed()))
onView(withId(R.id.button_next)).perform(click())
onView(withText(R.string.intro_all_set_message)).check(matches(isDisplayed()))
@ -88,7 +82,6 @@ class IntroActivityEspressoTest {
intended(hasComponent(IntroActivity::class.java.name), times(1))
intended(hasComponent(LoginActivity::class.java.name), times(1))
}
@After

View File

@ -5,27 +5,30 @@ import android.content.Intent
import android.support.test.InstrumentationRegistry
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
import android.support.test.espresso.action.ViewActions.*
import android.support.test.espresso.action.ViewActions.click
import android.support.test.espresso.action.ViewActions.closeSoftKeyboard
import android.support.test.espresso.action.ViewActions.pressBack
import android.support.test.espresso.action.ViewActions.typeText
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.intent.Intents
import android.support.test.espresso.intent.Intents.intended
import android.support.test.espresso.intent.Intents.times
import android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent
import android.support.test.espresso.matcher.ViewMatchers
import android.support.test.espresso.matcher.ViewMatchers.*
import android.support.test.espresso.matcher.ViewMatchers.isRoot
import android.support.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import android.support.test.espresso.matcher.ViewMatchers.withId
import android.support.test.espresso.matcher.ViewMatchers.withText
import android.support.test.rule.ActivityTestRule
import android.support.test.runner.AndroidJUnit4
import apps.amine.bou.readerforselfoss.utils.Config
import com.mikepenz.aboutlibraries.ui.LibsActivity
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import apps.amine.bou.readerforselfoss.utils.Config
import org.junit.After
@RunWith(AndroidJUnit4::class)
class LoginActivityEspressoTest {
@ -69,10 +72,8 @@ class LoginActivityEspressoTest {
onView(isRoot()).perform(pressBack())
intended(hasComponent(LoginActivity::class.java.name))
}
@Test
fun wrongLoginUrl() {
rule.launchActivity(Intent())
@ -103,7 +104,10 @@ class LoginActivityEspressoTest {
onView(withId(R.id.loginLayout)).check(matches(isHintOrErrorEnabled()))
onView(withId(R.id.passwordLayout)).check(matches(isHintOrErrorEnabled()))
onView(withId(R.id.loginView)).perform(click()).perform(typeText(username), closeSoftKeyboard())
onView(withId(R.id.loginView)).perform(click()).perform(
typeText(username),
closeSoftKeyboard()
)
onView(withId(R.id.passwordLayout)).check(matches(isHintOrErrorEnabled()))
@ -111,9 +115,9 @@ class LoginActivityEspressoTest {
onView(withId(R.id.passwordLayout)).check(
matches(
isHintOrErrorEnabled())
isHintOrErrorEnabled()
)
)
}
@Test
@ -125,16 +129,21 @@ class LoginActivityEspressoTest {
onView(withId(R.id.withLogin)).perform(click())
onView(withId(R.id.loginView)).perform(click()).perform(typeText(username), closeSoftKeyboard())
onView(withId(R.id.loginView)).perform(click()).perform(
typeText(username),
closeSoftKeyboard()
)
onView(withId(R.id.passwordView)).perform(click()).perform(typeText("WRONGPASS"), closeSoftKeyboard())
onView(withId(R.id.passwordView)).perform(click()).perform(
typeText("WRONGPASS"),
closeSoftKeyboard()
)
onView(withId(R.id.signInButton)).perform(click())
onView(withId(R.id.urlLayout)).check(matches(isHintOrErrorEnabled()))
onView(withId(R.id.loginLayout)).check(matches(isHintOrErrorEnabled()))
onView(withId(R.id.passwordLayout)).check(matches(isHintOrErrorEnabled()))
}
@Test
@ -146,19 +155,23 @@ class LoginActivityEspressoTest {
onView(withId(R.id.withLogin)).perform(click())
onView(withId(R.id.loginView)).perform(click()).perform(typeText(username), closeSoftKeyboard())
onView(withId(R.id.loginView)).perform(click()).perform(
typeText(username),
closeSoftKeyboard()
)
onView(withId(R.id.passwordView)).perform(click()).perform(typeText(password), closeSoftKeyboard())
onView(withId(R.id.passwordView)).perform(click()).perform(
typeText(password),
closeSoftKeyboard()
)
onView(withId(R.id.signInButton)).perform(click())
intended(hasComponent(HomeActivity::class.java.name))
}
@After
fun releaseIntents() {
Intents.release()
}
}

View File

@ -17,7 +17,6 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class MainActivityEspressoTest {
@ -48,7 +47,6 @@ class MainActivityEspressoTest {
intended(hasComponent(MainActivity::class.java.name))
intended(hasComponent(IntroActivity::class.java.name))
intended(hasComponent(LoginActivity::class.java.name), times(0))
}
@Test
@ -61,13 +59,10 @@ class MainActivityEspressoTest {
intended(hasComponent(MainActivity::class.java.name))
intended(hasComponent(LoginActivity::class.java.name))
intended(hasComponent(IntroActivity::class.java.name), times(0))
}
@After
fun releaseIntents() {
Intents.release()
}
}

View File

@ -1,31 +1,29 @@
package apps.amine.bou.readerforselfoss
import android.view.View
import android.support.design.widget.TextInputLayout
import android.support.test.espresso.matcher.ViewMatchers
import android.view.View
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.TypeSafeMatcher
import org.hamcrest.Matchers
import org.hamcrest.TypeSafeMatcher
fun isHintOrErrorEnabled(): Matcher<View> =
object : TypeSafeMatcher<View>() {
override fun describeTo(description: Description?) {}
override fun matchesSafely(item: View?): Boolean {
if (item !is TextInputLayout) {
return false
object : TypeSafeMatcher<View>() {
override fun describeTo(description: Description?) {
}
return item.isHintEnabled || item.isErrorEnabled
override fun matchesSafely(item: View?): Boolean {
if (item !is TextInputLayout) {
return false
}
return item.isHintEnabled || item.isErrorEnabled
}
}
}
fun withMenu(id: Int, titleId: Int): Matcher<View> =
Matchers.anyOf(
ViewMatchers.withId(id),
ViewMatchers.withText(titleId)
)
Matchers.anyOf(
ViewMatchers.withId(id),
ViewMatchers.withText(titleId)
)

View File

@ -1,13 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="apps.amine.bou.readerforselfoss">
package="apps.amine.bou.readerforselfoss"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<!-- For firebase only -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:name=".MyApp"
android:allowBackup="true"
@ -71,6 +68,14 @@
<meta-data
android:name="apps.amine.bou.readerforselfoss.utils.glide.SelfSignedGlideModule"
android:value="GlideModule" />
<meta-data android:name="android.webkit.WebView.MetricsOptOut"
android:value="true" />
<meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
android:value="true" />
<meta-data android:name="android.max_aspect" android:value="2.1" />
</application>
</manifest>
</manifest>

View File

@ -1,6 +1,7 @@
package apps.amine.bou.readerforselfoss
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.preference.PreferenceManager
import android.support.constraint.ConstraintLayout
@ -16,6 +17,8 @@ import android.widget.Toast
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.Spout
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.themes.Toppings
import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.isBaseUrlValid
import com.ftinc.scoop.Scoop
@ -23,30 +26,70 @@ import kotlinx.android.synthetic.main.activity_add_source.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import android.graphics.PorterDuff
class AddSourceActivity : AppCompatActivity() {
private var mSpoutsValue: String? = null
private lateinit var api: SelfossApi
private lateinit var appColors: AppColors
override fun onCreate(savedInstanceState: Bundle?) {
appColors = AppColors(this@AddSourceActivity)
super.onCreate(savedInstanceState)
Scoop.getInstance().apply(this)
setContentView(R.layout.activity_add_source)
val scoop = Scoop.getInstance()
scoop.bind(this, Toppings.PRIMARY.value, toolbar)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
scoop.bindStatusBar(this, Toppings.PRIMARY_DARK.value)
}
val drawable = nameInput.background
drawable.setColorFilter(appColors.colorAccent, PorterDuff.Mode.SRC_ATOP)
// TODO: clean
if(Build.VERSION.SDK_INT > 16) {
nameInput.background = drawable
} else{
nameInput.setBackgroundDrawable(drawable)
}
val drawable1 = sourceUri.background
drawable1.setColorFilter(appColors.colorAccent, PorterDuff.Mode.SRC_ATOP)
if(Build.VERSION.SDK_INT > 16) {
sourceUri.background = drawable1
} else{
sourceUri.setBackgroundDrawable(drawable1)
}
val drawable2 = tags.background
drawable2.setColorFilter(appColors.colorAccent, PorterDuff.Mode.SRC_ATOP)
if(Build.VERSION.SDK_INT > 16) {
tags.background = drawable2
} else{
tags.setBackgroundDrawable(drawable2)
}
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
var api: SelfossApi? = null
try {
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
api = SelfossApi(
this,
this@AddSourceActivity,
prefs.getBoolean("isSelfSignedCert", false),
prefs.getBoolean("should_log_everything", false)
this,
this@AddSourceActivity,
prefs.getBoolean("isSelfSignedCert", false),
prefs.getBoolean("should_log_everything", false)
)
} catch (e: IllegalArgumentException) {
mustLoginToAddSource()
@ -54,10 +97,15 @@ class AddSourceActivity : AppCompatActivity() {
maybeGetDetailsFromIntentSharing(intent, sourceUri, nameInput)
saveBtn.setTextColor(appColors.colorAccent)
saveBtn.setOnClickListener {
handleSaveSource(tags, nameInput.text.toString(), sourceUri.text.toString(), api!!)
}
}
override fun onResume() {
super.onResume()
val config = Config(this)
if (config.baseUrl.isEmpty() || !config.baseUrl.isBaseUrlValid()) {
@ -67,12 +115,19 @@ class AddSourceActivity : AppCompatActivity() {
}
}
private fun handleSpoutsSpinner(spoutsSpinner: Spinner, api: SelfossApi?, mProgress: ProgressBar, formContainer: ConstraintLayout) {
private fun handleSpoutsSpinner(
spoutsSpinner: Spinner,
api: SelfossApi?,
mProgress: ProgressBar,
formContainer: ConstraintLayout
) {
val spoutsKV = HashMap<String, String>()
spoutsSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(adapterView: AdapterView<*>, view: View, i: Int, l: Long) {
val spoutName = (view as TextView).text.toString()
mSpoutsValue = spoutsKV[spoutName]
override fun onItemSelected(adapterView: AdapterView<*>, view: View?, i: Int, l: Long) {
if (view != null) {
val spoutName = (view as TextView).text.toString()
mSpoutsValue = spoutsKV[spoutName]
}
}
override fun onNothingSelected(adapterView: AdapterView<*>) {
@ -82,26 +137,29 @@ class AddSourceActivity : AppCompatActivity() {
var items: Map<String, Spout>
api!!.spouts().enqueue(object : Callback<Map<String, Spout>> {
override fun onResponse(call: Call<Map<String, Spout>>, response: Response<Map<String, Spout>>) {
override fun onResponse(
call: Call<Map<String, Spout>>,
response: Response<Map<String, Spout>>
) {
if (response.body() != null) {
items = response.body()!!
val itemsStrings = items.map { it.value.name }
for ((key, value) in items) {
spoutsKV.put(value.name, key)
spoutsKV[value.name] = key
}
mProgress.visibility = View.GONE
formContainer.visibility = View.VISIBLE
val spinnerArrayAdapter =
ArrayAdapter(
this@AddSourceActivity,
android.R.layout.simple_spinner_item,
itemsStrings)
ArrayAdapter(
this@AddSourceActivity,
android.R.layout.simple_spinner_item,
itemsStrings
)
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spoutsSpinner.adapter = spinnerArrayAdapter
} else {
handleProblemWithSpouts()
}
@ -112,13 +170,21 @@ class AddSourceActivity : AppCompatActivity() {
}
private fun handleProblemWithSpouts() {
Toast.makeText(this@AddSourceActivity, R.string.cant_get_spouts, Toast.LENGTH_SHORT).show()
Toast.makeText(
this@AddSourceActivity,
R.string.cant_get_spouts,
Toast.LENGTH_SHORT
).show()
mProgress.visibility = View.GONE
}
})
}
private fun maybeGetDetailsFromIntentSharing(intent: Intent, sourceUri: EditText, nameInput: EditText) {
private fun maybeGetDetailsFromIntentSharing(
intent: Intent,
sourceUri: EditText,
nameInput: EditText
) {
if (Intent.ACTION_SEND == intent.action && "text/plain" == intent.type) {
sourceUri.setText(intent.getStringExtra(Intent.EXTRA_TEXT))
nameInput.setText(intent.getStringExtra(Intent.EXTRA_TITLE))
@ -134,28 +200,40 @@ class AddSourceActivity : AppCompatActivity() {
private fun handleSaveSource(tags: EditText, title: String, url: String, api: SelfossApi) {
val sourceDetailsAvailable = title.isEmpty() || url.isEmpty() || mSpoutsValue == null || mSpoutsValue!!.isEmpty()
val sourceDetailsAvailable =
title.isEmpty() || url.isEmpty() || mSpoutsValue == null || mSpoutsValue!!.isEmpty()
if (sourceDetailsAvailable) {
Toast.makeText(this, R.string.form_not_complete, Toast.LENGTH_SHORT).show()
} else {
api.createSource(
title,
url,
mSpoutsValue!!,
tags.text.toString(),
""
title,
url,
mSpoutsValue!!,
tags.text.toString(),
""
).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
if (response.body() != null && response.body()!!.isSuccess) {
finish()
} else {
Toast.makeText(this@AddSourceActivity, R.string.cant_create_source, Toast.LENGTH_SHORT).show()
Toast.makeText(
this@AddSourceActivity,
R.string.cant_create_source,
Toast.LENGTH_SHORT
).show()
}
}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
Toast.makeText(this@AddSourceActivity, R.string.cant_create_source, Toast.LENGTH_SHORT).show()
Toast.makeText(
this@AddSourceActivity,
R.string.cant_create_source,
Toast.LENGTH_SHORT
).show()
}
})
}

View File

@ -10,7 +10,6 @@ import android.preference.PreferenceManager
import android.support.v7.app.AppCompatDelegate
import android.view.View
class IntroActivity : MaterialIntroActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@ -18,33 +17,44 @@ class IntroActivity : MaterialIntroActivity() {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
addSlide(SlideFragmentBuilder()
.backgroundColor(R.color.colorPrimary)
.buttonsColor(R.color.colorAccent)
.image(R.drawable.web_hi_res_512)
.title(getString(R.string.intro_hello_title))
.description(getString(R.string.intro_hello_message))
.build())
addSlide(
SlideFragmentBuilder()
.backgroundColor(R.color.colorPrimary)
.buttonsColor(R.color.colorAccent)
.image(R.drawable.web_hi_res_512)
.title(getString(R.string.intro_hello_title))
.description(getString(R.string.intro_hello_message))
.build()
)
addSlide(SlideFragmentBuilder()
.backgroundColor(R.color.colorAccent)
.buttonsColor(R.color.colorPrimary)
.image(R.drawable.ic_info_outline_white_48px)
.title(getString(R.string.intro_needs_selfoss_title))
.description(getString(R.string.intro_needs_selfoss_message))
.build(),
MessageButtonBehaviour(View.OnClickListener {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://selfoss.aditu.de"))
startActivity(browserIntent)
}, getString(R.string.intro_needs_selfoss_link)))
addSlide(
SlideFragmentBuilder()
.backgroundColor(R.color.colorAccent)
.buttonsColor(R.color.colorPrimary)
.image(R.drawable.ic_info_outline_white_48px)
.title(getString(R.string.intro_needs_selfoss_title))
.description(getString(R.string.intro_needs_selfoss_message))
.build(),
MessageButtonBehaviour(
View.OnClickListener {
val browserIntent = Intent(
Intent.ACTION_VIEW,
Uri.parse("https://selfoss.aditu.de")
)
startActivity(browserIntent)
}, getString(R.string.intro_needs_selfoss_link)
)
)
addSlide(SlideFragmentBuilder()
.backgroundColor(R.color.colorPrimaryDark)
.buttonsColor(R.color.colorAccentDark)
.image(R.drawable.ic_thumb_up_white_48px)
.title(getString(R.string.intro_all_set_title))
.description(getString(R.string.intro_all_set_message))
.build())
addSlide(
SlideFragmentBuilder()
.backgroundColor(R.color.colorPrimaryDark)
.buttonsColor(R.color.colorAccentDark)
.image(R.drawable.ic_thumb_up_white_48px)
.title(getString(R.string.intro_all_set_title))
.description(getString(R.string.intro_all_set_message))
.build()
)
}
override fun onFinish() {

View File

@ -8,7 +8,6 @@ import android.content.SharedPreferences
import android.os.Bundle
import android.support.v7.app.AlertDialog
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.text.TextUtils
import android.view.Menu
import android.view.MenuItem
@ -18,19 +17,17 @@ import android.widget.TextView
import android.widget.Toast
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.isBaseUrlValid
import com.crashlytics.android.Crashlytics
import com.ftinc.scoop.Scoop
import com.google.firebase.analytics.FirebaseAnalytics
import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException
import com.mikepenz.aboutlibraries.Libs
import com.mikepenz.aboutlibraries.LibsBuilder
import kotlinx.android.synthetic.main.activity_login.*
import org.acra.ACRA
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import kotlinx.android.synthetic.main.activity_login.*
class LoginActivity : AppCompatActivity() {
@ -41,15 +38,15 @@ class LoginActivity : AppCompatActivity() {
private lateinit var settings: SharedPreferences
private lateinit var editor: SharedPreferences.Editor
private lateinit var firebaseAnalytics: FirebaseAnalytics
private lateinit var userIdentifier: String
private var logErrors: Boolean = false
private lateinit var appColors: AppColors
override fun onCreate(savedInstanceState: Bundle?) {
appColors = AppColors(this@LoginActivity)
super.onCreate(savedInstanceState)
Scoop.getInstance().apply(this)
setContentView(R.layout.activity_login)
setSupportActionBar(toolbar)
@ -67,8 +64,6 @@ class LoginActivity : AppCompatActivity() {
goToMain()
}
firebaseAnalytics = FirebaseAnalytics.getInstance(this)
handleActions()
}
@ -81,13 +76,15 @@ class LoginActivity : AppCompatActivity() {
warningText.visibility = visi
}
passwordView.setOnEditorActionListener(TextView.OnEditorActionListener { _, id, _ ->
if (id == R.id.loginView || id == EditorInfo.IME_NULL) {
attemptLogin()
return@OnEditorActionListener true
passwordView.setOnEditorActionListener(
TextView.OnEditorActionListener { _, id, _ ->
if (id == R.id.loginView || id == EditorInfo.IME_NULL) {
attemptLogin()
return@OnEditorActionListener true
}
false
}
false
})
)
signInButton.setOnClickListener { attemptLogin() }
@ -114,9 +111,10 @@ class LoginActivity : AppCompatActivity() {
alertDialog.setTitle(getString(R.string.warning_wrong_url))
alertDialog.setMessage(getString(R.string.base_url_error))
alertDialog.setButton(
AlertDialog.BUTTON_NEUTRAL,
"OK",
{ dialog, _ -> dialog.dismiss() })
AlertDialog.BUTTON_NEUTRAL,
"OK",
{ dialog, _ -> dialog.dismiss() }
)
alertDialog.show()
}
}
@ -156,9 +154,10 @@ class LoginActivity : AppCompatActivity() {
alertDialog.setTitle(getString(R.string.warning_wrong_url))
alertDialog.setMessage(getString(R.string.text_wrong_url))
alertDialog.setButton(
AlertDialog.BUTTON_NEUTRAL,
"OK",
{ dialog, _ -> dialog.dismiss() })
AlertDialog.BUTTON_NEUTRAL,
"OK",
{ dialog, _ -> dialog.dismiss() }
)
alertDialog.show()
inValidCount = 0
}
@ -191,7 +190,12 @@ class LoginActivity : AppCompatActivity() {
editor.putBoolean("isSelfSignedCert", isWithSelfSignedCert)
editor.apply()
val api = SelfossApi(this, this@LoginActivity, isWithSelfSignedCert, isWithSelfSignedCert)
val api = SelfossApi(
this,
this@LoginActivity,
isWithSelfSignedCert,
isWithSelfSignedCert
)
api.login().enqueue(object : Callback<SuccessResponse> {
private fun preferenceError(t: Throwable) {
editor.remove("url")
@ -206,17 +210,21 @@ class LoginActivity : AppCompatActivity() {
httpLoginView.error = getString(R.string.wrong_infos)
httpPasswordView.error = getString(R.string.wrong_infos)
if (logErrors) {
Crashlytics.setUserIdentifier(userIdentifier)
Crashlytics.log(100, "LOGIN_DEBUG_ERRROR", t.message)
Crashlytics.logException(t)
Toast.makeText(this@LoginActivity, t.message, Toast.LENGTH_LONG).show()
ACRA.getErrorReporter().maybeHandleSilentException(t, this@LoginActivity)
Toast.makeText(
this@LoginActivity,
t.message,
Toast.LENGTH_LONG
).show()
}
showProgress(false)
}
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
if (response.body() != null && response.body()!!.isSuccess) {
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.LOGIN, Bundle())
goToMain()
} else {
preferenceError(Exception("No response body..."))
@ -230,33 +238,34 @@ class LoginActivity : AppCompatActivity() {
}
}
private fun showProgress(show: Boolean) {
val shortAnimTime = resources.getInteger(android.R.integer.config_shortAnimTime)
loginForm.visibility = if (show) View.GONE else View.VISIBLE
loginForm
.animate()
.setDuration(shortAnimTime.toLong())
.alpha(
if (show) 0F else 1F
).setListener(object : AnimatorListenerAdapter() {
.animate()
.setDuration(shortAnimTime.toLong())
.alpha(
if (show) 0F else 1F
).setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
loginForm.visibility = if (show) View.GONE else View.VISIBLE
}
})
}
)
loginProgress.visibility = if (show) View.VISIBLE else View.GONE
loginProgress
.animate()
.setDuration(shortAnimTime.toLong())
.alpha(
if (show) 1F else 0F
).setListener(object : AnimatorListenerAdapter() {
.animate()
.setDuration(shortAnimTime.toLong())
.alpha(
if (show) 1F else 0F
).setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
loginProgress.visibility = if (show) View.VISIBLE else View.GONE
}
})
}
)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
@ -269,10 +278,10 @@ class LoginActivity : AppCompatActivity() {
when (item.itemId) {
R.id.about -> {
LibsBuilder()
.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR)
.withAboutIconShown(true)
.withAboutVersionShown(true)
.start(this)
.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR)
.withAboutIconShown(true)
.withAboutVersionShown(true)
.start(this)
return true
}
R.id.login_debug -> {

View File

@ -5,15 +5,16 @@ import android.os.Bundle
import android.preference.PreferenceManager
import android.support.v7.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (PreferenceManager.getDefaultSharedPreferences(baseContext).getBoolean("firstStart", true)) {
if (PreferenceManager.getDefaultSharedPreferences(baseContext).getBoolean(
"firstStart",
true
)) {
val i = Intent(this@MainActivity, IntroActivity::class.java)
startActivity(i)
} else {
@ -22,6 +23,5 @@ class MainActivity : AppCompatActivity() {
}
finish()
}
}

View File

@ -1,6 +1,7 @@
package apps.amine.bou.readerforselfoss
import android.content.Context
import android.content.SharedPreferences
import android.graphics.drawable.Drawable
import android.net.Uri
import android.preference.PreferenceManager
@ -10,25 +11,41 @@ import apps.amine.bou.readerforselfoss.utils.Config
import com.anupcowkur.reservoir.Reservoir
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.crashlytics.android.Crashlytics
import com.ftinc.scoop.Scoop
import com.github.stkent.amplify.feedback.DefaultEmailFeedbackCollector
import com.github.stkent.amplify.feedback.GooglePlayStoreFeedbackCollector
import com.github.stkent.amplify.tracking.Amplify
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
import com.mikepenz.materialdrawer.util.DrawerImageLoader
import io.fabric.sdk.android.Fabric
import org.acra.ACRA
import org.acra.ReportField
import org.acra.annotation.AcraCore
import org.acra.annotation.AcraDialog
import org.acra.annotation.AcraHttpSender
import org.acra.sender.HttpSender
import java.io.IOException
import java.util.UUID.randomUUID
@AcraHttpSender(uri = "http://amine-bou.fr:5984/acra-selfoss/_design/acra-storage/_update/report",
basicAuthLogin = "selfoss",
basicAuthPassword = "selfoss",
httpMethod = HttpSender.Method.PUT)
@AcraDialog(resText = R.string.crash_dialog_text,
resCommentPrompt = R.string.crash_dialog_comment,
resTheme = android.R.style.Theme_DeviceDefault_Dialog)
@AcraCore(reportContent = [ReportField.REPORT_ID, ReportField.INSTALLATION_ID,
ReportField.APP_VERSION_CODE, ReportField.APP_VERSION_NAME,
ReportField.BUILD, ReportField.ANDROID_VERSION, ReportField.BRAND, ReportField.PHONE_MODEL,
ReportField.AVAILABLE_MEM_SIZE, ReportField.TOTAL_MEM_SIZE,
ReportField.STACK_TRACE, ReportField.APPLICATION_LOG, ReportField.LOGCAT,
ReportField.INITIAL_CONFIGURATION, ReportField.CRASH_CONFIGURATION, ReportField.IS_SILENT,
ReportField.USER_APP_START_DATE, ReportField.USER_COMMENT, ReportField.USER_CRASH_DATE, ReportField.USER_EMAIL, ReportField.CUSTOM_DATA],
buildConfigClass = BuildConfig::class)
class MyApp : MultiDexApplication() {
override fun onCreate() {
super.onCreate()
Fabric.with(this, Crashlytics())
initAmplify()
@ -46,13 +63,20 @@ class MyApp : MultiDexApplication() {
initTheme()
tryToHandleBug()
}
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
val prefs = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
ACRA.init(this)
ACRA.getErrorReporter().putCustomData("unique_id", prefs.getString("unique_id", ""))
}
private fun initAmplify() {
Amplify.initSharedInstance(this)
.setPositiveFeedbackCollectors(GooglePlayStoreFeedbackCollector())
.setCriticalFeedbackCollectors(DefaultEmailFeedbackCollector(BuildConfig.FEEDBACK_EMAIL))
.setCriticalFeedbackCollectors(DefaultEmailFeedbackCollector(Config.feedbackEmail))
.applyAllDefaultRules()
}
@ -66,11 +90,15 @@ class MyApp : MultiDexApplication() {
private fun initDrawerImageLoader() {
DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
override fun set(imageView: ImageView?, uri: Uri?, placeholder: Drawable?, tag: String?) {
override fun set(
imageView: ImageView?,
uri: Uri?,
placeholder: Drawable?,
tag: String?
) {
Glide.with(imageView?.context)
.load(uri)
.apply(RequestOptions.fitCenterTransform()
.placeholder(placeholder))
.apply(RequestOptions.fitCenterTransform().placeholder(placeholder))
.into(imageView)
}
@ -87,19 +115,7 @@ class MyApp : MultiDexApplication() {
private fun initTheme() {
Scoop.waffleCone()
.addFlavor(getString(R.string.default_theme), R.style.NoBar, true)
.addFlavor(getString(R.string.default_dark_theme), R.style.NoBarDark)
.addFlavor(getString(R.string.teal_orange_theme), R.style.NoBarTealOrange)
.addFlavor(getString(R.string.teal_orange_dark_theme), R.style.NoBarTealOrangeDark)
.addFlavor(getString(R.string.cyan_pink_theme), R.style.NoBarCyanPink)
.addFlavor(getString(R.string.cyan_pink_dark_theme), R.style.NoBarCyanPinkDark)
.addFlavor(getString(R.string.grey_orange_theme), R.style.NoBarGreyOrange)
.addFlavor(getString(R.string.grey_orange_dark_theme), R.style.NoBarGreyOrangeDark)
.addFlavor(getString(R.string.blue_amber_theme), R.style.NoBarBlueAmber)
.addFlavor(getString(R.string.blue_amber_dark_theme), R.style.NoBarBlueAmberDark)
.addFlavor(getString(R.string.indigo_pink_theme), R.style.NoBarIndigoPink)
.addFlavor(getString(R.string.indigo_pink_dark_theme), R.style.NoBarIndigoPinkDark)
.addFlavor(getString(R.string.red_teal_theme), R.style.NoBarRedTeal)
.addFlavor(getString(R.string.red_teal_dark_theme), R.style.NoBarRedTealDark)
.addFlavor(getString(R.string.default_dark_theme), R.style.NoBarDark, false)
.setSharedPreferences(PreferenceManager.getDefaultSharedPreferences(this))
.initialize()
}
@ -108,11 +124,13 @@ class MyApp : MultiDexApplication() {
val oldHandler = Thread.getDefaultUncaughtExceptionHandler()
Thread.setDefaultUncaughtExceptionHandler { thread, e ->
if (e is java.lang.NoClassDefFoundError && e.stackTrace.asList().any { it.toString().contains("android.view.ViewDebug") })
if (e is java.lang.NoClassDefFoundError && e.stackTrace.asList().any {
it.toString().contains("android.view.ViewDebug")
}) {
Unit
else
} else {
oldHandler.uncaughtException(thread, e)
}
}
}
}

View File

@ -1,190 +1,267 @@
package apps.amine.bou.readerforselfoss
import android.content.SharedPreferences
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.os.Bundle
import android.preference.PreferenceManager
import android.support.customtabs.CustomTabsIntent
import android.support.design.widget.FloatingActionButton
import android.support.v4.widget.NestedScrollView
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentStatePagerAdapter
import android.support.v4.content.ContextCompat
import android.support.v4.view.ViewPager
import android.support.v7.app.AppCompatActivity
import android.text.Html
import android.text.method.LinkMovementMethod
import android.view.Menu
import android.view.MenuItem
import android.view.View
import apps.amine.bou.readerforselfoss.api.mercury.MercuryApi
import apps.amine.bou.readerforselfoss.api.mercury.ParsedContent
import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
import apps.amine.bou.readerforselfoss.utils.isEmptyOrNullOrNullString
import apps.amine.bou.readerforselfoss.utils.openItemUrl
import apps.amine.bou.readerforselfoss.utils.shareLink
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.crashlytics.android.Crashlytics
import android.view.ViewGroup
import android.widget.Toast
import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.fragments.ArticleFragment
import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.themes.Toppings
import apps.amine.bou.readerforselfoss.transformers.DepthPageTransformer
import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException
import apps.amine.bou.readerforselfoss.utils.succeeded
import apps.amine.bou.readerforselfoss.utils.toggleStar
import com.ftinc.scoop.Scoop
import com.github.rubensousa.floatingtoolbar.FloatingToolbar
import org.sufficientlysecure.htmltextview.HtmlHttpImageGetter
import kotlinx.android.synthetic.main.activity_reader.*
import me.relex.circleindicator.CircleIndicator
import org.acra.ACRA
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import kotlinx.android.synthetic.main.activity_reader.*
class ReaderActivity : AppCompatActivity() {
private lateinit var mCustomTabActivityHelper: CustomTabActivityHelper
//private lateinit var content: HtmlTextView
private lateinit var url: String
private lateinit var contentText: String
private lateinit var contentSource: String
private lateinit var contentImage: String
private lateinit var contentTitle: String
private lateinit var fab: FloatingActionButton
private var markOnScroll: Boolean = false
private var debugReadingItems: Boolean = false
private var currentItem: Int = 0
private lateinit var userIdentifier: String
override fun onStop() {
super.onStop()
mCustomTabActivityHelper.unbindCustomTabsService(this)
private lateinit var api: SelfossApi
private lateinit var toolbarMenu: Menu
private fun showMenuItem(willAddToFavorite: Boolean) {
toolbarMenu.findItem(R.id.save).isVisible = willAddToFavorite
toolbarMenu.findItem(R.id.unsave).isVisible = !willAddToFavorite
}
private fun canFavorite() {
showMenuItem(true)
}
private fun canRemoveFromFavorite() {
showMenuItem(false)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Scoop.getInstance().apply(this)
setContentView(R.layout.activity_reader)
url = intent.getStringExtra("url")
contentText = intent.getStringExtra("content")
contentTitle = intent.getStringExtra("title")
contentImage = intent.getStringExtra("image")
contentSource = intent.getStringExtra("source")
val scoop = Scoop.getInstance()
scoop.bind(this, Toppings.PRIMARY.value, toolBar)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
scoop.bindStatusBar(this, Toppings.PRIMARY_DARK.value)
}
fab = findViewById(R.id.fab)
val mFloatingToolbar: FloatingToolbar = findViewById(R.id.floatingToolbar)
mFloatingToolbar.attachFab(fab)
val customTabsIntent = this@ReaderActivity.buildCustomTabsIntent()
mCustomTabActivityHelper = CustomTabActivityHelper()
mCustomTabActivityHelper.bindCustomTabsService(this)
setSupportActionBar(toolBar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
mFloatingToolbar.setClickListener(object : FloatingToolbar.ItemClickListener {
override fun onItemClick(item: MenuItem) {
when (item.itemId) {
R.id.more_action -> getContentFromMercury(customTabsIntent, prefs)
R.id.share_action -> this@ReaderActivity.shareLink(url)
R.id.open_action -> this@ReaderActivity.openItemUrl(
url,
contentText,
contentImage,
contentTitle,
contentSource,
customTabsIntent,
false,
false,
this@ReaderActivity)
else -> Unit
debugReadingItems = prefs.getBoolean("read_debug", false)
userIdentifier = prefs.getString("unique_id", "")
markOnScroll = prefs.getBoolean("mark_on_scroll", false)
api = SelfossApi(
this,
this@ReaderActivity,
prefs.getBoolean("isSelfSignedCert", false),
prefs.getBoolean("should_log_everything", false)
)
if (allItems.isEmpty()) {
finish()
}
currentItem = intent.getIntExtra("currentItem", 0)
readItem(allItems[currentItem].id)
pager.adapter = ScreenSlidePagerAdapter(supportFragmentManager, AppColors(this@ReaderActivity))
pager.currentItem = currentItem
}
override fun onResume() {
super.onResume()
notifyAdapter()
pager.setPageTransformer(true, DepthPageTransformer())
(indicator as CircleIndicator).setViewPager(pager)
pager.addOnPageChangeListener(
object : ViewPager.SimpleOnPageChangeListener() {
override fun onPageSelected(position: Int) {
if (allItems[position].starred) {
canRemoveFromFavorite()
} else {
canFavorite()
}
readItem(allItems[pager.currentItem].id)
}
}
override fun onItemLongClick(item: MenuItem?) {
}
})
if (contentText.isEmptyOrNullOrNullString()) {
getContentFromMercury(customTabsIntent, prefs)
} else {
source.text = contentSource
titleView.text = contentTitle
tryToHandleHtml(contentText, customTabsIntent, prefs)
if (!contentImage.isEmptyOrNullOrNullString()) {
imageView.visibility = View.VISIBLE
Glide
.with(baseContext)
.asBitmap()
.load(contentImage)
.apply(RequestOptions.fitCenterTransform())
.into(imageView)
} else {
imageView.visibility = View.GONE
}
}
nestedScrollView.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, oldScrollY ->
if (scrollY > oldScrollY) {
fab.hide()
} else {
if (mFloatingToolbar.isShowing) mFloatingToolbar.hide() else fab.show()
}
})
content.movementMethod = LinkMovementMethod.getInstance()
}
private fun getContentFromMercury(customTabsIntent: CustomTabsIntent, prefs: SharedPreferences) {
progressBar.visibility = View.VISIBLE
val parser = MercuryApi(BuildConfig.MERCURY_KEY, prefs.getBoolean("should_log_everything", false))
parser.parseUrl(url).enqueue(object : Callback<ParsedContent> {
override fun onResponse(call: Call<ParsedContent>, response: Response<ParsedContent>) {
if (response.body() != null && response.body()!!.content != null && response.body()!!.content.isNotEmpty()) {
source.text = response.body()!!.domain
titleView.text = response.body()!!.title
this@ReaderActivity.url = response.body()!!.url
if (response.body()!!.content != null && !response.body()!!.content.isEmpty()) {
tryToHandleHtml(response.body()!!.content, customTabsIntent, prefs)
}
if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isEmpty()) {
imageView.visibility = View.VISIBLE
Glide
.with(baseContext)
.asBitmap()
.load(response.body()!!.lead_image_url)
.apply(RequestOptions.fitCenterTransform())
.into(imageView)
} else {
imageView.visibility = View.GONE
}
nestedScrollView.scrollTo(0, 0)
progressBar.visibility = View.GONE
} else openInBrowserAfterFailing(customTabsIntent)
}
override fun onFailure(call: Call<ParsedContent>, t: Throwable) = openInBrowserAfterFailing(customTabsIntent)
})
}
private fun tryToHandleHtml(c: String, customTabsIntent: CustomTabsIntent, prefs: SharedPreferences) {
try {
content.text = Html.fromHtml(c, HtmlHttpImageGetter(content, null, true), null)
//content.setHtml(response.body()!!.content, HtmlHttpImageGetter(content, null, true))
} catch (e: Exception) {
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
Crashlytics.log(100, "CANT_TRANSFORM_TO_HTML", e.message)
Crashlytics.logException(e)
openInBrowserAfterFailing(customTabsIntent)
}
}
private fun openInBrowserAfterFailing(customTabsIntent: CustomTabsIntent) {
progressBar.visibility = View.GONE
this@ReaderActivity.openItemUrl(
url,
contentText,
contentImage,
contentTitle,
contentSource,
customTabsIntent,
true,
false,
this@ReaderActivity
)
finish()
}
fun readItem(id: String) {
if (markOnScroll) {
api.markItem(id).enqueue(
object : Callback<SuccessResponse> {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
if (!response.succeeded() && debugReadingItems) {
val message =
"message: ${response.message()} " +
"response isSuccess: ${response.isSuccessful} " +
"response code: ${response.code()} " +
"response message: ${response.message()} " +
"response errorBody: ${response.errorBody()?.string()} " +
"body success: ${response.body()?.success} " +
"body isSuccess: ${response.body()?.isSuccess}"
ACRA.getErrorReporter()
.maybeHandleSilentException(Exception(message), this@ReaderActivity)
}
}
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
if (debugReadingItems) {
ACRA.getErrorReporter().maybeHandleSilentException(t, this@ReaderActivity)
}
}
}
)
}
}
private fun notifyAdapter() {
(pager.adapter as ScreenSlidePagerAdapter).notifyDataSetChanged()
}
override fun onPause() {
super.onPause()
if (markOnScroll) {
pager.clearOnPageChangeListeners()
}
}
override fun onSaveInstanceState(oldInstanceState: Bundle?) {
super.onSaveInstanceState(oldInstanceState)
oldInstanceState!!.clear()
}
private inner class ScreenSlidePagerAdapter(fm: FragmentManager, val appColors: AppColors) :
FragmentStatePagerAdapter(fm) {
override fun getCount(): Int {
return allItems.size
}
override fun getItem(position: Int): ArticleFragment {
return ArticleFragment.newInstance(position, allItems)
}
override fun startUpdate(container: ViewGroup) {
super.startUpdate(container)
container.background = ColorDrawable(ContextCompat.getColor(this@ReaderActivity, appColors.colorBackground))
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.reader_menu, menu)
toolbarMenu = menu
if (!allItems.isEmpty() && allItems[currentItem].starred) {
canRemoveFromFavorite()
} else {
canFavorite()
}
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
onBackPressed()
return true
}
R.id.save -> {
api.starrItem(allItems[pager.currentItem].id)
.enqueue(object : Callback<SuccessResponse> {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
allItems[pager.currentItem] = allItems[pager.currentItem].toggleStar()
notifyAdapter()
canRemoveFromFavorite()
}
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
Toast.makeText(
baseContext,
R.string.cant_mark_favortie,
Toast.LENGTH_SHORT
).show()
}
})
}
R.id.unsave -> {
api.unstarrItem(allItems[pager.currentItem].id)
.enqueue(object : Callback<SuccessResponse> {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
allItems[pager.currentItem] = allItems[pager.currentItem].toggleStar()
notifyAdapter()
canFavorite()
}
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
Toast.makeText(
baseContext,
R.string.cant_unmark_favortie,
Toast.LENGTH_SHORT
).show()
}
})
}
}
return super.onOptionsItemSelected(item)
}
companion object {
var allItems: ArrayList<Item> = ArrayList()
}
}

View File

@ -1,6 +1,8 @@
package apps.amine.bou.readerforselfoss
import android.content.Intent
import android.content.res.ColorStateList
import android.os.Build
import android.os.Bundle
import android.preference.PreferenceManager
import android.support.v7.app.AppCompatActivity
@ -9,23 +11,37 @@ import android.widget.Toast
import apps.amine.bou.readerforselfoss.adapters.SourcesListAdapter
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.Sources
import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.themes.Toppings
import com.ftinc.scoop.Scoop
import kotlinx.android.synthetic.main.activity_sources.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import kotlinx.android.synthetic.main.activity_sources.*
class SourcesActivity : AppCompatActivity() {
private lateinit var appColors: AppColors
override fun onCreate(savedInstanceState: Bundle?) {
appColors = AppColors(this@SourcesActivity)
super.onCreate(savedInstanceState)
Scoop.getInstance().apply(this)
setContentView(R.layout.activity_sources)
val scoop = Scoop.getInstance()
scoop.bind(this, Toppings.PRIMARY.value, toolbar)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
scoop.bindStatusBar(this, Toppings.PRIMARY_DARK.value)
}
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
fab.rippleColor = appColors.colorAccentDark
fab.backgroundTintList = ColorStateList.valueOf(appColors.colorAccent)
}
override fun onStop() {
@ -39,25 +55,43 @@ class SourcesActivity : AppCompatActivity() {
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
val api = SelfossApi(this, this@SourcesActivity, prefs.getBoolean("isSelfSignedCert", false), prefs.getBoolean("should_log_everything", false))
val api = SelfossApi(
this,
this@SourcesActivity,
prefs.getBoolean("isSelfSignedCert", false),
prefs.getBoolean("should_log_everything", false)
)
var items: ArrayList<Sources> = ArrayList()
recyclerView.setHasFixedSize(true)
recyclerView.layoutManager = mLayoutManager
api.sources.enqueue(object : Callback<List<Sources>> {
override fun onResponse(call: Call<List<Sources>>, response: Response<List<Sources>>) {
override fun onResponse(
call: Call<List<Sources>>,
response: Response<List<Sources>>
) {
if (response.body() != null && response.body()!!.isNotEmpty()) {
items = response.body() as ArrayList<Sources>
}
val mAdapter = SourcesListAdapter(this@SourcesActivity, items, api)
recyclerView.adapter = mAdapter
mAdapter.notifyDataSetChanged()
if (items.isEmpty()) Toast.makeText(this@SourcesActivity, R.string.nothing_here, Toast.LENGTH_SHORT).show()
if (items.isEmpty()) {
Toast.makeText(
this@SourcesActivity,
R.string.nothing_here,
Toast.LENGTH_SHORT
).show()
}
}
override fun onFailure(call: Call<List<Sources>>, t: Throwable) {
Toast.makeText(this@SourcesActivity, R.string.cant_get_sources, Toast.LENGTH_SHORT).show()
Toast.makeText(
this@SourcesActivity,
R.string.cant_get_sources,
Toast.LENGTH_SHORT
).show()
}
})

View File

@ -2,15 +2,13 @@ package apps.amine.bou.readerforselfoss.adapters
import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.support.design.widget.Snackbar
import android.support.v7.widget.CardView
import android.support.v7.widget.RecyclerView
import android.text.Html
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView.ScaleType
import android.widget.TextView
import android.widget.Toast
import apps.amine.bou.readerforselfoss.R
import apps.amine.bou.readerforselfoss.api.selfoss.Item
@ -25,31 +23,34 @@ import apps.amine.bou.readerforselfoss.utils.openInBrowserAsNewTask
import apps.amine.bou.readerforselfoss.utils.openItemUrl
import apps.amine.bou.readerforselfoss.utils.shareLink
import apps.amine.bou.readerforselfoss.utils.sourceAndDateText
import apps.amine.bou.readerforselfoss.utils.succeeded
import apps.amine.bou.readerforselfoss.utils.toTextDrawableString
import com.amulyakhare.textdrawable.TextDrawable
import com.amulyakhare.textdrawable.util.ColorGenerator
import com.bumptech.glide.Glide
import com.crashlytics.android.Crashlytics
import com.like.LikeButton
import com.like.OnLikeListener
import kotlinx.android.synthetic.main.card_item.view.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import kotlinx.android.synthetic.main.card_item.view.*
class ItemCardAdapter(private val app: Activity,
private val items: ArrayList<Item>,
private val api: SelfossApi,
private val helper: CustomTabActivityHelper,
private val internalBrowser: Boolean,
private val articleViewer: Boolean,
private val fullHeightCards: Boolean,
private val appColors: AppColors,
val debugReadingItems: Boolean,
val userIdentifier: String) : RecyclerView.Adapter<ItemCardAdapter.ViewHolder>() {
class ItemCardAdapter(
override val app: Activity,
override var items: ArrayList<Item>,
override val api: SelfossApi,
private val helper: CustomTabActivityHelper,
private val internalBrowser: Boolean,
private val articleViewer: Boolean,
private val fullHeightCards: Boolean,
override val appColors: AppColors,
override val debugReadingItems: Boolean,
override val userIdentifier: String,
override val updateItems: (ArrayList<Item>) -> Unit
) : ItemsAdapter<ItemCardAdapter.ViewHolder>() {
private val c: Context = app.baseContext
private val generator: ColorGenerator = ColorGenerator.MATERIAL
private val imageMaxHeight: Int =
c.resources.getDimension(R.dimen.card_image_max_height).toInt()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(c).inflate(R.layout.card_item, parent, false) as CardView
@ -63,12 +64,21 @@ class ItemCardAdapter(private val app: Activity,
holder.mView.favButton.isLiked = itm.starred
holder.mView.title.text = Html.fromHtml(itm.title)
holder.mView.title.setLinkTextColor(appColors.colorAccent)
holder.mView.sourceTitleAndDate.text = itm.sourceAndDateText()
if (!fullHeightCards) {
holder.mView.itemImage.maxHeight = imageMaxHeight
holder.mView.itemImage.scaleType = ScaleType.CENTER_CROP
}
if (itm.getThumbnail(c).isEmpty()) {
holder.mView.itemImage.visibility = View.GONE
Glide.with(c).clear(holder.mView.itemImage)
holder.mView.itemImage.setImageDrawable(null)
} else {
holder.mView.itemImage.visibility = View.VISIBLE
c.bitmapCenterCrop(itm.getThumbnail(c), holder.mView.itemImage)
}
@ -76,10 +86,10 @@ class ItemCardAdapter(private val app: Activity,
val color = generator.getColor(itm.sourcetitle)
val drawable =
TextDrawable
.builder()
.round()
.build(itm.sourcetitle.toTextDrawableString(), color)
TextDrawable
.builder()
.round()
.build(itm.sourcetitle.toTextDrawableString(c), color)
holder.mView.sourceImage.setImageDrawable(drawable)
} else {
c.circularBitmapDrawable(itm.getIcon(c), holder.mView.sourceImage)
@ -92,95 +102,35 @@ class ItemCardAdapter(private val app: Activity,
return items.size
}
private fun doUnmark(i: Item, position: Int) {
val s = Snackbar
.make(app.findViewById(R.id.coordLayout), R.string.marked_as_read, Snackbar.LENGTH_LONG)
.setAction(R.string.undo_string) {
items.add(position, i)
notifyItemInserted(position)
api.unmarkItem(i.id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
items.remove(i)
notifyItemRemoved(position)
doUnmark(i, position)
}
})
}
val view = s.view
val tv: TextView = view.findViewById(android.support.design.R.id.snackbar_text)
tv.setTextColor(Color.WHITE)
s.show()
}
fun removeItemAtIndex(position: Int) {
val i = items[position]
items.remove(i)
notifyItemRemoved(position)
api.markItem(i.id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
if (!response.succeeded() && debugReadingItems) {
val message =
"message: ${response.message()} " +
"response isSuccess: ${response.isSuccessful} " +
"response code: ${response.code()} " +
"response message: ${response.message()} " +
"response errorBody: ${response.errorBody()?.string()} " +
"body success: ${response.body()?.success} " +
"body isSuccess: ${response.body()?.isSuccess}"
Crashlytics.setUserIdentifier(userIdentifier)
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
Crashlytics.logException(Exception("Was success, but did it work ?"))
Toast.makeText(c, message, Toast.LENGTH_LONG).show()
}
doUnmark(i, position)
}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
if (debugReadingItems) {
Crashlytics.setUserIdentifier(userIdentifier)
Crashlytics.log(100, "READ_DEBUG_ERROR", t.message)
Crashlytics.logException(t)
Toast.makeText(c, t.message, Toast.LENGTH_LONG).show()
}
Toast.makeText(app, app.getString(R.string.cant_mark_read), Toast.LENGTH_SHORT).show()
items.add(i)
notifyItemInserted(position)
}
})
}
inner class ViewHolder(val mView: CardView) : RecyclerView.ViewHolder(mView) {
init {
mView.setCardBackgroundColor(appColors.cardBackground)
mView.setCardBackgroundColor(appColors.cardBackgroundColor)
handleClickListeners()
handleCustomTabActions()
}
private fun handleClickListeners() {
if (!fullHeightCards) {
mView.itemImage.maxHeight = c.resources.getDimension(R.dimen.card_image_max_height).toInt()
mView.itemImage.scaleType = ScaleType.CENTER_CROP
}
mView.favButton.setOnLikeListener(object : OnLikeListener {
override fun liked(likeButton: LikeButton) {
val (id) = items[adapterPosition]
api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
mView.favButton.isLiked = false
Toast.makeText(c, R.string.cant_mark_favortie, Toast.LENGTH_SHORT).show()
Toast.makeText(
c,
R.string.cant_mark_favortie,
Toast.LENGTH_SHORT
).show()
}
})
}
@ -188,11 +138,22 @@ class ItemCardAdapter(private val app: Activity,
override fun unLiked(likeButton: LikeButton) {
val (id) = items[adapterPosition]
api.unstarrItem(id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
mView.favButton.isLiked = true
Toast.makeText(c, R.string.cant_unmark_favortie, Toast.LENGTH_SHORT).show()
Toast.makeText(
c,
R.string.cant_unmark_favortie,
Toast.LENGTH_SHORT
).show()
}
})
}
@ -212,15 +173,15 @@ class ItemCardAdapter(private val app: Activity,
helper.bindCustomTabsService(app)
mView.setOnClickListener {
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
items[adapterPosition].content,
items[adapterPosition].getThumbnail(c),
items[adapterPosition].title,
items[adapterPosition].sourceAndDateText(),
customTabsIntent,
internalBrowser,
articleViewer,
app)
c.openItemUrl(
items,
adapterPosition,
items[adapterPosition].getLinkDecoded(),
customTabsIntent,
internalBrowser,
articleViewer,
app
)
}
}
}

View File

@ -1,23 +1,20 @@
package apps.amine.bou.readerforselfoss.adapters
import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.support.constraint.ConstraintLayout
import android.support.design.widget.Snackbar
import android.support.v7.widget.RecyclerView
import android.text.Html
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import apps.amine.bou.readerforselfoss.R
import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
import apps.amine.bou.readerforselfoss.utils.glide.bitmapCenterCrop
@ -26,34 +23,41 @@ import apps.amine.bou.readerforselfoss.utils.openInBrowserAsNewTask
import apps.amine.bou.readerforselfoss.utils.openItemUrl
import apps.amine.bou.readerforselfoss.utils.shareLink
import apps.amine.bou.readerforselfoss.utils.sourceAndDateText
import apps.amine.bou.readerforselfoss.utils.succeeded
import apps.amine.bou.readerforselfoss.utils.toTextDrawableString
import com.amulyakhare.textdrawable.TextDrawable
import com.amulyakhare.textdrawable.util.ColorGenerator
import com.crashlytics.android.Crashlytics
import com.like.LikeButton
import com.like.OnLikeListener
import kotlinx.android.synthetic.main.list_item.view.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.util.*
import kotlin.collections.ArrayList
import kotlinx.android.synthetic.main.list_item.view.*
class ItemListAdapter(private val app: Activity,
private val items: ArrayList<Item>,
private val api: SelfossApi,
private val helper: CustomTabActivityHelper,
private val clickBehavior: Boolean,
private val internalBrowser: Boolean,
private val articleViewer: Boolean,
val debugReadingItems: Boolean,
val userIdentifier: String) : RecyclerView.Adapter<ItemListAdapter.ViewHolder>() {
class ItemListAdapter(
override val app: Activity,
override var items: ArrayList<Item>,
override val api: SelfossApi,
private val helper: CustomTabActivityHelper,
private val clickBehavior: Boolean,
private val internalBrowser: Boolean,
private val articleViewer: Boolean,
override val debugReadingItems: Boolean,
override val userIdentifier: String,
override val appColors: AppColors,
override val updateItems: (ArrayList<Item>) -> Unit
) : ItemsAdapter<ItemListAdapter.ViewHolder>() {
private val generator: ColorGenerator = ColorGenerator.MATERIAL
private val c: Context = app.baseContext
private val bars: ArrayList<Boolean> = ArrayList(Collections.nCopies(items.size + 1, false))
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(c).inflate(R.layout.list_item, parent, false) as ConstraintLayout
val v = LayoutInflater.from(c).inflate(
R.layout.list_item,
parent,
false
) as ConstraintLayout
return ViewHolder(v)
}
@ -61,21 +65,24 @@ class ItemListAdapter(private val app: Activity,
val itm = items[position]
holder.mView.favButton.isLiked = itm.starred
holder.mView.title.text = Html.fromHtml(itm.title)
holder.mView.title.setLinkTextColor(appColors.colorAccent)
holder.mView.sourceTitleAndDate.text = itm.sourceAndDateText()
if (itm.getThumbnail(c).isEmpty()) {
val sizeInInt = 46
val sizeInDp = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, sizeInInt.toFloat(), c.resources
.displayMetrics).toInt()
TypedValue.COMPLEX_UNIT_DIP, sizeInInt.toFloat(), c.resources
.displayMetrics
).toInt()
val marginInInt = 16
val marginInDp = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, marginInInt.toFloat(), c.resources
.displayMetrics).toInt()
TypedValue.COMPLEX_UNIT_DIP, marginInInt.toFloat(), c.resources
.displayMetrics
).toInt()
val params = holder.mView.itemImage.layoutParams as ViewGroup.MarginLayoutParams
params.height = sizeInDp
@ -85,14 +92,13 @@ class ItemListAdapter(private val app: Activity,
if (itm.getIcon(c).isEmpty()) {
val color = generator.getColor(itm.sourcetitle)
val textDrawable = StringBuilder()
for (s in itm.sourcetitle.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
textDrawable.append(s[0])
}
val builder = TextDrawable.builder().round()
val drawable =
TextDrawable
.builder()
.round()
.build(itm.sourcetitle.toTextDrawableString(c), color)
val drawable = builder.build(textDrawable.toString(), color)
holder.mView.itemImage.setImageDrawable(drawable)
} else {
c.circularBitmapDrawable(itm.getIcon(c), holder.mView.itemImage)
@ -101,80 +107,22 @@ class ItemListAdapter(private val app: Activity,
c.bitmapCenterCrop(itm.getThumbnail(c), holder.mView.itemImage)
}
if (bars[position]) holder.mView.actionBar.visibility = View.VISIBLE else holder.mView.actionBar.visibility = View.GONE
// TODO: maybe handle this differently. It crashes when changing tab
try {
if (bars[position]) {
holder.mView.actionBar.visibility = View.VISIBLE
} else {
holder.mView.actionBar.visibility = View.GONE
}
} catch (e: IndexOutOfBoundsException) {
holder.mView.actionBar.visibility = View.GONE
}
holder.mView.favButton.isLiked = itm.starred
}
override fun getItemCount(): Int = items.size
private fun doUnmark(i: Item, position: Int) {
val s = Snackbar
.make(app.findViewById(R.id.coordLayout), R.string.marked_as_read, Snackbar.LENGTH_LONG)
.setAction(R.string.undo_string) {
items.add(position, i)
notifyItemInserted(position)
api.unmarkItem(i.id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
items.remove(i)
notifyItemRemoved(position)
doUnmark(i, position)
}
})
}
val view = s.view
val tv: TextView = view.findViewById(android.support.design.R.id.snackbar_text)
tv.setTextColor(Color.WHITE)
s.show()
}
fun removeItemAtIndex(position: Int) {
val i = items[position]
items.remove(i)
notifyItemRemoved(position)
api.markItem(i.id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
if (!response.succeeded() && debugReadingItems) {
val message =
"message: ${response.message()} " +
"response isSuccess: ${response.isSuccessful} " +
"response code: ${response.code()} " +
"response message: ${response.message()} " +
"response errorBody: ${response.errorBody()?.string()} " +
"body success: ${response.body()?.success} " +
"body isSuccess: ${response.body()?.isSuccess}"
Crashlytics.setUserIdentifier(userIdentifier)
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
Crashlytics.logException(Exception("Was success, but did it work ?"))
Toast.makeText(c, message, Toast.LENGTH_LONG).show()
}
doUnmark(i, position)
}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
if (debugReadingItems) {
Crashlytics.setUserIdentifier(userIdentifier)
Crashlytics.log(100, "READ_DEBUG_ERROR", t.message)
Crashlytics.logException(t)
Toast.makeText(c, t.message, Toast.LENGTH_LONG).show()
}
Toast.makeText(app, app.getString(R.string.cant_mark_read), Toast.LENGTH_SHORT).show()
items.add(i)
notifyItemInserted(position)
}
})
}
inner class ViewHolder(val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView) {
init {
@ -188,11 +136,22 @@ class ItemListAdapter(private val app: Activity,
override fun liked(likeButton: LikeButton) {
val (id) = items[adapterPosition]
api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
mView.favButton.isLiked = false
Toast.makeText(c, R.string.cant_mark_favortie, Toast.LENGTH_SHORT).show()
Toast.makeText(
c,
R.string.cant_mark_favortie,
Toast.LENGTH_SHORT
).show()
}
})
}
@ -200,11 +159,22 @@ class ItemListAdapter(private val app: Activity,
override fun unLiked(likeButton: LikeButton) {
val (id) = items[adapterPosition]
api.unstarrItem(id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
mView.favButton.isLiked = true
Toast.makeText(c, R.string.cant_unmark_favortie, Toast.LENGTH_SHORT).show()
Toast.makeText(
c,
R.string.cant_unmark_favortie,
Toast.LENGTH_SHORT
).show()
}
})
}
@ -220,7 +190,6 @@ class ItemListAdapter(private val app: Activity,
}
}
private fun handleCustomTabActions() {
val customTabsIntent = c.buildCustomTabsIntent()
helper.bindCustomTabsService(app)
@ -228,15 +197,15 @@ class ItemListAdapter(private val app: Activity,
if (!clickBehavior) {
mView.setOnClickListener {
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
items[adapterPosition].content,
items[adapterPosition].getThumbnail(c),
items[adapterPosition].title,
items[adapterPosition].sourceAndDateText(),
customTabsIntent,
internalBrowser,
articleViewer,
app)
c.openItemUrl(
items,
adapterPosition,
items[adapterPosition].getLinkDecoded(),
customTabsIntent,
internalBrowser,
articleViewer,
app
)
}
mView.setOnLongClickListener {
actionBarShowHide()
@ -245,15 +214,15 @@ class ItemListAdapter(private val app: Activity,
} else {
mView.setOnClickListener { actionBarShowHide() }
mView.setOnLongClickListener {
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
items[adapterPosition].content,
items[adapterPosition].getThumbnail(c),
items[adapterPosition].title,
items[adapterPosition].sourceAndDateText(),
customTabsIntent,
internalBrowser,
articleViewer,
app)
c.openItemUrl(
items,
adapterPosition,
items[adapterPosition].getLinkDecoded(),
customTabsIntent,
internalBrowser,
articleViewer,
app
)
true
}
}

View File

@ -0,0 +1,131 @@
package apps.amine.bou.readerforselfoss.adapters
import android.app.Activity
import android.graphics.Color
import android.support.design.widget.Snackbar
import android.support.v7.widget.RecyclerView
import android.widget.TextView
import android.widget.Toast
import apps.amine.bou.readerforselfoss.R
import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException
import apps.amine.bou.readerforselfoss.utils.succeeded
import org.acra.ACRA
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapter<VH>() {
abstract var items: ArrayList<Item>
abstract val api: SelfossApi
abstract val debugReadingItems: Boolean
abstract val userIdentifier: String
abstract val app: Activity
abstract val appColors: AppColors
abstract val updateItems: (ArrayList<Item>) -> Unit
fun updateAllItems(newItems: ArrayList<Item>) {
items = newItems
notifyDataSetChanged()
updateItems(items)
}
private fun doUnmark(i: Item, position: Int) {
val s = Snackbar
.make(
app.findViewById(R.id.coordLayout),
R.string.marked_as_read,
Snackbar.LENGTH_LONG
)
.setAction(R.string.undo_string) {
items.add(position, i)
notifyItemInserted(position)
updateItems(items)
api.unmarkItem(i.id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
items.remove(i)
notifyItemRemoved(position)
updateItems(items)
doUnmark(i, position)
}
})
}
val view = s.view
val tv: TextView = view.findViewById(android.support.design.R.id.snackbar_text)
tv.setTextColor(Color.WHITE)
s.show()
}
fun removeItemAtIndex(position: Int) {
val i = items[position]
items.remove(i)
notifyItemRemoved(position)
updateItems(items)
api.markItem(i.id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
if (!response.succeeded() && debugReadingItems) {
val message =
"message: ${response.message()} " +
"response isSuccess: ${response.isSuccessful} " +
"response code: ${response.code()} " +
"response message: ${response.message()} " +
"response errorBody: ${response.errorBody()?.string()} " +
"body success: ${response.body()?.success} " +
"body isSuccess: ${response.body()?.isSuccess}"
ACRA.getErrorReporter().maybeHandleSilentException(Exception(message), app)
Toast.makeText(app.baseContext, message, Toast.LENGTH_LONG).show()
}
doUnmark(i, position)
}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
if (debugReadingItems) {
ACRA.getErrorReporter().maybeHandleSilentException(t, app)
Toast.makeText(app.baseContext, t.message, Toast.LENGTH_LONG).show()
}
Toast.makeText(
app,
app.getString(R.string.cant_mark_read),
Toast.LENGTH_SHORT
).show()
items.add(i)
notifyItemInserted(position)
updateItems(items)
}
})
}
fun addItemAtIndex(item: Item, position: Int) {
items.add(position, item)
notifyItemInserted(position)
updateItems(items)
}
fun addItemsAtEnd(newItems: List<Item>) {
val oldSize = items.size
items.addAll(newItems)
notifyItemRangeInserted(oldSize, newItems.size)
updateItems(items)
}
}

View File

@ -7,8 +7,6 @@ import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import apps.amine.bou.readerforselfoss.R
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
@ -18,20 +16,25 @@ import apps.amine.bou.readerforselfoss.utils.glide.circularBitmapDrawable
import apps.amine.bou.readerforselfoss.utils.toTextDrawableString
import com.amulyakhare.textdrawable.TextDrawable
import com.amulyakhare.textdrawable.util.ColorGenerator
import kotlinx.android.synthetic.main.source_list_item.view.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import kotlinx.android.synthetic.main.source_list_item.view.*
class SourcesListAdapter(private val app: Activity,
private val items: ArrayList<Sources>,
private val api: SelfossApi) : RecyclerView.Adapter<SourcesListAdapter.ViewHolder>() {
class SourcesListAdapter(
private val app: Activity,
private val items: ArrayList<Sources>,
private val api: SelfossApi
) : RecyclerView.Adapter<SourcesListAdapter.ViewHolder>() {
private val c: Context = app.baseContext
private val generator: ColorGenerator = ColorGenerator.MATERIAL
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(c).inflate(R.layout.source_list_item, parent, false) as ConstraintLayout
val v = LayoutInflater.from(c).inflate(
R.layout.source_list_item,
parent,
false
) as ConstraintLayout
return ViewHolder(v)
}
@ -42,25 +45,21 @@ class SourcesListAdapter(private val app: Activity,
val color = generator.getColor(itm.title)
val drawable =
TextDrawable
.builder()
.round()
.build(itm.title.toTextDrawableString(), color)
holder.itemImage.setImageDrawable(drawable)
TextDrawable
.builder()
.round()
.build(itm.title.toTextDrawableString(c), color)
holder.mView.itemImage.setImageDrawable(drawable)
} else {
c.circularBitmapDrawable(itm.getIcon(c), holder.itemImage)
c.circularBitmapDrawable(itm.getIcon(c), holder.mView.itemImage)
}
holder.sourceTitle.text = itm.title
holder.mView.sourceTitle.text = itm.title
}
override fun getItemCount(): Int {
return items.size
}
override fun getItemCount(): Int = items.size
inner class ViewHolder(internal val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView) {
lateinit var itemImage: ImageView
lateinit var sourceTitle: TextView
init {
handleClickListeners()
@ -73,23 +72,32 @@ class SourcesListAdapter(private val app: Activity,
deleteBtn.setOnClickListener {
val (id) = items[adapterPosition]
api.deleteSource(id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
if (response.body() != null && response.body()!!.isSuccess) {
items.removeAt(adapterPosition)
notifyItemRemoved(adapterPosition)
notifyItemRangeChanged(adapterPosition, itemCount)
} else {
Toast.makeText(app, R.string.can_delete_source, Toast.LENGTH_SHORT).show()
Toast.makeText(
app,
R.string.can_delete_source,
Toast.LENGTH_SHORT
).show()
}
}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
Toast.makeText(app, R.string.can_delete_source, Toast.LENGTH_SHORT).show()
Toast.makeText(
app,
R.string.can_delete_source,
Toast.LENGTH_SHORT
).show()
}
})
}
}
}
}

View File

@ -7,27 +7,26 @@ import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class MercuryApi(private val key: String, shouldLog: Boolean) {
class MercuryApi(shouldLog: Boolean) {
private val service: MercuryService
init {
val interceptor = HttpLoggingInterceptor()
interceptor.level = if (shouldLog)
interceptor.level = if (shouldLog) {
HttpLoggingInterceptor.Level.BODY
else
} else {
HttpLoggingInterceptor.Level.NONE
}
val client = OkHttpClient.Builder().addInterceptor(interceptor).build()
val gson = GsonBuilder()
.setLenient()
.create()
.setLenient()
.create()
val retrofit =
Retrofit
.Builder()
.baseUrl("https://mercury.postlight.com")
.baseUrl("https://www.amine-bou.fr")
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
@ -35,6 +34,6 @@ class MercuryApi(private val key: String, shouldLog: Boolean) {
}
fun parseUrl(url: String): Call<ParsedContent> {
return service.parseUrl(url, this.key)
return service.parseUrl(url)
}
}

View File

@ -4,24 +4,27 @@ import android.os.Parcel
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
class ParsedContent(@SerializedName("title") val title: String,
@SerializedName("content") val content: String,
@SerializedName("date_published") val date_published: String,
@SerializedName("lead_image_url") val lead_image_url: String,
@SerializedName("dek") val dek: String,
@SerializedName("url") val url: String,
@SerializedName("domain") val domain: String,
@SerializedName("excerpt") val excerpt: String,
@SerializedName("total_pages") val total_pages: Int,
@SerializedName("rendered_pages") val rendered_pages: Int,
@SerializedName("next_page_url") val next_page_url: String) : Parcelable {
class ParsedContent(
@SerializedName("title") val title: String,
@SerializedName("content") val content: String?,
@SerializedName("date_published") val date_published: String,
@SerializedName("lead_image_url") val lead_image_url: String?,
@SerializedName("dek") val dek: String,
@SerializedName("url") val url: String,
@SerializedName("domain") val domain: String,
@SerializedName("excerpt") val excerpt: String,
@SerializedName("total_pages") val total_pages: Int,
@SerializedName("rendered_pages") val rendered_pages: Int,
@SerializedName("next_page_url") val next_page_url: String
) : Parcelable {
companion object {
@JvmField val CREATOR: Parcelable.Creator<ParsedContent> = object : Parcelable.Creator<ParsedContent> {
override fun createFromParcel(source: Parcel): ParsedContent = ParsedContent(source)
override fun newArray(size: Int): Array<ParsedContent?> = arrayOfNulls(size)
}
@JvmField
val CREATOR: Parcelable.Creator<ParsedContent> =
object : Parcelable.Creator<ParsedContent> {
override fun createFromParcel(source: Parcel): ParsedContent = ParsedContent(source)
override fun newArray(size: Int): Array<ParsedContent?> = arrayOfNulls(size)
}
}
constructor(source: Parcel) : this(

View File

@ -1,14 +1,11 @@
package apps.amine.bou.readerforselfoss.api.mercury
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Query
interface MercuryService {
@GET("parser")
fun parseUrl(@Query("url") url: String, @Header("x-api-key") key: String): Call<ParsedContent>
@GET("parser.php")
fun parseUrl(@Query("link") link: String): Call<ParsedContent>
}

View File

@ -6,11 +6,14 @@ import com.google.gson.JsonElement
import com.google.gson.JsonParseException
import java.lang.reflect.Type
internal class BooleanTypeAdapter : JsonDeserializer<Boolean> {
@Throws(JsonParseException::class)
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Boolean? =
override fun deserialize(
json: JsonElement,
typeOfT: Type,
context: JsonDeserializationContext
): Boolean? =
try {
json.asInt == 1
} catch (e: Exception) {

View File

@ -19,8 +19,12 @@ import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.ConcurrentHashMap
class SelfossApi(c: Context, callingActivity: Activity, isWithSelfSignedCert: Boolean, shouldLog: Boolean) {
class SelfossApi(
c: Context,
callingActivity: Activity,
isWithSelfSignedCert: Boolean,
shouldLog: Boolean
) {
private lateinit var service: SelfossService
private val config: Config = Config(c)
@ -49,7 +53,6 @@ class SelfossApi(c: Context, callingActivity: Activity, isWithSelfSignedCert: Bo
.addInterceptor(AuthenticationCacheInterceptor(authCache))
}
init {
userName = config.userLogin
password = config.userPassword
@ -68,10 +71,11 @@ class SelfossApi(c: Context, callingActivity: Activity, isWithSelfSignedCert: Bo
val logging = HttpLoggingInterceptor()
logging.level = if (shouldLog)
logging.level = if (shouldLog) {
HttpLoggingInterceptor.Level.BODY
else
} else {
HttpLoggingInterceptor.Level.NONE
}
val httpClient = authenticator.getHttpClien(isWithSelfSignedCert)
@ -94,16 +98,41 @@ class SelfossApi(c: Context, callingActivity: Activity, isWithSelfSignedCert: Bo
fun login(): Call<SuccessResponse> =
service.loginToSelfoss(config.userLogin, config.userPassword)
fun readItems(tag: String?, sourceId: Long?, search: String?, itemsNumber: Int, offset: Int): Call<List<Item>> =
fun readItems(
tag: String?,
sourceId: Long?,
search: String?,
itemsNumber: Int,
offset: Int
): Call<List<Item>> =
getItems("read", tag, sourceId, search, itemsNumber, offset)
fun newItems(tag: String?, sourceId: Long?, search: String?, itemsNumber: Int, offset: Int): Call<List<Item>> =
fun newItems(
tag: String?,
sourceId: Long?,
search: String?,
itemsNumber: Int,
offset: Int
): Call<List<Item>> =
getItems("unread", tag, sourceId, search, itemsNumber, offset)
fun starredItems(tag: String?, sourceId: Long?, search: String?, itemsNumber: Int, offset: Int): Call<List<Item>> =
fun starredItems(
tag: String?,
sourceId: Long?,
search: String?,
itemsNumber: Int,
offset: Int
): Call<List<Item>> =
getItems("starred", tag, sourceId, search, itemsNumber, offset)
private fun getItems(type: String, tag: String?, sourceId: Long?, search: String?, items: Int, offset: Int): Call<List<Item>> =
private fun getItems(
type: String,
tag: String?,
sourceId: Long?,
search: String?,
items: Int,
offset: Int
): Call<List<Item>> =
service.getItems(type, tag, sourceId, search, userName, password, items, offset)
fun markItem(itemId: String): Call<SuccessResponse> =
@ -139,7 +168,12 @@ class SelfossApi(c: Context, callingActivity: Activity, isWithSelfSignedCert: Bo
fun spouts(): Call<Map<String, Spout>> =
service.spouts(userName, password)
fun createSource(title: String, url: String, spout: String, tags: String, filter: String): Call<SuccessResponse> =
fun createSource(
title: String,
url: String,
spout: String,
tags: String,
filter: String
): Call<SuccessResponse> =
service.createSource(title, url, spout, tags, filter, userName, password)
}

View File

@ -9,59 +9,70 @@ import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.isEmptyOrNullOrNullString
import com.google.gson.annotations.SerializedName
private fun constructUrl(config: Config?, path: String, file: String): String {
val baseUriBuilder = Uri.parse(config!!.baseUrl).buildUpon()
baseUriBuilder.appendPath(path).appendPath(file)
return if (file.isEmptyOrNullOrNullString()) ""
else baseUriBuilder.toString()
return if (file.isEmptyOrNullOrNullString()) {
""
} else {
baseUriBuilder.toString()
}
}
data class Tag(@SerializedName("tag") val tag: String,
@SerializedName("color") val color: String,
@SerializedName("unread") val unread: Int)
data class Tag(
@SerializedName("tag") val tag: String,
@SerializedName("color") val color: String,
@SerializedName("unread") val unread: Int
)
class SuccessResponse(@SerializedName("success") val success: Boolean) {
val isSuccess: Boolean
get() = success
}
class Stats(@SerializedName("total") val total: Int,
@SerializedName("unread") val unread: Int,
@SerializedName("starred") val starred: Int)
class Stats(
@SerializedName("total") val total: Int,
@SerializedName("unread") val unread: Int,
@SerializedName("starred") val starred: Int
)
data class Spout(@SerializedName("name") val name: String,
@SerializedName("description") val description: String)
data class Spout(
@SerializedName("name") val name: String,
@SerializedName("description") val description: String
)
data class Sources(@SerializedName("id") val id: String,
@SerializedName("title") val title: String,
@SerializedName("tags") val tags: String,
@SerializedName("spout") val spout: String,
@SerializedName("error") val error: String,
@SerializedName("icon") val icon: String) {
data class Sources(
@SerializedName("id") val id: String,
@SerializedName("title") val title: String,
@SerializedName("tags") val tags: String,
@SerializedName("spout") val spout: String,
@SerializedName("error") val error: String,
@SerializedName("icon") val icon: String
) {
var config: Config? = null
fun getIcon(app: Context): String {
if (config == null) {
config = Config(app)
}
return constructUrl(config,"favicons", icon)
return constructUrl(config, "favicons", icon)
}
}
data class Item(@SerializedName("id") val id: String,
@SerializedName("datetime") val datetime: String,
@SerializedName("title") val title: String,
@SerializedName("content") val content: String,
@SerializedName("unread") val unread: Boolean,
@SerializedName("starred") val starred: Boolean,
@SerializedName("thumbnail") val thumbnail: String,
@SerializedName("icon") val icon: String,
@SerializedName("link") val link: String,
@SerializedName("sourcetitle") val sourcetitle: String) : Parcelable {
data class Item(
@SerializedName("id") val id: String,
@SerializedName("datetime") val datetime: String,
@SerializedName("title") val title: String,
@SerializedName("content") val content: String,
@SerializedName("unread") val unread: Boolean,
@SerializedName("starred") var starred: Boolean,
@SerializedName("thumbnail") val thumbnail: String,
@SerializedName("icon") val icon: String,
@SerializedName("link") val link: String,
@SerializedName("sourcetitle") val sourcetitle: String,
@SerializedName("tags") val tags: String
) : Parcelable {
var config: Config? = null
@ -73,16 +84,17 @@ data class Item(@SerializedName("id") val id: String,
}
constructor(source: Parcel) : this(
id = source.readString(),
datetime = source.readString(),
title = source.readString(),
content = source.readString(),
unread = 0.toByte() != source.readByte(),
starred = 0.toByte() != source.readByte(),
thumbnail = source.readString(),
icon = source.readString(),
link = source.readString(),
sourcetitle = source.readString()
id = source.readString(),
datetime = source.readString(),
title = source.readString(),
content = source.readString(),
unread = 0.toByte() != source.readByte(),
starred = 0.toByte() != source.readByte(),
thumbnail = source.readString(),
icon = source.readString(),
link = source.readString(),
sourcetitle = source.readString(),
tags = source.readString()
)
override fun describeContents() = 0
@ -98,6 +110,7 @@ data class Item(@SerializedName("id") val id: String,
dest.writeString(icon)
dest.writeString(link)
dest.writeString(sourcetitle)
dest.writeString(tags)
}
fun getIcon(app: Context): String {
@ -117,15 +130,16 @@ data class Item(@SerializedName("id") val id: String,
// TODO: maybe find a better way to handle these kind of urls
fun getLinkDecoded(): String {
var stringUrl: String
stringUrl = if (link.startsWith("http://news.google.com/news/") || link.startsWith("https://news.google.com/news/")) {
if (link.contains("&amp;url=")) {
link.substringAfter("&amp;url=")
} else {
this.link.replace("&amp;", "&")
}
} else {
this.link.replace("&amp;", "&")
}
stringUrl =
if (link.startsWith("http://news.google.com/news/") || link.startsWith("https://news.google.com/news/")) {
if (link.contains("&amp;url=")) {
link.substringAfter("&amp;url=")
} else {
this.link.replace("&amp;", "&")
}
} else {
this.link.replace("&amp;", "&")
}
// handle :443 => https
if (stringUrl.contains(":443")) {
@ -134,10 +148,9 @@ data class Item(@SerializedName("id") val id: String,
// handle url not starting with http
if (stringUrl.startsWith("//")) {
stringUrl = "http:" + stringUrl
stringUrl = "http:$stringUrl"
}
return stringUrl
}
}

View File

@ -10,97 +10,109 @@ import retrofit2.http.POST
import retrofit2.http.Path
import retrofit2.http.Query
internal interface SelfossService {
@GET("login")
fun loginToSelfoss(@Query("username") username: String, @Query("password") password: String): Call<SuccessResponse>
@GET("items")
fun getItems(@Query("type") type: String,
@Query("tag") tag: String?,
@Query("source") source: Long?,
@Query("search") search: String?,
@Query("username") username: String,
@Query("password") password: String,
@Query("items") items: Int,
@Query("offset") offset: Int): Call<List<Item>>
fun getItems(
@Query("type") type: String,
@Query("tag") tag: String?,
@Query("source") source: Long?,
@Query("search") search: String?,
@Query("username") username: String,
@Query("password") password: String,
@Query("items") items: Int,
@Query("offset") offset: Int
): Call<List<Item>>
@Headers("Content-Type: application/x-www-form-urlencoded")
@POST("mark/{id}")
fun markAsRead(@Path("id") id: String,
@Query("username") username: String,
@Query("password") password: String): Call<SuccessResponse>
fun markAsRead(
@Path("id") id: String,
@Query("username") username: String,
@Query("password") password: String
): Call<SuccessResponse>
@Headers("Content-Type: application/x-www-form-urlencoded")
@POST("unmark/{id}")
fun unmarkAsRead(@Path("id") id: String,
@Query("username") username: String,
@Query("password") password: String): Call<SuccessResponse>
fun unmarkAsRead(
@Path("id") id: String,
@Query("username") username: String,
@Query("password") password: String
): Call<SuccessResponse>
@FormUrlEncoded
@POST("mark")
fun markAllAsRead(@Field("ids[]") ids: List<String>,
@Query("username") username: String,
@Query("password") password: String): Call<SuccessResponse>
fun markAllAsRead(
@Field("ids[]") ids: List<String>,
@Query("username") username: String,
@Query("password") password: String
): Call<SuccessResponse>
@Headers("Content-Type: application/x-www-form-urlencoded")
@POST("starr/{id}")
fun starr(@Path("id") id: String,
@Query("username") username: String,
@Query("password") password: String): Call<SuccessResponse>
fun starr(
@Path("id") id: String,
@Query("username") username: String,
@Query("password") password: String
): Call<SuccessResponse>
@Headers("Content-Type: application/x-www-form-urlencoded")
@POST("unstarr/{id}")
fun unstarr(@Path("id") id: String,
@Query("username") username: String,
@Query("password") password: String): Call<SuccessResponse>
fun unstarr(
@Path("id") id: String,
@Query("username") username: String,
@Query("password") password: String
): Call<SuccessResponse>
@GET("stats")
fun stats(@Query("username") username: String,
@Query("password") password: String): Call<Stats>
fun stats(
@Query("username") username: String,
@Query("password") password: String
): Call<Stats>
@GET("tags")
fun tags(@Query("username") username: String,
@Query("password") password: String): Call<List<Tag>>
fun tags(
@Query("username") username: String,
@Query("password") password: String
): Call<List<Tag>>
@GET("update")
fun update(@Query("username") username: String,
@Query("password") password: String): Call<String>
fun update(
@Query("username") username: String,
@Query("password") password: String
): Call<String>
@GET("sources/spouts")
fun spouts(@Query("username") username: String,
@Query("password") password: String): Call<Map<String, Spout>>
fun spouts(
@Query("username") username: String,
@Query("password") password: String
): Call<Map<String, Spout>>
@GET("sources/list")
fun sources(@Query("username") username: String,
@Query("password") password: String): Call<List<Sources>>
fun sources(
@Query("username") username: String,
@Query("password") password: String
): Call<List<Sources>>
@DELETE("source/{id}")
fun deleteSource(@Path("id") id: String,
@Query("username") username: String,
@Query("password") password: String): Call<SuccessResponse>
fun deleteSource(
@Path("id") id: String,
@Query("username") username: String,
@Query("password") password: String
): Call<SuccessResponse>
@FormUrlEncoded
@POST("source")
fun createSource(@Field("title") title: String,
@Field("url") url: String,
@Field("spout") spout: String,
@Field("tags") tags: String,
@Field("filter") filter: String,
@Query("username") username: String,
@Query("password") password: String): Call<SuccessResponse>
fun createSource(
@Field("title") title: String,
@Field("url") url: String,
@Field("spout") spout: String,
@Field("tags") tags: String,
@Field("filter") filter: String,
@Query("username") username: String,
@Query("password") password: String
): Call<SuccessResponse>
}

View File

@ -0,0 +1,475 @@
package apps.amine.bou.readerforselfoss.fragments
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.res.ColorStateList
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.preference.PreferenceManager
import android.support.customtabs.CustomTabsIntent
import android.support.design.widget.FloatingActionButton
import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat
import android.support.v4.widget.NestedScrollView
import android.support.v7.app.AlertDialog
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.webkit.WebSettings
import apps.amine.bou.readerforselfoss.R
import apps.amine.bou.readerforselfoss.api.mercury.MercuryApi
import apps.amine.bou.readerforselfoss.api.mercury.ParsedContent
import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
import apps.amine.bou.readerforselfoss.utils.isEmptyOrNullOrNullString
import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException
import apps.amine.bou.readerforselfoss.utils.openItemUrl
import apps.amine.bou.readerforselfoss.utils.shareLink
import apps.amine.bou.readerforselfoss.utils.sourceAndDateText
import apps.amine.bou.readerforselfoss.utils.succeeded
import apps.amine.bou.readerforselfoss.utils.toPx
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.github.rubensousa.floatingtoolbar.FloatingToolbar
import kotlinx.android.synthetic.main.fragment_article.view.*
import org.acra.ACRA
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.net.MalformedURLException
import java.net.URL
class ArticleFragment : Fragment() {
private lateinit var pageNumber: Number
private var fontSize: Int = 14
private lateinit var allItems: ArrayList<Item>
private lateinit var mCustomTabActivityHelper: CustomTabActivityHelper
private lateinit var url: String
private lateinit var contentText: String
private lateinit var contentSource: String
private lateinit var contentImage: String
private lateinit var contentTitle: String
private var showMalformedUrl: Boolean = false
private lateinit var editor: SharedPreferences.Editor
private lateinit var fab: FloatingActionButton
private lateinit var appColors: AppColors
override fun onStop() {
super.onStop()
mCustomTabActivityHelper.unbindCustomTabsService(activity)
}
override fun onCreate(savedInstanceState: Bundle?) {
appColors = AppColors(activity!!)
super.onCreate(savedInstanceState)
pageNumber = arguments!!.getInt(ARG_POSITION)
allItems = arguments!!.getParcelableArrayList(ARG_ITEMS)
}
private lateinit var rootView: ViewGroup
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
rootView = inflater
.inflate(R.layout.fragment_article, container, false) as ViewGroup
url = allItems[pageNumber.toInt()].getLinkDecoded()
contentText = allItems[pageNumber.toInt()].content
contentTitle = allItems[pageNumber.toInt()].title
contentImage = allItems[pageNumber.toInt()].getThumbnail(activity!!)
contentSource = allItems[pageNumber.toInt()].sourceAndDateText()
val prefs = PreferenceManager.getDefaultSharedPreferences(activity)
editor = prefs.edit()
fontSize = prefs.getString("reader_font_size", "14").toInt()
showMalformedUrl = prefs.getBoolean("show_error_malformed_url", true)
val settings = activity!!.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
val debugReadingItems = prefs.getBoolean("read_debug", false)
val api = SelfossApi(
context!!,
activity!!,
settings.getBoolean("isSelfSignedCert", false),
prefs.getBoolean("should_log_everything", false)
)
fab = rootView.fab
fab.backgroundTintList = ColorStateList.valueOf(appColors.colorAccent)
fab.rippleColor = appColors.colorAccentDark
val floatingToolbar: FloatingToolbar = rootView.floatingToolbar
floatingToolbar.attachFab(fab)
floatingToolbar.background = ColorDrawable(appColors.colorAccent)
val customTabsIntent = activity!!.buildCustomTabsIntent()
mCustomTabActivityHelper = CustomTabActivityHelper()
mCustomTabActivityHelper.bindCustomTabsService(activity)
floatingToolbar.setClickListener(
object : FloatingToolbar.ItemClickListener {
override fun onItemClick(item: MenuItem) {
when (item.itemId) {
R.id.more_action -> getContentFromMercury(customTabsIntent, prefs)
R.id.share_action -> activity!!.shareLink(url)
R.id.open_action -> activity!!.openItemUrl(
allItems,
pageNumber.toInt(),
url,
customTabsIntent,
false,
false,
activity!!
)
R.id.unread_action -> api.unmarkItem(allItems[pageNumber.toInt()].id).enqueue(
object : Callback<SuccessResponse> {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
if (!response.succeeded() && debugReadingItems) {
val message =
"message: ${response.message()} " +
"response isSuccess: ${response.isSuccessful} " +
"response code: ${response.code()} " +
"response message: ${response.message()} " +
"response errorBody: ${response.errorBody()?.string()} " +
"body success: ${response.body()?.success} " +
"body isSuccess: ${response.body()?.isSuccess}"
ACRA.getErrorReporter().maybeHandleSilentException(Exception(message), activity!!)
}
}
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
if (debugReadingItems) {
ACRA.getErrorReporter().maybeHandleSilentException(t, activity!!)
}
}
}
)
else -> Unit
}
}
override fun onItemLongClick(item: MenuItem?) {
}
}
)
rootView.source.text = contentSource
if (contentText.isEmptyOrNullOrNullString()) {
getContentFromMercury(customTabsIntent, prefs)
} else {
rootView.titleView.text = contentTitle
htmlToWebview(contentText, prefs)
if (!contentImage.isEmptyOrNullOrNullString() && context != null) {
rootView.imageView.visibility = View.VISIBLE
Glide
.with(context!!)
.asBitmap()
.load(contentImage)
.apply(RequestOptions.fitCenterTransform())
.into(rootView.imageView)
} else {
rootView.imageView.visibility = View.GONE
}
}
rootView.nestedScrollView.setOnScrollChangeListener(
NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, oldScrollY ->
if (scrollY > oldScrollY) {
fab.hide()
} else {
if (floatingToolbar.isShowing) floatingToolbar.hide() else fab.show()
}
}
)
return rootView
}
private fun getContentFromMercury(
customTabsIntent: CustomTabsIntent,
prefs: SharedPreferences
) {
rootView.progressBar.visibility = View.VISIBLE
val parser = MercuryApi(
prefs.getBoolean("should_log_everything", false)
)
parser.parseUrl(url).enqueue(
object : Callback<ParsedContent> {
override fun onResponse(
call: Call<ParsedContent>,
response: Response<ParsedContent>
) {
// TODO: clean all the following after finding the mercury content issue
try {
if (response.body() != null && response.body()!!.content != null && !response.body()!!.content.isNullOrEmpty()) {
try {
rootView.titleView.text = response.body()!!.title
url = response.body()!!.url
} catch (e: Exception) {
if (context != null) {
ACRA.getErrorReporter().maybeHandleSilentException(e, context!!)
}
}
try {
htmlToWebview(response.body()!!.content.orEmpty(), prefs)
} catch (e: Exception) {
if (context != null) {
ACRA.getErrorReporter().maybeHandleSilentException(e, context!!)
}
}
try {
if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isNullOrEmpty() && context != null) {
rootView.imageView.visibility = View.VISIBLE
try {
Glide
.with(context!!)
.asBitmap()
.load(response.body()!!.lead_image_url)
.apply(RequestOptions.fitCenterTransform())
.into(rootView.imageView)
} catch (e: Exception) {
ACRA.getErrorReporter().maybeHandleSilentException(e, context!!)
}
} else {
rootView.imageView.visibility = View.GONE
}
} catch (e: Exception) {
if (context != null) {
ACRA.getErrorReporter().maybeHandleSilentException(e, context!!)
}
}
try {
rootView.nestedScrollView.scrollTo(0, 0)
rootView.progressBar.visibility = View.GONE
} catch (e: Exception) {
if (context != null) {
ACRA.getErrorReporter().maybeHandleSilentException(e, context!!)
}
}
} else {
try {
openInBrowserAfterFailing(customTabsIntent)
} catch (e: Exception) {
if (context != null) {
ACRA.getErrorReporter().maybeHandleSilentException(e, context!!)
}
}
}
} catch (e: Exception) {
if (context != null) {
ACRA.getErrorReporter().maybeHandleSilentException(e, context!!)
}
}
}
override fun onFailure(
call: Call<ParsedContent>,
t: Throwable
) = openInBrowserAfterFailing(customTabsIntent)
}
)
}
private fun htmlToWebview(c: String, prefs: SharedPreferences) {
val stringColor = String.format("#%06X", 0xFFFFFF and appColors.colorAccent)
rootView.webcontent.visibility = View.VISIBLE
val (textColor, backgroundColor) = if (appColors.isDarkTheme) {
if (context != null) {
rootView.webcontent.setBackgroundColor(
ContextCompat.getColor(
context!!,
R.color.dark_webview
)
)
Pair(ContextCompat.getColor(context!!, R.color.dark_webview_text), ContextCompat.getColor(context!!, R.color.light_webview_text))
} else {
Pair(null, null)
}
} else {
if (context != null) {
rootView.webcontent.setBackgroundColor(
ContextCompat.getColor(
context!!,
R.color.light_webview
)
)
Pair(ContextCompat.getColor(context!!, R.color.light_webview_text), ContextCompat.getColor(context!!, R.color.dark_webview_text))
} else {
Pair(null, null)
}
}
val stringTextColor: String = if (textColor != null) {
String.format("#%06X", 0xFFFFFF and textColor)
} else {
"#000000"
}
val stringBackgroundColor = if (backgroundColor != null) {
String.format("#%06X", 0xFFFFFF and backgroundColor)
} else {
"#FFFFFF"
}
rootView.webcontent.settings.useWideViewPort = true
rootView.webcontent.settings.loadWithOverviewMode = true
rootView.webcontent.settings.javaScriptEnabled = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
rootView.webcontent.settings.layoutAlgorithm =
WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING
} else {
rootView.webcontent.settings.layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN
}
var baseUrl: String? = null
try {
val itemUrl = URL(url)
baseUrl = itemUrl.protocol + "://" + itemUrl.host
} catch (e: MalformedURLException) {
if (showMalformedUrl && context != null) {
val alertDialog = AlertDialog.Builder(context!!).create()
alertDialog.setTitle("Error")
alertDialog.setMessage("You are encountering a bug that I can't solve. Can you please contact me to solve the issue, please ?")
alertDialog.setButton(
AlertDialog.BUTTON_POSITIVE,
"Send mail"
) { dialog, _ ->
// This won't be translated because it should only be temporary.
val to = Config.feedbackEmail
val subject= "[ReaderForSelfoss MalformedURLException]"
val body= "Please specify the source, item and spout you are using for the url below : \n ${e.message}"
val mailTo = "mailto:" + to + "?&subject=" + Uri.encode(subject) + "&body=" + Uri.encode(body)
val emailIntent = Intent(Intent.ACTION_VIEW)
emailIntent.data = Uri.parse(mailTo)
startActivity(emailIntent)
dialog.dismiss()
}
alertDialog.setButton(
AlertDialog.BUTTON_NEUTRAL,
"Not now"
) { dialog, _ -> dialog.dismiss() }
alertDialog.setButton(
AlertDialog.BUTTON_NEGATIVE,
"Don't show anymore."
) { dialog, _ ->
editor.putBoolean("show_error_malformed_url", false)
editor.apply()
dialog.dismiss()
}
alertDialog.show()
}
}
rootView.webcontent.loadDataWithBaseURL(
baseUrl,
"""<html>
|<head>
| <style>
| img {
| display: inline-block;
| height: auto;
| width: 100%;
| max-width: 100%;
| }
| a {
| color: $stringColor !important;
| }
| *:not(a) {
| color: $stringTextColor;
| }
| * {
| font-size: ${fontSize.toPx}px;
| text-align: justify;
| word-break: break-word;
| overflow:hidden;
| }
| a, pre, code {
| text-align: left;
| }
| pre, code {
| white-space: pre-wrap;
| width:100%;
| background-color: $stringBackgroundColor;
| }
| </style>
|</head>
|<body>
| $c
|</body>""".trimMargin(),
"text/html",
"utf-8",
null
)
}
private fun openInBrowserAfterFailing(customTabsIntent: CustomTabsIntent) {
rootView.progressBar.visibility = View.GONE
activity!!.openItemUrl(
allItems,
pageNumber.toInt(),
url,
customTabsIntent,
true,
false,
activity!!
)
}
companion object {
private const val ARG_POSITION = "position"
private const val ARG_ITEMS = "items"
fun newInstance(
position: Int,
allItems: ArrayList<Item>
): ArticleFragment {
val fragment = ArticleFragment()
val args = Bundle()
args.putInt(ARG_POSITION, position)
args.putParcelableArrayList(ARG_ITEMS, allItems)
fragment.arguments = args
return fragment
}
}
}

View File

@ -1,6 +1,7 @@
package apps.amine.bou.readerforselfoss.settings;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.support.annotation.LayoutRes;
@ -16,23 +17,27 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import apps.amine.bou.readerforselfoss.R;
import com.ftinc.scoop.Scoop;
import apps.amine.bou.readerforselfoss.R;
import apps.amine.bou.readerforselfoss.themes.AppColors;
import apps.amine.bou.readerforselfoss.themes.Toppings;
/**
* A {@link PreferenceActivity} which implements and proxies the necessary calls
* to be used with AppCompat.
*/
public abstract class AppCompatPreferenceActivity extends PreferenceActivity { //NOSONAR
public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
private AppCompatDelegate mDelegate;
@Override
protected void onCreate(Bundle savedInstanceState) {
new AppColors(this);
getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState);
Scoop.getInstance().apply(this);
super.onCreate(savedInstanceState);
}
@ -40,9 +45,16 @@ public abstract class AppCompatPreferenceActivity extends PreferenceActivity { /
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent();
LinearLayout root = (LinearLayout) findViewById(android.R.id.list).getParent().getParent().getParent();
AppBarLayout bar = (AppBarLayout) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
Toolbar toolbar = bar.findViewById(R.id.toolbar);
Scoop scoop = Scoop.getInstance();
scoop.bind(this, Toppings.PRIMARY.getValue(), toolbar);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
scoop.bindStatusBar(this, Toppings.PRIMARY_DARK.getValue());
}
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);

View File

@ -1,8 +1,6 @@
package apps.amine.bou.readerforselfoss.settings;
import java.util.List;
import android.annotation.TargetApi;
import android.content.ClipData;
import android.content.ClipboardManager;
@ -22,15 +20,21 @@ import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.preference.SwitchPreference;
import android.support.v7.app.ActionBar;
import android.text.Editable;
import android.text.InputFilter;
import android.text.Spanned;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
import java.util.List;
import apps.amine.bou.readerforselfoss.BuildConfig;
import apps.amine.bou.readerforselfoss.R;
import apps.amine.bou.readerforselfoss.themes.AppColors;
import apps.amine.bou.readerforselfoss.utils.Config;
import com.ftinc.scoop.ui.ScoopSettingsActivity;
/**
@ -44,7 +48,7 @@ import com.ftinc.scoop.ui.ScoopSettingsActivity;
* href="http://developer.android.com/guide/topics/ui/settings.html">Settings
* API Guide</a> for more information on developing a Settings UI.
*/
public class SettingsActivity extends AppCompatPreferenceActivity { //NOSONAR
public class SettingsActivity extends AppCompatPreferenceActivity {
/**
* A preference value change listener that updates the preference's summary
* to reflect its new value.
@ -90,6 +94,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity { //NOSONAR
@Override
protected void onCreate(Bundle savedInstanceState) {
new AppColors(this);
super.onCreate(savedInstanceState);
setupActionBar();
}
@ -130,8 +135,10 @@ public class SettingsActivity extends AppCompatPreferenceActivity { //NOSONAR
protected boolean isValidFragment(String fragmentName) {
return PreferenceFragment.class.getName().equals(fragmentName)
|| GeneralPreferenceFragment.class.getName().equals(fragmentName)
|| ArticleViewerPreferenceFragment.class.getName().equals(fragmentName)
|| DebugPreferenceFragment.class.getName().equals(fragmentName)
|| LinksPreferenceFragment.class.getName().equals(fragmentName);
|| LinksPreferenceFragment.class.getName().equals(fragmentName)
|| ThemePreferenceFragment.class.getName().equals(fragmentName);
}
/**
@ -150,7 +157,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity { //NOSONAR
final SwitchPreference tabOnTap = (SwitchPreference) findPreference("tab_on_tap");
tabOnTap.setEnabled(!cardViewActive.isChecked());
cardViewActive.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue){
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean isEnabled = (Boolean) newValue;
tabOnTap.setEnabled(!isEnabled);
return true;
@ -159,21 +166,72 @@ public class SettingsActivity extends AppCompatPreferenceActivity { //NOSONAR
EditTextPreference itemsNumber = (EditTextPreference) findPreference("prefer_api_items_number");
itemsNumber.getEditText().setFilters(new InputFilter[]{
new InputFilter (){
new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
int input = Integer.parseInt(dest.toString() + source.toString());
if (input <= 200 && input >0)
return null;
} catch (NumberFormatException nfe) {
Toast.makeText(getActivity(), R.string.items_number_should_be_number, Toast.LENGTH_LONG).show();
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
int input = Integer.parseInt(dest.toString() + source.toString());
if (input <= 200 && input > 0)
return null;
} catch (NumberFormatException nfe) {
Toast.makeText(getActivity(), R.string.items_number_should_be_number, Toast.LENGTH_LONG).show();
}
return "";
}
return "";
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
getActivity().finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class ArticleViewerPreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_viewer);
setHasOptionsMenu(true);
final EditTextPreference fontSize = (EditTextPreference) findPreference("reader_font_size");
fontSize.getEditText().addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
@Override
public void afterTextChanged(Editable editable) {
try {
fontSize.getEditText().setTextSize(Integer.parseInt(editable.toString()));
} catch (NumberFormatException e) {}
}
});
fontSize.getEditText().setFilters(new InputFilter[]{
new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
int input = Integer.parseInt(dest.toString() + source.toString());
if (input > 0)
return null;
} catch (NumberFormatException nfe) {}
return "";
}
}
});
}
@Override
@ -195,7 +253,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity { //NOSONAR
addPreferencesFromResource(R.xml.pref_debug);
setHasOptionsMenu(true);
SharedPreferences pref = getActivity().getSharedPreferences(Config.Companion.getSettingsName(), Context.MODE_PRIVATE);
SharedPreferences pref = getActivity().getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE);
final String id = pref.getString("unique_id", "...");
final Preference identifier = findPreference("debug_identifier");
@ -205,11 +263,14 @@ public class SettingsActivity extends AppCompatPreferenceActivity { //NOSONAR
identifier.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
ClipData clip = ClipData.newPlainText("Selfoss unique id", id);
clipboard.setPrimaryClip(clip);
if (clipboard != null) {
ClipData clip = ClipData.newPlainText("Selfoss unique id", id);
clipboard.setPrimaryClip(clip);
Toast.makeText(getActivity(), R.string.unique_id_to_clipboard, Toast.LENGTH_LONG).show();
return true;
Toast.makeText(getActivity(), R.string.unique_id_to_clipboard, Toast.LENGTH_LONG).show();
return true;
}
return false;
}
});
identifier.setTitle(id);
@ -243,10 +304,10 @@ public class SettingsActivity extends AppCompatPreferenceActivity { //NOSONAR
addPreferencesFromResource(R.xml.pref_links);
setHasOptionsMenu(true);
findPreference( "trackerLink" ).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
findPreference("trackerLink").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
openUrl(Uri.parse(BuildConfig.TRACKER_URL));
openUrl(Uri.parse(Config.trackerUrl));
return true;
}
});
@ -254,7 +315,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity { //NOSONAR
findPreference("sourceLink").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
openUrl(Uri.parse(BuildConfig.SOURCE_URL));
openUrl(Uri.parse(Config.sourceUrl));
return false;
}
});
@ -262,7 +323,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity { //NOSONAR
findPreference("translation").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
openUrl(Uri.parse(BuildConfig.TRANSLATION_URL));
openUrl(Uri.parse(Config.translationUrl));
return false;
}
});
@ -279,14 +340,38 @@ public class SettingsActivity extends AppCompatPreferenceActivity { //NOSONAR
}
}
@Override
public void onHeaderClick(Header header, int position) {
super.onHeaderClick(header, position);
if (header.id == R.id.theme_change) {
Intent intent = ScoopSettingsActivity.createIntent(getApplicationContext());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(intent);
finish();
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class ThemePreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_theme);
setHasOptionsMenu(true);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
getActivity().finish();
return true;
} else if (id == R.id.clear) {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getActivity());
SharedPreferences.Editor editor = pref.edit();
editor.remove("color_primary");
editor.remove("color_primary_dark");
editor.remove("color_accent");
editor.remove("color_accent_dark");
editor.remove("dark_theme");
editor.apply();
getActivity().finish();
}
return super.onOptionsItemSelected(item);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.settings_theme, menu);
}
}

View File

@ -2,50 +2,68 @@ package apps.amine.bou.readerforselfoss.themes
import android.app.Activity
import android.content.Context
import android.preference.PreferenceManager
import android.support.annotation.ColorInt
import android.support.v7.view.ContextThemeWrapper
import android.util.TypedValue
import apps.amine.bou.readerforselfoss.R
import android.view.LayoutInflater
import android.view.ViewGroup
class AppColors(a: Activity) {
@ColorInt val accent: Int
@ColorInt val dark: Int
@ColorInt val primary: Int
@ColorInt val cardBackground: Int
@ColorInt val windowBackground: Int
@ColorInt val colorPrimary: Int
@ColorInt val colorPrimaryDark: Int
@ColorInt val colorAccent: Int
@ColorInt val colorAccentDark: Int
@ColorInt val cardBackgroundColor: Int
@ColorInt val colorBackground: Int
val isDarkTheme: Boolean
init {
val sharedPref = PreferenceManager.getDefaultSharedPreferences(a)
colorPrimary =
sharedPref.getInt(
"color_primary",
a.resources.getColor(R.color.colorPrimary)
)
colorPrimaryDark =
sharedPref.getInt(
"color_primary_dark",
a.resources.getColor(R.color.colorPrimaryDark)
)
colorAccent =
sharedPref.getInt(
"color_accent",
a.resources.getColor(R.color.colorAccent)
)
colorAccentDark =
sharedPref.getInt(
"color_accent_dark",
a.resources.getColor(R.color.colorAccentDark)
)
isDarkTheme =
sharedPref.getBoolean(
"dark_theme",
false
)
colorBackground = if (isDarkTheme) {
a.setTheme(R.style.NoBarDark)
R.color.darkBackground
} else {
a.setTheme(R.style.NoBar)
android.R.color.background_light
}
val wrapper = Context::class.java
val method = wrapper!!.getMethod("getThemeResId")
method.isAccessible = true
isDarkTheme = when(method.invoke(a.baseContext)) {
R.style.NoBarTealOrangeDark,
R.style.NoBarDark,
R.style.NoBarBlueAmberDark,
R.style.NoBarGreyOrangeDark,
R.style.NoBarIndigoPinkDark,
R.style.NoBarRedTealDark,
R.style.NoBarCyanPinkDark -> true
else -> false
}
val typedAccent = TypedValue()
val typedAccentDark = TypedValue()
val typedPrimary = TypedValue()
val typedCardBackground = TypedValue()
val typedWindowBackground = TypedValue()
a.theme.resolveAttribute(R.attr.colorAccent, typedAccent, true)
a.theme.resolveAttribute(R.attr.colorAccent, typedAccent, true)
a.theme.resolveAttribute(R.attr.colorPrimary, typedPrimary, true)
a.theme.resolveAttribute(R.attr.cardBackgroundColor, typedCardBackground, true)
a.theme.resolveAttribute(android.R.attr.colorBackground, typedWindowBackground, true)
accent = typedAccent.data
dark = typedAccentDark.data
primary = typedPrimary.data
cardBackground = typedCardBackground.data
windowBackground = typedWindowBackground.data
cardBackgroundColor = typedCardBackground.data
}
}

View File

@ -0,0 +1,8 @@
package apps.amine.bou.readerforselfoss.themes
enum class Toppings(val value: Int) {
PRIMARY(1),
PRIMARY_DARK(2),
ACCENT(3),
ACCENT_DARK(4)
}

View File

@ -0,0 +1,43 @@
package apps.amine.bou.readerforselfoss.transformers
import android.support.v4.view.ViewPager
import android.view.View
class DepthPageTransformer : ViewPager.PageTransformer {
override fun transformPage(view: View, position: Float) {
val pageWidth = view.width
when {
position < -1 -> // [-Infinity,-1)
// This page is way off-screen to the left.
view.alpha = 0F
position <= 0 -> { // [-1,0]
// Use the default slide transition when moving to the left page
view.alpha = 1F
view.translationX = 0F
view.scaleX = 1F
view.scaleY = 1F
}
position <= 1 -> { // (0,1]
// Fade the page out.
view.alpha = 1 - position
// Counteract the default slide transition
view.translationX = pageWidth * -position
// Scale the page down (between MIN_SCALE and 1)
val scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position))
view.scaleX = scaleFactor
view.scaleY = scaleFactor
}
else -> // (1,+Infinity]
// This page is way off-screen to the right.
view.alpha = 0F
}
}
companion object {
private val MIN_SCALE = 0.75f
}
}

View File

@ -0,0 +1,12 @@
package apps.amine.bou.readerforselfoss.utils
import android.content.Context
import android.preference.PreferenceManager
import org.acra.ErrorReporter
fun ErrorReporter.maybeHandleSilentException(throwable: Throwable, ctx: Context) {
val sharedPref = PreferenceManager.getDefaultSharedPreferences(ctx)
if (sharedPref.getBoolean("acra_should_log", false)) {
this.handleSilentException(throwable)
}
}

View File

@ -2,55 +2,11 @@ package apps.amine.bou.readerforselfoss.utils
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
import android.support.v7.app.AlertDialog
import apps.amine.bou.readerforselfoss.R
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
fun String?.isEmptyOrNullOrNullString(): Boolean =
this == null || this == "null" || this.isEmpty()
fun Context.checkApkVersion(settings: SharedPreferences,
editor: SharedPreferences.Editor,
mFirebaseRemoteConfig: FirebaseRemoteConfig) = {
fun isThereAnUpdate() {
val APK_LINK = "github_apk"
val apkLink = mFirebaseRemoteConfig.getString(APK_LINK)
val storedLink = settings.getString(APK_LINK, "")
if (apkLink != storedLink && !apkLink.isEmpty()) {
val alertDialog = AlertDialog.Builder(this).create()
alertDialog.setTitle(getString(R.string.new_apk_available_title))
alertDialog.setMessage(getString(R.string.new_apk_available_message))
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, getString(R.string.new_apk_available_get)) { _, _ ->
editor.putString(APK_LINK, apkLink)
editor.apply()
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(apkLink))
startActivity(browserIntent)
}
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, getString(R.string.new_apk_available_no),
{ dialog, _ ->
editor.putString(APK_LINK, apkLink)
editor.apply()
dialog.dismiss()
})
alertDialog.show()
}
}
mFirebaseRemoteConfig.fetch(43200)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
mFirebaseRemoteConfig.activateFetched()
}
isThereAnUpdate()
}
}
fun String.longHash(): Long {
var h = 98764321261L
val l = this.length
@ -62,11 +18,12 @@ fun String.longHash(): Long {
return h
}
fun String.toStringUriWithHttp() =
if (!this.startsWith("https://") && !this.startsWith("http://"))
fun String.toStringUriWithHttp(): String =
if (!this.startsWith("https://") && !this.startsWith("http://")) {
"http://" + this
else
} else {
this
}
fun Context.shareLink(itemUrl: String) {
val sendIntent = Intent()
@ -74,5 +31,10 @@ fun Context.shareLink(itemUrl: String) {
sendIntent.action = Intent.ACTION_SEND
sendIntent.putExtra(Intent.EXTRA_TEXT, itemUrl.toStringUriWithHttp())
sendIntent.type = "text/plain"
startActivity(Intent.createChooser(sendIntent, getString(R.string.share)).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
startActivity(
Intent.createChooser(
sendIntent,
getString(R.string.share)
).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
)
}

View File

@ -6,7 +6,6 @@ import android.content.Intent
import android.content.SharedPreferences
import apps.amine.bou.readerforselfoss.LoginActivity
class Config(c: Context) {
val settings: SharedPreferences = c.getSharedPreferences(settingsName, Context.MODE_PRIVATE)
@ -26,21 +25,31 @@ class Config(c: Context) {
val httpUserPassword: String
get() = settings.getString("httpPassword", "")
companion object {
val settingsName = "paramsselfoss"
const val settingsName = "paramsselfoss"
fun logoutAndRedirect(c: Context,
callingActivity: Activity,
editor: SharedPreferences.Editor,
baseUrlFail: Boolean = false): Boolean {
const val feedbackEmail = "aminecmi@gmail.com"
const val translationUrl = "https://crwd.in/readerforselfoss"
const val sourceUrl = "https://github.com/aminecmi/ReaderforSelfoss"
const val trackerUrl = "https://github.com/aminecmi/ReaderforSelfoss/issues"
fun logoutAndRedirect(
c: Context,
callingActivity: Activity,
editor: SharedPreferences.Editor,
baseUrlFail: Boolean = false
): Boolean {
editor.remove("url")
editor.remove("login")
editor.remove("password")
editor.apply()
val intent = Intent(c, LoginActivity::class.java)
if (baseUrlFail)
if (baseUrlFail) {
intent.putExtra("baseUrlFail", baseUrlFail)
}
c.startActivity(intent)
callingActivity.finish()
return true

View File

@ -7,7 +7,7 @@ import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager
fun getUnsafeHttpClient() =
fun getUnsafeHttpClient(): OkHttpClient.Builder =
try {
// Create a trust manager that does not validate certificate chains
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
@ -15,13 +15,18 @@ fun getUnsafeHttpClient() =
arrayOf()
@Throws(CertificateException::class)
override fun checkClientTrusted(chain: Array<java.security.cert.X509Certificate>, authType: String) {
override fun checkClientTrusted(
chain: Array<java.security.cert.X509Certificate>,
authType: String
) {
}
@Throws(CertificateException::class)
override fun checkServerTrusted(chain: Array<java.security.cert.X509Certificate>, authType: String) {
override fun checkServerTrusted(
chain: Array<java.security.cert.X509Certificate>,
authType: String
) {
}
})
// Install the all-trusting trust manager
@ -33,7 +38,6 @@ fun getUnsafeHttpClient() =
OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
.hostnameVerifier { _, _ -> true }
} catch (e: Exception) {
throw RuntimeException(e)
}

View File

@ -1,16 +1,21 @@
package apps.amine.bou.readerforselfoss.utils
import android.content.Context
import android.text.format.DateUtils
import apps.amine.bou.readerforselfoss.api.selfoss.Item
import org.acra.ACRA
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
fun String.toTextDrawableString(): String {
fun String.toTextDrawableString(c: Context): String {
val textDrawable = StringBuilder()
for (s in this.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
textDrawable.append(s[0])
for (s in this.split(" ".toRegex()).filter { !it.isEmpty() }.toTypedArray()) {
try {
textDrawable.append(s[0])
} catch (e: StringIndexOutOfBoundsException) {
ACRA.getErrorReporter().maybeHandleSilentException(e, c)
}
}
return textDrawable.toString()
}
@ -29,4 +34,18 @@ fun Item.sourceAndDateText(): String {
}
return this.sourcetitle + formattedDate
}
}
fun Item.toggleStar(): Item {
this.starred = !this.starred
return this
}
fun List<Item>.flattenTags(): List<Item> =
this.flatMap {
val item = it
val tags: List<String> = it.tags.split(",")
tags.map {
item.copy(tags = it.trim())
}
}

View File

@ -14,15 +14,17 @@ import apps.amine.bou.readerforselfoss.ReaderActivity
import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
import okhttp3.HttpUrl
import xyz.klinker.android.drag_dismiss.DragDismissIntentBuilder
fun Context.buildCustomTabsIntent(): CustomTabsIntent {
val actionIntent = Intent(Intent.ACTION_SEND)
actionIntent.type = "text/plain"
val createPendingShareIntent: PendingIntent = PendingIntent.getActivity(this, 0, actionIntent, 0)
val createPendingShareIntent: PendingIntent = PendingIntent.getActivity(
this,
0,
actionIntent,
0
)
val intentBuilder = CustomTabsIntent.Builder()
@ -32,51 +34,49 @@ fun Context.buildCustomTabsIntent(): CustomTabsIntent {
intentBuilder.setShowTitle(true)
intentBuilder.setStartAnimations(this,
R.anim.slide_in_right,
R.anim.slide_out_left)
intentBuilder.setExitAnimations(this,
android.R.anim.slide_in_left,
android.R.anim.slide_out_right)
intentBuilder.setStartAnimations(
this,
R.anim.slide_in_right,
R.anim.slide_out_left
)
intentBuilder.setExitAnimations(
this,
android.R.anim.slide_in_left,
android.R.anim.slide_out_right
)
val closeicon = BitmapFactory.decodeResource(resources, R.drawable.ic_close_white_24dp)
intentBuilder.setCloseButtonIcon(closeicon)
val shareLabel = this.getString(R.string.label_share)
val icon = BitmapFactory.decodeResource(resources,
R.drawable.ic_share_white_24dp)
val icon = BitmapFactory.decodeResource(
resources,
R.drawable.ic_share_white_24dp
)
intentBuilder.setActionButton(icon, shareLabel, createPendingShareIntent)
return intentBuilder.build()
}
fun Context.openItemUrlInternally(linkDecoded: String,
content: String,
image: String,
title: String,
source: String,
customTabsIntent: CustomTabsIntent,
articleViewer: Boolean,
app: Activity) {
fun Context.openItemUrlInternally(
allItems: ArrayList<Item>,
currentItem: Int,
linkDecoded: String,
customTabsIntent: CustomTabsIntent,
articleViewer: Boolean,
app: Activity
) {
if (articleViewer) {
ReaderActivity.allItems = allItems
val intent = Intent(this, ReaderActivity::class.java)
/*DragDismissIntentBuilder(this)
.setFullscreenOnTablets(true) // defaults to false, tablets will have padding on each side
.setDragElasticity(DragDismissIntentBuilder.DragElasticity.NORMAL) // Larger elasticities will make it easier to dismiss.
.setDrawUnderStatusBar(true)
.build(intent)*/
intent.putExtra("url", linkDecoded)
intent.putExtra("content", content)
intent.putExtra("title", title)
intent.putExtra("image", image)
intent.putExtra("source", source)
intent.putExtra("currentItem", currentItem)
app.startActivity(intent)
} else {
try {
CustomTabActivityHelper.openCustomTab(app, customTabsIntent, Uri.parse(linkDecoded)
CustomTabActivityHelper.openCustomTab(
app,
customTabsIntent,
Uri.parse(linkDecoded)
) { _, uri ->
val intent = Intent(Intent.ACTION_VIEW, uri)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
@ -88,23 +88,34 @@ fun Context.openItemUrlInternally(linkDecoded: String,
}
}
fun Context.openItemUrl(linkDecoded: String,
content: String,
image: String,
title: String,
source: String,
customTabsIntent: CustomTabsIntent,
internalBrowser: Boolean,
articleViewer: Boolean,
app: Activity) {
fun Context.openItemUrl(
allItems: ArrayList<Item>,
currentItem: Int,
linkDecoded: String,
customTabsIntent: CustomTabsIntent,
internalBrowser: Boolean,
articleViewer: Boolean,
app: Activity
) {
if (!linkDecoded.isUrlValid()) {
Toast.makeText(this, this.getString(R.string.cant_open_invalid_url), Toast.LENGTH_LONG).show()
Toast.makeText(
this,
this.getString(R.string.cant_open_invalid_url),
Toast.LENGTH_LONG
).show()
} else {
if (!internalBrowser) {
openInBrowser(linkDecoded, app)
} else {
this.openItemUrlInternally(linkDecoded, content, image, title, source, customTabsIntent, articleViewer, app)
this.openItemUrlInternally(
allItems,
currentItem,
linkDecoded,
customTabsIntent,
articleViewer,
app
)
}
}
}
@ -116,7 +127,7 @@ private fun openInBrowser(linkDecoded: String, app: Activity) {
}
fun String.isUrlValid(): Boolean =
HttpUrl.parse(this) != null && Patterns.WEB_URL.matcher(this).matches()
HttpUrl.parse(this) != null && Patterns.WEB_URL.matcher(this).matches()
fun String.isBaseUrlValid(): Boolean {
val baseUrl = HttpUrl.parse(this)

View File

@ -6,18 +6,40 @@ import android.support.design.widget.FloatingActionButton
import android.util.AttributeSet
import android.view.View
class ScrollAwareFABBehavior(context: Context, attrs: AttributeSet) : CoordinatorLayout.Behavior<FloatingActionButton>() {
class ScrollAwareFABBehavior(
context: Context,
attrs: AttributeSet
) : CoordinatorLayout.Behavior<FloatingActionButton>() {
override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout, child: FloatingActionButton,
directTargetChild: View, target: View, nestedScrollAxes: Int): Boolean {
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: FloatingActionButton,
directTargetChild: View,
target: View,
nestedScrollAxes: Int
): Boolean {
return true
}
override fun onNestedScroll(coordinatorLayout: CoordinatorLayout,
child: FloatingActionButton,
target: View, dxConsumed: Int, dyConsumed: Int,
dxUnconsumed: Int, dyUnconsumed: Int) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed)
override fun onNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: FloatingActionButton,
target: View,
dxConsumed: Int,
dyConsumed: Int,
dxUnconsumed: Int,
dyUnconsumed: Int
) {
super.onNestedScroll(
coordinatorLayout,
child,
target,
dxConsumed,
dyConsumed,
dxUnconsumed,
dyUnconsumed
)
if (dyConsumed > 0 && child.visibility == View.VISIBLE) {
child.hide(object : FloatingActionButton.OnVisibilityChangedListener() {
override fun onHidden(fab: FloatingActionButton?) {
@ -25,7 +47,6 @@ class ScrollAwareFABBehavior(context: Context, attrs: AttributeSet) : Coordinato
fab!!.visibility = View.INVISIBLE
}
})
} else if (dyConsumed < 0 && child.visibility != View.VISIBLE) {
child.show()
}

View File

@ -0,0 +1,9 @@
package apps.amine.bou.readerforselfoss.utils
import android.content.res.Resources
val Int.toPx: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
val Int.toDp: Int
get() = (this / Resources.getSystem().displayMetrics.density).toInt()

View File

@ -2,7 +2,6 @@ package apps.amine.bou.readerforselfoss.utils.bottombar
import com.ashokvarma.bottomnavigation.TextBadgeItem
fun TextBadgeItem.removeBadge(): TextBadgeItem {
this.setText("")
this.hide()
@ -10,7 +9,4 @@ fun TextBadgeItem.removeBadge(): TextBadgeItem {
}
fun TextBadgeItem.maybeShow(): TextBadgeItem =
if (this.isHidden)
this.show()
else
this
if (this.isHidden) this.show() else this

View File

@ -1,8 +1,6 @@
package apps.amine.bou.readerforselfoss.utils.customtabs;
import java.util.List;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
@ -11,6 +9,8 @@ import android.support.customtabs.CustomTabsIntent;
import android.support.customtabs.CustomTabsServiceConnection;
import android.support.customtabs.CustomTabsSession;
import java.util.List;
/**
* This is a helper class to manage the connection to the Custom Tabs Service.
*/
@ -23,15 +23,15 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
/**
* Opens the URL on a Custom Tab if possible. Otherwise fallsback to opening it on a WebView.
*
* @param activity The host activity.
* @param activity The host activity.
* @param customTabsIntent a CustomTabsIntent to be used if Custom Tabs is available.
* @param uri the Uri to be opened.
* @param fallback a CustomTabFallback to be used if Custom Tabs is not available.
* @param uri the Uri to be opened.
* @param fallback a CustomTabFallback to be used if Custom Tabs is not available.
*/
public static void openCustomTab(Activity activity,
CustomTabsIntent customTabsIntent,
Uri uri,
CustomTabFallback fallback) {
CustomTabsIntent customTabsIntent,
Uri uri,
CustomTabFallback fallback) {
String packageName = CustomTabsHelper.getPackageNameToUse(activity);
//If we cant find a package name, it means theres no browser that supports
@ -48,6 +48,7 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
/**
* Unbinds the Activity from the Custom Tabs Service.
*
* @param activity the activity that is connected to the service.
*/
public void unbindCustomTabsService(Activity activity) {
@ -74,6 +75,7 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
/**
* Register a Callback to be called when connected or disconnected from the Custom Tabs Service.
*
* @param connectionCallback
*/
public void setConnectionCallback(ConnectionCallback connectionCallback) {
@ -82,6 +84,7 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
/**
* Binds the Activity to the Custom Tabs Service.
*
* @param activity the activity to be binded to the service.
*/
public void bindCustomTabsService(Activity activity) {
@ -95,16 +98,15 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
}
/**
* @see {@link CustomTabsSession#mayLaunchUrl(Uri, Bundle, List)}.
* @return true if call to mayLaunchUrl was accepted.
* @see {@link CustomTabsSession#mayLaunchUrl(Uri, Bundle, List)}.
*/
public boolean mayLaunchUrl(Uri uri, Bundle extras, List<Bundle> otherLikelyBundles) {
if (mClient == null) return false;
CustomTabsSession session = getSession();
if (session == null) return false;
return session != null && session.mayLaunchUrl(uri, extras, otherLikelyBundles);
return session.mayLaunchUrl(uri, extras, otherLikelyBundles);
}
@Override
@ -142,9 +144,8 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
*/
public interface CustomTabFallback {
/**
*
* @param activity The Activity that wants to open the Uri.
* @param uri The uri to be opened by the fallback.
* @param uri The uri to be opened by the fallback.
*/
void openUri(Activity activity, Uri uri);
}

View File

@ -1,9 +1,6 @@
package apps.amine.bou.readerforselfoss.utils.customtabs;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@ -14,6 +11,9 @@ import android.support.customtabs.CustomTabsService;
import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import apps.amine.bou.readerforselfoss.utils.customtabs.helpers.KeepAliveService;
@SuppressWarnings("ALL")
@ -28,7 +28,8 @@ class CustomTabsHelper {
private static String sPackageNameToUse;
private CustomTabsHelper() {}
private CustomTabsHelper() {
}
public static void addKeepAliveExtra(Context context, Intent intent) {
Intent keepAliveIntent = new Intent().setClassName(
@ -40,7 +41,7 @@ class CustomTabsHelper {
* Goes through all apps that handle VIEW intents and have a warmup service. Picks
* the one chosen by the user if there is one, otherwise makes a best effort to return a
* valid package name.
*
* <p>
* This is <strong>not</strong> threadsafe.
*
* @param context {@link Context} to use for accessing {@link PackageManager}.
@ -94,6 +95,7 @@ class CustomTabsHelper {
/**
* Used to check whether there is a specialized handler for a given intent.
*
* @param intent The intent to check with.
* @return Whether there is a specialized handler for the given intent.
*/

View File

@ -1,12 +1,12 @@
package apps.amine.bou.readerforselfoss.utils.customtabs;
import java.lang.ref.WeakReference;
import android.content.ComponentName;
import android.support.customtabs.CustomTabsClient;
import android.support.customtabs.CustomTabsServiceConnection;
import java.lang.ref.WeakReference;
/**
* Implementation for the CustomTabsServiceConnection that avoids leaking the
* ServiceConnectionCallback

View File

@ -7,6 +7,7 @@ import android.support.customtabs.CustomTabsClient;
public interface ServiceConnectionCallback {
/**
* Called when the service is connected.
*
* @param client a CustomTabsClient
*/
void onServiceConnected(CustomTabsClient client);

View File

@ -8,8 +8,6 @@ import android.widget.TextView
import apps.amine.bou.readerforselfoss.R
open class CustomBaseViewHolder(var view: View) : RecyclerView.ViewHolder(view) {
var icon: ImageView = view.findViewById(R.id.material_drawer_icon)
var name: TextView = view.findViewById(R.id.material_drawer_name)

View File

@ -15,9 +15,8 @@ import com.mikepenz.materialdrawer.util.DrawerImageLoader
import com.mikepenz.materialdrawer.util.DrawerUIUtils
import com.mikepenz.materialize.util.UIUtils
abstract class CustomUrlBasePrimaryDrawerItem<T, VH : RecyclerView.ViewHolder> : BaseDrawerItem<T, VH>() {
abstract class CustomUrlBasePrimaryDrawerItem<T, VH : RecyclerView.ViewHolder> :
BaseDrawerItem<T, VH>() {
fun withIcon(url: String): T {
this.icon = ImageHolder(url)
return this as T
@ -77,7 +76,10 @@ abstract class CustomUrlBasePrimaryDrawerItem<T, VH : RecyclerView.ViewHolder> :
val selectedIconColor = getSelectedIconColor(ctx)
//set the background for the item
UIUtils.setBackground(viewHolder.view, UIUtils.getSelectableBackground(ctx, selectedColor, true))
UIUtils.setBackground(
viewHolder.view,
UIUtils.getSelectableBackground(ctx, selectedColor, true)
)
//set the text for the name
StringHolder.applyTo(this.getName(), viewHolder.name)
//set the text for the description or hide
@ -86,8 +88,11 @@ abstract class CustomUrlBasePrimaryDrawerItem<T, VH : RecyclerView.ViewHolder> :
//set the colors for textViews
viewHolder.name.setTextColor(getTextColorStateList(color, selectedTextColor))
//set the description text color
ColorHolder.applyToOr(descriptionTextColor,
viewHolder.description, getTextColorStateList(color, selectedTextColor))
ColorHolder.applyToOr(
descriptionTextColor,
viewHolder.description,
getTextColorStateList(color, selectedTextColor)
)
//define the typeface for our textViews
if (getTypeface() != null) {

View File

@ -10,8 +10,9 @@ import com.mikepenz.materialdrawer.holder.BadgeStyle
import com.mikepenz.materialdrawer.holder.StringHolder
import com.mikepenz.materialdrawer.model.interfaces.ColorfulBadgeable
class CustomUrlPrimaryDrawerItem : CustomUrlBasePrimaryDrawerItem<CustomUrlPrimaryDrawerItem, CustomUrlPrimaryDrawerItem.ViewHolder>(), ColorfulBadgeable<CustomUrlPrimaryDrawerItem> {
class CustomUrlPrimaryDrawerItem :
CustomUrlBasePrimaryDrawerItem<CustomUrlPrimaryDrawerItem, CustomUrlPrimaryDrawerItem.ViewHolder>(),
ColorfulBadgeable<CustomUrlPrimaryDrawerItem> {
protected var mBadge: StringHolder = StringHolder("")
protected var mBadgeStyle = BadgeStyle()
@ -64,7 +65,10 @@ class CustomUrlPrimaryDrawerItem : CustomUrlBasePrimaryDrawerItem<CustomUrlPrima
val badgeVisible = StringHolder.applyToOrHide(mBadge, viewHolder.badge)
//style the badge if it is visible
if (badgeVisible) {
mBadgeStyle.style(viewHolder.badge, getTextColorStateList(getColor(ctx), getSelectedTextColor(ctx)))
mBadgeStyle.style(
viewHolder.badge,
getTextColorStateList(getColor(ctx), getSelectedTextColor(ctx))
)
viewHolder.badgeContainer.visibility = View.VISIBLE
} else {
viewHolder.badgeContainer.visibility = View.GONE
@ -86,6 +90,5 @@ class CustomUrlPrimaryDrawerItem : CustomUrlBasePrimaryDrawerItem<CustomUrlPrima
class ViewHolder(view: View) : CustomBaseViewHolder(view) {
val badgeContainer: View = view.findViewById(R.id.material_drawer_badge_container)
val badge: TextView = view.findViewById(R.id.material_drawer_badge)
}
}

View File

@ -8,21 +8,31 @@ import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.BitmapImageViewTarget
fun Context.bitmapCenterCrop(url: String, iv: ImageView) =
Glide.with(this).asBitmap().load(url).apply(RequestOptions.centerCropTransform()).into(iv)
Glide.with(this)
.asBitmap()
.load(url)
.apply(RequestOptions.centerCropTransform())
.into(iv)
fun Context.bitmapFitCenter(url: String, iv: ImageView) =
Glide.with(this).asBitmap().load(url).apply(RequestOptions.fitCenterTransform()).into(iv)
Glide.with(this)
.asBitmap()
.load(url)
.apply(RequestOptions.fitCenterTransform())
.into(iv)
fun Context.circularBitmapDrawable(url: String, iv: ImageView) =
Glide.with(this)
.asBitmap()
.load(url)
.apply(RequestOptions.centerCropTransform()).
into(object : BitmapImageViewTarget(iv) {
.apply(RequestOptions.centerCropTransform())
.into(object : BitmapImageViewTarget(iv) {
override fun setResource(resource: Bitmap?) {
val circularBitmapDrawable = RoundedBitmapDrawableFactory.create(resources, resource)
val circularBitmapDrawable = RoundedBitmapDrawableFactory.create(
resources,
resource
)
circularBitmapDrawable.isCircular = true
iv.setImageDrawable(circularBitmapDrawable)
}

View File

@ -10,10 +10,10 @@ import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.module.GlideModule
import java.io.InputStream
class SelfSignedGlideModule : GlideModule {
override fun applyOptions(context: Context?, builder: GlideBuilder?) {}
override fun applyOptions(context: Context?, builder: GlideBuilder?) {
}
override fun registerComponents(context: Context?, glide: Glide?, registry: Registry?) {
@ -22,11 +22,12 @@ class SelfSignedGlideModule : GlideModule {
if (pref.getBoolean("isSelfSignedCert", false)) {
val client = getUnsafeHttpClient().build()
registry?.append(GlideUrl::class.java, InputStream::class.java,
com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader.Factory(client))
registry?.append(
GlideUrl::class.java,
InputStream::class.java,
com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader.Factory(client)
)
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 986 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,36 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
<ScrollView xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="apps.amine.bou.readerforselfoss.AddSourceActivity"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
tools:context="apps.amine.bou.readerforselfoss.AddSourceActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:theme="@style/ToolBarStyle"
app:popupTheme="?attr/toolbarPopupTheme" />
</android.support.design.widget.AppBarLayout>
<android.support.constraint.ConstraintLayout
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.constraint.ConstraintLayout
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:theme="@style/ToolBarStyle"
app:popupTheme="?attr/toolbarPopupTheme" />
</android.support.design.widget.AppBarLayout>
<android.support.constraint.ConstraintLayout
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:layout_height="match_parent"
android:layout_width="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
@ -119,19 +120,20 @@
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="16dp"
app:layout_constraintVertical_bias="0.0"/>
</android.support.constraint.ConstraintLayout>
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progress"
app:layout_constraintTop_toTopOf="parent"
style="?android:attr/progressBarStyleLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="visible"/>
app:layout_constraintTop_toTopOf="parent"
tools:visibility="gone" />
</android.support.constraint.ConstraintLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -88,12 +88,14 @@
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:background="@color/transparent"
android:visibility="gone" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/transparent"
android:clipToPadding="false"
android:paddingBottom="60dp"
android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</LinearLayout>

View File

@ -115,6 +115,7 @@
android:visibility="gone">
<EditText
android:inputType="text"
android:id="@+id/httpLoginView"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -1,148 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.NestedScrollView
android:id="@+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="200dp"
android:scaleType="centerCrop"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="@+id/source"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textSize="12sp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
<TextView
android:id="@+id/titleView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="6dp"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:textStyle="bold"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/source" />
<TextView
android:id="@+id/content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:paddingBottom="48dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleView"
android:textColorLink="?attr/colorAccent"/>
<!--<org.sufficientlysecure.htmltextview.HtmlTextView
android:id="@+id/content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:paddingBottom="48dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleView" />-->
</android.support.constraint.ConstraintLayout>
</android.support.v4.widget.NestedScrollView>
<FrameLayout
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_gravity="end|bottom|right">
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.github.rubensousa.floatingtoolbar.FloatingToolbar
android:id="@+id/floatingToolbar"
<android.support.v7.widget.Toolbar
android:id="@+id/toolBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
app:floatingItemBackground="?attr/colorAccent"
app:floatingMenu="@menu/reader_toolbar" />
app:popupTheme="?attr/toolbarPopupTheme"
app:theme="@style/ToolBarStyle" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_gravity="end|bottom|right"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:src="@drawable/ic_add"
app:backgroundTint="?attr/colorAccent"
app:fabSize="mini"
app:rippleColor="?attr/colorAccentDark" />
</FrameLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/progressBar"
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:animateLayoutChanges="true"
android:alpha="0.8"
android:background="@color/black"
android:clickable="false">
android:layout_height="0dp"
android:paddingTop="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appBarLayout" />
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:progressTint="?attr/colorAccent" />
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
<me.relex.circleindicator.CircleIndicator
android:id="@+id/indicator"
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="#55000000"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/pager" />
</android.support.constraint.ConstraintLayout>

View File

@ -1,13 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="apps.amine.bou.readerforselfoss.SourcesActivity"
xmlns:fab="http://schemas.android.com/apk/res-auto">
tools:context="apps.amine.bou.readerforselfoss.SourcesActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
@ -35,7 +33,6 @@
android:layout_height="wrap_content"
android:layout_gravity="end|bottom|right"
android:src="@drawable/ic_add"
android:tint="?android:textColorPrimary"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:layout_alignParentBottom="true"

View File

@ -0,0 +1,126 @@
<android.support.design.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:descendantFocusability="blocksDescendants">
<android.support.v4.widget.NestedScrollView
android:id="@+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="200dp"
android:scaleType="centerCrop"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="@+id/source"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textSize="12sp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleView" />
<TextView
android:id="@+id/titleView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:textStyle="bold"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
<WebView
android:id="@+id/webcontent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColorLink="?attr/colorAccent"
android:visibility="gone"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="24dp"
android:paddingBottom="48dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/source"
tools:visibility="visible" />
</android.support.constraint.ConstraintLayout>
</android.support.v4.widget.NestedScrollView>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_gravity="end|bottom|right">
<com.github.rubensousa.floatingtoolbar.FloatingToolbar
android:id="@+id/floatingToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
app:floatingMenu="@menu/reader_toolbar" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom|right"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:src="@drawable/ic_add"
app:backgroundTint="?attr/colorAccent"
app:fabSize="mini"
app:rippleColor="?attr/colorAccentDark" />
</FrameLayout>
<FrameLayout
android:id="@+id/progressBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:animateLayoutChanges="true"
android:alpha="0.8"
android:background="@color/black"
android:clickable="false">
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:progressTint="?attr/colorAccent" />
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>

View File

@ -1,55 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.constraint.ConstraintLayout 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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="88dp">
<ImageView
android:id="@+id/itemImage"
android:layout_width="88dp"
android:layout_height="88dp"
android:src="@color/about_libraries_accent"
app:layout_constraintBottom_toTopOf="@+id/actionBar"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
app:layout_constraintBottom_toBottomOf="@+id/actionBar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginTop="8dp"
android:ellipsize="end"
android:fontFamily="sans-serif"
android:gravity="start"
android:maxLines="3"
android:textAlignment="viewStart"
android:textAllCaps="false"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toRightOf="@+id/itemImage"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toEndOf="@+id/itemImage"
app:layout_constraintTop_toTopOf="parent"
tools:text="Titre" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/sourceTitleAndDate"
android:textSize="14sp"
tools:text="Google Actualité Il y a 5h"
android:textAlignment="viewStart"
app:layout_constraintTop_toBottomOf="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
app:layout_constraintLeft_toLeftOf="@+id/title"
android:gravity="start" />
android:gravity="start"
android:textAlignment="viewStart"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="@+id/actionBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/itemImage"
app:layout_constraintTop_toBottomOf="@+id/title"
tools:text="Google Actualité Il y a 5h" />
<RelativeLayout
android:id="@+id/actionBar"
@ -58,9 +61,9 @@
android:background="#BBBBBB"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sourceTitleAndDate">
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:visibility="visible">
<com.like.LikeButton
android:id="@+id/favButton"
@ -68,7 +71,6 @@
android:layout_height="35dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
@ -110,7 +112,7 @@
android:padding="4dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_open_in_browser_black_24dp" />
</RelativeLayout>
</android.support.constraint.ConstraintLayout>

View File

@ -12,7 +12,7 @@
android:icon="@drawable/ic_done_all_white_24dp"
android:title="@string/readAll"
android:orderInCategory="1"
app:showAsAction="ifRoom"/>
app:showAsAction="always"/>
<item
android:id="@+id/refresh"
@ -20,11 +20,6 @@
android:orderInCategory="99"
android:title="@string/menu_home_refresh" />
<item
android:id="@+id/action_share_the_app"
android:orderInCategory="102"
android:title="@string/menu_share_the_app" />
<item android:id="@+id/action_disconnect"
android:title="@string/action_disconnect"
android:orderInCategory="104"

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/unsave"
android:icon="@drawable/heart_on"
android:title="@string/remove_to_favs_reader"
android:visible="true"
app:showAsAction="ifRoom" />
<item
android:id="@+id/save"
android:icon="@drawable/heart_off"
android:title="@string/add_to_favs_reader"
android:visible="true"
app:showAsAction="ifRoom" />
</menu>

View File

@ -1,8 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/unread_action"
android:icon="@drawable/ic_fiber_new"
android:title="@string/unmark"
app:showAsAction="ifRoom" />
<item
android:id="@+id/more_action"
android:icon="@drawable/ic_chrome_reader_mode"

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/clear"
android:icon="@drawable/ic_history"
android:title="@string/drawer_action_clear"
app:showAsAction="ifRoom" />
</menu>

View File

@ -64,7 +64,6 @@
<string name="switch_unread_count">"Display the unread count as a badge for the bottom bar."</string>
<string name="switch_unread_count_title">"Display unread count"</string>
<string name="display_all_counts_title">"Display count for favorite and read"</string>
<string name="menu_share_the_app">"Invite friends"</string>
<string name="invitation_title">"Try this app for your Selfoss RSS feeds !"</string>
<string name="invitation_message">"I use this app for my Selfoss RSS feeds. You may like it too !"</string>
<string name="invitation_cta">"Try the app"</string>
@ -75,7 +74,7 @@
<string name="prefer_article_viewer_title">"Use the article viewer"</string>
<string name="prefer_article_viewer_on">"Will use the article viewer instead of the internal browser"</string>
<string name="prefer_article_viewer_off">"Will use the internal browser instead of the article viewer"</string>
<string name="pref_general_category_links">"Link handeling"</string>
<string name="pref_general_category_links">"Link handling"</string>
<string name="pref_general_category_displaying">"Displaying"</string>
<string name="pref_general_category_actions">"Actions"</string>
<string name="pref_switch_card_view_on">"The articles will be displayed as cards"</string>
@ -118,19 +117,7 @@
<string name="base_url_error">There was an issue when trying to communicate with your Selfoss Instance. If the issue persists, please get in touch with me.</string>
<string name="pref_header_theme">Themes</string>
<string name="default_theme">Default</string>
<string name="teal_orange_theme">Teal/Orange/Light</string>
<string name="cyan_pink_theme">Cyan/Pink/Light</string>
<string name="grey_orange_theme">Grey/Orange/Light</string>
<string name="blue_amber_theme">Blue/Amber/Light</string>
<string name="indigo_pink_theme">Indigo/Pink/Light</string>
<string name="red_teal_theme">Red/Teal/Light</string>
<string name="teal_orange_dark_theme">Teal/Orange/Dark</string>
<string name="cyan_pink_dark_theme">Cyan/Pink/Dark</string>
<string name="default_dark_theme">Default/Dark</string>
<string name="grey_orange_dark_theme">Grey/Orange/Dark</string>
<string name="blue_amber_dark_theme">Blue/Amber/Dark</string>
<string name="indigo_pink_dark_theme">Indigo/Pink/Dark</string>
<string name="red_teal_dark_theme">Red/Teal/Dark</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activate to log login errors</string>
<string name="login_debug_on">Any error on the login page will be logged</string>
@ -140,6 +127,7 @@
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="pref_hidden_tags">Hidden Tags</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
@ -150,7 +138,7 @@
<string name="login_everything_title">Logging every api calls</string>
<string name="login_everything_on">This will log every api call for debug purpose.</string>
<string name="login_everything_off">No api call will be logged</string>
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
<string name="translation">Translation</string>
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
<string name="drawer_report_bug">Report a bug</string>
@ -158,4 +146,27 @@
<string name="reader_action_more">Read more</string>
<string name="reader_action_open">Open in browser</string>
<string name="reader_action_share">Share</string>
<string name="pref_switch_actions_pager_scroll_on">Mark articles as read when swiping between articles.</string>
<string name="add_to_favs_reader">Add to favorites</string>
<string name="remove_to_favs_reader">Remove from favorites</string>
<string name="pref_content_reader_font_size">Article reader content font size</string>
<string name="pref_header_viewer">Article viewer</string>
<string name="refresh_dialog_message">This will refresh your Selfoss instance.</string>
<string name="markall_dialog_message">This will mark all the items as read.</string>
<string name="pref_switch_actions_pager_scroll">Mark as read on swipe</string>
<string name="pref_switch_actions_pager_scroll_off">Don\'t mark articles as read when swiping.</string>
<string name="gdpr_dialog_message">The app does not collect any personal data. Every analytics tools were removed. Crash reports sending is now optional, as is the debug logging. Keep in mind that debugging and crash reports are essential for the app development (You can configure everything in Settings &gt; Debug).</string>
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
<string name="crash_dialog_text">Something went wrong. Please send the report to the developer.</string>
<string name="crash_dialog_comment">You can add any helpful details in the comment bellow. Don\'t include any personal data in your comment. You could send me and email with your debug id, and I\'ll keep you posted when the issue is resolved.</string>
<string name="pref_acra_user_email">Contact email</string>
<string name="pref_acra_user_email_summary">Add an email so I can contact you about the crash reports you send.</string>
<string name="pref_acra_alwaysaccept">Automatically send crash reports</string>
<string name="pref_acra_alwaysaccept_enabled">Will send crash reports automatically</string>
<string name="pref_acra_alwaysaccept_disabled">Will ask everytime when sending crash reports.</string>
<string name="pref_debug_crash_reports">Crash reports</string>
<string name="pref_debug_debug_logs">Debug logging (these will be sent without a dialog)</string>
<string name="acra_login">Enable logging</string>
<string name="drawer_item_hidden_tags">Hidden Tags</string>
<string name="unmark">Mark item as unread</string>
</resources>

View File

@ -64,7 +64,6 @@
<string name="switch_unread_count">"Display the unread count as a badge for the bottom bar."</string>
<string name="switch_unread_count_title">"Display unread count"</string>
<string name="display_all_counts_title">"Display count for favorite and read"</string>
<string name="menu_share_the_app">"Invite friends"</string>
<string name="invitation_title">"Try this app for your Selfoss RSS feeds !"</string>
<string name="invitation_message">"I use this app for my Selfoss RSS feeds. You may like it too !"</string>
<string name="invitation_cta">"Try the app"</string>
@ -75,7 +74,7 @@
<string name="prefer_article_viewer_title">"Use the article viewer"</string>
<string name="prefer_article_viewer_on">"Will use the article viewer instead of the internal browser"</string>
<string name="prefer_article_viewer_off">"Will use the internal browser instead of the article viewer"</string>
<string name="pref_general_category_links">"Link handeling"</string>
<string name="pref_general_category_links">"Link handling"</string>
<string name="pref_general_category_displaying">"Displaying"</string>
<string name="pref_general_category_actions">"Actions"</string>
<string name="pref_switch_card_view_on">"The articles will be displayed as cards"</string>
@ -118,19 +117,7 @@
<string name="base_url_error">There was an issue when trying to communicate with your Selfoss Instance. If the issue persists, please get in touch with me.</string>
<string name="pref_header_theme">Themes</string>
<string name="default_theme">Default</string>
<string name="teal_orange_theme">Teal/Orange/Light</string>
<string name="cyan_pink_theme">Cyan/Pink/Light</string>
<string name="grey_orange_theme">Grey/Orange/Light</string>
<string name="blue_amber_theme">Blue/Amber/Light</string>
<string name="indigo_pink_theme">Indigo/Pink/Light</string>
<string name="red_teal_theme">Red/Teal/Light</string>
<string name="teal_orange_dark_theme">Teal/Orange/Dark</string>
<string name="cyan_pink_dark_theme">Cyan/Pink/Dark</string>
<string name="default_dark_theme">Default/Dark</string>
<string name="grey_orange_dark_theme">Grey/Orange/Dark</string>
<string name="blue_amber_dark_theme">Blue/Amber/Dark</string>
<string name="indigo_pink_dark_theme">Indigo/Pink/Dark</string>
<string name="red_teal_dark_theme">Red/Teal/Dark</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activate to log login errors</string>
<string name="login_debug_on">Any error on the login page will be logged</string>
@ -140,6 +127,7 @@
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="pref_hidden_tags">Hidden Tags</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
@ -150,7 +138,7 @@
<string name="login_everything_title">Logging every api calls</string>
<string name="login_everything_on">This will log every api call for debug purpose.</string>
<string name="login_everything_off">No api call will be logged</string>
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
<string name="translation">Translation</string>
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
<string name="drawer_report_bug">Report a bug</string>
@ -158,4 +146,27 @@
<string name="reader_action_more">Read more</string>
<string name="reader_action_open">Open in browser</string>
<string name="reader_action_share">Share</string>
<string name="pref_switch_actions_pager_scroll_on">Mark articles as read when swiping between articles.</string>
<string name="add_to_favs_reader">Add to favorites</string>
<string name="remove_to_favs_reader">Remove from favorites</string>
<string name="pref_content_reader_font_size">Article reader content font size</string>
<string name="pref_header_viewer">Article viewer</string>
<string name="refresh_dialog_message">This will refresh your Selfoss instance.</string>
<string name="markall_dialog_message">This will mark all the items as read.</string>
<string name="pref_switch_actions_pager_scroll">Mark as read on swipe</string>
<string name="pref_switch_actions_pager_scroll_off">Don\'t mark articles as read when swiping.</string>
<string name="gdpr_dialog_message">The app does not collect any personal data. Every analytics tools were removed. Crash reports sending is now optional, as is the debug logging. Keep in mind that debugging and crash reports are essential for the app development (You can configure everything in Settings &gt; Debug).</string>
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
<string name="crash_dialog_text">Something went wrong. Please send the report to the developer.</string>
<string name="crash_dialog_comment">You can add any helpful details in the comment bellow. Don\'t include any personal data in your comment. You could send me and email with your debug id, and I\'ll keep you posted when the issue is resolved.</string>
<string name="pref_acra_user_email">Contact email</string>
<string name="pref_acra_user_email_summary">Add an email so I can contact you about the crash reports you send.</string>
<string name="pref_acra_alwaysaccept">Automatically send crash reports</string>
<string name="pref_acra_alwaysaccept_enabled">Will send crash reports automatically</string>
<string name="pref_acra_alwaysaccept_disabled">Will ask everytime when sending crash reports.</string>
<string name="pref_debug_crash_reports">Crash reports</string>
<string name="pref_debug_debug_logs">Debug logging (these will be sent without a dialog)</string>
<string name="acra_login">Enable logging</string>
<string name="drawer_item_hidden_tags">Hidden Tags</string>
<string name="unmark">Mark item as unread</string>
</resources>

View File

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">"Lector per a Selfoss"</string>
<string name="title_activity_login">"Inicia la sessió"</string>
<string name="prompt_password">"Contrasenya"</string>
<string name="prompt_http_password">"Contrasenya HTTP"</string>
<string name="action_sign_in">"Vés-hi"</string>
<string name="error_invalid_password">"La contrasenya és massa curta"</string>
<string name="error_field_required">"Camp necessari"</string>
<string name="prompt_url">"URL"</string>
<string name="withLoginSwitch">"Autenticació (si és necessària)"</string>
<string name="withHttpLoginSwitch">"Autenticació HTTP (si és necessària)"</string>
<string name="login_url_problem">"Pot ser que falti una \"/\" al final de l'url."</string>
<string name="prompt_login">"Nom d'usuari"</string>
<string name="prompt_http_login">"Nom d'usuari HTTP"</string>
<string name="label_share">"Comparteix"</string>
<string name="readAll">"Llegeix-ho tot"</string>
<string name="action_disconnect">"Desconnecta't"</string>
<string name="title_activity_settings">"Configuració"</string>
<string name="pref_header_general">"General"</string>
<string name="pref_switch_actions_tap_title">"Fer un toc als articles"</string>
<string name="add_source_hint_tags">"Etiqueta1, Etiqueta2, Etiqueta3"</string>
<string name="add_source_hint_url">"Enllaç"</string>
<string name="add_source_hint_name">"Nom"</string>
<string name="add_source">"Afegeix una font"</string>
<string name="add_source_save">"Desa"</string>
<string name="wrong_infos">"Torneu a comprovar la informació."</string>
<string name="all_posts_not_read">"No s'han llegit totes les publicacions"</string>
<string name="all_posts_read">"S'han llegit totes les publicacions"</string>
<string name="cant_get_favs">"No es poden obtenir preferits"</string>
<string name="cant_get_new_elements">"No es pot accedir als articles nous"</string>
<string name="cant_get_read">"No es poden llegir els articles"</string>
<string name="nothing_here">"No hi ha res"</string>
<string name="tab_new">"Nou"</string>
<string name="tab_read">"Tot"</string>
<string name="tab_favs">"Preferits"</string>
<string name="action_about">"Quant a"</string>
<string name="marked_as_read">"Element llegit"</string>
<string name="undo_string">"Desfés"</string>
<string name="addStringNoUrl">"Inicieu la sessió per afegir fonts."</string>
<string name="cant_get_sources">"No es pot obtenir la llista de fonts."</string>
<string name="cant_create_source">"No es pot crear la font."</string>
<string name="cant_get_spouts">"No es pot obtenir la llista de canals."</string>
<string name="form_not_complete">"El formulari no està complet"</string>
<string name="pref_header_links">"Enllaços"</string>
<string name="issue_tracker_link">"Detector de problemes"</string>
<string name="issue_tracker_summary">"Informa d'un error o pregunta sobre funcions noves"</string>
<string name="warning_wrong_url">"ADVERTÈNCIA"</string>
<string name="pref_switch_card_view_title">"Visualització de targeta"</string>
<string name="cant_mark_favortie">"No es pot marcar l'article com a preferit"</string>
<string name="cant_unmark_favortie">"No es pot treure l'element de preferits"</string>
<string name="share">"Comparteix"</string>
<string name="rating_prompt_title">"Us agrada l'aplicació?"</string>
<string name="rating_prompt_yes">"Sí."</string>
<string name="rating_prompt_no">"No gaire…"</string>
<string name="rating_prompt_feedback_title">"Ens podeu dir per què?"</string>
<string name="rating_prompt_feedback_yes">"D'acord."</string>
<string name="rating_prompt_feedback_no">"Ara no."</string>
<string name="rating_prompt_rating_title">"Perfecte! Ens podeu puntuar a la Botiga?"</string>
<string name="rating_prompt_rating_yes">"Sí."</string>
<string name="rating_prompt_rating_no">"Ara no."</string>
<string name="rating_prompt_thanks">"Gràcies. La vostra opinió ens ajuda a millorar l'aplicació."</string>
<string name="switch_unread_count">"Mostra el recompte d'articles no llegits amb un distintiu a la barra inferior."</string>
<string name="switch_unread_count_title">"Recompte d'articles no llegits"</string>
<string name="display_all_counts_title">"Recompte d'articles llegits i preferits"</string>
<string name="invitation_title">"Prova aquesta aplicació per als canals RSS de Selfoss."</string>
<string name="invitation_message">"Jo utilitzo aquesta aplicació per llegir els canals RSS de Selfoss. Segur que a tu també t'agrada!"</string>
<string name="invitation_cta">"Prova l'aplicació"</string>
<string name="text_wrong_url">"Sembla que esteu utilitzant un URL no vàlid. Assegureu-vos que és correcte, i si el problema persisteix, poseu-vos en contacte amb mi (a través de l'enllaç de contacte que hi ha a la Botiga). Tingueu en compte que per utilitzar aquesta aplicació cal que també utilitzeu Selfoss. Si no, no podreu accedir a canals RSS."</string>
<string name="pref_general_internal_browser_title">"Obre els enllaços dins de l'aplicació"</string>
<string name="pref_general_internal_browser_on">"Els articles s'obriran dins de l'aplicació"</string>
<string name="pref_general_internal_browser_off">"Els articles s'obriran amb el navegador predeterminat"</string>
<string name="prefer_article_viewer_title">"Obre el visualitzador d'articles"</string>
<string name="prefer_article_viewer_on">"S'obrirà el visualitzador d'articles en lloc del navegador intern"</string>
<string name="prefer_article_viewer_off">"S'obrirà el navegador intern en lloc del visualitzador d'articles"</string>
<string name="pref_general_category_links">"Gestió d'enllaços"</string>
<string name="pref_general_category_displaying">"Visualització"</string>
<string name="pref_general_category_actions">"Accions"</string>
<string name="pref_switch_card_view_on">"Els articles es mostraran com a targetes"</string>
<string name="pref_switch_card_view_off">"Els articles es mostraran en forma de llista"</string>
<string name="pref_switch_actions_tap_on">"Mostra la barra d'acció sota l'article"</string>
<string name="pref_switch_actions_tap_off">"En seleccionar un article, s'obrirà al navegador seleccionat"</string>
<string name="menu_home_refresh">"Actualitza l'accés remot"</string>
<string name="refresh_success_response">"S'ha actualitzat el remot. Torneu a carregar la llista d'articles"</string>
<string name="refresh_failer_message">"L'actualització no ha funcionat. Torneu a provar-ho més tard o consulteu els registres de Selfoss."</string>
<string name="refresh_in_progress">"S'està actualitzant"</string>
<string name="new_apk_available_title">"Hi ha un nou APK disponible."</string>
<string name="new_apk_available_message">"Podeu baixar l'APK nou des del dipòsit oficial."</string>
<string name="new_apk_available_get">"Baixa-ho ara"</string>
<string name="new_apk_available_no">"Ignora la versió"</string>
<string name="intro_hello_title">"Hola!"</string>
<string name="intro_hello_message">"Gràcies per baixar l'aplicació!"</string>
<string name="intro_needs_selfoss_title">"Abans de començar…"</string>
<string name="intro_needs_selfoss_message">"No podeu utilitzar l'aplicació sense una instància de Selfoss."</string>
<string name="intro_needs_selfoss_link">"Què és Selfoss?"</string>
<string name="intro_all_set_title">"Tot a punt!"</string>
<string name="intro_all_set_message">"Ja podeu començar a utilitzar l'aplicació. Configureu l'aplicació des de la pàgina Configuració. Allà hi trobareu enllaços que us poden ser útils."</string>
<string name="card_height_title">Alçada completa de les targetes</string>
<string name="card_height_on">L\'alçada de les targetes s\'ajustarà al seu contingut</string>
<string name="card_height_off">L\'alçada de les targetes serà fixa</string>
<string name="source_code">Codi font</string>
<string name="cant_mark_read">No es pot marcar l\'article com a llegit</string>
<string name="drawer_error_loading_tags">S\'ha produït un error en carregar les etiquetes</string>
<string name="drawer_error_loading_sources">S\'ha produït un error en carregar les fonts</string>
<string name="drawer_item_filters">Filtres</string>
<string name="drawer_action_clear">Esborra</string>
<string name="drawer_item_tags">Etiquetes</string>
<string name="drawer_item_sources">Fonts</string>
<string name="drawer_action_edit">Edita</string>
<string name="cache_drawer_error" tools:keep="@string/cache_drawer_error">La informació del calaix no s\'ha pogut emmagatzemar a la memòria cau</string>
<string name="no_tags_loaded">No s\'ha carregat cap etiqueta</string>
<string name="no_sources_loaded">No s\'ha carregat cap font</string>
<string name="drawer_loading">S\'està carregant…</string>
<string name="menu_home_search">Cerca</string>
<string name="can_delete_source">No es pot suprimir la font</string>
<string name="base_url_error">S\'ha produït un error en comunicar-se amb la instància de Selfoss. Si el problema persisteix, posa\'t en contacte amb mi.</string>
<string name="pref_header_theme">Temes</string>
<string name="default_theme">Predeterminat</string>
<string name="default_dark_theme">Predeterminat/Fosc</string>
<string name="pref_header_debug">Depuració</string>
<string name="login_debug_title">Registra els errors d\'inici de sessió</string>
<string name="login_debug_on">Es registraran tots els errors que es produeixin a la pàgina d\'inici de sessió</string>
<string name="login_debug_off">No es registrarà cap error que es produeixi a la pàgina d\'inici de sessió</string>
<string name="login_menu_debug">Depuració</string>
<string name="self_hosted_cert_switch">Utilitzeu un certificat autoallotjat?</string>
<string name="self_signed_cert_warning">Per raons de seguretat, els certificats autosignats no seran compatibles per defecte. En activar aquesta opció, sereu responsable de qualsevol problema de seguretat que es pugui produir.</string>
<string name="pref_selfoss_category">API de Selfoss</string>
<string name="pref_api_items_number_title">Nombre d\'elements carregats</string>
<string name="pref_hidden_tags">Hidden Tags</string>
<string name="read_debug_title">Voleu llegir els articles que apareixen com a no llegits?</string>
<string name="read_debug_off">No es registraran quan es marquen elements com a llegits</string>
<string name="read_debug_on">Les crides de l\'API es registraran en marcar un article com a llegit</string>
<string name="summary_debug_identifier">Identificador de depuració</string>
<string name="unique_id_to_clipboard">S\'ha copiat l\'identificador al porta-retalls</string>
<string name="display_header_drawer_summary">Mostra una capçalera amb la instància URL de Selfoss al panell lateral.</string>
<string name="display_header_drawer_title">Capçalera de menú</string>
<string name="login_everything_title">Registra totes les crides de l\'API</string>
<string name="login_everything_on">Aquesta acció registrarà totes les crides de l\'API per als programadors.</string>
<string name="login_everything_off">No es registrarà cap crida de l\'API</string>
<string name="pref_general_infinite_loading_title">Carrega articles en desplaçar</string>
<string name="translation">Traducció</string>
<string name="cant_open_invalid_url">L\'element URL no és vàlid. Estic intentant solucionar aquest problema perquè l\'aplicació no falli.</string>
<string name="drawer_report_bug">Informa d\'un error</string>
<string name="items_number_should_be_number">El nombre d\'elements ha de ser enter.</string>
<string name="reader_action_more">Més informació</string>
<string name="reader_action_open">Obre al navegador</string>
<string name="reader_action_share">Comparteix</string>
<string name="pref_switch_actions_pager_scroll_on">Es marcaran els articles com a llegits en lliscar el dit d\'un article a l\'altre.</string>
<string name="add_to_favs_reader">Afegeix als preferits</string>
<string name="remove_to_favs_reader">Suprimeix dels preferits</string>
<string name="pref_content_reader_font_size">Mida de la lletra del lector darticles</string>
<string name="pref_header_viewer">Visualitzador d\'articles</string>
<string name="refresh_dialog_message">Aquesta acció actualitzarà la vostra instància de Selfoss.</string>
<string name="markall_dialog_message">Aquesta acció marcarà els elements com a llegits.</string>
<string name="pref_switch_actions_pager_scroll">Marca com a llegit en lliscar el dit</string>
<string name="pref_switch_actions_pager_scroll_off">No es marcaran els articles com a llegits en lliscar el dit d\'un article a l\'altre.</string>
<string name="gdpr_dialog_message">Aquesta aplicació no recull cap dada personal. S\'han suprimit totes les eines d\'anàlisi. A partir d\'ara, l\'enviament d\'informes és opcional, així com el registre de depuració d\'errors. Recordeu que la depuració i els informes d\'error són essencials per al desenvolupament de l\'aplicació (Ho podeu configurar tot a Configuració &gt; Depura).</string>
<string name="gdpr_dialog_title">Aquesta aplicació no comparteix cap dada personal vostra.</string>
<string name="crash_dialog_text">Alguna cosa ha anat malament. Envieu l\'informe al desenvolupador.</string>
<string name="crash_dialog_comment">Podeu afegir informació útil en la secció de comentaris. No incloeu cap dada personal en el vostre comentari. També em podeu enviar un correu electrònic amb l\'identificador de depuració i us ho faré saber quan el problema s\'hagi resolt.</string>
<string name="pref_acra_user_email">Correu electrònic de contacte</string>
<string name="pref_acra_user_email_summary">Afegiu una adreça de correu electrònic per tal que pugui contactar-vos en relació amb l\'informe d\'errors que heu enviat.</string>
<string name="pref_acra_alwaysaccept">Envia informes d\'error automàtics</string>
<string name="pref_acra_alwaysaccept_enabled">S\'enviaran informes d\'error automàticament</string>
<string name="pref_acra_alwaysaccept_disabled">Us preguntarem abans d\'enviar un informe d\'error.</string>
<string name="pref_debug_crash_reports">Informes d\'error</string>
<string name="pref_debug_debug_logs">Registre de depuració (s\'enviarà automàticament)</string>
<string name="acra_login">Habilita el registre</string>
<string name="drawer_item_hidden_tags">Hidden Tags</string>
<string name="unmark">Mark item as unread</string>
</resources>

View File

@ -64,7 +64,6 @@
<string name="switch_unread_count">"Display the unread count as a badge for the bottom bar."</string>
<string name="switch_unread_count_title">"Display unread count"</string>
<string name="display_all_counts_title">"Display count for favorite and read"</string>
<string name="menu_share_the_app">"Invite friends"</string>
<string name="invitation_title">"Try this app for your Selfoss RSS feeds !"</string>
<string name="invitation_message">"I use this app for my Selfoss RSS feeds. You may like it too !"</string>
<string name="invitation_cta">"Try the app"</string>
@ -75,7 +74,7 @@
<string name="prefer_article_viewer_title">"Use the article viewer"</string>
<string name="prefer_article_viewer_on">"Will use the article viewer instead of the internal browser"</string>
<string name="prefer_article_viewer_off">"Will use the internal browser instead of the article viewer"</string>
<string name="pref_general_category_links">"Link handeling"</string>
<string name="pref_general_category_links">"Link handling"</string>
<string name="pref_general_category_displaying">"Displaying"</string>
<string name="pref_general_category_actions">"Actions"</string>
<string name="pref_switch_card_view_on">"The articles will be displayed as cards"</string>
@ -118,19 +117,7 @@
<string name="base_url_error">There was an issue when trying to communicate with your Selfoss Instance. If the issue persists, please get in touch with me.</string>
<string name="pref_header_theme">Themes</string>
<string name="default_theme">Default</string>
<string name="teal_orange_theme">Teal/Orange/Light</string>
<string name="cyan_pink_theme">Cyan/Pink/Light</string>
<string name="grey_orange_theme">Grey/Orange/Light</string>
<string name="blue_amber_theme">Blue/Amber/Light</string>
<string name="indigo_pink_theme">Indigo/Pink/Light</string>
<string name="red_teal_theme">Red/Teal/Light</string>
<string name="teal_orange_dark_theme">Teal/Orange/Dark</string>
<string name="cyan_pink_dark_theme">Cyan/Pink/Dark</string>
<string name="default_dark_theme">Default/Dark</string>
<string name="grey_orange_dark_theme">Grey/Orange/Dark</string>
<string name="blue_amber_dark_theme">Blue/Amber/Dark</string>
<string name="indigo_pink_dark_theme">Indigo/Pink/Dark</string>
<string name="red_teal_dark_theme">Red/Teal/Dark</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activate to log login errors</string>
<string name="login_debug_on">Any error on the login page will be logged</string>
@ -140,6 +127,7 @@
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="pref_hidden_tags">Hidden Tags</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
@ -150,7 +138,7 @@
<string name="login_everything_title">Logging every api calls</string>
<string name="login_everything_on">This will log every api call for debug purpose.</string>
<string name="login_everything_off">No api call will be logged</string>
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
<string name="translation">Translation</string>
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
<string name="drawer_report_bug">Report a bug</string>
@ -158,4 +146,27 @@
<string name="reader_action_more">Read more</string>
<string name="reader_action_open">Open in browser</string>
<string name="reader_action_share">Share</string>
<string name="pref_switch_actions_pager_scroll_on">Mark articles as read when swiping between articles.</string>
<string name="add_to_favs_reader">Add to favorites</string>
<string name="remove_to_favs_reader">Remove from favorites</string>
<string name="pref_content_reader_font_size">Article reader content font size</string>
<string name="pref_header_viewer">Article viewer</string>
<string name="refresh_dialog_message">This will refresh your Selfoss instance.</string>
<string name="markall_dialog_message">This will mark all the items as read.</string>
<string name="pref_switch_actions_pager_scroll">Mark as read on swipe</string>
<string name="pref_switch_actions_pager_scroll_off">Don\'t mark articles as read when swiping.</string>
<string name="gdpr_dialog_message">The app does not collect any personal data. Every analytics tools were removed. Crash reports sending is now optional, as is the debug logging. Keep in mind that debugging and crash reports are essential for the app development (You can configure everything in Settings &gt; Debug).</string>
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
<string name="crash_dialog_text">Something went wrong. Please send the report to the developer.</string>
<string name="crash_dialog_comment">You can add any helpful details in the comment bellow. Don\'t include any personal data in your comment. You could send me and email with your debug id, and I\'ll keep you posted when the issue is resolved.</string>
<string name="pref_acra_user_email">Contact email</string>
<string name="pref_acra_user_email_summary">Add an email so I can contact you about the crash reports you send.</string>
<string name="pref_acra_alwaysaccept">Automatically send crash reports</string>
<string name="pref_acra_alwaysaccept_enabled">Will send crash reports automatically</string>
<string name="pref_acra_alwaysaccept_disabled">Will ask everytime when sending crash reports.</string>
<string name="pref_debug_crash_reports">Crash reports</string>
<string name="pref_debug_debug_logs">Debug logging (these will be sent without a dialog)</string>
<string name="acra_login">Enable logging</string>
<string name="drawer_item_hidden_tags">Hidden Tags</string>
<string name="unmark">Mark item as unread</string>
</resources>

View File

@ -64,7 +64,6 @@
<string name="switch_unread_count">"Display the unread count as a badge for the bottom bar."</string>
<string name="switch_unread_count_title">"Display unread count"</string>
<string name="display_all_counts_title">"Display count for favorite and read"</string>
<string name="menu_share_the_app">"Invite friends"</string>
<string name="invitation_title">"Try this app for your Selfoss RSS feeds !"</string>
<string name="invitation_message">"I use this app for my Selfoss RSS feeds. You may like it too !"</string>
<string name="invitation_cta">"Try the app"</string>
@ -75,7 +74,7 @@
<string name="prefer_article_viewer_title">"Use the article viewer"</string>
<string name="prefer_article_viewer_on">"Will use the article viewer instead of the internal browser"</string>
<string name="prefer_article_viewer_off">"Will use the internal browser instead of the article viewer"</string>
<string name="pref_general_category_links">"Link handeling"</string>
<string name="pref_general_category_links">"Link handling"</string>
<string name="pref_general_category_displaying">"Displaying"</string>
<string name="pref_general_category_actions">"Actions"</string>
<string name="pref_switch_card_view_on">"The articles will be displayed as cards"</string>
@ -118,19 +117,7 @@
<string name="base_url_error">There was an issue when trying to communicate with your Selfoss Instance. If the issue persists, please get in touch with me.</string>
<string name="pref_header_theme">Themes</string>
<string name="default_theme">Default</string>
<string name="teal_orange_theme">Teal/Orange/Light</string>
<string name="cyan_pink_theme">Cyan/Pink/Light</string>
<string name="grey_orange_theme">Grey/Orange/Light</string>
<string name="blue_amber_theme">Blue/Amber/Light</string>
<string name="indigo_pink_theme">Indigo/Pink/Light</string>
<string name="red_teal_theme">Red/Teal/Light</string>
<string name="teal_orange_dark_theme">Teal/Orange/Dark</string>
<string name="cyan_pink_dark_theme">Cyan/Pink/Dark</string>
<string name="default_dark_theme">Default/Dark</string>
<string name="grey_orange_dark_theme">Grey/Orange/Dark</string>
<string name="blue_amber_dark_theme">Blue/Amber/Dark</string>
<string name="indigo_pink_dark_theme">Indigo/Pink/Dark</string>
<string name="red_teal_dark_theme">Red/Teal/Dark</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activate to log login errors</string>
<string name="login_debug_on">Any error on the login page will be logged</string>
@ -140,6 +127,7 @@
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="pref_hidden_tags">Hidden Tags</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
@ -150,7 +138,7 @@
<string name="login_everything_title">Logging every api calls</string>
<string name="login_everything_on">This will log every api call for debug purpose.</string>
<string name="login_everything_off">No api call will be logged</string>
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
<string name="translation">Translation</string>
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
<string name="drawer_report_bug">Report a bug</string>
@ -158,4 +146,27 @@
<string name="reader_action_more">Read more</string>
<string name="reader_action_open">Open in browser</string>
<string name="reader_action_share">Share</string>
<string name="pref_switch_actions_pager_scroll_on">Mark articles as read when swiping between articles.</string>
<string name="add_to_favs_reader">Add to favorites</string>
<string name="remove_to_favs_reader">Remove from favorites</string>
<string name="pref_content_reader_font_size">Article reader content font size</string>
<string name="pref_header_viewer">Article viewer</string>
<string name="refresh_dialog_message">This will refresh your Selfoss instance.</string>
<string name="markall_dialog_message">This will mark all the items as read.</string>
<string name="pref_switch_actions_pager_scroll">Mark as read on swipe</string>
<string name="pref_switch_actions_pager_scroll_off">Don\'t mark articles as read when swiping.</string>
<string name="gdpr_dialog_message">The app does not collect any personal data. Every analytics tools were removed. Crash reports sending is now optional, as is the debug logging. Keep in mind that debugging and crash reports are essential for the app development (You can configure everything in Settings &gt; Debug).</string>
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
<string name="crash_dialog_text">Something went wrong. Please send the report to the developer.</string>
<string name="crash_dialog_comment">You can add any helpful details in the comment bellow. Don\'t include any personal data in your comment. You could send me and email with your debug id, and I\'ll keep you posted when the issue is resolved.</string>
<string name="pref_acra_user_email">Contact email</string>
<string name="pref_acra_user_email_summary">Add an email so I can contact you about the crash reports you send.</string>
<string name="pref_acra_alwaysaccept">Automatically send crash reports</string>
<string name="pref_acra_alwaysaccept_enabled">Will send crash reports automatically</string>
<string name="pref_acra_alwaysaccept_disabled">Will ask everytime when sending crash reports.</string>
<string name="pref_debug_crash_reports">Crash reports</string>
<string name="pref_debug_debug_logs">Debug logging (these will be sent without a dialog)</string>
<string name="acra_login">Enable logging</string>
<string name="drawer_item_hidden_tags">Hidden Tags</string>
<string name="unmark">Mark item as unread</string>
</resources>

View File

@ -1,161 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">"Reader for Selfoss"</string>
<string name="title_activity_login">"Log in"</string>
<string name="prompt_password">"Password"</string>
<string name="prompt_http_password">"HTTP Password"</string>
<string name="action_sign_in">"Go"</string>
<string name="error_invalid_password">"Password not long enough"</string>
<string name="error_field_required">"Field required"</string>
<string name="prompt_url">"Url"</string>
<string name="withLoginSwitch">"Login required ?"</string>
<string name="withHttpLoginSwitch">"HTTP Login required ?"</string>
<string name="login_url_problem">"Oops. You may need to add a \"/\" at the end of the url."</string>
<string name="prompt_login">"Username"</string>
<string name="prompt_http_login">"HTTP Username"</string>
<string name="label_share">"Share"</string>
<string name="readAll">"Read all"</string>
<string name="action_disconnect">"Disconnect"</string>
<string name="title_activity_settings">"Settings"</string>
<string name="pref_header_general">"General"</string>
<string name="pref_switch_actions_tap_title">"Tap action on the articles"</string>
<string name="add_source_hint_tags">"Tag1, Tag2, Tag3"</string>
<string name="add_source_hint_url">"Link"</string>
<string name="add_source_hint_name">"Name"</string>
<string name="add_source">"Add a source"</string>
<string name="add_source_save">"Save"</string>
<string name="wrong_infos">"Check your details again."</string>
<string name="all_posts_not_read">"All posts weren't read"</string>
<string name="all_posts_read">"All posts were read"</string>
<string name="cant_get_favs">"Can't get favorites"</string>
<string name="cant_get_new_elements">"Can't get new articles"</string>
<string name="cant_get_read">"Can't get read articles"</string>
<string name="nothing_here">"Nothing here"</string>
<string name="tab_new">"New"</string>
<string name="tab_read">"All"</string>
<string name="tab_favs">"Favorites"</string>
<string name="action_about">"About"</string>
<string name="marked_as_read">"Item read"</string>
<string name="undo_string">"Undo"</string>
<string name="addStringNoUrl">"Log in to add sources."</string>
<string name="cant_get_sources">"Can't get sources list."</string>
<string name="cant_create_source">"Can't create source."</string>
<string name="cant_get_spouts">"Can't get spouts list."</string>
<string name="form_not_complete">"The form is not complete"</string>
<string name="pref_header_links">"Links"</string>
<string name="issue_tracker_link">"Issue Tracker"</string>
<string name="issue_tracker_summary">"Report a bug or ask for a new feature"</string>
<string name="warning_wrong_url">"WARNING"</string>
<string name="pref_switch_card_view_title">"Card View"</string>
<string name="cant_mark_favortie">"Can't mark article as favorite"</string>
<string name="cant_unmark_favortie">"Can't remove item from favorite"</string>
<string name="share">"Share"</string>
<string name="rating_prompt_title">"Enjoying the app ?"</string>
<string name="rating_prompt_yes">"Yes !"</string>
<string name="rating_prompt_no">"Not really …"</string>
<string name="rating_prompt_feedback_title">"Can you tell us why ?"</string>
<string name="rating_prompt_feedback_yes">"OK !"</string>
<string name="rating_prompt_feedback_no">"Not now."</string>
<string name="rating_prompt_rating_title">"Great ! Can you rate us on the Store ?"</string>
<string name="rating_prompt_rating_yes">"Sure !"</string>
<string name="rating_prompt_rating_no">"Not right now."</string>
<string name="rating_prompt_thanks">"Thanks, your feedback help enhance the app !"</string>
<string name="switch_unread_count">"Display the unread count as a badge for the bottom bar."</string>
<string name="switch_unread_count_title">"Display unread count"</string>
<string name="display_all_counts_title">"Display count for favorite and read"</string>
<string name="menu_share_the_app">"Invite friends"</string>
<string name="invitation_title">"Try this app for your Selfoss RSS feeds !"</string>
<string name="invitation_message">"I use this app for my Selfoss RSS feeds. You may like it too !"</string>
<string name="invitation_cta">"Try the app"</string>
<string name="text_wrong_url">"You seem to be trying to use an invalid URL. Make sure it is correct, and if the problem persists, contact me (via the store contact link). Please note that the app needs you to be using Selfoss. You can't access RSS feeds without it."</string>
<string name="pref_general_internal_browser_title">"Open links inside the app"</string>
<string name="pref_general_internal_browser_on">"Articles will open inside the app"</string>
<string name="pref_general_internal_browser_off">"Articles will open with your default browser"</string>
<string name="prefer_article_viewer_title">"Use the article viewer"</string>
<string name="prefer_article_viewer_on">"Will use the article viewer instead of the internal browser"</string>
<string name="prefer_article_viewer_off">"Will use the internal browser instead of the article viewer"</string>
<string name="pref_general_category_links">"Link handeling"</string>
<string name="pref_general_category_displaying">"Displaying"</string>
<string name="pref_general_category_actions">"Actions"</string>
<string name="pref_switch_card_view_on">"The articles will be displayed as cards"</string>
<string name="pref_switch_card_view_off">"The articles will be displayed as a list"</string>
<string name="pref_switch_actions_tap_on">"Displays the action bar under the article"</string>
<string name="pref_switch_actions_tap_off">"When selecting an article it will open in your selected browser"</string>
<string name="menu_home_refresh">"Update remote"</string>
<string name="refresh_success_response">"The remote is updated, you can now reload the articles list"</string>
<string name="refresh_failer_message">"The update didn't work, try again later, or check your selfoss logs."</string>
<string name="refresh_in_progress">"Refresh in progress"</string>
<string name="new_apk_available_title">"A new APK is available."</string>
<string name="new_apk_available_message">"A new APK is available to download on the official repository."</string>
<string name="new_apk_available_get">"Download now"</string>
<string name="new_apk_available_no">"Ignore version"</string>
<string name="intro_hello_title">"Hi there !"</string>
<string name="intro_hello_message">"Thanks for downloading the app !"</string>
<string name="intro_needs_selfoss_title">"Before you start…"</string>
<string name="intro_needs_selfoss_message">"You can't use the app without a Selfoss instance."</string>
<string name="intro_needs_selfoss_link">"What is Selfoss ?"</string>
<string name="intro_all_set_title">"All set !"</string>
<string name="intro_all_set_message">"You are ready to use the app. Don't forget to go to the settings page to configure your app, and where you'll find some useful links."</string>
<string name="card_height_title">Full height cards</string>
<string name="card_height_on">Cards height will adjust to its content</string>
<string name="card_height_off">Card height will be fixed</string>
<string name="source_code">Source code</string>
<string name="cant_mark_read">Can\'t mark article as read</string>
<string name="drawer_error_loading_tags">Error loading tags…</string>
<string name="drawer_error_loading_sources">Error loading sources…</string>
<string name="drawer_item_filters">Filters</string>
<string name="drawer_action_clear">clear</string>
<string name="drawer_item_tags">Tags</string>
<string name="drawer_item_sources">Sources</string>
<string name="drawer_action_edit">edit</string>
<string name="cache_drawer_error" tools:keep="@string/cache_drawer_error">Couldn\'t cache your drawer data</string>
<string name="no_tags_loaded">No tags loaded</string>
<string name="no_sources_loaded">No sources loaded</string>
<string name="drawer_loading">Loading …</string>
<string name="menu_home_search">Search</string>
<string name="can_delete_source">Can\'t delete the source…</string>
<string name="base_url_error">There was an issue when trying to communicate with your Selfoss Instance. If the issue persists, please get in touch with me.</string>
<string name="pref_header_theme">Themes</string>
<string name="default_theme">Default</string>
<string name="teal_orange_theme">Teal/Orange/Light</string>
<string name="cyan_pink_theme">Cyan/Pink/Light</string>
<string name="grey_orange_theme">Grey/Orange/Light</string>
<string name="blue_amber_theme">Blue/Amber/Light</string>
<string name="indigo_pink_theme">Indigo/Pink/Light</string>
<string name="red_teal_theme">Red/Teal/Light</string>
<string name="teal_orange_dark_theme">Teal/Orange/Dark</string>
<string name="cyan_pink_dark_theme">Cyan/Pink/Dark</string>
<string name="default_dark_theme">Default/Dark</string>
<string name="grey_orange_dark_theme">Grey/Orange/Dark</string>
<string name="blue_amber_dark_theme">Blue/Amber/Dark</string>
<string name="indigo_pink_dark_theme">Indigo/Pink/Dark</string>
<string name="red_teal_dark_theme">Red/Teal/Dark</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activate to log login errors</string>
<string name="login_debug_on">Any error on the login page will be logged</string>
<string name="login_debug_off">No log on the login page</string>
<string name="login_menu_debug">Debug</string>
<string name="self_hosted_cert_switch">Using a self hosted certificate ?</string>
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
<string name="summary_debug_identifier">Debug identifier</string>
<string name="unique_id_to_clipboard">Identifier copied to your clipboard</string>
<string name="display_header_drawer_summary">Display a header with the selfoss instance url on the lateral drawer.</string>
<string name="display_header_drawer_title">Account header</string>
<string name="login_everything_title">Logging every api calls</string>
<string name="login_everything_on">This will log every api call for debug purpose.</string>
<string name="login_everything_off">No api call will be logged</string>
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
<string name="translation">Translation</string>
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
<string name="drawer_report_bug">Report a bug</string>
<string name="items_number_should_be_number">The items number should be an integer.</string>
<string name="reader_action_more">Read more</string>
<string name="reader_action_open">Open in browser</string>
<string name="reader_action_share">Share</string>
</resources>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">"Reader für Selfoss"</string>
<string name="app_name">"Reader für selfoss"</string>
<string name="title_activity_login">"Anmelden"</string>
<string name="prompt_password">"Passwort"</string>
<string name="prompt_http_password">"HTTP Passwort"</string>
@ -33,7 +33,7 @@
<string name="cant_get_read">"Gelese Artikel können nicht abgerufen werden"</string>
<string name="nothing_here">"Keine Einträge vorhanden"</string>
<string name="tab_new">"Neu"</string>
<string name="tab_read">"All"</string>
<string name="tab_read">"Alle"</string>
<string name="tab_favs">"Favoriten"</string>
<string name="action_about">"Über"</string>
<string name="marked_as_read">"Artikel gelesen"</string>
@ -64,7 +64,6 @@
<string name="switch_unread_count">"Zeige die Zahl ungelesener Artikel in der unteren Leiste."</string>
<string name="switch_unread_count_title">"Zeige Anzahl ungelesener Artikel"</string>
<string name="display_all_counts_title">"Zeige Anzahl der Favoriten und gelesenen Artikel"</string>
<string name="menu_share_the_app">"Freunde einladen"</string>
<string name="invitation_title">"Probiere diese App für deine Selfoss RSS-Feeds!"</string>
<string name="invitation_message">"Ich benutze diese App für meine Selfoss RSS-Feeds. Vielleicht magst du sie auch!"</string>
<string name="invitation_cta">"Probier die App"</string>
@ -118,19 +117,7 @@
<string name="base_url_error">Beim Versuch deine Selfoss-Instanz zu erreichen ist ein Fehler aufgetreten. Solltet dieser Fehler bestehen bleiben, trete bitte mit mir in Kontakt.</string>
<string name="pref_header_theme">Designs</string>
<string name="default_theme">Standard</string>
<string name="teal_orange_theme">Türkis/Orange/Hell</string>
<string name="cyan_pink_theme">Cyan/Pink/Hell</string>
<string name="grey_orange_theme">Türkis/Orange/Hell</string>
<string name="blue_amber_theme">Blau/Amber/Hell</string>
<string name="indigo_pink_theme">Indigo/Pink/Hell</string>
<string name="red_teal_theme">Rot/Türkis/Hell</string>
<string name="teal_orange_dark_theme">Türkis/Orange/Dunkel</string>
<string name="cyan_pink_dark_theme">Cyan/Pink/Dunkel</string>
<string name="default_dark_theme">Standard (Dunkel)</string>
<string name="grey_orange_dark_theme">Grau/Orange/Dunkel</string>
<string name="blue_amber_dark_theme">Blau/Gelb/Dunkel</string>
<string name="indigo_pink_dark_theme">Indigo/Pink/Dunkel</string>
<string name="red_teal_dark_theme">Rot/Türkis/Dunkel</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Aktivieren, um Login-Fehler zu protokollieren</string>
<string name="login_debug_on">Fehler auf der Login-Seite werden protokolliert</string>
@ -138,8 +125,9 @@
<string name="login_menu_debug">Debug</string>
<string name="self_hosted_cert_switch">Verwenden Sie einen selbst gehostetes Zertifikat?</string>
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_selfoss_category">selfoss API</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="pref_hidden_tags">Hidden Tags</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
@ -150,12 +138,35 @@
<string name="login_everything_title">Logging every api calls</string>
<string name="login_everything_on">This will log every api call for debug purpose.</string>
<string name="login_everything_off">No api call will be logged</string>
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
<string name="translation">Übersetzung</string>
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
<string name="drawer_report_bug">Report a bug</string>
<string name="drawer_report_bug">Melde einen Fehler</string>
<string name="items_number_should_be_number">The items number should be an integer.</string>
<string name="reader_action_more">Read more</string>
<string name="reader_action_open">Open in browser</string>
<string name="reader_action_share">Share</string>
<string name="reader_action_open">Im Browser öffnen</string>
<string name="reader_action_share">Teilen</string>
<string name="pref_switch_actions_pager_scroll_on">Mark articles as read when swiping between articles.</string>
<string name="add_to_favs_reader">Zu Favoriten hinzufügen</string>
<string name="remove_to_favs_reader">Remove from favorites</string>
<string name="pref_content_reader_font_size">Article reader content font size</string>
<string name="pref_header_viewer">Article viewer</string>
<string name="refresh_dialog_message">This will refresh your Selfoss instance.</string>
<string name="markall_dialog_message">This will mark all the items as read.</string>
<string name="pref_switch_actions_pager_scroll">Mark as read on swipe</string>
<string name="pref_switch_actions_pager_scroll_off">Don\'t mark articles as read when swiping.</string>
<string name="gdpr_dialog_message">The app does not collect any personal data. Every analytics tools were removed. Crash reports sending is now optional, as is the debug logging. Keep in mind that debugging and crash reports are essential for the app development (You can configure everything in Settings &gt; Debug).</string>
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
<string name="crash_dialog_text">Something went wrong. Please send the report to the developer.</string>
<string name="crash_dialog_comment">You can add any helpful details in the comment bellow. Don\'t include any personal data in your comment. You could send me and email with your debug id, and I\'ll keep you posted when the issue is resolved.</string>
<string name="pref_acra_user_email">Contact email</string>
<string name="pref_acra_user_email_summary">Add an email so I can contact you about the crash reports you send.</string>
<string name="pref_acra_alwaysaccept">Automatically send crash reports</string>
<string name="pref_acra_alwaysaccept_enabled">Will send crash reports automatically</string>
<string name="pref_acra_alwaysaccept_disabled">Will ask everytime when sending crash reports.</string>
<string name="pref_debug_crash_reports">Crash reports</string>
<string name="pref_debug_debug_logs">Debug logging (these will be sent without a dialog)</string>
<string name="acra_login">Enable logging</string>
<string name="drawer_item_hidden_tags">Hidden Tags</string>
<string name="unmark">Mark item as unread</string>
</resources>

View File

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">"Reader for Selfoss"</string>
<string name="title_activity_login">"Log in"</string>
<string name="prompt_password">"Password"</string>
<string name="prompt_http_password">"HTTP Password"</string>
<string name="action_sign_in">"Go"</string>
<string name="error_invalid_password">"Password not long enough"</string>
<string name="error_field_required">"Field required"</string>
<string name="prompt_url">"Url"</string>
<string name="withLoginSwitch">"Login required ?"</string>
<string name="withHttpLoginSwitch">"HTTP Login required ?"</string>
<string name="login_url_problem">"Oops. You may need to add a \"/\" at the end of the url."</string>
<string name="prompt_login">"Username"</string>
<string name="prompt_http_login">"HTTP Username"</string>
<string name="label_share">"Share"</string>
<string name="readAll">"Read all"</string>
<string name="action_disconnect">"Disconnect"</string>
<string name="title_activity_settings">"Settings"</string>
<string name="pref_header_general">"General"</string>
<string name="pref_switch_actions_tap_title">"Tap action on the articles"</string>
<string name="add_source_hint_tags">"Tag1, Tag2, Tag3"</string>
<string name="add_source_hint_url">"Link"</string>
<string name="add_source_hint_name">"Name"</string>
<string name="add_source">"Add a source"</string>
<string name="add_source_save">"Save"</string>
<string name="wrong_infos">"Check your details again."</string>
<string name="all_posts_not_read">"All posts weren't read"</string>
<string name="all_posts_read">"All posts were read"</string>
<string name="cant_get_favs">"Can't get favorites"</string>
<string name="cant_get_new_elements">"Can't get new articles"</string>
<string name="cant_get_read">"Can't get read articles"</string>
<string name="nothing_here">"Nothing here"</string>
<string name="tab_new">"New"</string>
<string name="tab_read">"All"</string>
<string name="tab_favs">"Favorites"</string>
<string name="action_about">"About"</string>
<string name="marked_as_read">"Item read"</string>
<string name="undo_string">"Undo"</string>
<string name="addStringNoUrl">"Log in to add sources."</string>
<string name="cant_get_sources">"Can't get sources list."</string>
<string name="cant_create_source">"Can't create source."</string>
<string name="cant_get_spouts">"Can't get spouts list."</string>
<string name="form_not_complete">"The form is not complete"</string>
<string name="pref_header_links">"Links"</string>
<string name="issue_tracker_link">"Issue Tracker"</string>
<string name="issue_tracker_summary">"Report a bug or ask for a new feature"</string>
<string name="warning_wrong_url">"WARNING"</string>
<string name="pref_switch_card_view_title">"Card View"</string>
<string name="cant_mark_favortie">"Can't mark article as favorite"</string>
<string name="cant_unmark_favortie">"Can't remove item from favorite"</string>
<string name="share">"Share"</string>
<string name="rating_prompt_title">"Enjoying the app ?"</string>
<string name="rating_prompt_yes">"Yes !"</string>
<string name="rating_prompt_no">"Not really …"</string>
<string name="rating_prompt_feedback_title">"Can you tell us why ?"</string>
<string name="rating_prompt_feedback_yes">"OK !"</string>
<string name="rating_prompt_feedback_no">"Not now."</string>
<string name="rating_prompt_rating_title">"Great ! Can you rate us on the Store ?"</string>
<string name="rating_prompt_rating_yes">"Sure !"</string>
<string name="rating_prompt_rating_no">"Not right now."</string>
<string name="rating_prompt_thanks">"Thanks, your feedback help enhance the app !"</string>
<string name="switch_unread_count">"Display the unread count as a badge for the bottom bar."</string>
<string name="switch_unread_count_title">"Display unread count"</string>
<string name="display_all_counts_title">"Display count for favorite and read"</string>
<string name="invitation_title">"Try this app for your Selfoss RSS feeds !"</string>
<string name="invitation_message">"I use this app for my Selfoss RSS feeds. You may like it too !"</string>
<string name="invitation_cta">"Try the app"</string>
<string name="text_wrong_url">"You seem to be trying to use an invalid URL. Make sure it is correct, and if the problem persists, contact me (via the store contact link). Please note that the app needs you to be using Selfoss. You can't access RSS feeds without it."</string>
<string name="pref_general_internal_browser_title">"Open links inside the app"</string>
<string name="pref_general_internal_browser_on">"Articles will open inside the app"</string>
<string name="pref_general_internal_browser_off">"Articles will open with your default browser"</string>
<string name="prefer_article_viewer_title">"Use the article viewer"</string>
<string name="prefer_article_viewer_on">"Will use the article viewer instead of the internal browser"</string>
<string name="prefer_article_viewer_off">"Will use the internal browser instead of the article viewer"</string>
<string name="pref_general_category_links">"Link handling"</string>
<string name="pref_general_category_displaying">"Displaying"</string>
<string name="pref_general_category_actions">"Actions"</string>
<string name="pref_switch_card_view_on">"The articles will be displayed as cards"</string>
<string name="pref_switch_card_view_off">"The articles will be displayed as a list"</string>
<string name="pref_switch_actions_tap_on">"Displays the action bar under the article"</string>
<string name="pref_switch_actions_tap_off">"When selecting an article it will open in your selected browser"</string>
<string name="menu_home_refresh">"Update remote"</string>
<string name="refresh_success_response">"The remote is updated, you can now reload the articles list"</string>
<string name="refresh_failer_message">"The update didn't work, try again later, or check your selfoss logs."</string>
<string name="refresh_in_progress">"Refresh in progress"</string>
<string name="new_apk_available_title">"A new APK is available."</string>
<string name="new_apk_available_message">"A new APK is available to download on the official repository."</string>
<string name="new_apk_available_get">"Download now"</string>
<string name="new_apk_available_no">"Ignore version"</string>
<string name="intro_hello_title">"Hi there !"</string>
<string name="intro_hello_message">"Thanks for downloading the app !"</string>
<string name="intro_needs_selfoss_title">"Before you start…"</string>
<string name="intro_needs_selfoss_message">"You can't use the app without a Selfoss instance."</string>
<string name="intro_needs_selfoss_link">"What is Selfoss ?"</string>
<string name="intro_all_set_title">"All set !"</string>
<string name="intro_all_set_message">"You are ready to use the app. Don't forget to go to the settings page to configure your app, and where you'll find some useful links."</string>
<string name="card_height_title">Full height cards</string>
<string name="card_height_on">Cards height will adjust to its content</string>
<string name="card_height_off">Card height will be fixed</string>
<string name="source_code">Source code</string>
<string name="cant_mark_read">Can\'t mark article as read</string>
<string name="drawer_error_loading_tags">Error loading tags…</string>
<string name="drawer_error_loading_sources">Error loading sources…</string>
<string name="drawer_item_filters">Filters</string>
<string name="drawer_action_clear">clear</string>
<string name="drawer_item_tags">Tags</string>
<string name="drawer_item_sources">Sources</string>
<string name="drawer_action_edit">edit</string>
<string name="cache_drawer_error" tools:keep="@string/cache_drawer_error">Couldn\'t cache your drawer data</string>
<string name="no_tags_loaded">No tags loaded</string>
<string name="no_sources_loaded">No sources loaded</string>
<string name="drawer_loading">Loading …</string>
<string name="menu_home_search">Search</string>
<string name="can_delete_source">Can\'t delete the source…</string>
<string name="base_url_error">There was an issue when trying to communicate with your Selfoss Instance. If the issue persists, please get in touch with me.</string>
<string name="pref_header_theme">Themes</string>
<string name="default_theme">Default</string>
<string name="default_dark_theme">Default/Dark</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activate to log login errors</string>
<string name="login_debug_on">Any error on the login page will be logged</string>
<string name="login_debug_off">No log on the login page</string>
<string name="login_menu_debug">Debug</string>
<string name="self_hosted_cert_switch">Using a self hosted certificate ?</string>
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="pref_hidden_tags">Hidden Tags</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
<string name="summary_debug_identifier">Debug identifier</string>
<string name="unique_id_to_clipboard">Identifier copied to your clipboard</string>
<string name="display_header_drawer_summary">Display a header with the selfoss instance url on the lateral drawer.</string>
<string name="display_header_drawer_title">Account header</string>
<string name="login_everything_title">Logging every api calls</string>
<string name="login_everything_on">This will log every api call for debug purpose.</string>
<string name="login_everything_off">No api call will be logged</string>
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
<string name="translation">Translation</string>
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
<string name="drawer_report_bug">Report a bug</string>
<string name="items_number_should_be_number">The items number should be an integer.</string>
<string name="reader_action_more">Read more</string>
<string name="reader_action_open">Open in browser</string>
<string name="reader_action_share">Share</string>
<string name="pref_switch_actions_pager_scroll_on">Mark articles as read when swiping between articles.</string>
<string name="add_to_favs_reader">Add to favorites</string>
<string name="remove_to_favs_reader">Remove from favorites</string>
<string name="pref_content_reader_font_size">Article reader content font size</string>
<string name="pref_header_viewer">Article viewer</string>
<string name="refresh_dialog_message">This will refresh your Selfoss instance.</string>
<string name="markall_dialog_message">This will mark all the items as read.</string>
<string name="pref_switch_actions_pager_scroll">Mark as read on swipe</string>
<string name="pref_switch_actions_pager_scroll_off">Don\'t mark articles as read when swiping.</string>
<string name="gdpr_dialog_message">The app does not collect any personal data. Every analytics tools were removed. Crash reports sending is now optional, as is the debug logging. Keep in mind that debugging and crash reports are essential for the app development (You can configure everything in Settings &gt; Debug).</string>
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
<string name="crash_dialog_text">Something went wrong. Please send the report to the developer.</string>
<string name="crash_dialog_comment">You can add any helpful details in the comment bellow. Don\'t include any personal data in your comment. You could send me and email with your debug id, and I\'ll keep you posted when the issue is resolved.</string>
<string name="pref_acra_user_email">Contact email</string>
<string name="pref_acra_user_email_summary">Add an email so I can contact you about the crash reports you send.</string>
<string name="pref_acra_alwaysaccept">Automatically send crash reports</string>
<string name="pref_acra_alwaysaccept_enabled">Will send crash reports automatically</string>
<string name="pref_acra_alwaysaccept_disabled">Will ask everytime when sending crash reports.</string>
<string name="pref_debug_crash_reports">Crash reports</string>
<string name="pref_debug_debug_logs">Debug logging (these will be sent without a dialog)</string>
<string name="acra_login">Enable logging</string>
<string name="drawer_item_hidden_tags">Hidden Tags</string>
<string name="unmark">Mark item as unread</string>
</resources>

View File

@ -1,161 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">"Reader for Selfoss"</string>
<string name="title_activity_login">"Log in"</string>
<string name="prompt_password">"Password"</string>
<string name="prompt_http_password">"HTTP Password"</string>
<string name="action_sign_in">"Go"</string>
<string name="error_invalid_password">"Password not long enough"</string>
<string name="error_field_required">"Field required"</string>
<string name="prompt_url">"Url"</string>
<string name="withLoginSwitch">"Login required ?"</string>
<string name="withHttpLoginSwitch">"HTTP Login required ?"</string>
<string name="login_url_problem">"Oops. You may need to add a \"/\" at the end of the url."</string>
<string name="prompt_login">"Username"</string>
<string name="prompt_http_login">"HTTP Username"</string>
<string name="label_share">"Share"</string>
<string name="readAll">"Read all"</string>
<string name="action_disconnect">"Disconnect"</string>
<string name="title_activity_settings">"Settings"</string>
<string name="pref_header_general">"General"</string>
<string name="pref_switch_actions_tap_title">"Tap action on the articles"</string>
<string name="add_source_hint_tags">"Tag1, Tag2, Tag3"</string>
<string name="add_source_hint_url">"Link"</string>
<string name="add_source_hint_name">"Name"</string>
<string name="add_source">"Add a source"</string>
<string name="add_source_save">"Save"</string>
<string name="wrong_infos">"Check your details again."</string>
<string name="all_posts_not_read">"All posts weren't read"</string>
<string name="all_posts_read">"All posts were read"</string>
<string name="cant_get_favs">"Can't get favorites"</string>
<string name="cant_get_new_elements">"Can't get new articles"</string>
<string name="cant_get_read">"Can't get read articles"</string>
<string name="nothing_here">"Nothing here"</string>
<string name="tab_new">"New"</string>
<string name="tab_read">"All"</string>
<string name="tab_favs">"Favorites"</string>
<string name="action_about">"About"</string>
<string name="marked_as_read">"Item read"</string>
<string name="undo_string">"Undo"</string>
<string name="addStringNoUrl">"Log in to add sources."</string>
<string name="cant_get_sources">"Can't get sources list."</string>
<string name="cant_create_source">"Can't create source."</string>
<string name="cant_get_spouts">"Can't get spouts list."</string>
<string name="form_not_complete">"The form is not complete"</string>
<string name="pref_header_links">"Links"</string>
<string name="issue_tracker_link">"Issue Tracker"</string>
<string name="issue_tracker_summary">"Report a bug or ask for a new feature"</string>
<string name="warning_wrong_url">"WARNING"</string>
<string name="pref_switch_card_view_title">"Card View"</string>
<string name="cant_mark_favortie">"Can't mark article as favorite"</string>
<string name="cant_unmark_favortie">"Can't remove item from favorite"</string>
<string name="share">"Share"</string>
<string name="rating_prompt_title">"Enjoying the app ?"</string>
<string name="rating_prompt_yes">"Yes !"</string>
<string name="rating_prompt_no">"Not really …"</string>
<string name="rating_prompt_feedback_title">"Can you tell us why ?"</string>
<string name="rating_prompt_feedback_yes">"OK !"</string>
<string name="rating_prompt_feedback_no">"Not now."</string>
<string name="rating_prompt_rating_title">"Great ! Can you rate us on the Store ?"</string>
<string name="rating_prompt_rating_yes">"Sure !"</string>
<string name="rating_prompt_rating_no">"Not right now."</string>
<string name="rating_prompt_thanks">"Thanks, your feedback help enhance the app !"</string>
<string name="switch_unread_count">"Display the unread count as a badge for the bottom bar."</string>
<string name="switch_unread_count_title">"Display unread count"</string>
<string name="display_all_counts_title">"Display count for favorite and read"</string>
<string name="menu_share_the_app">"Invite friends"</string>
<string name="invitation_title">"Try this app for your Selfoss RSS feeds !"</string>
<string name="invitation_message">"I use this app for my Selfoss RSS feeds. You may like it too !"</string>
<string name="invitation_cta">"Try the app"</string>
<string name="text_wrong_url">"You seem to be trying to use an invalid URL. Make sure it is correct, and if the problem persists, contact me (via the store contact link). Please note that the app needs you to be using Selfoss. You can't access RSS feeds without it."</string>
<string name="pref_general_internal_browser_title">"Open links inside the app"</string>
<string name="pref_general_internal_browser_on">"Articles will open inside the app"</string>
<string name="pref_general_internal_browser_off">"Articles will open with your default browser"</string>
<string name="prefer_article_viewer_title">"Use the article viewer"</string>
<string name="prefer_article_viewer_on">"Will use the article viewer instead of the internal browser"</string>
<string name="prefer_article_viewer_off">"Will use the internal browser instead of the article viewer"</string>
<string name="pref_general_category_links">"Link handeling"</string>
<string name="pref_general_category_displaying">"Displaying"</string>
<string name="pref_general_category_actions">"Actions"</string>
<string name="pref_switch_card_view_on">"The articles will be displayed as cards"</string>
<string name="pref_switch_card_view_off">"The articles will be displayed as a list"</string>
<string name="pref_switch_actions_tap_on">"Displays the action bar under the article"</string>
<string name="pref_switch_actions_tap_off">"When selecting an article it will open in your selected browser"</string>
<string name="menu_home_refresh">"Update remote"</string>
<string name="refresh_success_response">"The remote is updated, you can now reload the articles list"</string>
<string name="refresh_failer_message">"The update didn't work, try again later, or check your selfoss logs."</string>
<string name="refresh_in_progress">"Refresh in progress"</string>
<string name="new_apk_available_title">"A new APK is available."</string>
<string name="new_apk_available_message">"A new APK is available to download on the official repository."</string>
<string name="new_apk_available_get">"Download now"</string>
<string name="new_apk_available_no">"Ignore version"</string>
<string name="intro_hello_title">"Hi there !"</string>
<string name="intro_hello_message">"Thanks for downloading the app !"</string>
<string name="intro_needs_selfoss_title">"Before you start…"</string>
<string name="intro_needs_selfoss_message">"You can't use the app without a Selfoss instance."</string>
<string name="intro_needs_selfoss_link">"What is Selfoss ?"</string>
<string name="intro_all_set_title">"All set !"</string>
<string name="intro_all_set_message">"You are ready to use the app. Don't forget to go to the settings page to configure your app, and where you'll find some useful links."</string>
<string name="card_height_title">Full height cards</string>
<string name="card_height_on">Cards height will adjust to its content</string>
<string name="card_height_off">Card height will be fixed</string>
<string name="source_code">Source code</string>
<string name="cant_mark_read">Can\'t mark article as read</string>
<string name="drawer_error_loading_tags">Error loading tags…</string>
<string name="drawer_error_loading_sources">Error loading sources…</string>
<string name="drawer_item_filters">Filters</string>
<string name="drawer_action_clear">clear</string>
<string name="drawer_item_tags">Tags</string>
<string name="drawer_item_sources">Sources</string>
<string name="drawer_action_edit">edit</string>
<string name="cache_drawer_error" tools:keep="@string/cache_drawer_error">Couldn\'t cache your drawer data</string>
<string name="no_tags_loaded">No tags loaded</string>
<string name="no_sources_loaded">No sources loaded</string>
<string name="drawer_loading">Loading …</string>
<string name="menu_home_search">Search</string>
<string name="can_delete_source">Can\'t delete the source…</string>
<string name="base_url_error">There was an issue when trying to communicate with your Selfoss Instance. If the issue persists, please get in touch with me.</string>
<string name="pref_header_theme">Themes</string>
<string name="default_theme">Default</string>
<string name="teal_orange_theme">Teal/Orange/Light</string>
<string name="cyan_pink_theme">Cyan/Pink/Light</string>
<string name="grey_orange_theme">Grey/Orange/Light</string>
<string name="blue_amber_theme">Blue/Amber/Light</string>
<string name="indigo_pink_theme">Indigo/Pink/Light</string>
<string name="red_teal_theme">Red/Teal/Light</string>
<string name="teal_orange_dark_theme">Teal/Orange/Dark</string>
<string name="cyan_pink_dark_theme">Cyan/Pink/Dark</string>
<string name="default_dark_theme">Default/Dark</string>
<string name="grey_orange_dark_theme">Grey/Orange/Dark</string>
<string name="blue_amber_dark_theme">Blue/Amber/Dark</string>
<string name="indigo_pink_dark_theme">Indigo/Pink/Dark</string>
<string name="red_teal_dark_theme">Red/Teal/Dark</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activate to log login errors</string>
<string name="login_debug_on">Any error on the login page will be logged</string>
<string name="login_debug_off">No log on the login page</string>
<string name="login_menu_debug">Debug</string>
<string name="self_hosted_cert_switch">Using a self hosted certificate ?</string>
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
<string name="summary_debug_identifier">Debug identifier</string>
<string name="unique_id_to_clipboard">Identifier copied to your clipboard</string>
<string name="display_header_drawer_summary">Display a header with the selfoss instance url on the lateral drawer.</string>
<string name="display_header_drawer_title">Account header</string>
<string name="login_everything_title">Logging every api calls</string>
<string name="login_everything_on">This will log every api call for debug purpose.</string>
<string name="login_everything_off">No api call will be logged</string>
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
<string name="translation">Translation</string>
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
<string name="drawer_report_bug">Report a bug</string>
<string name="items_number_should_be_number">The items number should be an integer.</string>
<string name="reader_action_more">Read more</string>
<string name="reader_action_open">Open in browser</string>
<string name="reader_action_share">Share</string>
</resources>

View File

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">"Lector para Selfoss"</string>
<string name="title_activity_login">"Iniciar sesión"</string>
<string name="prompt_password">"Contraseña"</string>
<string name="prompt_http_password">"Contraseña HTTP"</string>
<string name="action_sign_in">"Empezar"</string>
<string name="error_invalid_password">"La contraseña no es suficientemente larga"</string>
<string name="error_field_required">"Campo requerido"</string>
<string name="prompt_url">"Url"</string>
<string name="withLoginSwitch">"Inicio de sesión requerido ?"</string>
<string name="withHttpLoginSwitch">"Inicio de sesión HTTP requerido ?"</string>
<string name="login_url_problem">"Oops. Puede que necesite añadir un \"/\" al final de la url."</string>
<string name="prompt_login">"Nombre de usuario"</string>
<string name="prompt_http_login">"Nombre de usuario HTTP"</string>
<string name="label_share">"Compartir"</string>
<string name="readAll">"Leer todo"</string>
<string name="action_disconnect">"Desconectar"</string>
<string name="title_activity_settings">"Configuración"</string>
<string name="pref_header_general">"General"</string>
<string name="pref_switch_actions_tap_title">"Acción tocar en los artículos"</string>
<string name="add_source_hint_tags">"Etiqueta1, Etiqueta2, Etiqueta3"</string>
<string name="add_source_hint_url">"Enlace"</string>
<string name="add_source_hint_name">"Nombre"</string>
<string name="add_source">"Añadir una fuente"</string>
<string name="add_source_save">"Guardar"</string>
<string name="wrong_infos">"Revise sus datos de nuevo."</string>
<string name="all_posts_not_read">"No todas las publicaciones fueron leídas"</string>
<string name="all_posts_read">"Todas las publicaciones fueron leídas"</string>
<string name="cant_get_favs">"No se pueden obtener favoritos"</string>
<string name="cant_get_new_elements">"No puede recibir nuevos artículos"</string>
<string name="cant_get_read">"No puede recibir artículos leídos"</string>
<string name="nothing_here">"Nada aquí"</string>
<string name="tab_new">"Nuevo"</string>
<string name="tab_read">"Todo"</string>
<string name="tab_favs">"Favoritos"</string>
<string name="action_about">"Acerca de"</string>
<string name="marked_as_read">"Artículo leído"</string>
<string name="undo_string">"Deshacer"</string>
<string name="addStringNoUrl">"Iniciar sesión para añadir fuentes."</string>
<string name="cant_get_sources">"No se puede obtener la lista de fuentes."</string>
<string name="cant_create_source">"No se puede crear la fuente."</string>
<string name="cant_get_spouts">"No se puede obtener la lista de fuentes."</string>
<string name="form_not_complete">"El formulario no está completo"</string>
<string name="pref_header_links">"Enlaces"</string>
<string name="issue_tracker_link">"Rastreador de Incidencias"</string>
<string name="issue_tracker_summary">"Reportar un error o solicitar una nueva función"</string>
<string name="warning_wrong_url">"ADVERTENCIA"</string>
<string name="pref_switch_card_view_title">"Vista de la tarjeta"</string>
<string name="cant_mark_favortie">"No puede marcar el artículo como favorito"</string>
<string name="cant_unmark_favortie">"No se puede quitar el artículo de favoritos"</string>
<string name="share">"Compartir"</string>
<string name="rating_prompt_title">"¿Disfrutando la aplicación?"</string>
<string name="rating_prompt_yes">"¡Sí!"</string>
<string name="rating_prompt_no">"La verdad es que no…"</string>
<string name="rating_prompt_feedback_title">"¿Puede decirnos por qué?"</string>
<string name="rating_prompt_feedback_yes">"¡Vale!"</string>
<string name="rating_prompt_feedback_no">"Ahora no."</string>
<string name="rating_prompt_rating_title">"¡Excelente! ¿Puede valorarnos en la tienda?"</string>
<string name="rating_prompt_rating_yes">"¡Claro!"</string>
<string name="rating_prompt_rating_no">"No en este momento."</string>
<string name="rating_prompt_thanks">"¡Gracias, sus comentarios ayudan a mejorar la aplicación!"</string>
<string name="switch_unread_count">"Mostrar el recuento no leído como una insignia de la barra inferior."</string>
<string name="switch_unread_count_title">"Mostrar recuento no leído"</string>
<string name="display_all_counts_title">"Mostrar recuento de favoritos y leídos"</string>
<string name="invitation_title">"¡Prueba esta aplicación para tu contenido RSS de Selfoss!"</string>
<string name="invitation_message">"Yo uso esta aplicación para mi contenido RSS de Selfoss. ¡Te puede gusta también!"</string>
<string name="invitation_cta">"Probar la aplicación"</string>
<string name="text_wrong_url">"Parece estar tratando de utilizar una dirección URL inválida. Asegúrese de que sea correcta y si el problema persiste, póngase en contacto conmigo (mediante el enlace de contacto de la tienda). Tenga en cuenta que la aplicación necesita utilizar Selfoss. No se puede acceder al contenido RSS sin él."</string>
<string name="pref_general_internal_browser_title">"Abrir enlaces dentro de la aplicación"</string>
<string name="pref_general_internal_browser_on">"Los artículos se abrirán dentro de la aplicación"</string>
<string name="pref_general_internal_browser_off">"Los artículos se abrirán con tu navegador predeterminado"</string>
<string name="prefer_article_viewer_title">"Utilizar el visor de artículo"</string>
<string name="prefer_article_viewer_on">"Se usará el visor de artículos en lugar del navegador interno"</string>
<string name="prefer_article_viewer_off">"Se utilizará el navegador interno en lugar del visor de artículo"</string>
<string name="pref_general_category_links">"Control de enlaces"</string>
<string name="pref_general_category_displaying">"Mostrando"</string>
<string name="pref_general_category_actions">"Acciones"</string>
<string name="pref_switch_card_view_on">"Los artículos se mostrarán como tarjetas"</string>
<string name="pref_switch_card_view_off">"Los artículos se mostrarán como una lista"</string>
<string name="pref_switch_actions_tap_on">"Muestra la barra de acción debajo del artículo"</string>
<string name="pref_switch_actions_tap_off">"Al seleccionar un artículo se abrirá en el navegador seleccionado"</string>
<string name="menu_home_refresh">"Actualizar remoto"</string>
<string name="refresh_success_response">"Se actualizó el remoto, ahora puede recargar la lista de artículos"</string>
<string name="refresh_failer_message">"La actualización no funcionó, inténtalo más tarde o compruebe los registros de selfoss."</string>
<string name="refresh_in_progress">"Actualización en progreso"</string>
<string name="new_apk_available_title">"Una nueva versión está disponible."</string>
<string name="new_apk_available_message">"Un APK nuevo está disponible para descarga en el repositorio oficial."</string>
<string name="new_apk_available_get">"Descargar ahora"</string>
<string name="new_apk_available_no">"Ignorar versión"</string>
<string name="intro_hello_title">"¡Hola!"</string>
<string name="intro_hello_message">"¡Gracias por descargar la aplicación!"</string>
<string name="intro_needs_selfoss_title">"Antes de empezar…"</string>
<string name="intro_needs_selfoss_message">"No se puede utilizar la aplicación sin una instancia de Selfoss."</string>
<string name="intro_needs_selfoss_link">"¿Qué es Selfoss?"</string>
<string name="intro_all_set_title">"¡Todo listo!"</string>
<string name="intro_all_set_message">"Estás listo para utilizar la aplicación. No olvides ir a la página de configuración para configurar su aplicación, y donde usted encontrará algunos enlaces útiles."</string>
<string name="card_height_title">Tarjetas de altura completas</string>
<string name="card_height_on">Altura de tarjetas se ajustará a su contenido</string>
<string name="card_height_off">Se fijará la altura de la tarjeta</string>
<string name="source_code">Código fuente</string>
<string name="cant_mark_read">No puede marcar el artículo como leído</string>
<string name="drawer_error_loading_tags">Error al cargar etiquetas…</string>
<string name="drawer_error_loading_sources">Error al cargar fuentes…</string>
<string name="drawer_item_filters">Filtros</string>
<string name="drawer_action_clear">limpiar</string>
<string name="drawer_item_tags">Etiquetas</string>
<string name="drawer_item_sources">Fuentes</string>
<string name="drawer_action_edit">editar</string>
<string name="cache_drawer_error" tools:keep="@string/cache_drawer_error">No se pudieron guardar en caché los datos de su cajón</string>
<string name="no_tags_loaded">No hay etiquetas cargadas</string>
<string name="no_sources_loaded">No hay fuentes cargadas</string>
<string name="drawer_loading">Cargando…</string>
<string name="menu_home_search">Buscar</string>
<string name="can_delete_source">No se puede eliminar la fuente…</string>
<string name="base_url_error">Hubo un problema al intentar comunicarse con su instancia de Selfoss. Si el problema persiste, póngase en contacto conmigo.</string>
<string name="pref_header_theme">Temas</string>
<string name="default_theme">Predeterminado</string>
<string name="default_dark_theme">Predeterminado/Oscuro</string>
<string name="pref_header_debug">Depurar</string>
<string name="login_debug_title">Activar para registrar errores de inicio de sesión</string>
<string name="login_debug_on">Cualquier error en la página de inicio de sesión se registrará</string>
<string name="login_debug_off">No hay registro en la página de inicio de sesión</string>
<string name="login_menu_debug">Depurar</string>
<string name="self_hosted_cert_switch">Utilizando un certificado alojado propiamente ?</string>
<string name="self_signed_cert_warning">Por razones de seguridad, los certificados propios no son compatibles por defecto. Activando esto, no seré responsable de cualquier problema de seguridad que encuentre.</string>
<string name="pref_selfoss_category">Api de Selfoss</string>
<string name="pref_api_items_number_title">Número de artículos cargados</string>
<string name="pref_hidden_tags">Etiquetas ocultas</string>
<string name="read_debug_title">¿Leer los artículos que aparecen como no leídos?</string>
<string name="read_debug_off">Sin registro al marcar un elemento como leído</string>
<string name="read_debug_on">Llamadas a la Api se registrarán al marcar un artículo como leído</string>
<string name="summary_debug_identifier">Identificador de depuración</string>
<string name="unique_id_to_clipboard">Identificador copiado a su portapapeles</string>
<string name="display_header_drawer_summary">Mostrar una cabecera con la url de instancia de selfoss en el cajón lateral.</string>
<string name="display_header_drawer_title">Cabecera de cuenta</string>
<string name="login_everything_title">Registrando todas las llamadas a la api</string>
<string name="login_everything_on">Esto registrará cada llamada a la api para propósito de depuración.</string>
<string name="login_everything_off">Ninguna llamada de api se registrará</string>
<string name="pref_general_infinite_loading_title">Cargar más artículos en desplazamiento</string>
<string name="translation">Traducción</string>
<string name="cant_open_invalid_url">La url del elemento no es válida. Estoy buscando resolver este problema para que la aplicación no colapse.</string>
<string name="drawer_report_bug">Reportar un error</string>
<string name="items_number_should_be_number">El número de artículos debe ser un número entero.</string>
<string name="reader_action_more">Leer más</string>
<string name="reader_action_open">Abrir en el navegador</string>
<string name="reader_action_share">Compartir</string>
<string name="pref_switch_actions_pager_scroll_on">Marcar artículos como leidos al desplazarse entre ellos.</string>
<string name="add_to_favs_reader">Añadir a Favoritos</string>
<string name="remove_to_favs_reader">Eliminar de favoritos</string>
<string name="pref_content_reader_font_size">Tamaño de la fuente del lector</string>
<string name="pref_header_viewer">Visor de artículos</string>
<string name="refresh_dialog_message">Esto actualizará su instancia de Selfoss.</string>
<string name="markall_dialog_message">Esto marcará todos los artículos como leídos.</string>
<string name="pref_switch_actions_pager_scroll">Marcar artículos como leídos al deslizar con el dedo hacia los lados</string>
<string name="pref_switch_actions_pager_scroll_off">No marcar artículos como leídos al deslizar con el dedo hacia los lados.</string>
<string name="gdpr_dialog_message">La aplicación no recopila ningún dato personal. Todas las herramientas de analítica fueron eliminadas. El envío de informes de errores es opcional, así como los registros de depuración. Ten en cuenta que tanto los registros como los informes de errores son esenciales para el desarrollo de la aplicación (Puedes configurar todo en \"Configuración &gt; Depurar\").</string>
<string name="gdpr_dialog_title">La aplicación no comparte ningún dato personal sobre usted.</string>
<string name="crash_dialog_text">Algo salió mal. Envié el informe al desarrollador.</string>
<string name="crash_dialog_comment">Puede agregar cualquier información útil en el siguiente comentario. No incluya ningún dato personal en el comentario. Podría enviarme un correo electrónico con el id de depuración para ser notificado cuando el problema se resuelva.</string>
<string name="pref_acra_user_email">Correo electrónico de contacto</string>
<string name="pref_acra_user_email_summary">Añade un correo electrónico para que pueda ponerme en contacto contigo sobre los informes de fallos que has enviado.</string>
<string name="pref_acra_alwaysaccept">Enviar automáticamente informe de fallos</string>
<string name="pref_acra_alwaysaccept_enabled">Se enviaran automáticamente los informes de fallos</string>
<string name="pref_acra_alwaysaccept_disabled">Le preguntará al enviar informes de fallos.</string>
<string name="pref_debug_crash_reports">Informe de fallos</string>
<string name="pref_debug_debug_logs">Registro de depuración (éstos se enviarán sin diálogo)</string>
<string name="acra_login">Habilitar el registro</string>
<string name="drawer_item_hidden_tags">Etiquetas ocultas</string>
<string name="unmark">Marcar artículo como no leído</string>
</resources>

View File

@ -1,161 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">"Reader for Selfoss"</string>
<string name="title_activity_login">"Log in"</string>
<string name="prompt_password">"Password"</string>
<string name="prompt_http_password">"HTTP Password"</string>
<string name="action_sign_in">"Go"</string>
<string name="error_invalid_password">"Password not long enough"</string>
<string name="error_field_required">"Field required"</string>
<string name="prompt_url">"Url"</string>
<string name="withLoginSwitch">"Login required ?"</string>
<string name="withHttpLoginSwitch">"HTTP Login required ?"</string>
<string name="login_url_problem">"Oops. You may need to add a \"/\" at the end of the url."</string>
<string name="prompt_login">"Username"</string>
<string name="prompt_http_login">"HTTP Username"</string>
<string name="label_share">"Share"</string>
<string name="readAll">"Read all"</string>
<string name="action_disconnect">"Disconnect"</string>
<string name="title_activity_settings">"Settings"</string>
<string name="pref_header_general">"General"</string>
<string name="pref_switch_actions_tap_title">"Tap action on the articles"</string>
<string name="add_source_hint_tags">"Tag1, Tag2, Tag3"</string>
<string name="add_source_hint_url">"Link"</string>
<string name="add_source_hint_name">"Name"</string>
<string name="add_source">"Add a source"</string>
<string name="add_source_save">"Save"</string>
<string name="wrong_infos">"Check your details again."</string>
<string name="all_posts_not_read">"All posts weren't read"</string>
<string name="all_posts_read">"All posts were read"</string>
<string name="cant_get_favs">"Can't get favorites"</string>
<string name="cant_get_new_elements">"Can't get new articles"</string>
<string name="cant_get_read">"Can't get read articles"</string>
<string name="nothing_here">"Nothing here"</string>
<string name="tab_new">"New"</string>
<string name="tab_read">"All"</string>
<string name="tab_favs">"Favorites"</string>
<string name="action_about">"About"</string>
<string name="marked_as_read">"Item read"</string>
<string name="undo_string">"Undo"</string>
<string name="addStringNoUrl">"Log in to add sources."</string>
<string name="cant_get_sources">"Can't get sources list."</string>
<string name="cant_create_source">"Can't create source."</string>
<string name="cant_get_spouts">"Can't get spouts list."</string>
<string name="form_not_complete">"The form is not complete"</string>
<string name="pref_header_links">"Links"</string>
<string name="issue_tracker_link">"Issue Tracker"</string>
<string name="issue_tracker_summary">"Report a bug or ask for a new feature"</string>
<string name="warning_wrong_url">"WARNING"</string>
<string name="pref_switch_card_view_title">"Card View"</string>
<string name="cant_mark_favortie">"Can't mark article as favorite"</string>
<string name="cant_unmark_favortie">"Can't remove item from favorite"</string>
<string name="share">"Share"</string>
<string name="rating_prompt_title">"Enjoying the app ?"</string>
<string name="rating_prompt_yes">"Yes !"</string>
<string name="rating_prompt_no">"Not really …"</string>
<string name="rating_prompt_feedback_title">"Can you tell us why ?"</string>
<string name="rating_prompt_feedback_yes">"OK !"</string>
<string name="rating_prompt_feedback_no">"Not now."</string>
<string name="rating_prompt_rating_title">"Great ! Can you rate us on the Store ?"</string>
<string name="rating_prompt_rating_yes">"Sure !"</string>
<string name="rating_prompt_rating_no">"Not right now."</string>
<string name="rating_prompt_thanks">"Thanks, your feedback help enhance the app !"</string>
<string name="switch_unread_count">"Display the unread count as a badge for the bottom bar."</string>
<string name="switch_unread_count_title">"Display unread count"</string>
<string name="display_all_counts_title">"Display count for favorite and read"</string>
<string name="menu_share_the_app">"Invite friends"</string>
<string name="invitation_title">"Try this app for your Selfoss RSS feeds !"</string>
<string name="invitation_message">"I use this app for my Selfoss RSS feeds. You may like it too !"</string>
<string name="invitation_cta">"Try the app"</string>
<string name="text_wrong_url">"You seem to be trying to use an invalid URL. Make sure it is correct, and if the problem persists, contact me (via the store contact link). Please note that the app needs you to be using Selfoss. You can't access RSS feeds without it."</string>
<string name="pref_general_internal_browser_title">"Open links inside the app"</string>
<string name="pref_general_internal_browser_on">"Articles will open inside the app"</string>
<string name="pref_general_internal_browser_off">"Articles will open with your default browser"</string>
<string name="prefer_article_viewer_title">"Use the article viewer"</string>
<string name="prefer_article_viewer_on">"Will use the article viewer instead of the internal browser"</string>
<string name="prefer_article_viewer_off">"Will use the internal browser instead of the article viewer"</string>
<string name="pref_general_category_links">"Link handeling"</string>
<string name="pref_general_category_displaying">"Displaying"</string>
<string name="pref_general_category_actions">"Actions"</string>
<string name="pref_switch_card_view_on">"The articles will be displayed as cards"</string>
<string name="pref_switch_card_view_off">"The articles will be displayed as a list"</string>
<string name="pref_switch_actions_tap_on">"Displays the action bar under the article"</string>
<string name="pref_switch_actions_tap_off">"When selecting an article it will open in your selected browser"</string>
<string name="menu_home_refresh">"Update remote"</string>
<string name="refresh_success_response">"The remote is updated, you can now reload the articles list"</string>
<string name="refresh_failer_message">"The update didn't work, try again later, or check your selfoss logs."</string>
<string name="refresh_in_progress">"Refresh in progress"</string>
<string name="new_apk_available_title">"A new APK is available."</string>
<string name="new_apk_available_message">"A new APK is available to download on the official repository."</string>
<string name="new_apk_available_get">"Download now"</string>
<string name="new_apk_available_no">"Ignore version"</string>
<string name="intro_hello_title">"Hi there !"</string>
<string name="intro_hello_message">"Thanks for downloading the app !"</string>
<string name="intro_needs_selfoss_title">"Before you start…"</string>
<string name="intro_needs_selfoss_message">"You can't use the app without a Selfoss instance."</string>
<string name="intro_needs_selfoss_link">"What is Selfoss ?"</string>
<string name="intro_all_set_title">"All set !"</string>
<string name="intro_all_set_message">"You are ready to use the app. Don't forget to go to the settings page to configure your app, and where you'll find some useful links."</string>
<string name="card_height_title">Full height cards</string>
<string name="card_height_on">Cards height will adjust to its content</string>
<string name="card_height_off">Card height will be fixed</string>
<string name="source_code">Source code</string>
<string name="cant_mark_read">Can\'t mark article as read</string>
<string name="drawer_error_loading_tags">Error loading tags…</string>
<string name="drawer_error_loading_sources">Error loading sources…</string>
<string name="drawer_item_filters">Filters</string>
<string name="drawer_action_clear">clear</string>
<string name="drawer_item_tags">Tags</string>
<string name="drawer_item_sources">Sources</string>
<string name="drawer_action_edit">edit</string>
<string name="cache_drawer_error" tools:keep="@string/cache_drawer_error">Couldn\'t cache your drawer data</string>
<string name="no_tags_loaded">No tags loaded</string>
<string name="no_sources_loaded">No sources loaded</string>
<string name="drawer_loading">Loading …</string>
<string name="menu_home_search">Search</string>
<string name="can_delete_source">Can\'t delete the source…</string>
<string name="base_url_error">There was an issue when trying to communicate with your Selfoss Instance. If the issue persists, please get in touch with me.</string>
<string name="pref_header_theme">Themes</string>
<string name="default_theme">Default</string>
<string name="teal_orange_theme">Teal/Orange/Light</string>
<string name="cyan_pink_theme">Cyan/Pink/Light</string>
<string name="grey_orange_theme">Grey/Orange/Light</string>
<string name="blue_amber_theme">Blue/Amber/Light</string>
<string name="indigo_pink_theme">Indigo/Pink/Light</string>
<string name="red_teal_theme">Red/Teal/Light</string>
<string name="teal_orange_dark_theme">Teal/Orange/Dark</string>
<string name="cyan_pink_dark_theme">Cyan/Pink/Dark</string>
<string name="default_dark_theme">Default/Dark</string>
<string name="grey_orange_dark_theme">Grey/Orange/Dark</string>
<string name="blue_amber_dark_theme">Blue/Amber/Dark</string>
<string name="indigo_pink_dark_theme">Indigo/Pink/Dark</string>
<string name="red_teal_dark_theme">Red/Teal/Dark</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activate to log login errors</string>
<string name="login_debug_on">Any error on the login page will be logged</string>
<string name="login_debug_off">No log on the login page</string>
<string name="login_menu_debug">Debug</string>
<string name="self_hosted_cert_switch">Using a self hosted certificate ?</string>
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
<string name="summary_debug_identifier">Debug identifier</string>
<string name="unique_id_to_clipboard">Identifier copied to your clipboard</string>
<string name="display_header_drawer_summary">Display a header with the selfoss instance url on the lateral drawer.</string>
<string name="display_header_drawer_title">Account header</string>
<string name="login_everything_title">Logging every api calls</string>
<string name="login_everything_on">This will log every api call for debug purpose.</string>
<string name="login_everything_off">No api call will be logged</string>
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
<string name="translation">Translation</string>
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
<string name="drawer_report_bug">Report a bug</string>
<string name="items_number_should_be_number">The items number should be an integer.</string>
<string name="reader_action_more">Read more</string>
<string name="reader_action_open">Open in browser</string>
<string name="reader_action_share">Share</string>
</resources>

View File

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">"Reader for Selfoss"</string>
<string name="title_activity_login">"Log in"</string>
<string name="prompt_password">"Password"</string>
<string name="prompt_http_password">"HTTP Password"</string>
<string name="action_sign_in">"Go"</string>
<string name="error_invalid_password">"Password not long enough"</string>
<string name="error_field_required">"Field required"</string>
<string name="prompt_url">"Url"</string>
<string name="withLoginSwitch">"Login required ?"</string>
<string name="withHttpLoginSwitch">"HTTP Login required ?"</string>
<string name="login_url_problem">"Oops. You may need to add a \"/\" at the end of the url."</string>
<string name="prompt_login">"Username"</string>
<string name="prompt_http_login">"HTTP Username"</string>
<string name="label_share">"Share"</string>
<string name="readAll">"Read all"</string>
<string name="action_disconnect">"Disconnect"</string>
<string name="title_activity_settings">"Settings"</string>
<string name="pref_header_general">"General"</string>
<string name="pref_switch_actions_tap_title">"Tap action on the articles"</string>
<string name="add_source_hint_tags">"Tag1, Tag2, Tag3"</string>
<string name="add_source_hint_url">"Link"</string>
<string name="add_source_hint_name">"Name"</string>
<string name="add_source">"Add a source"</string>
<string name="add_source_save">"Save"</string>
<string name="wrong_infos">"Check your details again."</string>
<string name="all_posts_not_read">"All posts weren't read"</string>
<string name="all_posts_read">"All posts were read"</string>
<string name="cant_get_favs">"Can't get favorites"</string>
<string name="cant_get_new_elements">"Can't get new articles"</string>
<string name="cant_get_read">"Can't get read articles"</string>
<string name="nothing_here">"Nothing here"</string>
<string name="tab_new">"New"</string>
<string name="tab_read">"All"</string>
<string name="tab_favs">"Favorites"</string>
<string name="action_about">"About"</string>
<string name="marked_as_read">"Item read"</string>
<string name="undo_string">"Undo"</string>
<string name="addStringNoUrl">"Log in to add sources."</string>
<string name="cant_get_sources">"Can't get sources list."</string>
<string name="cant_create_source">"Can't create source."</string>
<string name="cant_get_spouts">"Can't get spouts list."</string>
<string name="form_not_complete">"The form is not complete"</string>
<string name="pref_header_links">"Links"</string>
<string name="issue_tracker_link">"Issue Tracker"</string>
<string name="issue_tracker_summary">"Report a bug or ask for a new feature"</string>
<string name="warning_wrong_url">"WARNING"</string>
<string name="pref_switch_card_view_title">"Card View"</string>
<string name="cant_mark_favortie">"Can't mark article as favorite"</string>
<string name="cant_unmark_favortie">"Can't remove item from favorite"</string>
<string name="share">"Share"</string>
<string name="rating_prompt_title">"Enjoying the app ?"</string>
<string name="rating_prompt_yes">"Yes !"</string>
<string name="rating_prompt_no">"Not really …"</string>
<string name="rating_prompt_feedback_title">"Can you tell us why ?"</string>
<string name="rating_prompt_feedback_yes">"OK !"</string>
<string name="rating_prompt_feedback_no">"Not now."</string>
<string name="rating_prompt_rating_title">"Great ! Can you rate us on the Store ?"</string>
<string name="rating_prompt_rating_yes">"Sure !"</string>
<string name="rating_prompt_rating_no">"Not right now."</string>
<string name="rating_prompt_thanks">"Thanks, your feedback help enhance the app !"</string>
<string name="switch_unread_count">"Display the unread count as a badge for the bottom bar."</string>
<string name="switch_unread_count_title">"Display unread count"</string>
<string name="display_all_counts_title">"Display count for favorite and read"</string>
<string name="invitation_title">"Try this app for your Selfoss RSS feeds !"</string>
<string name="invitation_message">"I use this app for my Selfoss RSS feeds. You may like it too !"</string>
<string name="invitation_cta">"Try the app"</string>
<string name="text_wrong_url">"You seem to be trying to use an invalid URL. Make sure it is correct, and if the problem persists, contact me (via the store contact link). Please note that the app needs you to be using Selfoss. You can't access RSS feeds without it."</string>
<string name="pref_general_internal_browser_title">"Open links inside the app"</string>
<string name="pref_general_internal_browser_on">"Articles will open inside the app"</string>
<string name="pref_general_internal_browser_off">"Articles will open with your default browser"</string>
<string name="prefer_article_viewer_title">"Use the article viewer"</string>
<string name="prefer_article_viewer_on">"Will use the article viewer instead of the internal browser"</string>
<string name="prefer_article_viewer_off">"Will use the internal browser instead of the article viewer"</string>
<string name="pref_general_category_links">"Link handling"</string>
<string name="pref_general_category_displaying">"Displaying"</string>
<string name="pref_general_category_actions">"Actions"</string>
<string name="pref_switch_card_view_on">"The articles will be displayed as cards"</string>
<string name="pref_switch_card_view_off">"The articles will be displayed as a list"</string>
<string name="pref_switch_actions_tap_on">"Displays the action bar under the article"</string>
<string name="pref_switch_actions_tap_off">"When selecting an article it will open in your selected browser"</string>
<string name="menu_home_refresh">"Update remote"</string>
<string name="refresh_success_response">"The remote is updated, you can now reload the articles list"</string>
<string name="refresh_failer_message">"The update didn't work, try again later, or check your selfoss logs."</string>
<string name="refresh_in_progress">"Refresh in progress"</string>
<string name="new_apk_available_title">"A new APK is available."</string>
<string name="new_apk_available_message">"A new APK is available to download on the official repository."</string>
<string name="new_apk_available_get">"Download now"</string>
<string name="new_apk_available_no">"Ignore version"</string>
<string name="intro_hello_title">"Hi there !"</string>
<string name="intro_hello_message">"Thanks for downloading the app !"</string>
<string name="intro_needs_selfoss_title">"Before you start…"</string>
<string name="intro_needs_selfoss_message">"You can't use the app without a Selfoss instance."</string>
<string name="intro_needs_selfoss_link">"What is Selfoss ?"</string>
<string name="intro_all_set_title">"All set !"</string>
<string name="intro_all_set_message">"You are ready to use the app. Don't forget to go to the settings page to configure your app, and where you'll find some useful links."</string>
<string name="card_height_title">Full height cards</string>
<string name="card_height_on">Cards height will adjust to its content</string>
<string name="card_height_off">Card height will be fixed</string>
<string name="source_code">Source code</string>
<string name="cant_mark_read">Can\'t mark article as read</string>
<string name="drawer_error_loading_tags">Error loading tags…</string>
<string name="drawer_error_loading_sources">Error loading sources…</string>
<string name="drawer_item_filters">Filters</string>
<string name="drawer_action_clear">clear</string>
<string name="drawer_item_tags">Tags</string>
<string name="drawer_item_sources">Sources</string>
<string name="drawer_action_edit">edit</string>
<string name="cache_drawer_error" tools:keep="@string/cache_drawer_error">Couldn\'t cache your drawer data</string>
<string name="no_tags_loaded">No tags loaded</string>
<string name="no_sources_loaded">No sources loaded</string>
<string name="drawer_loading">Loading …</string>
<string name="menu_home_search">Search</string>
<string name="can_delete_source">Can\'t delete the source…</string>
<string name="base_url_error">There was an issue when trying to communicate with your Selfoss Instance. If the issue persists, please get in touch with me.</string>
<string name="pref_header_theme">Themes</string>
<string name="default_theme">Default</string>
<string name="default_dark_theme">Default/Dark</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activate to log login errors</string>
<string name="login_debug_on">Any error on the login page will be logged</string>
<string name="login_debug_off">No log on the login page</string>
<string name="login_menu_debug">Debug</string>
<string name="self_hosted_cert_switch">Using a self hosted certificate ?</string>
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="pref_hidden_tags">Hidden Tags</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
<string name="summary_debug_identifier">Debug identifier</string>
<string name="unique_id_to_clipboard">Identifier copied to your clipboard</string>
<string name="display_header_drawer_summary">Display a header with the selfoss instance url on the lateral drawer.</string>
<string name="display_header_drawer_title">Account header</string>
<string name="login_everything_title">Logging every api calls</string>
<string name="login_everything_on">This will log every api call for debug purpose.</string>
<string name="login_everything_off">No api call will be logged</string>
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
<string name="translation">Translation</string>
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
<string name="drawer_report_bug">Report a bug</string>
<string name="items_number_should_be_number">The items number should be an integer.</string>
<string name="reader_action_more">Read more</string>
<string name="reader_action_open">Open in browser</string>
<string name="reader_action_share">Share</string>
<string name="pref_switch_actions_pager_scroll_on">Mark articles as read when swiping between articles.</string>
<string name="add_to_favs_reader">Add to favorites</string>
<string name="remove_to_favs_reader">Remove from favorites</string>
<string name="pref_content_reader_font_size">Article reader content font size</string>
<string name="pref_header_viewer">Article viewer</string>
<string name="refresh_dialog_message">This will refresh your Selfoss instance.</string>
<string name="markall_dialog_message">This will mark all the items as read.</string>
<string name="pref_switch_actions_pager_scroll">Mark as read on swipe</string>
<string name="pref_switch_actions_pager_scroll_off">Don\'t mark articles as read when swiping.</string>
<string name="gdpr_dialog_message">The app does not collect any personal data. Every analytics tools were removed. Crash reports sending is now optional, as is the debug logging. Keep in mind that debugging and crash reports are essential for the app development (You can configure everything in Settings &gt; Debug).</string>
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
<string name="crash_dialog_text">Something went wrong. Please send the report to the developer.</string>
<string name="crash_dialog_comment">You can add any helpful details in the comment bellow. Don\'t include any personal data in your comment. You could send me and email with your debug id, and I\'ll keep you posted when the issue is resolved.</string>
<string name="pref_acra_user_email">Contact email</string>
<string name="pref_acra_user_email_summary">Add an email so I can contact you about the crash reports you send.</string>
<string name="pref_acra_alwaysaccept">Automatically send crash reports</string>
<string name="pref_acra_alwaysaccept_enabled">Will send crash reports automatically</string>
<string name="pref_acra_alwaysaccept_disabled">Will ask everytime when sending crash reports.</string>
<string name="pref_debug_crash_reports">Crash reports</string>
<string name="pref_debug_debug_logs">Debug logging (these will be sent without a dialog)</string>
<string name="acra_login">Enable logging</string>
<string name="drawer_item_hidden_tags">Hidden Tags</string>
<string name="unmark">Mark item as unread</string>
</resources>

View File

@ -1,161 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">"Reader for Selfoss"</string>
<string name="title_activity_login">"Log in"</string>
<string name="prompt_password">"Password"</string>
<string name="prompt_http_password">"HTTP Password"</string>
<string name="action_sign_in">"Go"</string>
<string name="error_invalid_password">"Password not long enough"</string>
<string name="error_field_required">"Field required"</string>
<string name="prompt_url">"Url"</string>
<string name="withLoginSwitch">"Login required ?"</string>
<string name="withHttpLoginSwitch">"HTTP Login required ?"</string>
<string name="login_url_problem">"Oops. You may need to add a \"/\" at the end of the url."</string>
<string name="prompt_login">"Username"</string>
<string name="prompt_http_login">"HTTP Username"</string>
<string name="label_share">"Share"</string>
<string name="readAll">"Read all"</string>
<string name="action_disconnect">"Disconnect"</string>
<string name="title_activity_settings">"Settings"</string>
<string name="pref_header_general">"General"</string>
<string name="pref_switch_actions_tap_title">"Tap action on the articles"</string>
<string name="add_source_hint_tags">"Tag1, Tag2, Tag3"</string>
<string name="add_source_hint_url">"Link"</string>
<string name="add_source_hint_name">"Name"</string>
<string name="add_source">"Add a source"</string>
<string name="add_source_save">"Save"</string>
<string name="wrong_infos">"Check your details again."</string>
<string name="all_posts_not_read">"All posts weren't read"</string>
<string name="all_posts_read">"All posts were read"</string>
<string name="cant_get_favs">"Can't get favorites"</string>
<string name="cant_get_new_elements">"Can't get new articles"</string>
<string name="cant_get_read">"Can't get read articles"</string>
<string name="nothing_here">"Nothing here"</string>
<string name="tab_new">"New"</string>
<string name="tab_read">"All"</string>
<string name="tab_favs">"Favorites"</string>
<string name="action_about">"About"</string>
<string name="marked_as_read">"Item read"</string>
<string name="undo_string">"Undo"</string>
<string name="addStringNoUrl">"Log in to add sources."</string>
<string name="cant_get_sources">"Can't get sources list."</string>
<string name="cant_create_source">"Can't create source."</string>
<string name="cant_get_spouts">"Can't get spouts list."</string>
<string name="form_not_complete">"The form is not complete"</string>
<string name="pref_header_links">"Links"</string>
<string name="issue_tracker_link">"Issue Tracker"</string>
<string name="issue_tracker_summary">"Report a bug or ask for a new feature"</string>
<string name="warning_wrong_url">"WARNING"</string>
<string name="pref_switch_card_view_title">"Card View"</string>
<string name="cant_mark_favortie">"Can't mark article as favorite"</string>
<string name="cant_unmark_favortie">"Can't remove item from favorite"</string>
<string name="share">"Share"</string>
<string name="rating_prompt_title">"Enjoying the app ?"</string>
<string name="rating_prompt_yes">"Yes !"</string>
<string name="rating_prompt_no">"Not really …"</string>
<string name="rating_prompt_feedback_title">"Can you tell us why ?"</string>
<string name="rating_prompt_feedback_yes">"OK !"</string>
<string name="rating_prompt_feedback_no">"Not now."</string>
<string name="rating_prompt_rating_title">"Great ! Can you rate us on the Store ?"</string>
<string name="rating_prompt_rating_yes">"Sure !"</string>
<string name="rating_prompt_rating_no">"Not right now."</string>
<string name="rating_prompt_thanks">"Thanks, your feedback help enhance the app !"</string>
<string name="switch_unread_count">"Display the unread count as a badge for the bottom bar."</string>
<string name="switch_unread_count_title">"Display unread count"</string>
<string name="display_all_counts_title">"Display count for favorite and read"</string>
<string name="menu_share_the_app">"Invite friends"</string>
<string name="invitation_title">"Try this app for your Selfoss RSS feeds !"</string>
<string name="invitation_message">"I use this app for my Selfoss RSS feeds. You may like it too !"</string>
<string name="invitation_cta">"Try the app"</string>
<string name="text_wrong_url">"You seem to be trying to use an invalid URL. Make sure it is correct, and if the problem persists, contact me (via the store contact link). Please note that the app needs you to be using Selfoss. You can't access RSS feeds without it."</string>
<string name="pref_general_internal_browser_title">"Open links inside the app"</string>
<string name="pref_general_internal_browser_on">"Articles will open inside the app"</string>
<string name="pref_general_internal_browser_off">"Articles will open with your default browser"</string>
<string name="prefer_article_viewer_title">"Use the article viewer"</string>
<string name="prefer_article_viewer_on">"Will use the article viewer instead of the internal browser"</string>
<string name="prefer_article_viewer_off">"Will use the internal browser instead of the article viewer"</string>
<string name="pref_general_category_links">"Link handeling"</string>
<string name="pref_general_category_displaying">"Displaying"</string>
<string name="pref_general_category_actions">"Actions"</string>
<string name="pref_switch_card_view_on">"The articles will be displayed as cards"</string>
<string name="pref_switch_card_view_off">"The articles will be displayed as a list"</string>
<string name="pref_switch_actions_tap_on">"Displays the action bar under the article"</string>
<string name="pref_switch_actions_tap_off">"When selecting an article it will open in your selected browser"</string>
<string name="menu_home_refresh">"Update remote"</string>
<string name="refresh_success_response">"The remote is updated, you can now reload the articles list"</string>
<string name="refresh_failer_message">"The update didn't work, try again later, or check your selfoss logs."</string>
<string name="refresh_in_progress">"Refresh in progress"</string>
<string name="new_apk_available_title">"A new APK is available."</string>
<string name="new_apk_available_message">"A new APK is available to download on the official repository."</string>
<string name="new_apk_available_get">"Download now"</string>
<string name="new_apk_available_no">"Ignore version"</string>
<string name="intro_hello_title">"Hi there !"</string>
<string name="intro_hello_message">"Thanks for downloading the app !"</string>
<string name="intro_needs_selfoss_title">"Before you start…"</string>
<string name="intro_needs_selfoss_message">"You can't use the app without a Selfoss instance."</string>
<string name="intro_needs_selfoss_link">"What is Selfoss ?"</string>
<string name="intro_all_set_title">"All set !"</string>
<string name="intro_all_set_message">"You are ready to use the app. Don't forget to go to the settings page to configure your app, and where you'll find some useful links."</string>
<string name="card_height_title">Full height cards</string>
<string name="card_height_on">Cards height will adjust to its content</string>
<string name="card_height_off">Card height will be fixed</string>
<string name="source_code">Source code</string>
<string name="cant_mark_read">Can\'t mark article as read</string>
<string name="drawer_error_loading_tags">Error loading tags…</string>
<string name="drawer_error_loading_sources">Error loading sources…</string>
<string name="drawer_item_filters">Filters</string>
<string name="drawer_action_clear">clear</string>
<string name="drawer_item_tags">Tags</string>
<string name="drawer_item_sources">Sources</string>
<string name="drawer_action_edit">edit</string>
<string name="cache_drawer_error" tools:keep="@string/cache_drawer_error">Couldn\'t cache your drawer data</string>
<string name="no_tags_loaded">No tags loaded</string>
<string name="no_sources_loaded">No sources loaded</string>
<string name="drawer_loading">Loading …</string>
<string name="menu_home_search">Search</string>
<string name="can_delete_source">Can\'t delete the source…</string>
<string name="base_url_error">There was an issue when trying to communicate with your Selfoss Instance. If the issue persists, please get in touch with me.</string>
<string name="pref_header_theme">Themes</string>
<string name="default_theme">Default</string>
<string name="teal_orange_theme">Teal/Orange/Light</string>
<string name="cyan_pink_theme">Cyan/Pink/Light</string>
<string name="grey_orange_theme">Grey/Orange/Light</string>
<string name="blue_amber_theme">Blue/Amber/Light</string>
<string name="indigo_pink_theme">Indigo/Pink/Light</string>
<string name="red_teal_theme">Red/Teal/Light</string>
<string name="teal_orange_dark_theme">Teal/Orange/Dark</string>
<string name="cyan_pink_dark_theme">Cyan/Pink/Dark</string>
<string name="default_dark_theme">Default/Dark</string>
<string name="grey_orange_dark_theme">Grey/Orange/Dark</string>
<string name="blue_amber_dark_theme">Blue/Amber/Dark</string>
<string name="indigo_pink_dark_theme">Indigo/Pink/Dark</string>
<string name="red_teal_dark_theme">Red/Teal/Dark</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activate to log login errors</string>
<string name="login_debug_on">Any error on the login page will be logged</string>
<string name="login_debug_off">No log on the login page</string>
<string name="login_menu_debug">Debug</string>
<string name="self_hosted_cert_switch">Using a self hosted certificate ?</string>
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
<string name="summary_debug_identifier">Debug identifier</string>
<string name="unique_id_to_clipboard">Identifier copied to your clipboard</string>
<string name="display_header_drawer_summary">Display a header with the selfoss instance url on the lateral drawer.</string>
<string name="display_header_drawer_title">Account header</string>
<string name="login_everything_title">Logging every api calls</string>
<string name="login_everything_on">This will log every api call for debug purpose.</string>
<string name="login_everything_off">No api call will be logged</string>
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
<string name="translation">Translation</string>
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
<string name="drawer_report_bug">Report a bug</string>
<string name="items_number_should_be_number">The items number should be an integer.</string>
<string name="reader_action_more">Read more</string>
<string name="reader_action_open">Open in browser</string>
<string name="reader_action_share">Share</string>
</resources>

View File

@ -43,8 +43,8 @@
<string name="cant_create_source">"Impossible de créer la source."</string>
<string name="cant_get_spouts">"Impossible de récupérer vos Spouts pour rajouter des sources"</string>
<string name="form_not_complete">"Il manque des données. Terminez le formulaire."</string>
<string name="pref_header_links">"Liens utils"</string>
<string name="issue_tracker_link">"Suivie des problèmes"</string>
<string name="pref_header_links">"Liens utiles"</string>
<string name="issue_tracker_link">"Suivi des problèmes"</string>
<string name="issue_tracker_summary">"Pour signaler un bug ou demander une nouvelle fonctionnalité"</string>
<string name="warning_wrong_url">"ATTENTION"</string>
<string name="pref_switch_card_view_title">"Card View"</string>
@ -64,11 +64,10 @@
<string name="switch_unread_count">"Afficher le nombre d'articles non lus sur la barre en bas de l'écran"</string>
<string name="switch_unread_count_title">"Afficher le nombre de non lus"</string>
<string name="display_all_counts_title">"Afficher le nombre de favoris et d'articles lus"</string>
<string name="menu_share_the_app">"Inviter des amis"</string>
<string name="invitation_title">"Essaye cette application pour les flux RSS Selfoss !"</string>
<string name="invitation_title">"Essaye cette application pour les flux RSS Selfoss !"</string>
<string name="invitation_message">"J'utilise cette applications pour mon flux RSS Selfoss. Tu aimeras peut être !"</string>
<string name="invitation_cta">"Essayer maintenant"</string>
<string name="text_wrong_url">"Vous semblez essayer de vous connceter avec une URL invalide. Assurez-vous que c'est la bonne, et si le problème persiste, contactez-moi via le lien du play store. Notez aussi que l'application ne peut fonctionner sans l'application web Selfoss. Vous ne pouvez pas utiliser l'application pour accéder directement aux flux RSS."</string>
<string name="text_wrong_url">"Vous semblez essayer de vous connecter avec une URL invalide. Assurez-vous que c'est la bonne, et si le problème persiste, contactez-moi via le lien du play store. Notez aussi que l'application ne peut fonctionner sans l'application web Selfoss. Vous ne pouvez pas utiliser l'application pour accéder directement aux flux RSS."</string>
<string name="pref_general_internal_browser_title">"Ouvrir les liens dans l'application"</string>
<string name="pref_general_internal_browser_on">"Les articles s'ouvriront dans l'application"</string>
<string name="pref_general_internal_browser_off">"Les articles s'ouvriront dans votre naviguateur par défaut"</string>
@ -81,7 +80,7 @@
<string name="pref_switch_card_view_on">"Les articles seront affichés en forme de carte"</string>
<string name="pref_switch_card_view_off">"Les articles seront affichés en liste"</string>
<string name="pref_switch_actions_tap_on">"Afficher la barre d'action sous l'article"</string>
<string name="pref_switch_actions_tap_off">"Le clique sur un article l'ouvrira dans le naviguateur selectionné"</string>
<string name="pref_switch_actions_tap_off">"Le clic sur un article l'ouvrira dans le navigateur sélectionné"</string>
<string name="menu_home_refresh">"Mettre à jour"</string>
<string name="refresh_success_response">"Mise à jour effectuée."</string>
<string name="refresh_failer_message">"La mise à jour n'a pas fonctionné. Vérifiez vos logs selfoss."</string>
@ -118,39 +117,28 @@
<string name="base_url_error">Il y a eu un souci lors de la communication avec votre instance Selfoss. Si le problèmes persiste, contactez-moi pour trouver une solution.</string>
<string name="pref_header_theme">Thèmes</string>
<string name="default_theme">Par défaut</string>
<string name="teal_orange_theme">Sarcelle/Orange/Clair</string>
<string name="cyan_pink_theme">Cyan/Rose/Clair</string>
<string name="grey_orange_theme">Gris/Orange/Clair</string>
<string name="blue_amber_theme">Bleu/Ambre/Clair</string>
<string name="indigo_pink_theme">Indigo/Rose/Clair</string>
<string name="red_teal_theme">Rouge/Sarcelle/Clair</string>
<string name="teal_orange_dark_theme">Sarcelle/Orange/Foncé</string>
<string name="cyan_pink_dark_theme">Cyan/Rose/Foncé</string>
<string name="default_dark_theme">Par défaut/Foncé</string>
<string name="grey_orange_dark_theme">Gris/Orange/Foncé</string>
<string name="blue_amber_dark_theme">Bleu/Ambre/Foncé</string>
<string name="indigo_pink_dark_theme">Indigo/Rose/Foncé</string>
<string name="red_teal_dark_theme">Rouge/Sarcelle/Foncé</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activez pour logguer toutes les erreurs de connexion</string>
<string name="login_debug_title">Activez pour loguer toutes les erreurs de connexion</string>
<string name="login_debug_on">Toutes les erreurs de connexion vont être loguées</string>
<string name="login_debug_off">Aucune erreur de connexion ne sera loguée</string>
<string name="login_menu_debug">Debug</string>
<string name="self_hosted_cert_switch">Certificat auto-signé ?</string>
<string name="self_signed_cert_warning">Pour des raisons de sécurités, les certificats auto-signés sont désactivés par défaut. En les activant, je ne serais pas responsable de quelconques problèmes de sécurité rencontrés.</string>
<string name="self_signed_cert_warning">Pour des raisons de sécurité, les certificats auto-signés sont désactivés par défaut. En les activant, je ne serais pas responsable de quelconques problèmes de sécurité rencontrés.</string>
<string name="pref_selfoss_category">Api Selfoss</string>
<string name="pref_api_items_number_title">Nombre d\'articles chargés</string>
<string name="pref_hidden_tags">Tags Cachés</string>
<string name="read_debug_title">Des articles lus marqués comme non lus ?</string>
<string name="read_debug_off">Aucun log quand un article est marqué comme lu</string>
<string name="read_debug_on">Les appels API vont être logués lorsqu\'un article est marqué comme lu</string>
<string name="summary_debug_identifier">Identifiant de debug</string>
<string name="unique_id_to_clipboard">Texte copié</string>
<string name="unique_id_to_clipboard">Texte copié</string>
<string name="display_header_drawer_summary">Afficher une entête avec l\'url de votre instance de Selfoss en haut du drawer lateral.</string>
<string name="display_header_drawer_title">Entête de compte</string>
<string name="login_everything_title">Log de tous les appels à l\'API</string>
<string name="login_everything_on">Tous les appels à l\'API vont êtres logués</string>
<string name="login_everything_off">Aucun appel à l\'API ne sera logué</string>
<string name="pref_general_infinite_loading_title">(BETA) Charger plus d\'articles au scroll</string>
<string name="pref_general_infinite_loading_title">Charger plus d\'articles au scroll</string>
<string name="translation">Traduction</string>
<string name="cant_open_invalid_url">Lurl de lélément nest pas valide. En attendant la résolution du problème, le lien ne s\'ouvrira pas.</string>
<string name="drawer_report_bug">Signaler un bug</string>
@ -158,4 +146,27 @@
<string name="reader_action_more">Lire plus</string>
<string name="reader_action_open">Ouvrir</string>
<string name="reader_action_share">Partager</string>
<string name="pref_switch_actions_pager_scroll_on">Marquer les articles comme lus à la navigation dans le lecteur d\'article.</string>
<string name="add_to_favs_reader">Ajouter aux favoris</string>
<string name="remove_to_favs_reader">Supprimer des favoris</string>
<string name="pref_content_reader_font_size">Taille du texte du contenu du lecteur d\'articles</string>
<string name="pref_header_viewer">Lecteur d\'articles</string>
<string name="refresh_dialog_message">En validant, votre instance Selfoss sera mise à jour.</string>
<string name="markall_dialog_message">Marquer tous les éléments comme lus ?</string>
<string name="pref_switch_actions_pager_scroll">Marquer comme lu à la navigation.</string>
<string name="pref_switch_actions_pager_scroll_off">Ne pas marquer les articles comme lus à la navigation.</string>
<string name="gdpr_dialog_message">L\'application ne collecte aucune donnée personnelle. Tous les outils d\'analytics ont été supprimés. Les rapports d\'erreurs sont maintenant optionnels, ainsi que les logs. N\'oubliez pas que les rapports d\'erreurs sont essentiels pour la résolution des bugs (vous pouvez configurer tout cela dans Paramètres &gt; Debug).</string>
<string name="gdpr_dialog_title">L\'application ne partage aucune de vos données.</string>
<string name="crash_dialog_text">Quelque chose s\'est mal passé, S\'il vous plaît, envoyez le rapport au développeur.</string>
<string name="crash_dialog_comment">Vous pouvez ajouter tous les détails utiles dans le champ de commentaire plus bas. N\'ajoutez aucune information personnelle. Vous pouvez m\'envoyer un email avec votre identifiant de debug, et je vous informerai à la correction du problème.</string>
<string name="pref_acra_user_email">Email de contact</string>
<string name="pref_acra_user_email_summary">Ajoutez un mail pour que le développeur puisse vous contacter pour résoudre le problème.</string>
<string name="pref_acra_alwaysaccept">Envoyer automatiquement les rapports d\'erreur</string>
<string name="pref_acra_alwaysaccept_enabled">Enverra automatiquement les rapports d\'erreur</string>
<string name="pref_acra_alwaysaccept_disabled">Demandera une confirmation à chaque incident.</string>
<string name="pref_debug_crash_reports">Rapport d\'erreur</string>
<string name="pref_debug_debug_logs">Log de debug (seront envoyés automatiquement)</string>
<string name="acra_login">Activer les logs</string>
<string name="drawer_item_hidden_tags">Tags Cachés</string>
<string name="unmark">Marquer l\'article comme non lu</string>
</resources>

View File

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">"Lector para Selfoss"</string>
<string name="title_activity_login">"Acceder"</string>
<string name="prompt_password">"Contrasinal"</string>
<string name="prompt_http_password">"Contrasinal HTTP"</string>
<string name="action_sign_in">"Ir"</string>
<string name="error_invalid_password">"O contrasinal non é suficientemente longo"</string>
<string name="error_field_required">"Campo requirido"</string>
<string name="prompt_url">"URL"</string>
<string name="withLoginSwitch">"É preciso iniciar sesión?"</string>
<string name="withHttpLoginSwitch">"É preciso iniciar sesión HTTP?"</string>
<string name="login_url_problem">"Ups! Pode que precises engadir un \"/\" o final da URL."</string>
<string name="prompt_login">"Nome de usuario"</string>
<string name="prompt_http_login">"Nome de usuario HTTP"</string>
<string name="label_share">"Compartir"</string>
<string name="readAll">"Ler todos"</string>
<string name="action_disconnect">"Desconectar"</string>
<string name="title_activity_settings">"Axustes"</string>
<string name="pref_header_general">"Xeral"</string>
<string name="pref_switch_actions_tap_title">"Dar un toque nos artigos"</string>
<string name="add_source_hint_tags">"Etiqueta1, Etiqueta2, Etiqueta3"</string>
<string name="add_source_hint_url">"Ligazón"</string>
<string name="add_source_hint_name">"Nome"</string>
<string name="add_source">"Engadir unha fonte"</string>
<string name="add_source_save">"Gardar"</string>
<string name="wrong_infos">"Comprobar os teus detalles de novo."</string>
<string name="all_posts_not_read">"Non se leron todas as publicacións"</string>
<string name="all_posts_read">"Leronse todas as publicacións"</string>
<string name="cant_get_favs">"Non se poden obter os favoritos"</string>
<string name="cant_get_new_elements">"Non se poden recibir os novos artigos"</string>
<string name="cant_get_read">"Non se poden recibir os artigos lidos"</string>
<string name="nothing_here">"Non hai nada aquí"</string>
<string name="tab_new">"Novo"</string>
<string name="tab_read">"Todos"</string>
<string name="tab_favs">"Favoritos"</string>
<string name="action_about">"Acerca de"</string>
<string name="marked_as_read">"Elemento lido"</string>
<string name="undo_string">"Desfacer"</string>
<string name="addStringNoUrl">"Accede pra engadir fontes."</string>
<string name="cant_get_sources">"Non se pode obter a lista de fontes."</string>
<string name="cant_create_source">"Non se pode crear unha fonte."</string>
<string name="cant_get_spouts">"Non se pode obter a lista de fontes."</string>
<string name="form_not_complete">"O formulario non está completo"</string>
<string name="pref_header_links">"Ligazóns"</string>
<string name="issue_tracker_link">"Rastrexador de Incidencias"</string>
<string name="issue_tracker_summary">"Informar dun erro ou pedir unha nova característica"</string>
<string name="warning_wrong_url">"AVISO"</string>
<string name="pref_switch_card_view_title">"Vista de tarxeta"</string>
<string name="cant_mark_favortie">"Non se pode marcar o artigo como favorito"</string>
<string name="cant_unmark_favortie">"Non se pode eliminar o elemento dos favoritos"</string>
<string name="share">"Compartir"</string>
<string name="rating_prompt_title">"Estás gozando coa aplicación?"</string>
<string name="rating_prompt_yes">"Si !"</string>
<string name="rating_prompt_no">"Non moito …"</string>
<string name="rating_prompt_feedback_title">"Podes dicirnos por qué?"</string>
<string name="rating_prompt_feedback_yes">"Dacordo!"</string>
<string name="rating_prompt_feedback_no">"Agora non."</string>
<string name="rating_prompt_rating_title">"Xenial! Podes puntuarnos na tenda?"</string>
<string name="rating_prompt_rating_yes">"Claro!"</string>
<string name="rating_prompt_rating_no">"Agora mesmo non."</string>
<string name="rating_prompt_thanks">"Grazas, a túa opinión axudanos a mellorar a aplicación!"</string>
<string name="switch_unread_count">"Mostrar o reconto de artigos non lidos cunha insignia na barra inferior."</string>
<string name="switch_unread_count_title">"Mostrar reconto de artigos non lidos"</string>
<string name="display_all_counts_title">"Mostrar reconto de artigos lidos e favoritos"</string>
<string name="invitation_title">"Proba esta aplicación pras túas canles RSS de Selfoss!"</string>
<string name="invitation_message">"Uso esta aplicación praos meus canles RSS de Selfoss. Quizás tamén che guste!"</string>
<string name="invitation_cta">"Proba a aplicación"</string>
<string name="text_wrong_url">"Semella que intentas usar unha URL non válida. Asegúrate de que é correcta, e se o problema persiste, ponte en contacto conmigo (a través da ligazón de contacto na tenda). Por favor ten en conta que a aplicación precisa que uses Selfoss. Non podes acceder a canles RSS se non o tes."</string>
<string name="pref_general_internal_browser_title">"Abrir ligazóns dentro da aplicación"</string>
<string name="pref_general_internal_browser_on">"Os artigos abriranse dentro da aplicación"</string>
<string name="pref_general_internal_browser_off">"Os artigos abriranse co teu navegador prederminado"</string>
<string name="prefer_article_viewer_title">"Usar o visor de artigos"</string>
<string name="prefer_article_viewer_on">"Usarase o visor de artigos en lugar do navegador interno"</string>
<string name="prefer_article_viewer_off">"Usarase o navegador interno en lugar do visor de artigos"</string>
<string name="pref_general_category_links">"Xestión de ligazóns"</string>
<string name="pref_general_category_displaying">"Visualización"</string>
<string name="pref_general_category_actions">"Accións"</string>
<string name="pref_switch_card_view_on">"Os artigos amosaranse coma tarxetas"</string>
<string name="pref_switch_card_view_off">"Os artigos amosaranse coma unha lista"</string>
<string name="pref_switch_actions_tap_on">"Amosar a barra de acción debaixo do artigo"</string>
<string name="pref_switch_actions_tap_off">"Ao seleccionar un artigo, abrirase no navegador escollido"</string>
<string name="menu_home_refresh">"Actualizar o remoto"</string>
<string name="refresh_success_response">"O remoto foi actualizado, xa podes refrescar a lista de artigos"</string>
<string name="refresh_failer_message">"A actualización non funcionou, proba de novo máis tarde ou comproba os teus rexistros de Selfoss."</string>
<string name="refresh_in_progress">"Actualizazación en progreso"</string>
<string name="new_apk_available_title">"Unha nova versión está dispoñible."</string>
<string name="new_apk_available_message">"Unha nova actualización está dispoñible pra descargar no repositorio oficial."</string>
<string name="new_apk_available_get">"Descargar agora"</string>
<string name="new_apk_available_no">"Ignorar versión"</string>
<string name="intro_hello_title">"Ola!"</string>
<string name="intro_hello_message">"Grazas por descargar a aplicación!"</string>
<string name="intro_needs_selfoss_title">"Antes de comezar…"</string>
<string name="intro_needs_selfoss_message">"Non podes usar a aplicación sen unha instancia de Selfoss."</string>
<string name="intro_needs_selfoss_link">"Qué é Selfoss?"</string>
<string name="intro_all_set_title">"Todo listo!"</string>
<string name="intro_all_set_message">"Estás listo pra usar a aplicación. Non esquezas ir a páxina de Axustes pra configurar a aplicación. Alí atoparás algunhas ligazóns de utilidade."</string>
<string name="card_height_title">Tarxetas de altura completa</string>
<string name="card_height_on">A altura das tarxetas axustarase ao seu contido</string>
<string name="card_height_off">A altura das tarxetas será fixa</string>
<string name="source_code">Código fonte</string>
<string name="cant_mark_read">Non se pode marcar o artigo como lido</string>
<string name="drawer_error_loading_tags">Produciuse un erro ao cargar as etiquetas…</string>
<string name="drawer_error_loading_sources">Produciuse un erro ao cargar as fontes…</string>
<string name="drawer_item_filters">Filtros</string>
<string name="drawer_action_clear">limpar</string>
<string name="drawer_item_tags">Etiquetas</string>
<string name="drawer_item_sources">Fontes</string>
<string name="drawer_action_edit">editar</string>
<string name="cache_drawer_error" tools:keep="@string/cache_drawer_error">Non se puideron gardar na memoria os datos do seu panel</string>
<string name="no_tags_loaded">Non se cargou ningunha etiqueta</string>
<string name="no_sources_loaded">Non se cargou ningunha fonte</string>
<string name="drawer_loading">Cargando…</string>
<string name="menu_home_search">Procurar</string>
<string name="can_delete_source">Non se puido eliminar a fonte…</string>
<string name="base_url_error">Houno unha incidencia ao tratar de comunicarse coa túa instancia de Selfoss. Se o problema persiste, prégolle que se poña en contacto conmigo.</string>
<string name="pref_header_theme">Temas</string>
<string name="default_theme">Predeterminado</string>
<string name="default_dark_theme">Predeterminado/Escuro</string>
<string name="pref_header_debug">Depuración</string>
<string name="login_debug_title">Activar pra rexistrar os erros de acceso</string>
<string name="login_debug_on">Rexistrarse todos os erros na páxina de acceso</string>
<string name="login_debug_off">Non se rexistrará ningún erro na páxina de acceso</string>
<string name="login_menu_debug">Depuración</string>
<string name="self_hosted_cert_switch">Utilizas un certificado autoaloxado?</string>
<string name="self_signed_cert_warning">Por razóns de seguridade, por defecto non se permiten os certificados autoasinados. Activando isto, non serei responsable de calquera problema de seguridade que atopes.</string>
<string name="pref_selfoss_category">API de Selfoss</string>
<string name="pref_api_items_number_title">Número de elementos cargados</string>
<string name="pref_hidden_tags">Etiquetas ocultas</string>
<string name="read_debug_title">Ler os artigos que aparecen coma non lidos?</string>
<string name="read_debug_off">Non rexistrar cando se marca un elemento coma lido</string>
<string name="read_debug_on">As chamadas á API serán rexistradas cando se marque un artigo coma lido</string>
<string name="summary_debug_identifier">Identificador de depuración</string>
<string name="unique_id_to_clipboard">Copiouse o identificador ao portapapeis</string>
<string name="display_header_drawer_summary">Amosar unha cabeceira coa URL da instancia de Selfoss no panel lateral.</string>
<string name="display_header_drawer_title">Cabeceira da conta</string>
<string name="login_everything_title">Rexistrando todas as chamadas á API</string>
<string name="login_everything_on">Isto rexistrará todas as chamadas á API con fins de depuración.</string>
<string name="login_everything_off">Non se rexistrará ningunha chamada á API</string>
<string name="pref_general_infinite_loading_title">Cargar máis artigos ao desprazarse</string>
<string name="translation">Traducción</string>
<string name="cant_open_invalid_url">A URL do elemento non é válida. Estou tratando de solucionar isto pra que a aplicación non falle.</string>
<string name="drawer_report_bug">Informar dun erro</string>
<string name="items_number_should_be_number">O número de elementos debería ser un enteiro.</string>
<string name="reader_action_more">Ler máis</string>
<string name="reader_action_open">Abrir no navegador</string>
<string name="reader_action_share">Compartir</string>
<string name="pref_switch_actions_pager_scroll_on">Marcar artigos como lidos cando se desliza o dedo dun a outro.</string>
<string name="add_to_favs_reader">Engadir a favoritos</string>
<string name="remove_to_favs_reader">Eliminar dos favoritos</string>
<string name="pref_content_reader_font_size">Tamaño da fonte do lector</string>
<string name="pref_header_viewer">Visor de artigos</string>
<string name="refresh_dialog_message">Isto actualizará a súa instancia de Selfoss.</string>
<string name="markall_dialog_message">Isto marcara todos os elementos como lidos.</string>
<string name="pref_switch_actions_pager_scroll">Marcar artigos como lidos ao deslizar co dedo cara os lados</string>
<string name="pref_switch_actions_pager_scroll_off">Non marcar artigos como lidos ao deslizar co dedo cara os lados.</string>
<string name="gdpr_dialog_message">A aplicación non recolle ningún dato persoal. Todas as ferramentas de analítica foron eliminadas. O envío de informes de erros agora é opcional, así coma os rexistros de depuración. Ten en conta que tanto os rexistros coma os informes de erros son esenciais prao desenvolvemento da aplicación (Podes configurar todo en \"Axustes &gt; Depurar\").</string>
<string name="gdpr_dialog_title">A aplicación non comparte ningún dato persoal seu.</string>
<string name="crash_dialog_text">Algo foi mal. Pregámoslle que envíe o informe de erro ao desarrollador.</string>
<string name="crash_dialog_comment">Podes engadir calquera información útil nos comentarios. Non inclúas datos persoais. Podes enviarme un correo coa Id de depuración pra que me poña en contacto contigo cando a incidencia se resolva.</string>
<string name="pref_acra_user_email">Enderezo electrónico de contacto</string>
<string name="pref_acra_user_email_summary">Engade un enderezo electrónico pra que me poida poñer en contacto sobre o informe de erros que enviaches.</string>
<string name="pref_acra_alwaysaccept">Enviar automáticamente informes de erros</string>
<string name="pref_acra_alwaysaccept_enabled">Enviaranse automáticamente os informes de erros</string>
<string name="pref_acra_alwaysaccept_disabled">Preguntarase cada vez pra enviar os informes de erros.</string>
<string name="pref_debug_crash_reports">Informes de erros</string>
<string name="pref_debug_debug_logs">Rexistro de depuración (Estes enviaranse automáticamente)</string>
<string name="acra_login">Habilitar o rexistro</string>
<string name="drawer_item_hidden_tags">Etiquetas ocultas</string>
<string name="unmark">Marcar artículo como non lido</string>
</resources>

View File

@ -1,161 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">"Reader for Selfoss"</string>
<string name="title_activity_login">"Log in"</string>
<string name="prompt_password">"Password"</string>
<string name="prompt_http_password">"HTTP Password"</string>
<string name="action_sign_in">"Go"</string>
<string name="error_invalid_password">"Password not long enough"</string>
<string name="error_field_required">"Field required"</string>
<string name="prompt_url">"Url"</string>
<string name="withLoginSwitch">"Login required ?"</string>
<string name="withHttpLoginSwitch">"HTTP Login required ?"</string>
<string name="login_url_problem">"Oops. You may need to add a \"/\" at the end of the url."</string>
<string name="prompt_login">"Username"</string>
<string name="prompt_http_login">"HTTP Username"</string>
<string name="label_share">"Share"</string>
<string name="readAll">"Read all"</string>
<string name="action_disconnect">"Disconnect"</string>
<string name="title_activity_settings">"Settings"</string>
<string name="pref_header_general">"General"</string>
<string name="pref_switch_actions_tap_title">"Tap action on the articles"</string>
<string name="add_source_hint_tags">"Tag1, Tag2, Tag3"</string>
<string name="add_source_hint_url">"Link"</string>
<string name="add_source_hint_name">"Name"</string>
<string name="add_source">"Add a source"</string>
<string name="add_source_save">"Save"</string>
<string name="wrong_infos">"Check your details again."</string>
<string name="all_posts_not_read">"All posts weren't read"</string>
<string name="all_posts_read">"All posts were read"</string>
<string name="cant_get_favs">"Can't get favorites"</string>
<string name="cant_get_new_elements">"Can't get new articles"</string>
<string name="cant_get_read">"Can't get read articles"</string>
<string name="nothing_here">"Nothing here"</string>
<string name="tab_new">"New"</string>
<string name="tab_read">"All"</string>
<string name="tab_favs">"Favorites"</string>
<string name="action_about">"About"</string>
<string name="marked_as_read">"Item read"</string>
<string name="undo_string">"Undo"</string>
<string name="addStringNoUrl">"Log in to add sources."</string>
<string name="cant_get_sources">"Can't get sources list."</string>
<string name="cant_create_source">"Can't create source."</string>
<string name="cant_get_spouts">"Can't get spouts list."</string>
<string name="form_not_complete">"The form is not complete"</string>
<string name="pref_header_links">"Links"</string>
<string name="issue_tracker_link">"Issue Tracker"</string>
<string name="issue_tracker_summary">"Report a bug or ask for a new feature"</string>
<string name="warning_wrong_url">"WARNING"</string>
<string name="pref_switch_card_view_title">"Card View"</string>
<string name="cant_mark_favortie">"Can't mark article as favorite"</string>
<string name="cant_unmark_favortie">"Can't remove item from favorite"</string>
<string name="share">"Share"</string>
<string name="rating_prompt_title">"Enjoying the app ?"</string>
<string name="rating_prompt_yes">"Yes !"</string>
<string name="rating_prompt_no">"Not really …"</string>
<string name="rating_prompt_feedback_title">"Can you tell us why ?"</string>
<string name="rating_prompt_feedback_yes">"OK !"</string>
<string name="rating_prompt_feedback_no">"Not now."</string>
<string name="rating_prompt_rating_title">"Great ! Can you rate us on the Store ?"</string>
<string name="rating_prompt_rating_yes">"Sure !"</string>
<string name="rating_prompt_rating_no">"Not right now."</string>
<string name="rating_prompt_thanks">"Thanks, your feedback help enhance the app !"</string>
<string name="switch_unread_count">"Display the unread count as a badge for the bottom bar."</string>
<string name="switch_unread_count_title">"Display unread count"</string>
<string name="display_all_counts_title">"Display count for favorite and read"</string>
<string name="menu_share_the_app">"Invite friends"</string>
<string name="invitation_title">"Try this app for your Selfoss RSS feeds !"</string>
<string name="invitation_message">"I use this app for my Selfoss RSS feeds. You may like it too !"</string>
<string name="invitation_cta">"Try the app"</string>
<string name="text_wrong_url">"You seem to be trying to use an invalid URL. Make sure it is correct, and if the problem persists, contact me (via the store contact link). Please note that the app needs you to be using Selfoss. You can't access RSS feeds without it."</string>
<string name="pref_general_internal_browser_title">"Open links inside the app"</string>
<string name="pref_general_internal_browser_on">"Articles will open inside the app"</string>
<string name="pref_general_internal_browser_off">"Articles will open with your default browser"</string>
<string name="prefer_article_viewer_title">"Use the article viewer"</string>
<string name="prefer_article_viewer_on">"Will use the article viewer instead of the internal browser"</string>
<string name="prefer_article_viewer_off">"Will use the internal browser instead of the article viewer"</string>
<string name="pref_general_category_links">"Link handeling"</string>
<string name="pref_general_category_displaying">"Displaying"</string>
<string name="pref_general_category_actions">"Actions"</string>
<string name="pref_switch_card_view_on">"The articles will be displayed as cards"</string>
<string name="pref_switch_card_view_off">"The articles will be displayed as a list"</string>
<string name="pref_switch_actions_tap_on">"Displays the action bar under the article"</string>
<string name="pref_switch_actions_tap_off">"When selecting an article it will open in your selected browser"</string>
<string name="menu_home_refresh">"Update remote"</string>
<string name="refresh_success_response">"The remote is updated, you can now reload the articles list"</string>
<string name="refresh_failer_message">"The update didn't work, try again later, or check your selfoss logs."</string>
<string name="refresh_in_progress">"Refresh in progress"</string>
<string name="new_apk_available_title">"A new APK is available."</string>
<string name="new_apk_available_message">"A new APK is available to download on the official repository."</string>
<string name="new_apk_available_get">"Download now"</string>
<string name="new_apk_available_no">"Ignore version"</string>
<string name="intro_hello_title">"Hi there !"</string>
<string name="intro_hello_message">"Thanks for downloading the app !"</string>
<string name="intro_needs_selfoss_title">"Before you start…"</string>
<string name="intro_needs_selfoss_message">"You can't use the app without a Selfoss instance."</string>
<string name="intro_needs_selfoss_link">"What is Selfoss ?"</string>
<string name="intro_all_set_title">"All set !"</string>
<string name="intro_all_set_message">"You are ready to use the app. Don't forget to go to the settings page to configure your app, and where you'll find some useful links."</string>
<string name="card_height_title">Full height cards</string>
<string name="card_height_on">Cards height will adjust to its content</string>
<string name="card_height_off">Card height will be fixed</string>
<string name="source_code">Source code</string>
<string name="cant_mark_read">Can\'t mark article as read</string>
<string name="drawer_error_loading_tags">Error loading tags…</string>
<string name="drawer_error_loading_sources">Error loading sources…</string>
<string name="drawer_item_filters">Filters</string>
<string name="drawer_action_clear">clear</string>
<string name="drawer_item_tags">Tags</string>
<string name="drawer_item_sources">Sources</string>
<string name="drawer_action_edit">edit</string>
<string name="cache_drawer_error" tools:keep="@string/cache_drawer_error">Couldn\'t cache your drawer data</string>
<string name="no_tags_loaded">No tags loaded</string>
<string name="no_sources_loaded">No sources loaded</string>
<string name="drawer_loading">Loading …</string>
<string name="menu_home_search">Search</string>
<string name="can_delete_source">Can\'t delete the source…</string>
<string name="base_url_error">There was an issue when trying to communicate with your Selfoss Instance. If the issue persists, please get in touch with me.</string>
<string name="pref_header_theme">Themes</string>
<string name="default_theme">Default</string>
<string name="teal_orange_theme">Teal/Orange/Light</string>
<string name="cyan_pink_theme">Cyan/Pink/Light</string>
<string name="grey_orange_theme">Grey/Orange/Light</string>
<string name="blue_amber_theme">Blue/Amber/Light</string>
<string name="indigo_pink_theme">Indigo/Pink/Light</string>
<string name="red_teal_theme">Red/Teal/Light</string>
<string name="teal_orange_dark_theme">Teal/Orange/Dark</string>
<string name="cyan_pink_dark_theme">Cyan/Pink/Dark</string>
<string name="default_dark_theme">Default/Dark</string>
<string name="grey_orange_dark_theme">Grey/Orange/Dark</string>
<string name="blue_amber_dark_theme">Blue/Amber/Dark</string>
<string name="indigo_pink_dark_theme">Indigo/Pink/Dark</string>
<string name="red_teal_dark_theme">Red/Teal/Dark</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activate to log login errors</string>
<string name="login_debug_on">Any error on the login page will be logged</string>
<string name="login_debug_off">No log on the login page</string>
<string name="login_menu_debug">Debug</string>
<string name="self_hosted_cert_switch">Using a self hosted certificate ?</string>
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
<string name="summary_debug_identifier">Debug identifier</string>
<string name="unique_id_to_clipboard">Identifier copied to your clipboard</string>
<string name="display_header_drawer_summary">Display a header with the selfoss instance url on the lateral drawer.</string>
<string name="display_header_drawer_title">Account header</string>
<string name="login_everything_title">Logging every api calls</string>
<string name="login_everything_on">This will log every api call for debug purpose.</string>
<string name="login_everything_off">No api call will be logged</string>
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
<string name="translation">Translation</string>
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
<string name="drawer_report_bug">Report a bug</string>
<string name="items_number_should_be_number">The items number should be an integer.</string>
<string name="reader_action_more">Read more</string>
<string name="reader_action_open">Open in browser</string>
<string name="reader_action_share">Share</string>
</resources>

View File

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">"Reader for Selfoss"</string>
<string name="title_activity_login">"Log in"</string>
<string name="prompt_password">"Password"</string>
<string name="prompt_http_password">"HTTP Password"</string>
<string name="action_sign_in">"Go"</string>
<string name="error_invalid_password">"Password not long enough"</string>
<string name="error_field_required">"Field required"</string>
<string name="prompt_url">"Url"</string>
<string name="withLoginSwitch">"Login required ?"</string>
<string name="withHttpLoginSwitch">"HTTP Login required ?"</string>
<string name="login_url_problem">"Oops. You may need to add a \"/\" at the end of the url."</string>
<string name="prompt_login">"Username"</string>
<string name="prompt_http_login">"HTTP Username"</string>
<string name="label_share">"Share"</string>
<string name="readAll">"Read all"</string>
<string name="action_disconnect">"Disconnect"</string>
<string name="title_activity_settings">"Settings"</string>
<string name="pref_header_general">"General"</string>
<string name="pref_switch_actions_tap_title">"Tap action on the articles"</string>
<string name="add_source_hint_tags">"Tag1, Tag2, Tag3"</string>
<string name="add_source_hint_url">"Link"</string>
<string name="add_source_hint_name">"Name"</string>
<string name="add_source">"Add a source"</string>
<string name="add_source_save">"Save"</string>
<string name="wrong_infos">"Check your details again."</string>
<string name="all_posts_not_read">"All posts weren't read"</string>
<string name="all_posts_read">"All posts were read"</string>
<string name="cant_get_favs">"Can't get favorites"</string>
<string name="cant_get_new_elements">"Can't get new articles"</string>
<string name="cant_get_read">"Can't get read articles"</string>
<string name="nothing_here">"Nothing here"</string>
<string name="tab_new">"New"</string>
<string name="tab_read">"All"</string>
<string name="tab_favs">"Favorites"</string>
<string name="action_about">"About"</string>
<string name="marked_as_read">"Item read"</string>
<string name="undo_string">"Undo"</string>
<string name="addStringNoUrl">"Log in to add sources."</string>
<string name="cant_get_sources">"Can't get sources list."</string>
<string name="cant_create_source">"Can't create source."</string>
<string name="cant_get_spouts">"Can't get spouts list."</string>
<string name="form_not_complete">"The form is not complete"</string>
<string name="pref_header_links">"Links"</string>
<string name="issue_tracker_link">"Issue Tracker"</string>
<string name="issue_tracker_summary">"Report a bug or ask for a new feature"</string>
<string name="warning_wrong_url">"WARNING"</string>
<string name="pref_switch_card_view_title">"Card View"</string>
<string name="cant_mark_favortie">"Can't mark article as favorite"</string>
<string name="cant_unmark_favortie">"Can't remove item from favorite"</string>
<string name="share">"Share"</string>
<string name="rating_prompt_title">"Enjoying the app ?"</string>
<string name="rating_prompt_yes">"Yes !"</string>
<string name="rating_prompt_no">"Not really …"</string>
<string name="rating_prompt_feedback_title">"Can you tell us why ?"</string>
<string name="rating_prompt_feedback_yes">"OK !"</string>
<string name="rating_prompt_feedback_no">"Not now."</string>
<string name="rating_prompt_rating_title">"Great ! Can you rate us on the Store ?"</string>
<string name="rating_prompt_rating_yes">"Sure !"</string>
<string name="rating_prompt_rating_no">"Not right now."</string>
<string name="rating_prompt_thanks">"Thanks, your feedback help enhance the app !"</string>
<string name="switch_unread_count">"Display the unread count as a badge for the bottom bar."</string>
<string name="switch_unread_count_title">"Display unread count"</string>
<string name="display_all_counts_title">"Display count for favorite and read"</string>
<string name="invitation_title">"Try this app for your Selfoss RSS feeds !"</string>
<string name="invitation_message">"I use this app for my Selfoss RSS feeds. You may like it too !"</string>
<string name="invitation_cta">"Try the app"</string>
<string name="text_wrong_url">"You seem to be trying to use an invalid URL. Make sure it is correct, and if the problem persists, contact me (via the store contact link). Please note that the app needs you to be using Selfoss. You can't access RSS feeds without it."</string>
<string name="pref_general_internal_browser_title">"Open links inside the app"</string>
<string name="pref_general_internal_browser_on">"Articles will open inside the app"</string>
<string name="pref_general_internal_browser_off">"Articles will open with your default browser"</string>
<string name="prefer_article_viewer_title">"Use the article viewer"</string>
<string name="prefer_article_viewer_on">"Will use the article viewer instead of the internal browser"</string>
<string name="prefer_article_viewer_off">"Will use the internal browser instead of the article viewer"</string>
<string name="pref_general_category_links">"Link handling"</string>
<string name="pref_general_category_displaying">"Displaying"</string>
<string name="pref_general_category_actions">"Actions"</string>
<string name="pref_switch_card_view_on">"The articles will be displayed as cards"</string>
<string name="pref_switch_card_view_off">"The articles will be displayed as a list"</string>
<string name="pref_switch_actions_tap_on">"Displays the action bar under the article"</string>
<string name="pref_switch_actions_tap_off">"When selecting an article it will open in your selected browser"</string>
<string name="menu_home_refresh">"Update remote"</string>
<string name="refresh_success_response">"The remote is updated, you can now reload the articles list"</string>
<string name="refresh_failer_message">"The update didn't work, try again later, or check your selfoss logs."</string>
<string name="refresh_in_progress">"Refresh in progress"</string>
<string name="new_apk_available_title">"A new APK is available."</string>
<string name="new_apk_available_message">"A new APK is available to download on the official repository."</string>
<string name="new_apk_available_get">"Download now"</string>
<string name="new_apk_available_no">"Ignore version"</string>
<string name="intro_hello_title">"Hi there !"</string>
<string name="intro_hello_message">"Thanks for downloading the app !"</string>
<string name="intro_needs_selfoss_title">"Before you start…"</string>
<string name="intro_needs_selfoss_message">"You can't use the app without a Selfoss instance."</string>
<string name="intro_needs_selfoss_link">"What is Selfoss ?"</string>
<string name="intro_all_set_title">"All set !"</string>
<string name="intro_all_set_message">"You are ready to use the app. Don't forget to go to the settings page to configure your app, and where you'll find some useful links."</string>
<string name="card_height_title">Full height cards</string>
<string name="card_height_on">Cards height will adjust to its content</string>
<string name="card_height_off">Card height will be fixed</string>
<string name="source_code">Source code</string>
<string name="cant_mark_read">Can\'t mark article as read</string>
<string name="drawer_error_loading_tags">Error loading tags…</string>
<string name="drawer_error_loading_sources">Error loading sources…</string>
<string name="drawer_item_filters">Filters</string>
<string name="drawer_action_clear">clear</string>
<string name="drawer_item_tags">Tags</string>
<string name="drawer_item_sources">Sources</string>
<string name="drawer_action_edit">edit</string>
<string name="cache_drawer_error" tools:keep="@string/cache_drawer_error">Couldn\'t cache your drawer data</string>
<string name="no_tags_loaded">No tags loaded</string>
<string name="no_sources_loaded">No sources loaded</string>
<string name="drawer_loading">Loading …</string>
<string name="menu_home_search">Search</string>
<string name="can_delete_source">Can\'t delete the source…</string>
<string name="base_url_error">There was an issue when trying to communicate with your Selfoss Instance. If the issue persists, please get in touch with me.</string>
<string name="pref_header_theme">Themes</string>
<string name="default_theme">Default</string>
<string name="default_dark_theme">Default/Dark</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activate to log login errors</string>
<string name="login_debug_on">Any error on the login page will be logged</string>
<string name="login_debug_off">No log on the login page</string>
<string name="login_menu_debug">Debug</string>
<string name="self_hosted_cert_switch">Using a self hosted certificate ?</string>
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="pref_hidden_tags">Hidden Tags</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
<string name="summary_debug_identifier">Debug identifier</string>
<string name="unique_id_to_clipboard">Identifier copied to your clipboard</string>
<string name="display_header_drawer_summary">Display a header with the selfoss instance url on the lateral drawer.</string>
<string name="display_header_drawer_title">Account header</string>
<string name="login_everything_title">Logging every api calls</string>
<string name="login_everything_on">This will log every api call for debug purpose.</string>
<string name="login_everything_off">No api call will be logged</string>
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
<string name="translation">Translation</string>
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
<string name="drawer_report_bug">Report a bug</string>
<string name="items_number_should_be_number">The items number should be an integer.</string>
<string name="reader_action_more">Read more</string>
<string name="reader_action_open">Open in browser</string>
<string name="reader_action_share">Share</string>
<string name="pref_switch_actions_pager_scroll_on">Mark articles as read when swiping between articles.</string>
<string name="add_to_favs_reader">Add to favorites</string>
<string name="remove_to_favs_reader">Remove from favorites</string>
<string name="pref_content_reader_font_size">Article reader content font size</string>
<string name="pref_header_viewer">Article viewer</string>
<string name="refresh_dialog_message">This will refresh your Selfoss instance.</string>
<string name="markall_dialog_message">This will mark all the items as read.</string>
<string name="pref_switch_actions_pager_scroll">Mark as read on swipe</string>
<string name="pref_switch_actions_pager_scroll_off">Don\'t mark articles as read when swiping.</string>
<string name="gdpr_dialog_message">The app does not collect any personal data. Every analytics tools were removed. Crash reports sending is now optional, as is the debug logging. Keep in mind that debugging and crash reports are essential for the app development (You can configure everything in Settings &gt; Debug).</string>
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
<string name="crash_dialog_text">Something went wrong. Please send the report to the developer.</string>
<string name="crash_dialog_comment">You can add any helpful details in the comment bellow. Don\'t include any personal data in your comment. You could send me and email with your debug id, and I\'ll keep you posted when the issue is resolved.</string>
<string name="pref_acra_user_email">Contact email</string>
<string name="pref_acra_user_email_summary">Add an email so I can contact you about the crash reports you send.</string>
<string name="pref_acra_alwaysaccept">Automatically send crash reports</string>
<string name="pref_acra_alwaysaccept_enabled">Will send crash reports automatically</string>
<string name="pref_acra_alwaysaccept_disabled">Will ask everytime when sending crash reports.</string>
<string name="pref_debug_crash_reports">Crash reports</string>
<string name="pref_debug_debug_logs">Debug logging (these will be sent without a dialog)</string>
<string name="acra_login">Enable logging</string>
<string name="drawer_item_hidden_tags">Hidden Tags</string>
<string name="unmark">Mark item as unread</string>
</resources>

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