mirror of
				https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy.git
				synced 2025-10-31 17:08:11 +01:00 
			
		
		
		
	Compare commits
	
		
			432 Commits
		
	
	
		
			v0.0.5
			...
			releare-0.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 8a9102bc8a | ||
|  | 40a9091b7d | ||
|  | af7148ce58 | ||
|  | ff0bacff1d | ||
|  | 083bde8149 | ||
|  | ff3ccca3eb | ||
|  | b4569d56e6 | ||
|  | 0b1171c5b2 | ||
|  | 48776d28bb | ||
|  | 88f932ad5a | ||
|  | 8bb8bf3b31 | ||
|  | 23a40f27c7 | ||
|  | 0a30fdfb27 | ||
|  | f6c95b27b4 | ||
|  | 384543824d | ||
|  | de2a6351c7 | ||
|  | 25495b737a | ||
|  | e5ffaf3d97 | ||
|  | 48d41103b6 | ||
|  | 04a60211c6 | ||
|  | 55f4689984 | ||
|  | 9f02969dd2 | ||
|  | fd833a65c5 | ||
|  | 16dfc65c64 | ||
|  | 67115e0dd6 | ||
|  | 5f6b966160 | ||
|  | 4a200d7343 | ||
|  | aa75fb5592 | ||
|  | 5618e2e88b | ||
|  | 03ee3899d7 | ||
|  | 6b09f0379c | ||
|  | fe565d2ef3 | ||
|  | 14e568e642 | ||
|  | ec3b89a056 | ||
|  | 343484aff2 | ||
|  | ec7ef689c9 | ||
|  | 312a768351 | ||
|  | c4992aac74 | ||
|  | df37db5fed | ||
|  | d699e3a434 | ||
|  | c111ee35b4 | ||
|  | 766c2dc2c5 | ||
|  | ec484cd51d | ||
|  | 494545500f | ||
|  | db9c7a77e5 | ||
|  | 5a2954b432 | ||
|  | 751c2bd421 | ||
|  | 3940f9b402 | ||
|  | dd72afc115 | ||
|  | 7c87bf19d2 | ||
|  | 3d5d26f6ec | ||
|  | 12eec8cc6b | ||
|  | 1d17b4be9e | ||
|  | 4896aad901 | ||
|  | 46b6ab82d5 | ||
|  | 523db3c659 | ||
|  | 4614ee0ae2 | ||
|  | a874b9b455 | ||
|  | 998e4dd802 | ||
|  | cca17e0e81 | ||
|  | f9deaccb5a | ||
|  | 04a9679429 | ||
|  | caffec6b2a | ||
|  | 17c98e85ac | ||
|  | 2c46ac079c | ||
|  | 95b4325f3e | ||
|  | 673d717ef1 | ||
|  | 8c9460c6c0 | ||
|  | b1d1f7ec72 | ||
|  | 7d394d5a13 | ||
|  | e07ffc69ed | ||
|  | 80f7d1e331 | ||
|  | f06775de4b | ||
|  | 2184d73e3e | ||
|  | 0ff2e70867 | ||
|  | e7e83946eb | ||
|  | 2de2614d6f | ||
|  | 67349a134d | ||
|  | 25caea0b72 | ||
|  | 5522884bb2 | ||
|  | 9de9ba19e7 | ||
|  | 05f1f929e1 | ||
|  | ab6573b3cf | ||
|  | 7ba12262ca | ||
|  | 82f5be2568 | ||
|  | e33b4a3ec6 | ||
|  | 40f28071d6 | ||
|  | 2783bcd1e4 | ||
|  | 3e9db084b0 | ||
|  | a648993f78 | ||
|  | 75416b8b1b | ||
|  | 6f273d5e58 | ||
|  | 8654512584 | ||
|  | 46b2e0b816 | ||
|  | d708ef5300 | ||
|  | 9c8c667c41 | ||
|  | ff270e6895 | ||
|  | 7869bd3b2b | ||
|  | 36d932e9fe | ||
|  | 5b2f3eb9b4 | ||
|  | ddb1d6746b | ||
|  | f2440e0e2e | ||
|  | af6245eed7 | ||
|  | 4397e09016 | ||
|  | 262d9f02ba | ||
|  | 45b0399766 | ||
|  | 3bee0deb11 | ||
|  | 27a7b96ffb | ||
|  | 11a845e21c | ||
|  | 6d6a79bcb6 | ||
|  | 6ff46f928a | ||
|  | 81e1c73c65 | ||
|  | 554dfff4ad | ||
|  | 741ec08386 | ||
|  | f8a21fa3ba | ||
|  | fd6bc82214 | ||
|  | 0ae8826732 | ||
|  | 5311edc404 | ||
|  | d8dc8c39b2 | ||
|  | c43ced8b00 | ||
|  | 908f294130 | ||
|  | 95408f8125 | ||
|  | 6d5ba059f8 | ||
|  | ecdd9da9c8 | ||
|  | 1c17e6b7d2 | ||
|  | 9f60eca225 | ||
|  | 9deba8b10e | ||
|  | 05948d74f4 | ||
|  | 1007be50f8 | ||
|  | 28617cf9a8 | ||
|  | 5d2d43eebc | ||
|  | f2b2525823 | ||
|  | 29547f4750 | ||
|  | af63bba54a | ||
|  | caf4f177d2 | ||
|  | 1e67b34440 | ||
|  | 67afcd7e88 | ||
|  | 9406f29562 | ||
|  | b626c5fb73 | ||
|  | 0393ff6e77 | ||
|  | 30ecc17d55 | ||
|  | 7c5f184cc8 | ||
|  | d5fff14cb0 | ||
|  | 5cdda037b2 | ||
|  | 0942f7c5ec | ||
|  | efe90d0030 | ||
|  | 2d45f337d7 | ||
|  | 70cf6f3340 | ||
|  | 6542859892 | ||
|  | 143bc5e1b6 | ||
|  | 6e51ea6ee7 | ||
|  | d7c4e3d5bc | ||
|  | 1ed86c138e | ||
|  | 2d83545865 | ||
|  | 3594f10fdd | ||
|  | a903ac9dbd | ||
|  | ed90a278a6 | ||
|  | 6221b33a3d | ||
|  | 2561ba8bd0 | ||
|  | 9859608764 | ||
|  | b40077f83f | ||
|  | 76dc0ff083 | ||
|  | 6a2d59ed48 | ||
|  | a09d6f85f8 | ||
|  | 2f3d39ed31 | ||
|  | 83e0fc039f | ||
|  | d4ca682882 | ||
|  | e2b75a3928 | ||
|  | d9f9fb51db | ||
|  | a8b2091e69 | ||
|  | f14ebe9a0d | ||
|  | 4010e02438 | ||
|  | 5cbe6152c9 | ||
|  | c7233e05c4 | ||
|  | 9d4657dea8 | ||
|  | 7c3ddfda5c | ||
|  | 77f37a5698 | ||
|  | c45528a7f3 | ||
|  | 0dcc441bae | ||
|  | 8c05b6e1ea | ||
|  | 351033600f | ||
|  | fb4289a812 | ||
|  | 37eb16f6c4 | ||
|  | 77c5bcb038 | ||
|  | 3c65bfcf1b | ||
|  | ce7c284c6b | ||
|  | 267570d7b4 | ||
|  | c9e6a0bc2e | ||
|  | 1f8348bbfa | ||
|  | d4fe5235e2 | ||
|  | 76fee50cd5 | ||
|  | e2956e3f1c | ||
|  | 21b0b36359 | ||
|  | a55820a11d | ||
|  | 3322b5b4e8 | ||
|  | 0384914c16 | ||
|  | 0550219d58 | ||
|  | deaa4e596d | ||
|  | bf1036c919 | ||
|  | 116deebf87 | ||
|  | 0f3197d7e4 | ||
|  | db9edc47c0 | ||
|  | 2392d9fa29 | ||
|  | 3272f609a8 | ||
|  | d5092f50f6 | ||
|  | d216fc4640 | ||
|  | f61c12a30b | ||
|  | bbbd4ddcb0 | ||
|  | 495a1d025f | ||
|  | a245ebad09 | ||
|  | 0e31e40ef1 | ||
|  | bae68d4a99 | ||
|  | 3e17e3364d | ||
|  | 9626500586 | ||
|  | 92fcb811c3 | ||
|  | 81e2fdcf91 | ||
|  | 171338f492 | ||
|  | cc21588a66 | ||
|  | b5356ee5eb | ||
|  | ec9be3f6af | ||
|  | ac5e67c032 | ||
|  | fd24f04254 | ||
|  | 0b74574fa6 | ||
|  | 2704ff0ecf | ||
|  | f4c33e08e2 | ||
|  | 5dddf2e39d | ||
|  | 487afce565 | ||
|  | f31a13568c | ||
|  | 04341991bf | ||
|  | a7c2a67d0c | ||
|  | 4ec6666f93 | ||
|  | fcc0181075 | ||
|  | 1c4e5f3659 | ||
|  | a120fcf068 | ||
|  | 0328f34df2 | ||
|  | 7849115000 | ||
|  | 41e14aab9d | ||
|  | 074b5d012c | ||
|  | 8a3ee7931d | ||
|  | dce5a8d89c | ||
|  | a82f2b68e3 | ||
|  | a36ddccefd | ||
|  | bbe696a37b | ||
|  | 13ec5f84c4 | ||
|  | 587ebbb309 | ||
|  | 485611970f | ||
|  | c0738947b7 | ||
|  | f1145d826e | ||
|  | aa4f587443 | ||
|  | e559e4acd2 | ||
|  | db1e000325 | ||
|  | 4f57c17f73 | ||
|  | 21af736fa4 | ||
|  | 72ba80ff87 | ||
|  | 450e96fdbe | ||
|  | fcc60e1b16 | ||
|  | e888282d24 | ||
|  | 237d33f2e4 | ||
|  | babb0d28bb | ||
|  | 53eb7cbe91 | ||
|  | fed84f9942 | ||
|  | d4896a1f87 | ||
|  | 21879bec7d | ||
|  | bb143cfecb | ||
|  | 6475b4808a | ||
|  | 57a58cc518 | ||
|  | 8a5b6aa972 | ||
|  | 6813770d57 | ||
|  | 118b6cd430 | ||
|  | b984e35284 | ||
|  | f2a2a3029d | ||
|  | b4ab1ba414 | ||
|  | d244e0ed42 | ||
|  | 81c190a9c0 | ||
|  | e2f36c334b | ||
|  | 891215fcb3 | ||
|  | 04e022cbbc | ||
|  | 1f4f3a475d | ||
|  | 3e6d435116 | ||
|  | 9c6f946602 | ||
|  | 053c9e73b0 | ||
|  | acd1aef851 | ||
|  | a3a753a9dd | ||
|  | 0ea491bcfc | ||
|  | 946d35b5d9 | ||
|  | 5098cb698d | ||
|  | 47a06c372e | ||
|  | 7877001533 | ||
|  | 23d41846d0 | ||
|  | dc4dc17b6c | ||
|  | 6c8892938a | ||
|  | 2f2d86bc3f | ||
|  | ecd3d008de | ||
|  | f5172a17db | ||
|  | 662a5bd597 | ||
|  | 6621748de5 | ||
|  | 37fa76b79a | ||
|  | c7acb50522 | ||
|  | 64304ad637 | ||
|  | 635ca332da | ||
|  | e2a15ab925 | ||
|  | 016801419f | ||
|  | 48d79bc353 | ||
|  | b8094fded8 | ||
|  | 8c82ba0e91 | ||
|  | 3ff9c06843 | ||
|  | 45ae8342ee | ||
|  | b8c3dae807 | ||
|  | 3afd2601f0 | ||
|  | 82414bba55 | ||
|  | 7a39b2341b | ||
|  | 37ab47bc34 | ||
|  | 21b111cc2d | ||
|  | b3c2f6213d | ||
|  | c3de94012a | ||
|  | 804eb64b5b | ||
|  | 6a4aa8075d | ||
|  | 692aca4eca | ||
|  | dd00802561 | ||
|  | a3e0fea200 | ||
|  | 304125ea0d | ||
|  | a465ebb5b4 | ||
|  | b39d00eba6 | ||
|  | 1ebdce309d | ||
|  | d29b7585f7 | ||
|  | 276560678c | ||
|  | 10c23a65c5 | ||
|  | 4e4f4377e7 | ||
|  | 2e6c9db614 | ||
|  | 2375ba9d35 | ||
|  | a11ccb7cf6 | ||
|  | a54241294d | ||
|  | 46b509c1fb | ||
|  | b13dd58c70 | ||
|  | 4312b250ce | ||
|  | ff4c9180a0 | ||
|  | be0bd40995 | ||
|  | 726d6d0faf | ||
|  | 14ce356c4d | ||
|  | 930a425af5 | ||
|  | 7168cecbcb | ||
|  | 7f067023e7 | ||
|  | 167aecb696 | ||
|  | 9872e6e806 | ||
|  | 05adc343a2 | ||
|  | 58e3dfa084 | ||
|  | 3068423c01 | ||
|  | 3c960f60d1 | ||
|  | a153fc4afb | ||
|  | 4a19fbb745 | ||
|  | bb8c10fc98 | ||
|  | 97af73f055 | ||
|  | 73d18082c4 | ||
|  | 4b78e80edd | ||
|  | 78ba4b0fda | ||
|  | a1c5baac6b | ||
|  | c4b811090d | ||
|  | fbdccfb639 | ||
|  | c1162fd618 | ||
|  | 4d7a148cfe | ||
|  | c7b1602648 | ||
|  | a82a454ad2 | ||
|  | 9533378003 | ||
|  | dc1edcc78c | ||
|  | 6d8b040f6d | ||
|  | 60f07f7707 | ||
|  | f6b7130d0c | ||
|  | 9fea056063 | ||
|  | 859e9ab5d6 | ||
|  | 4821718407 | ||
|  | 67a13f8ecb | ||
|  | 40e4782b32 | ||
|  | 2ab5ab3ce5 | ||
|  | 88fb054640 | ||
|  | 4ce8fd6a63 | ||
|  | ffc2d669e5 | ||
|  | 926e1162f0 | ||
|  | 6cf69ee26d | ||
|  | 279820c1be | ||
|  | 1d7031f3d4 | ||
|  | 252e00b67a | ||
|  | a8d63c7480 | ||
|  | 2020172b56 | ||
|  | 2d55a4c8ec | ||
|  | 20a3e0220b | ||
|  | feeeefa2d2 | ||
|  | d25137020f | ||
|  | 3c4fb4162e | ||
|  | 28e9ae950e | ||
|  | 888e741aa9 | ||
|  | 9f7a6e1738 | ||
|  | 76f4a0738f | ||
|  | 63327946be | ||
|  | 84d90adc54 | ||
|  | cf15732a39 | ||
|  | 2eee73753f | ||
|  | 62d097357a | ||
|  | c35a690335 | ||
|  | 18af76ce92 | ||
|  | 6e7256d9a5 | ||
|  | 2af6c5a742 | ||
|  | 5c39fddbc6 | ||
|  | a708853199 | ||
|  | acb651cf92 | ||
|  | 562c91acb2 | ||
|  | 484f9607b1 | ||
|  | 9149ee224c | ||
|  | 1bb1d3b9af | ||
|  | 0b76390069 | ||
|  | 5de8751079 | ||
|  | 4bfe1b0c02 | ||
|  | 15c1676d0b | ||
|  | 49ff90aad1 | ||
|  | 6adaaf1965 | ||
|  | 6d114f84fa | ||
|  | 394cff9ebe | ||
|  | 465abd4498 | ||
|  | 0178569f14 | ||
|  | f7185445e1 | ||
|  | d4b107bc79 | ||
|  | fd14753a1d | ||
|  | 7cc4e93ad4 | ||
|  | 4c95404fe1 | ||
|  | 1c2212f0fe | ||
|  | 065fcedd34 | ||
|  | 3a66a79f49 | ||
|  | 907f6e92c3 | ||
|  | 426c3e6979 | ||
|  | 92292be472 | ||
|  | 3e10186c7c | ||
|  | 1974322013 | ||
|  | a2e22bc525 | 
							
								
								
									
										
											BIN
										
									
								
								.assets/codeberg.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								.assets/codeberg.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 17 KiB | 
							
								
								
									
										
											BIN
										
									
								
								.assets/fdroid-badge.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								.assets/fdroid-badge.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 14 KiB | 
							
								
								
									
										
											BIN
										
									
								
								.assets/google-play-badge.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								.assets/google-play-badge.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 4.8 KiB | 
							
								
								
									
										49
									
								
								.gitea/issue_template/bug_report.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								.gitea/issue_template/bug_report.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| --- | ||||
|  | ||||
| name: "Bug Report" | ||||
| about: "Report a Bug!" | ||||
| title: " [Bug] " | ||||
| ref: "master" | ||||
| labels: | ||||
|  | ||||
| - Kind/Bug | ||||
|  | ||||
| ---  | ||||
| ### Description of the Issue: | ||||
|  | ||||
| <!-- Provide a clear and concise description of what the issue is about. --> | ||||
|  | ||||
| ### Steps to Reproduce: | ||||
|  | ||||
| <!-- Explain the steps to reproduce the issue, if applicable. --> | ||||
|  | ||||
| 1.  | ||||
| 2.  | ||||
| 3.  | ||||
|  | ||||
| ### Expected Behavior: | ||||
|  | ||||
| <!-- Describe what you expected to happen. --> | ||||
|  | ||||
| ### Actual Behavior: | ||||
|  | ||||
| <!-- Describe what actually happened. Include screenshots if applicable. --> | ||||
|  | ||||
| ### App Information: | ||||
|  | ||||
| - **Version:** <!-- e.g. 1.0.0 --> | ||||
| - **Device:** <!-- e.g. Samsung Galaxy S10 --> | ||||
| - **Android Version:** <!-- e.g. Android 11 --> | ||||
| - **Installation Source:** <!-- e.g. Google Play Store, APK --> | ||||
|  | ||||
| ### Log Files: | ||||
|  | ||||
| <!-- If applicable, include log files or error messages related to this issue. --> | ||||
|  | ||||
| ### Additional Context: | ||||
|  | ||||
| <!-- Add any other context about the problem here, such as relevant system configuration or screenshots. --> | ||||
|  | ||||
| ### Potential Solutions or Workarounds: | ||||
|  | ||||
| <!-- If you know of any potential solutions or workarounds for this issue, please describe them here. --> | ||||
							
								
								
									
										28
									
								
								.gitea/issue_template/feature_request.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								.gitea/issue_template/feature_request.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| --- | ||||
|  | ||||
| name: "Feature request" | ||||
| about: "Request a feature!" | ||||
| title: "[Feature] " | ||||
| ref: "master" | ||||
| labels: | ||||
|  | ||||
| - Kind/Feature | ||||
|  | ||||
| --- | ||||
|  | ||||
| ### Description | ||||
| <!-- A clear and concise description of what the feature is and what problem it solves. --> | ||||
|  | ||||
| ### Background | ||||
| <!-- Any background information or context that would be helpful. --> | ||||
|  | ||||
| ### Proposed Solution | ||||
| <!-- | ||||
| - Describe the solution you'd like. | ||||
| - A clear and concise description of what you want to happen. | ||||
| - Include any alternative solutions or features you've considered. | ||||
| - Add any technical details, mockups, or examples if available. | ||||
| --> | ||||
|  | ||||
| ### Additional Context | ||||
| <!-- Add any other context, screenshots, or links to existing issues/discussions about the feature here. --> | ||||
							
								
								
									
										1
									
								
								.github/CODE_OF_CONDUCT.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/CODE_OF_CONDUCT.md
									
									
									
									
										vendored
									
									
								
							| @@ -1 +0,0 @@ | ||||
|  | ||||
							
								
								
									
										1
									
								
								.github/CONTRIBUTING.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/CONTRIBUTING.md
									
									
									
									
										vendored
									
									
								
							| @@ -1 +0,0 @@ | ||||
|  | ||||
							
								
								
									
										14
									
								
								.github/DISCUSSION_TEMPLATE/announcements.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.github/DISCUSSION_TEMPLATE/announcements.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,14 +0,0 @@ | ||||
| body: | ||||
|   - type: markdown | ||||
|     attributes: | ||||
|       value: | | ||||
|         Thanks for taking the time to read this announcement! | ||||
|  | ||||
|   - type: textarea | ||||
|     id: description | ||||
|     attributes: | ||||
|       label: description | ||||
|       description: Please describe the announcement in as much detail as possible. | ||||
|       placeholder: Make an announcement here... | ||||
|     validations: | ||||
|       required: true | ||||
							
								
								
									
										74
									
								
								.github/DISCUSSION_TEMPLATE/ideas.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										74
									
								
								.github/DISCUSSION_TEMPLATE/ideas.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,74 +0,0 @@ | ||||
| body: | ||||
|   - type: markdown | ||||
|     attributes: | ||||
|       value: | | ||||
|         Have an idea for a new feature or an improvement? Let us know here! | ||||
|  | ||||
|   - type: checkboxes | ||||
|     id: checklist | ||||
|     attributes: | ||||
|       label: Checklist | ||||
|       options: | ||||
|         - label: I have used the search function for [open](https://github.com/Docile-Alligator/Infinity-For-Reddit/discussions/categories/ideas) **and** [closed](https://github.com/Docile-Alligator/Infinity-For-Reddit/discussions/categories/completed-ideas) ideas to see if someone else has already submitted the same request. | ||||
|           required: true | ||||
|         - label: I will describe the feature with as much detail as possible. | ||||
|           required: true | ||||
|  | ||||
|   - type: markdown | ||||
|     attributes: | ||||
|       value: | | ||||
|         Thanks for taking the time to share your idea! | ||||
|  | ||||
|   - type: textarea | ||||
|     id: description | ||||
|     attributes: | ||||
|       label: Description | ||||
|       description: Please describe your idea in as much detail as possible. | ||||
|       placeholder: I think it would be great if... | ||||
|     validations: | ||||
|       required: true | ||||
|  | ||||
|   - type: textarea | ||||
|     id: alternatives | ||||
|     attributes: | ||||
|       label: Alternatives | ||||
|       description: Please describe any alternative solutions or features you've considered. | ||||
|       placeholder: I've considered... | ||||
|     validations: | ||||
|       required: false | ||||
|  | ||||
|   - type: textarea | ||||
|     id: additional | ||||
|     attributes: | ||||
|       label: Additional context | ||||
|       description: Add your use-case, screenshots, mock-up, or anything else you think might be helpful. | ||||
|       placeholder: I think this would be a great addition because... | ||||
|     validations: | ||||
|       required: true | ||||
|  | ||||
|   - type: dropdown | ||||
|     id: importance | ||||
|     attributes: | ||||
|       label: How important is this feature? | ||||
|       multiple: false | ||||
|       options: | ||||
|         - Critical | ||||
|         - Important | ||||
|         - Nice to have | ||||
|  | ||||
|   - type: textarea | ||||
|     id: other | ||||
|     attributes: | ||||
|       label: Anything else? | ||||
|       description: Is there anything else you'd like to add? | ||||
|     validations: | ||||
|       required: false | ||||
|  | ||||
|   - type: textarea | ||||
|     id: solution | ||||
|     attributes: | ||||
|       label: Solution | ||||
|       description: If you have an idea of how this can be implemented, please share it here. | ||||
|       placeholder: I think this could be done by... | ||||
|     validations: | ||||
|       required: false | ||||
							
								
								
									
										2
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,2 +0,0 @@ | ||||
| github: Docile-Alligator | ||||
| patreon: docile_alligator | ||||
							
								
								
									
										94
									
								
								.github/ISSUE_TEMPLATE/BUG_REPORT.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										94
									
								
								.github/ISSUE_TEMPLATE/BUG_REPORT.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,94 +0,0 @@ | ||||
| name: Bug Report | ||||
| description: Create a report to help us improve existing features | ||||
| labels: ['type: possible bug'] | ||||
|  | ||||
| body: | ||||
|   - type: markdown | ||||
|     attributes: | ||||
|       value: | | ||||
|         Thanks for taking the time to fill out this bug report! | ||||
|  | ||||
|   - type: checkboxes | ||||
|     id: checklist | ||||
|     attributes: | ||||
|       label: Checklist | ||||
|       options: | ||||
|         - label: I have used the search function for [open](https://github.com/Docile-Alligator/Infinity-For-Reddit/issues) **and** [closed](https://github.com/Docile-Alligator/Infinity-For-Reddit/issues?q=is%3Aissue+is%3Aclosed) issues to see if someone else has already submitted the same bug report. | ||||
|           required: true | ||||
|         - label: I will describe the problem with as much detail as possible. | ||||
|           required: true | ||||
|         - label: If the bug only occurs with a certain link, post, image..., I will include the URL. | ||||
|           required: true | ||||
|  | ||||
|   - type: input | ||||
|     id: version | ||||
|     attributes: | ||||
|       label: App version | ||||
|       description: We need the actual version number found on the settings screen. | ||||
|       placeholder: x.y.z | ||||
|     validations: | ||||
|       required: true | ||||
|  | ||||
|   - type: dropdown | ||||
|     id: source | ||||
|     attributes: | ||||
|       label: Where did you get the app from | ||||
|       multiple: false | ||||
|       options: | ||||
|         - Google Play | ||||
|         - F-Droid | ||||
|         - Other | ||||
|     validations: | ||||
|       required: true | ||||
|  | ||||
|   - type: input | ||||
|     id: android_version | ||||
|     attributes: | ||||
|       label: Android version | ||||
|       description: Please mention if you are using a custom rom! | ||||
|     validations: | ||||
|       required: true | ||||
|  | ||||
|   - type: input | ||||
|     id: device | ||||
|     attributes: | ||||
|       label: Device model | ||||
|  | ||||
|   - type: input | ||||
|     id: first | ||||
|     attributes: | ||||
|       label: First occurred | ||||
|       placeholder: about x days/weeks ago | ||||
|  | ||||
|   - type: textarea | ||||
|     id: steps | ||||
|     attributes: | ||||
|       label: Steps to reproduce | ||||
|       placeholder: | | ||||
|         1. This | ||||
|         2. Then that | ||||
|         3. Then this | ||||
|         4. Etc. | ||||
|  | ||||
|   - type: textarea | ||||
|     id: links | ||||
|     attributes: | ||||
|       label: Example post, link, markdown... | ||||
|  | ||||
|   - type: textarea | ||||
|     id: expected | ||||
|     attributes: | ||||
|       label: Expected behaviour | ||||
|       description: After following the steps, what did you think Infinity would do? | ||||
|  | ||||
|   - type: textarea | ||||
|     id: current | ||||
|     attributes: | ||||
|       label: Current behaviour | ||||
|       description: What did Infinity do instead? Screenshots might help. Usually, you can take a screenshot of your smartphone by pressing *Power* + *Volume down* for a few seconds. | ||||
|  | ||||
|   - type: textarea | ||||
|     id: logs | ||||
|     attributes: | ||||
|       label: Logs | ||||
|       description: If you are experiencing a crash, including the stacktrace will likely get it fixed sooner. | ||||
							
								
								
									
										11
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,11 +0,0 @@ | ||||
| blank_issues_enabled: false | ||||
| contact_links: | ||||
|   - name: Feature Request | ||||
|     url: https://github.com/Docile-Alligator/Infinity-For-Reddit/discussions/categories/ideas | ||||
|     about: Discuss ideas for new features of changes | ||||
|   - name: Questions | ||||
|     url: https://github.com/Docile-Alligator/Infinity-For-Reddit/discussions/categories/q-a | ||||
|     about: Please ask and answer questions here. | ||||
|   - name: Help needed | ||||
|     url: https://github.com/Docile-Alligator/Infinity-For-Reddit/discussions/categories/help-needed | ||||
|     about: Please ask for help here | ||||
							
								
								
									
										23
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,23 +0,0 @@ | ||||
| version: 2 | ||||
| updates: | ||||
|   # Updates for Gradle dependencies used in the app | ||||
|   - package-ecosystem: gradle | ||||
|     directory: "/" | ||||
|     schedule: | ||||
|       interval: "daily" | ||||
|     commit-message: | ||||
|       prefix: "⬆[Gradle]" | ||||
|     reviewers: | ||||
|       - "Wladefant" | ||||
|       - "Docile-Alligator" | ||||
|  | ||||
|   # Updates for GitHub Actions used in the repository | ||||
|   - package-ecosystem: github-actions | ||||
|     directory: "/" | ||||
|     schedule: | ||||
|       interval: "weekly" | ||||
|     commit-message: | ||||
|       prefix: "⬆[GitHub Actions]" | ||||
|     reviewers: | ||||
|       - "Wladefant" | ||||
|       - "Docile-Alligator" | ||||
							
								
								
									
										32
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,32 +0,0 @@ | ||||
| name: Build | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|   pull_request: | ||||
|   workflow_dispatch: | ||||
|  | ||||
| jobs: | ||||
|   Build: | ||||
|     runs-on: ubuntu-latest | ||||
|  | ||||
|     steps: | ||||
|     - name: Checkout Repository | ||||
|       uses: actions/checkout@v3 | ||||
|  | ||||
|     - name: Set-up JDK 11 | ||||
|       uses: actions/setup-java@v3 | ||||
|       with: | ||||
|         java-version: '11' | ||||
|         distribution: 'temurin' | ||||
|  | ||||
|     - name: Setup and build with Gradle | ||||
|       uses: gradle/gradle-build-action@v2 | ||||
|       with: | ||||
|         arguments: build -x lint | ||||
|  | ||||
|     - name: Upload apk | ||||
|       uses: actions/upload-artifact@v3 | ||||
|       with: | ||||
|         name: Infinity-${{github.sha}} | ||||
|         path: app/build/outputs/apk/ | ||||
|         if-no-files-found: error | ||||
							
								
								
									
										34
									
								
								.github/workflows/codeql-analysis.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								.github/workflows/codeql-analysis.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,34 +0,0 @@ | ||||
| name: CodeQL | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     branches: | ||||
|       - master | ||||
|   pull_request: | ||||
|   workflow_dispatch: | ||||
|   schedule: | ||||
|     - cron: '0 12 * * *' | ||||
|  | ||||
| jobs: | ||||
|   Analyze: | ||||
|     runs-on: ubuntu-latest | ||||
|  | ||||
|     permissions: | ||||
|       actions: read | ||||
|       contents: read | ||||
|       security-events: write | ||||
|  | ||||
|     steps: | ||||
|     - name: Checkout repository | ||||
|       uses: actions/checkout@v3 | ||||
|  | ||||
|     - name: Initialize CodeQL | ||||
|       uses: github/codeql-action/init@v2 | ||||
|       with: | ||||
|         languages: java | ||||
|  | ||||
|     - name: Autobuild | ||||
|       uses: github/codeql-action/autobuild@v2 | ||||
|  | ||||
|     - name: Perform CodeQL Analysis | ||||
|       uses: github/codeql-action/analyze@v2 | ||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -56,6 +56,8 @@ gen-external-apklibs | ||||
|  | ||||
| # NDK | ||||
| obj/ | ||||
| **/ndkHelperBin | ||||
| **/.cxx | ||||
|  | ||||
| # IntelliJ IDEA | ||||
| *.iml | ||||
|   | ||||
| @@ -1,14 +1,15 @@ | ||||
| pipeline: | ||||
| steps: | ||||
|   build: | ||||
|     image: alvrme/alpine-android:android-33-jdk11 | ||||
|     commands: | ||||
|       - apk add --no-cache python3 | ||||
|       - ./gradlew :app:assembleRelease | ||||
|     when: | ||||
|       path: [ app/**, build.gradle ] | ||||
|   sign: | ||||
|     image: alvrme/alpine-android:android-33-jdk11 | ||||
|     commands: | ||||
|       - ./scripts/apk-sign.sh LemmInfinity-signed.apk app/build/outputs/apk/release/app-release-unsigned.apk | ||||
|       - ./scripts/apk-sign.sh Eternity-signed.apk app/build/outputs/apk/release/app-release-unsigned.apk | ||||
|     secrets: [ APK_KS_PASS, APK_KS, APK_KS_ALIAS ] | ||||
|     when: | ||||
|       event: [ tag ] | ||||
| @@ -17,11 +18,13 @@ pipeline: | ||||
|     settings: | ||||
|       base_url: https://codeberg.org | ||||
|       files: | ||||
|         - LemmInfinity-signed.apk | ||||
|         - Eternity-signed.apk | ||||
|       api_key: | ||||
|         from_secret: GITEA_ACCESS_TOKEN | ||||
|       target: main | ||||
|       prerelease: true | ||||
|       note: "This is an alpha release. Expect many bugs and unfinished features!" | ||||
|     when: | ||||
|       event: [ tag ] | ||||
|       event: [ tag ] | ||||
| when: | ||||
|   event: [ push, tag, pull_request ] | ||||
|   | ||||
							
								
								
									
										77
									
								
								.woodpecker/nightly.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								.woodpecker/nightly.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| clone: | ||||
|   git: | ||||
|     image: woodpeckerci/plugin-git | ||||
|     settings: | ||||
|       partial: false | ||||
|  | ||||
| steps: | ||||
|   build: | ||||
|     image: alvrme/alpine-android:android-33-jdk11 | ||||
|     commands: | ||||
|       - apk add --no-cache python3 | ||||
|       - ./gradlew :app:assembleNightly | ||||
|   sign: | ||||
|     image: alvrme/alpine-android:android-33-jdk11 | ||||
|     commands: | ||||
|       - ./scripts/apk-sign.sh eu.toldi.infinityforlemmy.nightly.apk app/build/outputs/apk/nightly/eu.toldi.infinityforlemmy.nightly.apk | ||||
|     secrets: [ APK_KS_PASS, APK_KS, APK_KS_ALIAS ] | ||||
|   pull-repo-config: | ||||
|     image: codeberg.org/freeyourgadget/android-fdroid-tools:latest | ||||
|     commands: | ||||
|       - cd .. | ||||
|       - pwd | ||||
|       - mkdir repoconfig | ||||
|       - cd repoconfig | ||||
|       - pwd | ||||
|       - git clone --depth 1 https://codeberg.org/Bazsalanszky/fdroid-repo-config | ||||
|       - cp /woodpecker/src/codeberg.org/Bazsalanszky/Eternity/eu.toldi.infinityforlemmy.nightly.apk fdroid-repo-config/repo/ | ||||
|  | ||||
|   pull-pages: | ||||
|     image: codeberg.org/freeyourgadget/android-fdroid-tools:latest | ||||
|     commands: | ||||
|       - cd .. | ||||
|       - pwd | ||||
|       - mkdir pages | ||||
|       - cd pages | ||||
|       - pwd | ||||
|       - git clone --depth 2 https://codeberg.org/Bazsalanszky/pages | ||||
|       - cd pages | ||||
|       - git config user.name "CODEBERG CI" | ||||
|       - git config user.email "noreply@nodomain.nodomain" | ||||
|       # reset and remove, later force push, to keep repo size small | ||||
|       - git reset --soft HEAD~1 | ||||
|       - git status | ||||
|  | ||||
|   update-fdroid-data: | ||||
|     image: cs8898/android-fdroid-sdk:33.0.0 | ||||
|     commands: | ||||
|       - pwd | ||||
|       - cd ../repoconfig/fdroid-repo-config/ | ||||
|       - echo -n "$${FDROID_KS}" | base64 -d > keystore.p12 | ||||
|       - cat keystore.p12 | sha256sum | ||||
|       - sed -i "s|KS_PASS|$${FDROID_KS_PASS}|g" config.yml | ||||
|       - sed -i "s|KEY_PASS|$${FDROID_KEY_PASS}|g" config.yml | ||||
|       - fdroid update | ||||
|       - fdroid deploy | ||||
|       - ls -laR repo | ||||
|     secrets: [ FDROID_KS_PASS, FDROID_KEY_PASS, FDROID_KS ] | ||||
|   push-pages-update-repo: | ||||
|     image: codeberg.org/freeyourgadget/android-fdroid-tools:latest | ||||
|     commands: | ||||
|       - if [ -f .do_not_build ]; then return 0; fi | ||||
|       - cd ../pages/pages/ | ||||
|       - git add -A | ||||
|       - git status | ||||
|       - git diff | ||||
|       - ls -lsR fdroid/repo | ||||
|       - git commit -m "autodeploy" | ||||
|       - git remote remove origin | ||||
|       - git remote add origin https://Bazsalanszky:"$${GITEA_ACCESS_TOKEN}"@codeberg.org/Bazsalanszky/pages.git | ||||
|       # force push as we removed all data | ||||
|       - git push -f origin main | ||||
|       - cd ../../ | ||||
|       - pwd | ||||
|       - ls -la | ||||
|     secrets: [ GITEA_ACCESS_TOKEN ] | ||||
| when: | ||||
|   event: cron | ||||
							
								
								
									
										110
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,53 +1,97 @@ | ||||
| <h1 align="center"> | ||||
|   Infinity for Lemmy | ||||
|   Eternity for Lemmy | ||||
| </h1> | ||||
|  | ||||
| <div align="center"> | ||||
|  | ||||
| A Lemmy client for Android written in Java. It's a fork of the [Infinity for Reddit](https://github.com/Docile-Alligator/Infinity-For-Reddit) project, currenty in early development. | ||||
|  | ||||
| <img align="right" src="https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/raw/branch/master/fastlane/metadata/android/en-US/images/icon.png" width=200> | ||||
|  | ||||
| </div> | ||||
|  | ||||
| <br> | ||||
|  | ||||
|  | ||||
| <div align="center"> | ||||
| <img src="https://codeberg.org/Bazsalanszky/Eternity/raw/branch/master/fastlane/metadata/android/en-US/images/icon.png" width=256> | ||||
|  | ||||
| [](https://ci.codeberg.org/12474) | ||||
| [](https://ci.codeberg.org/repos/12474) | ||||
| [](https://liberapay.com/Bazsalanszky) | ||||
|  | ||||
| <a href="https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/issues">Report a Bug</a> | ||||
| <a href="https://codeberg.org/Bazsalanszky/Eternity/issues">Report a Bug</a> | ||||
|  | ||||
| </div> | ||||
|  | ||||
|  | ||||
|  | ||||
| <br> | ||||
|  | ||||
| <div align="center"> | ||||
| <a href="https://f-droid.org/packages/eu.toldi.infinityforlemmy/"> | ||||
|     <img src="./.assets/fdroid-badge.png" height="80"> | ||||
| </a> | ||||
| <a href="https://play.google.com/store/apps/details?id=eu.toldi.infinityforlemmy"> | ||||
|     <img src="./.assets/google-play-badge.png" height="80"> | ||||
| </a> | ||||
|  | ||||
| <a href="https://codeberg.org/Bazsalanszky/Eternity/releases/"> | ||||
|     <img src="./.assets/codeberg.png" height="80"> | ||||
| </a> | ||||
|  | ||||
|  | ||||
|  | ||||
| </div> | ||||
|  | ||||
|  | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## Action Items for Infinity for Lemmy | ||||
| ## Features | ||||
|  | ||||
| Infinity for Lemmy is currently in the early stages of development. Expect many unfinished features and bugs! | ||||
| Eternity is currently in the early stages of development. Expect many unfinished features and bugs! | ||||
|  | ||||
| - [x] Implementation of basic post browsing feature | ||||
| - [x] Support for multiple account handling | ||||
| - [x] Functionality for post upvotes/downvotes | ||||
| - [x] Functionality to browse comments | ||||
| - [ ] Capability for creating a new post | ||||
| - [x] Ability to create comments | ||||
| - [ ] Elimination of code/string references specific to Reddit | ||||
| - [ ] Incorporation of private messaging feature | ||||
| - [ ] Feature for saving posts | ||||
| - [ ] Account editing function | ||||
| - [ ] Multi community view? | ||||
| ### Browsing Lemmy | ||||
|  | ||||
|  - Explore various feeds (Subscribed/Local/All) and communities | ||||
|  - Subscribe or unsubscribe from specific communities, with the option to block | ||||
|  - Discover communities federated with the current instance | ||||
|  - Favorite a community for quick access | ||||
|  - Manage your subscriptions and blocked communities | ||||
|  | ||||
| ### Content Engagement | ||||
|  | ||||
| - Engage with content by voting, saving, sharing, and creating posts or comments | ||||
| - Enjoy endless scrolling through feeds and posts | ||||
| - Tailor the view settings for posts (card,compact, gallery) | ||||
| - Set default preferences for post and comment sorting | ||||
| - Stay updated with notifications for replies | ||||
|  | ||||
| ### Account Management | ||||
|  | ||||
| - Sign in to multiple accounts or instances, and effortlessly switch between them | ||||
| - Use the inbox features to view replies, mentions, and private messages | ||||
| - Access your profile to view your posts, comments, and saved content | ||||
|  | ||||
| ### Customization | ||||
|  | ||||
| - Choose between various theme options including Light, Dark, OLED | ||||
| - Support Material You theming | ||||
| - Explore user-created themes | ||||
| - Customize font settings | ||||
| - Optional bottom navigation bar | ||||
| - Discover a plethora of other customization features | ||||
|  | ||||
| <img  | ||||
|   src="https://codeberg.org/Bazsalanszky/Eternity/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png"  | ||||
|   alt="Screenshot 1" | ||||
|   height="200" > | ||||
| <img  | ||||
|   src="https://codeberg.org/Bazsalanszky/Eternity/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png"  | ||||
|   alt="Screenshot 2" | ||||
|   height="200" > | ||||
| <img  | ||||
|   src="https://codeberg.org/Bazsalanszky/Eternity/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png"  | ||||
|   alt="Screenshot 3" | ||||
|   height="200" > | ||||
| <img  | ||||
|   src="https://codeberg.org/Bazsalanszky/Eternity/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png"  | ||||
|   alt="Screenshot 4" | ||||
|   height="200" > | ||||
| <img  | ||||
|   src="https://codeberg.org/Bazsalanszky/Eternity/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png"  | ||||
|   alt="Screenshot 5" | ||||
|   height="200" > | ||||
|  | ||||
|  | ||||
| ## Contributing | ||||
| @@ -65,16 +109,21 @@ Don't forget to give the project a star! Thanks again! | ||||
| 4. Push to the Branch (`git push origin feature/AmazingFeature`) | ||||
| 5. Open a Pull Request | ||||
|  | ||||
| Here are other ways you can help: | ||||
| ### Translation | ||||
|  | ||||
| - [Report Bugs](https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/issues) | ||||
| You can also help Eternity by translating it to your native langugage! Translations are done via [Weblate](https://translate.codeberg.org/projects/infinity-for-lemmy/app/)! | ||||
|  | ||||
| [](https://translate.codeberg.org/engage/Eternity/) | ||||
|  | ||||
| ### Reporting bugs | ||||
|  | ||||
| You can also contribute by [reporting bugs](https://codeberg.org/Bazsalanszky/Eternity/issues) | ||||
|  | ||||
| <p align="right">(<a href="#top">back to top</a>)</p> | ||||
|  | ||||
| ## License | ||||
|  | ||||
| Distributed under the AGPL-3.0 License. See <a href="https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/src/branch/master/LICENSE">LICENSE</a> for more information. | ||||
| Distributed under the AGPL-3.0 License. See <a href="https://codeberg.org/Bazsalanszky/Eternity/src/branch/master/LICENSE">LICENSE</a> for more information. | ||||
|  | ||||
| <p align="right">(<a href="#top">back to top</a>)</p> | ||||
|  | ||||
| @@ -82,7 +131,6 @@ Distributed under the AGPL-3.0 License. See <a href="https://codeberg.org/Bazsal | ||||
|  | ||||
| [@bazsalanszky@lemmy.toldi.eu](https://lemmy.toldi.eu/u/bazsalanszky) - (Owner) | ||||
|  | ||||
|  | ||||
| Project Link: [https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy](https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy) | ||||
| Project Link: [https://codeberg.org/Bazsalanszky/Eternity](https://codeberg.org/Bazsalanszky/Eternity) | ||||
|  | ||||
| <p align="right">(<a href="#top">back to top</a>)</p> | ||||
|   | ||||
							
								
								
									
										122
									
								
								app/build.gradle
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								app/build.gradle
									
									
									
									
									
								
							| @@ -1,5 +1,18 @@ | ||||
| plugins { | ||||
|     id 'com.android.application' | ||||
|     id 'org.jetbrains.kotlin.android' | ||||
| } | ||||
| def getCommitVersionCode = { -> | ||||
|     try { | ||||
|         def stdout = new ByteArrayOutputStream() | ||||
|         exec { | ||||
|             commandLine 'git', 'rev-list', 'HEAD', '--count' | ||||
|             standardOutput = stdout | ||||
|         } | ||||
|         return Integer.valueOf(stdout.toString().trim()) | ||||
|     } catch (ignored) { | ||||
|         return null | ||||
|     } | ||||
| } | ||||
|  | ||||
| android { | ||||
| @@ -8,8 +21,8 @@ android { | ||||
|         applicationId "eu.toldi.infinityforlemmy" | ||||
|         minSdk 21 | ||||
|         targetSdk 33 | ||||
|         versionCode 125 | ||||
|         versionName "0.0.5" | ||||
|         versionCode 131 | ||||
|         versionName "0.1.2" | ||||
|         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||||
|         javaCompileOptions { | ||||
|             annotationProcessorOptions { | ||||
| @@ -18,10 +31,13 @@ android { | ||||
|         } | ||||
|     } | ||||
|     buildTypes { | ||||
|  | ||||
|         release { | ||||
|             minifyEnabled false | ||||
|             minifyEnabled true | ||||
|             shrinkResources true | ||||
|             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | ||||
|         } | ||||
|  | ||||
|         minifiedRelease { | ||||
|             initWith buildTypes.release | ||||
|             zipAlignEnabled true | ||||
| @@ -33,7 +49,33 @@ android { | ||||
|             applicationIdSuffix '.debug' | ||||
|             versionNameSuffix ' (DEBUG)' | ||||
|         } | ||||
|  | ||||
|         nightly { | ||||
|             minifyEnabled false | ||||
|             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | ||||
|             applicationIdSuffix '.nightly' | ||||
|             versionNameSuffix ' (NIGHTLY)' | ||||
|         } | ||||
|         applicationVariants.all { variant -> | ||||
|             variant.resValue "string", "applicationId", variant.applicationId | ||||
|  | ||||
|  | ||||
|             if (variant.buildType.name == 'nightly') { | ||||
|                 variant.outputs.all { | ||||
|                     setVersionCodeOverride(getCommitVersionCode()) | ||||
|  | ||||
|                     setVersionNameOverride(variant.versionName) | ||||
|                     outputFileName = "${applicationId}.apk" | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     sourceSets { | ||||
|         main.java.srcDirs += 'src/main/kotlin' | ||||
|     } | ||||
|  | ||||
|     compileOptions { | ||||
|         sourceCompatibility JavaVersion.VERSION_11 | ||||
|         targetCompatibility JavaVersion.VERSION_11 | ||||
| @@ -52,7 +94,41 @@ android { | ||||
|     buildFeatures { | ||||
|         viewBinding true | ||||
|     } | ||||
|  | ||||
|     packagingOptions { | ||||
|         doNotStrip '**/*.so' | ||||
|     } | ||||
|  | ||||
|     // Kotlin jvm target | ||||
|     kotlinOptions { | ||||
|         jvmTarget = '11' | ||||
|     } | ||||
|  | ||||
|     namespace 'eu.toldi.infinityforlemmy' | ||||
|  | ||||
|  | ||||
|     task rearrangeClass(type: Exec) { | ||||
|         commandLine 'python3', '../scripts/fixEventBus.py' | ||||
|     } | ||||
|  | ||||
|     applicationVariants.all { variant -> | ||||
|         if (variant.name == 'release') { | ||||
|             task("compileSingleFile${variant.name.capitalize()}", type: JavaCompile, dependsOn: rearrangeClass) { | ||||
|                 def filePath = project.rootDir.absolutePath + '/app/build/generated/ap_generated_sources/release/out/eu/toldi/infinityforlemmy/' | ||||
|                 source = files(filePath) | ||||
|                 includes = ["**/EventBusIndex.java"] | ||||
|                 classpath = variant.getCompileClasspath() + files(project.rootDir.absolutePath + '/app/build/intermediates/javac/release/classes') | ||||
|                 destinationDir = file("$buildDir/intermediates/javac/release/classes") | ||||
|             } | ||||
|  | ||||
|             tasks.withType(JavaCompile).all { task -> | ||||
|                 if (task.name == 'compileReleaseJavaWithJavac') { | ||||
|                     task.finalizedBy "compileSingleFile${variant.name.capitalize()}" | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| dependencies { | ||||
| @@ -63,6 +139,7 @@ dependencies { | ||||
|     implementation 'androidx.cardview:cardview:1.0.0' | ||||
|     implementation 'androidx.constraintlayout:constraintlayout:2.1.4' | ||||
|     implementation 'androidx.legacy:legacy-support-v4:1.0.0' | ||||
|  | ||||
|     def lifecycleVersion = "2.5.1" | ||||
|     implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion" | ||||
|     implementation "androidx.lifecycle:lifecycle-livedata:$lifecycleVersion" | ||||
| @@ -108,6 +185,7 @@ dependencies { | ||||
|     implementation "com.google.dagger:dagger:$daggerVersion" | ||||
|     annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" | ||||
|  | ||||
|  | ||||
|     // Binding | ||||
|     // NOTE: Deprecated in favor of viewbinding | ||||
|     def butterknifeVersion = "10.2.3" | ||||
| @@ -149,11 +227,12 @@ dependencies { | ||||
|     def glideVersion = "4.12.0" | ||||
|     implementation "com.github.bumptech.glide:glide:$glideVersion" | ||||
|     annotationProcessor "com.github.bumptech.glide:compiler:$glideVersion" | ||||
|     implementation "com.github.bumptech.glide:okhttp-integration:$glideVersion" | ||||
|     implementation 'jp.wasabeef:glide-transformations:4.3.0' | ||||
|     implementation 'com.github.santalu:aspect-ratio-imageview:1.0.9' | ||||
|     implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.23' | ||||
|     def bivVersion = "1.8.1" | ||||
|     implementation "com.github.piasy:BigImageViewer:bivVersion" | ||||
|     implementation "com.github.piasy:BigImageViewer:$bivVersion" | ||||
|     implementation "com.github.piasy:GlideImageLoader:$bivVersion" | ||||
|     implementation "com.github.piasy:GlideImageViewFactory:$bivVersion" | ||||
|  | ||||
| @@ -165,6 +244,7 @@ dependencies { | ||||
|     implementation "io.noties.markwon:recycler-table:$markwonVersion" | ||||
|     implementation "io.noties.markwon:simple-ext:$markwonVersion" | ||||
|     implementation "io.noties.markwon:inline-parser:$markwonVersion" | ||||
|     implementation "io.noties.markwon:image-glide:$markwonVersion" | ||||
|     implementation 'com.atlassian.commonmark:commonmark-ext-gfm-tables:0.14.0' | ||||
|     implementation 'me.saket:better-link-movement-method:2.2.0' | ||||
|  | ||||
| @@ -191,8 +271,42 @@ dependencies { | ||||
|  | ||||
|     implementation 'com.otaliastudios:zoomlayout:1.9.0' | ||||
|  | ||||
|     implementation 'androidx.core:core-splashscreen:1.0.1' | ||||
|  | ||||
|  | ||||
| /**** Builds and flavors ****/ | ||||
|     // debugImplementation because LeakCanary should only run in debug builds. | ||||
|     //debugImplementation 'com.squareup.leakcanary:leakcanary-android:x.y' | ||||
| } | ||||
|  | ||||
| // NB: Android Studio can't find the imports; this does not affect the | ||||
| // actual build since Gradle can find them just fine. | ||||
|  | ||||
| import com.android.tools.profgen.ArtProfileKt | ||||
| import com.android.tools.profgen.ArtProfileSerializer | ||||
| import com.android.tools.profgen.DexFile | ||||
|  | ||||
| project.afterEvaluate { | ||||
|     tasks.each { task -> | ||||
|         if (task.name.startsWith("compile") && task.name.endsWith("ReleaseArtProfile")) { | ||||
|             task.doLast { | ||||
|                 outputs.files.each { file -> | ||||
|                     if (file.name.endsWith(".profm")) { | ||||
|                         println("Sorting ${file} ...") | ||||
|                         def version = ArtProfileSerializer.valueOf("METADATA_0_0_2") | ||||
|                         def profile = ArtProfileKt.ArtProfile(file) | ||||
|                         def keys = new ArrayList(profile.profileData.keySet()) | ||||
|                         def sortedData = new LinkedHashMap() | ||||
|                         Collections.sort keys, new DexFile.Companion() | ||||
|                         keys.each { key -> sortedData[key] = profile.profileData[key] } | ||||
|                         new FileOutputStream(file).with { | ||||
|                             write(version.magicBytes$profgen) | ||||
|                             write(version.versionBytes$profgen) | ||||
|                             version.write$profgen(it, sortedData, "") | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										2
									
								
								app/proguard-rules.pro
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								app/proguard-rules.pro
									
									
									
									
										vendored
									
									
								
							| @@ -5,6 +5,8 @@ | ||||
| # If you keep the line number information, uncomment this to | ||||
| # hide the original source file name. | ||||
| #-renamesourcefileattribute SourceFile | ||||
| -dontobfuscate | ||||
| -keepattributes SourceFile,LineNumberTable | ||||
|  | ||||
| ## Preferences reflection | ||||
| -keep class * extends androidx.preference.PreferenceFragmentCompat | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| <resources> | ||||
|    <string name="application_name" translatable="false">Infinity for Lemmy (Debug)</string> | ||||
|    <string name="application_name" translatable="false">Eternity (Debug)</string> | ||||
| </resources> | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:tools="http://schemas.android.com/tools"> | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     package="eu.toldi.infinityforlemmy"> | ||||
|  | ||||
|     <queries> | ||||
|         <intent> | ||||
| @@ -23,7 +24,7 @@ | ||||
|  | ||||
|     <uses-permission android:name="android.permission.WAKE_LOCK" /> | ||||
|  | ||||
|     <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> | ||||
|     <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> | ||||
|  | ||||
|     <application | ||||
|         android:name=".Infinity" | ||||
| @@ -35,6 +36,29 @@ | ||||
|         android:theme="@style/AppTheme" | ||||
|         android:usesCleartextTraffic="true" | ||||
|         tools:replace="android:label"> | ||||
|         <activity | ||||
|             android:name=".activities.InstanceInfoActivity" | ||||
|             android:label="@string/instance_info" | ||||
|             android:configChanges="orientation|screenLayout|screenSize|layoutDirection" | ||||
|             android:parentActivityName=".activities.MainActivity" | ||||
|             android:theme="@style/AppTheme.Slidable" /> | ||||
|         <activity | ||||
|             android:name=".activities.CommentFilterUsageListingActivity" | ||||
|             android:parentActivityName=".activities.SettingsActivity" | ||||
|             android:theme="@style/AppTheme.NoActionBar" | ||||
|             android:exported="false" /> | ||||
|         <activity | ||||
|             android:name=".activities.CustomizeCommentFilterActivity" | ||||
|             android:label="@string/customize_comment_filter_activity_label" | ||||
|             android:parentActivityName=".activities.SettingsActivity" | ||||
|             android:theme="@style/AppTheme.NoActionBar" | ||||
|             android:exported="false" /> | ||||
|         <activity | ||||
|             android:name=".activities.CommentFilterPreferenceActivity" | ||||
|             android:label="@string/comment_filter_preference_activity_label" | ||||
|             android:parentActivityName=".activities.SettingsActivity" | ||||
|             android:theme="@style/AppTheme.NoActionBar" | ||||
|             android:exported="false" /> | ||||
|         <activity | ||||
|             android:name=".activities.HistoryActivity" | ||||
|             android:exported="false" | ||||
| @@ -430,12 +454,38 @@ | ||||
|             android:label="@string/application_name" | ||||
|             android:theme="@style/AppTheme.Launcher" | ||||
|             android:windowSoftInputMode="adjustPan"> | ||||
|             <intent-filter> | ||||
|                 <category android:name="android.intent.category.LAUNCHER" /> | ||||
|             </intent-filter> | ||||
|         </activity> | ||||
|  | ||||
|         <activity-alias | ||||
|             android:name=".DefaultIcon" | ||||
|             android:targetActivity=".activities.MainActivity" | ||||
|             android:label="@string/application_name" | ||||
|             android:enabled="true" | ||||
|             android:icon="@mipmap/ic_launcher" | ||||
|             android:exported="true"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.MAIN" /> | ||||
|  | ||||
|                 <category android:name="android.intent.category.LAUNCHER" /> | ||||
|             </intent-filter> | ||||
|         </activity> | ||||
|         </activity-alias> | ||||
|  | ||||
|         <activity-alias | ||||
|             android:name=".OriginalIcon" | ||||
|             android:targetActivity=".activities.MainActivity" | ||||
|             android:label="@string/application_name" | ||||
|             android:enabled="false" | ||||
|             android:icon="@mipmap/original_ic_launcher" | ||||
|             android:exported="true"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.MAIN" /> | ||||
|                 <category android:name="android.intent.category.LAUNCHER" /> | ||||
|             </intent-filter> | ||||
|         </activity-alias> | ||||
|  | ||||
|         <activity | ||||
|             android:name=".activities.LoginActivity" | ||||
|             android:configChanges="orientation|screenLayout|screenSize|layoutDirection" | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								app/src/main/ic_launcher-playstore.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								app/src/main/ic_launcher-playstore.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 33 KiB | 
| @@ -2,16 +2,22 @@ package eu.toldi.infinityforlemmy; | ||||
|  | ||||
| import android.app.Application; | ||||
|  | ||||
| import org.jetbrains.annotations.NotNull; | ||||
|  | ||||
| import javax.inject.Singleton; | ||||
|  | ||||
| import dagger.BindsInstance; | ||||
| import dagger.Component; | ||||
| import eu.toldi.infinityforlemmy.activities.AccountPostsActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.AccountSavedThingActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.BlockedThingListingActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.CommentActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.CommentFilterPreferenceActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.CommentFilterUsageListingActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.CreateMultiRedditActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.CustomThemeListingActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.CustomThemePreviewActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.CustomizeCommentFilterActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.CustomizePostFilterActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.CustomizeThemeActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.EditCommentActivity; | ||||
| @@ -22,8 +28,8 @@ import eu.toldi.infinityforlemmy.activities.FetchRandomSubredditOrPostActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.FilteredPostsActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.FullMarkdownActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.GiveAwardActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.HistoryActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.InboxActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.InstanceInfoActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.LinkResolverActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.LockScreenActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.LoginActivity; | ||||
| @@ -65,14 +71,17 @@ import eu.toldi.infinityforlemmy.activities.ViewVideoActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.WebViewActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.WikiActivity; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.AccountChooserBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.CommentMoreBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.FlairBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.BlockedCommunitiesListingFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.BlockedUsersListingFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.CommentsListingFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.FollowedUsersListingFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.HistoryPostFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.InboxFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.MorePostsInfoFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.MultiRedditListingFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.PostFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.PrivateMessageFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.SidebarFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.SubredditListingFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.SubscribedSubredditsListingFragment; | ||||
| @@ -105,7 +114,7 @@ import eu.toldi.infinityforlemmy.settings.TranslationFragment; | ||||
| import eu.toldi.infinityforlemmy.settings.VideoPreferenceFragment; | ||||
|  | ||||
| @Singleton | ||||
| @Component(modules = {AppModule.class, NetworkModule.class}) | ||||
| @Component(modules = {AppModule.class, NetworkModule.class, PostEnricherModule.class}) | ||||
| public interface AppComponent { | ||||
|     void inject(MainActivity mainActivity); | ||||
|  | ||||
| @@ -301,12 +310,26 @@ public interface AppComponent { | ||||
|  | ||||
|     void inject(MaterialYouWorker materialYouWorker); | ||||
|  | ||||
|     void inject(HistoryPostFragment historyPostFragment); | ||||
|  | ||||
|     void inject(HistoryActivity historyActivity); | ||||
|  | ||||
|     void inject(MorePostsInfoFragment morePostsInfoFragment); | ||||
|  | ||||
|     void inject(BlockedThingListingActivity blockedThingListingActivity); | ||||
|  | ||||
|     void inject(BlockedCommunitiesListingFragment blockedCommunitiesListingFragment); | ||||
|  | ||||
|     void inject(BlockedUsersListingFragment blockedUsersListingFragment); | ||||
|  | ||||
|     void inject(CommentMoreBottomSheetFragment commentMoreBottomSheetFragment); | ||||
|  | ||||
|     void inject(PrivateMessageFragment privateMessageFragment); | ||||
|  | ||||
|     void inject(@NotNull InstanceInfoActivity instanceInfoActivity); | ||||
|  | ||||
|     void inject(CommentFilterPreferenceActivity commentFilterPreferenceActivity); | ||||
|  | ||||
|     void inject(CustomizeCommentFilterActivity customizeCommentFilterActivity); | ||||
|  | ||||
|     void inject(CommentFilterUsageListingActivity commentFilterUsageListingActivity); | ||||
|  | ||||
|     @Component.Factory | ||||
|     interface Factory { | ||||
|         AppComponent create(@BindsInstance Application application); | ||||
|   | ||||
| @@ -22,6 +22,8 @@ import dagger.Module; | ||||
| import dagger.Provides; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.customviews.LoopAvailableExoCreator; | ||||
| import eu.toldi.infinityforlemmy.post.MarkPostAsRead; | ||||
| import eu.toldi.infinityforlemmy.post.ObjectResolver; | ||||
| import eu.toldi.infinityforlemmy.utils.CustomThemeSharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.videoautoplay.Config; | ||||
| @@ -192,8 +194,8 @@ abstract class AppModule { | ||||
|     @Provides | ||||
|     @Singleton | ||||
|     static ExoCreator provideExoCreator(Config config, | ||||
|                                  ToroExo toroExo, | ||||
|                                  @Named("default") SharedPreferences sharedPreferences) { | ||||
|                                         ToroExo toroExo, | ||||
|                                         @Named("default") SharedPreferences sharedPreferences) { | ||||
|         return new LoopAvailableExoCreator(toroExo, config, sharedPreferences); | ||||
|     } | ||||
|  | ||||
| @@ -202,4 +204,16 @@ abstract class AppModule { | ||||
|     static Executor provideExecutor() { | ||||
|         return Executors.newFixedThreadPool(4); | ||||
|     } | ||||
|  | ||||
|     @Provides | ||||
|     @Singleton | ||||
|     static ObjectResolver provideObjectResolver(@Named("no_oauth") RetrofitHolder retrofitHolder) { | ||||
|         return new ObjectResolver(retrofitHolder); | ||||
|     } | ||||
|  | ||||
|     @Provides | ||||
|     @Singleton | ||||
|     static MarkPostAsRead provideMarkPostAsRead(@Named("no_oauth") RetrofitHolder retrofitHolder) { | ||||
|         return new MarkPostAsRead(retrofitHolder); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -5,7 +5,9 @@ import androidx.annotation.NonNull; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.apis.RedditAPI; | ||||
| import eu.toldi.infinityforlemmy.apis.LemmyAPI; | ||||
| import eu.toldi.infinityforlemmy.dto.DeleteCommentDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.DeletePostDTO; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| import retrofit2.Call; | ||||
| import retrofit2.Callback; | ||||
| @@ -13,10 +15,11 @@ import retrofit2.Response; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
| public class DeleteThing { | ||||
|     public static void delete(Retrofit oauthRetrofit, String fullname, String accessToken, DeleteThingListener deleteThingListener) { | ||||
|  | ||||
|     public static void deletePost(Retrofit retrofit, int post_id, String accessToken, DeleteThingListener deleteThingListener) { | ||||
|         Map<String, String> params = new HashMap<>(); | ||||
|         params.put(APIUtils.ID_KEY, fullname); | ||||
|         oauthRetrofit.create(RedditAPI.class).delete(APIUtils.getOAuthHeader(accessToken), params).enqueue(new Callback<String>() { | ||||
|         params.put(APIUtils.ID_KEY, String.valueOf(post_id)); | ||||
|         retrofit.create(LemmyAPI.class).postDelete(new DeletePostDTO(post_id, true, accessToken)).enqueue(new Callback<String>() { | ||||
|             @Override | ||||
|             public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { | ||||
|                 if (response.isSuccessful()) { | ||||
| @@ -33,6 +36,27 @@ public class DeleteThing { | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public static void deleteComment(Retrofit retrofit, int comment_id, String accessToken, DeleteThingListener deleteThingListener) { | ||||
|         Map<String, String> params = new HashMap<>(); | ||||
|         params.put(APIUtils.ID_KEY, String.valueOf(comment_id)); | ||||
|         retrofit.create(LemmyAPI.class).commentDelete(new DeleteCommentDTO(comment_id, true, accessToken)).enqueue(new Callback<String>() { | ||||
|             @Override | ||||
|             public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { | ||||
|                 if (response.isSuccessful()) { | ||||
|                     deleteThingListener.deleteSuccess(); | ||||
|                 } else { | ||||
|                     deleteThingListener.deleteFailed(); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { | ||||
|                 deleteThingListener.deleteFailed(); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public interface DeleteThingListener { | ||||
|         void deleteSuccess(); | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,5 @@ | ||||
| package eu.toldi.infinityforlemmy; | ||||
|  | ||||
| import android.content.Context; | ||||
| import android.content.SharedPreferences; | ||||
| import android.os.Handler; | ||||
|  | ||||
| import org.json.JSONException; | ||||
| @@ -12,9 +10,7 @@ import java.util.concurrent.Executor; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.apis.GfycatAPI; | ||||
| import eu.toldi.infinityforlemmy.apis.RedgifsAPI; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.JSONUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import retrofit2.Call; | ||||
| import retrofit2.Response; | ||||
| import retrofit2.Retrofit; | ||||
| @@ -44,14 +40,12 @@ public class FetchGfycatOrRedgifsVideoLinks { | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public static void fetchRedgifsVideoLinks(Context context, Executor executor, Handler handler, Retrofit redgifsRetrofit, | ||||
|                                               SharedPreferences currentAccountSharedPreferences, | ||||
|     public static void fetchRedgifsVideoLinks(Executor executor, Handler handler, Retrofit redgifsRetrofit, | ||||
|                                               String gfycatId, | ||||
|                                               FetchGfycatOrRedgifsVideoLinksListener fetchGfycatOrRedgifsVideoLinksListener) { | ||||
|         executor.execute(() -> { | ||||
|             try { | ||||
|                 Response<String> response = redgifsRetrofit.create(RedgifsAPI.class).getRedgifsData(APIUtils.getRedgifsOAuthHeader(currentAccountSharedPreferences.getString(SharedPreferencesUtils.REDGIFS_ACCESS_TOKEN, "")), | ||||
|                          gfycatId, APIUtils.USER_AGENT).execute(); | ||||
|                 Response<String> response = redgifsRetrofit.create(RedgifsAPI.class).getRedgifsData(gfycatId).execute(); | ||||
|                 if (response.isSuccessful()) { | ||||
|                     parseRedgifsVideoLinks(handler, response.body(), fetchGfycatOrRedgifsVideoLinksListener); | ||||
|                 } else { | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| package eu.toldi.infinityforlemmy; | ||||
|  | ||||
| import android.os.AsyncTask; | ||||
| import android.text.Html; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
|  | ||||
| @@ -9,9 +8,6 @@ import org.json.JSONException; | ||||
| import org.json.JSONObject; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.apis.LemmyAPI; | ||||
| import eu.toldi.infinityforlemmy.apis.RedditAPI; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.JSONUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.LemmyUtils; | ||||
| import retrofit2.Call; | ||||
| import retrofit2.Callback; | ||||
| @@ -83,7 +79,7 @@ public class FetchMyInfo { | ||||
|                 if (!person.isNull("banner")) { | ||||
|                     bannerImageUrl = person.getString("banner"); | ||||
|                 } | ||||
|                 display_name = person.getString("name"); | ||||
|                 display_name = (person.has("display_name")) ? person.getString("display_name") : person.getString("name"); | ||||
|                 redditDataRoomDatabase.accountDao().updateAccountInfo(name, profileImageUrl, bannerImageUrl); | ||||
|             } catch (JSONException e) { | ||||
|                 parseFailed = true; | ||||
|   | ||||
| @@ -20,6 +20,7 @@ import retrofit2.Response; | ||||
| public class FetchStreamableVideo { | ||||
|     public interface FetchStreamableVideoListener { | ||||
|         void success(StreamableVideo streamableVideo); | ||||
|  | ||||
|         void failed(); | ||||
|     } | ||||
|  | ||||
| @@ -33,7 +34,12 @@ public class FetchStreamableVideo { | ||||
|                     String title = jsonObject.getString(JSONUtils.TITLE_KEY); | ||||
|                     JSONObject filesObject = jsonObject.getJSONObject(JSONUtils.FILES_KEY); | ||||
|                     StreamableVideo.Media mp4 = parseMedia(filesObject.getJSONObject(JSONUtils.MP4_KEY)); | ||||
|                     StreamableVideo.Media mp4Mobile = parseMedia(filesObject.getJSONObject(JSONUtils.MP4_MOBILE_KEY)); | ||||
|                     StreamableVideo.Media mp4MobileTemp = null; | ||||
|                     try { | ||||
|                         mp4MobileTemp = parseMedia(filesObject.getJSONObject(JSONUtils.MP4_MOBILE_KEY)); | ||||
|                     } catch (JSONException e) { | ||||
|                     } | ||||
|                     StreamableVideo.Media mp4Mobile = mp4MobileTemp; | ||||
|                     handler.post(() -> fetchStreamableVideoListener.success(new StreamableVideo(title, mp4, mp4Mobile))); | ||||
|                 } else { | ||||
|                     handler.post(fetchStreamableVideoListener::failed); | ||||
| @@ -55,7 +61,12 @@ public class FetchStreamableVideo { | ||||
|                     String title = jsonObject.getString(JSONUtils.TITLE_KEY); | ||||
|                     JSONObject filesObject = jsonObject.getJSONObject(JSONUtils.FILES_KEY); | ||||
|                     StreamableVideo.Media mp4 = parseMedia(filesObject.getJSONObject(JSONUtils.MP4_KEY)); | ||||
|                     StreamableVideo.Media mp4Mobile = parseMedia(filesObject.getJSONObject(JSONUtils.MP4_MOBILE_KEY)); | ||||
|                     StreamableVideo.Media mp4MobileTemp = null; | ||||
|                     try { | ||||
|                         mp4MobileTemp = parseMedia(filesObject.getJSONObject(JSONUtils.MP4_MOBILE_KEY)); | ||||
|                     } catch (JSONException e) { | ||||
|                     } | ||||
|                     StreamableVideo.Media mp4Mobile = mp4MobileTemp; | ||||
|                     if (mp4 == null && mp4Mobile == null) { | ||||
|                         handler.post(fetchStreamableVideoListener::failed); | ||||
|                         return; | ||||
|   | ||||
| @@ -11,6 +11,16 @@ import android.os.Bundle; | ||||
| import android.view.WindowManager; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.lifecycle.Lifecycle; | ||||
| import androidx.lifecycle.LifecycleObserver; | ||||
| import androidx.lifecycle.OnLifecycleEvent; | ||||
| import androidx.lifecycle.ProcessLifecycleOwner; | ||||
|  | ||||
| import com.bumptech.glide.Glide; | ||||
| import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader; | ||||
| import com.bumptech.glide.load.model.GlideUrl; | ||||
| import com.evernote.android.state.StateSaver; | ||||
| import com.livefront.bridge.Bridge; | ||||
| import com.livefront.bridge.SavedStateHandler; | ||||
| @@ -18,15 +28,11 @@ import com.livefront.bridge.SavedStateHandler; | ||||
| import org.greenrobot.eventbus.EventBus; | ||||
| import org.greenrobot.eventbus.Subscribe; | ||||
|  | ||||
| import java.io.InputStream; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.lifecycle.Lifecycle; | ||||
| import androidx.lifecycle.LifecycleObserver; | ||||
| import androidx.lifecycle.OnLifecycleEvent; | ||||
| import androidx.lifecycle.ProcessLifecycleOwner; | ||||
| import eu.toldi.infinityforlemmy.activities.LockScreenActivity; | ||||
| import eu.toldi.infinityforlemmy.broadcastreceivers.NetworkWifiStatusReceiver; | ||||
| import eu.toldi.infinityforlemmy.broadcastreceivers.WallpaperChangeReceiver; | ||||
| @@ -38,6 +44,8 @@ import eu.toldi.infinityforlemmy.font.FontFamily; | ||||
| import eu.toldi.infinityforlemmy.font.TitleFontFamily; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
| import okhttp3.Call; | ||||
| import okhttp3.OkHttpClient; | ||||
|  | ||||
| public class Infinity extends Application implements LifecycleObserver { | ||||
|     public Typeface typeface; | ||||
| @@ -55,6 +63,9 @@ public class Infinity extends Application implements LifecycleObserver { | ||||
|     @Inject | ||||
|     @Named("security") | ||||
|     SharedPreferences mSecuritySharedPreferences; | ||||
|     @Inject | ||||
|     @Named("glide") | ||||
|     OkHttpClient glideOkHttpClient; | ||||
|  | ||||
|     @Override | ||||
|     public void onCreate() { | ||||
| @@ -159,6 +170,9 @@ public class Infinity extends Application implements LifecycleObserver { | ||||
|         registerReceiver(mNetworkWifiStatusReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); | ||||
|  | ||||
|         registerReceiver(new WallpaperChangeReceiver(mSharedPreferences), new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED)); | ||||
|  | ||||
|         OkHttpUrlLoader.Factory factory = new OkHttpUrlLoader.Factory((Call.Factory) glideOkHttpClient); | ||||
|         Glide.get(this).getRegistry().replace(GlideUrl.class, InputStream.class, factory); | ||||
|     } | ||||
|  | ||||
|     @OnLifecycleEvent(Lifecycle.Event.ON_START) | ||||
|   | ||||
| @@ -9,16 +9,16 @@ import javax.inject.Singleton; | ||||
|  | ||||
| import dagger.Module; | ||||
| import dagger.Provides; | ||||
| import eu.toldi.infinityforlemmy.apis.RedgifsAPI; | ||||
| import eu.toldi.infinityforlemmy.apis.StreamableAPI; | ||||
| import eu.toldi.infinityforlemmy.network.SortTypeConverterFactory; | ||||
| import eu.toldi.infinityforlemmy.comment.LemmyCommentAPI; | ||||
| import eu.toldi.infinityforlemmy.post.LemmyPostAPI; | ||||
| import eu.toldi.infinityforlemmy.privatemessage.LemmyPrivateMessageAPI; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| import okhttp3.ConnectionPool; | ||||
| import okhttp3.Interceptor; | ||||
| import okhttp3.OkHttpClient; | ||||
| import retrofit2.Retrofit; | ||||
| import retrofit2.adapter.guava.GuavaCallAdapterFactory; | ||||
| import retrofit2.converter.gson.GsonConverterFactory; | ||||
| import retrofit2.converter.scalars.ScalarsConverterFactory; | ||||
|  | ||||
| @Module(includes = AppModule.class) | ||||
| abstract class NetworkModule { | ||||
| @@ -35,6 +35,21 @@ abstract class NetworkModule { | ||||
|                 .build(); | ||||
|     } | ||||
|  | ||||
|     @Provides | ||||
|     @Named("glide") | ||||
|     @Singleton | ||||
|     static OkHttpClient provideGlideOkHttp(@Named("base") OkHttpClient baseOkHttp, | ||||
|                                            @Named("RedgifsAccessTokenAuthenticator") Interceptor redGifsAuthenticator) { | ||||
|         return baseOkHttp.newBuilder() | ||||
|                 .addInterceptor(chain -> chain.proceed( | ||||
|                         chain.request() | ||||
|                                 .newBuilder() | ||||
|                                 .header("User-Agent", APIUtils.USER_AGENT) | ||||
|                                 .build() | ||||
|                 )) | ||||
|                 .addInterceptor(redGifsAuthenticator) | ||||
|                 .build(); | ||||
|     } | ||||
|  | ||||
|     @Provides | ||||
|     @Named("base") | ||||
| @@ -166,6 +181,12 @@ abstract class NetworkModule { | ||||
|                 .build(); | ||||
|     } | ||||
|  | ||||
|     @Provides | ||||
|     @Singleton | ||||
|     static RedgifsAPI provideRedgifsAPI(@Named("redgifs") Retrofit redgifsRetrofit) { | ||||
|         return redgifsRetrofit.create(RedgifsAPI.class); | ||||
|     } | ||||
|  | ||||
|     @Provides | ||||
|     @Named("imgur") | ||||
|     @Singleton | ||||
| @@ -216,4 +237,31 @@ abstract class NetworkModule { | ||||
|     static StreamableAPI provideStreamableApi(@Named("streamable") Retrofit streamableRetrofit) { | ||||
|         return streamableRetrofit.create(StreamableAPI.class); | ||||
|     } | ||||
|  | ||||
|     @Provides | ||||
|     @Singleton | ||||
|     static LemmyPostAPI providePostAPI(@Named("no_oauth") RetrofitHolder retrofitHolder) { | ||||
|         return new LemmyPostAPI(retrofitHolder); | ||||
|     } | ||||
|  | ||||
|     @Provides | ||||
|     @Singleton | ||||
|     static LemmyCommentAPI provideCommentAPI(@Named("no_oauth") RetrofitHolder retrofitHolder) { | ||||
|         return new LemmyCommentAPI(retrofitHolder); | ||||
|     } | ||||
|  | ||||
|     @Provides | ||||
|     @Singleton | ||||
|     static LemmyPrivateMessageAPI provideLemmyPrivateMessageAPI(@Named("base") RetrofitHolder retrofit) { | ||||
|         return new LemmyPrivateMessageAPI(retrofit); | ||||
|     } | ||||
|  | ||||
|     @Provides | ||||
|     @Named("lemmyVerse") | ||||
|     @Singleton | ||||
|     static Retrofit provideLemmyVerseRetrofit(@Named("base") RetrofitHolder retrofit) { | ||||
|         return retrofit.getRetrofit().newBuilder() | ||||
|                 .baseUrl(APIUtils.LEMMYVERSE_API_BASE_URI) | ||||
|                 .build(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -110,9 +110,9 @@ class ParseSubscribedThing { | ||||
|                     boolean postingRestrictedToMods = community.getBoolean("posting_restricted_to_mods"); | ||||
|                     int instanceId = community.getInt("instance_id"); | ||||
|                     int subscribers = data.getJSONObject("counts").getInt("subscribers"); | ||||
|  | ||||
|                     newSubscribedSubredditData.add(new SubscribedSubredditData(id, title, LemmyUtils.actorID2FullName(actorId), iconUrl, accountName)); | ||||
|                     newSubredditData.add(new SubredditData(id,name,title,description,removed,published,updated,deleted,nsfw,actorId,local,iconUrl,bannerImageUrl,hidden,postingRestrictedToMods,instanceId,subscribers)); | ||||
|                     boolean isBlocked = data.getBoolean("blocked"); | ||||
|                     newSubscribedSubredditData.add(new SubscribedSubredditData(id, title, LemmyUtils.actorID2FullName(actorId), iconUrl, accountName, false)); | ||||
|                     newSubredditData.add(new SubredditData(id, name, title, description, removed, published, updated, deleted, nsfw, actorId, local, iconUrl, bannerImageUrl, hidden, postingRestrictedToMods, instanceId, subscribers, isBlocked)); | ||||
|  | ||||
|                 } | ||||
|             } catch (JSONException e) { | ||||
|   | ||||
| @@ -0,0 +1,26 @@ | ||||
| package eu.toldi.infinityforlemmy; | ||||
|  | ||||
| import java.util.Set; | ||||
|  | ||||
| import dagger.Module; | ||||
| import dagger.Provides; | ||||
| import dagger.multibindings.IntoSet; | ||||
| import eu.toldi.infinityforlemmy.apis.RedgifsAPI; | ||||
| import eu.toldi.infinityforlemmy.post.enrich.CompositePostEnricher; | ||||
| import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; | ||||
| import eu.toldi.infinityforlemmy.post.enrich.RedGifsPostEnricher; | ||||
|  | ||||
| @Module | ||||
| abstract class PostEnricherModule { | ||||
|  | ||||
|     @Provides | ||||
|     @IntoSet | ||||
|     static PostEnricher provideRedGifsPostEnricher(RedgifsAPI redgifsAPI) { | ||||
|         return new RedGifsPostEnricher(redgifsAPI); | ||||
|     } | ||||
|  | ||||
|     @Provides | ||||
|     static PostEnricher providePostEnricher(Set<PostEnricher> postEnrichers) { | ||||
|         return new CompositePostEnricher(postEnrichers); | ||||
|     } | ||||
| } | ||||
| @@ -4,10 +4,12 @@ import android.app.PendingIntent; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.pm.PackageManager; | ||||
| import android.net.Uri; | ||||
| import android.os.Build; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.core.app.ActivityCompat; | ||||
| import androidx.core.app.NotificationCompat; | ||||
| import androidx.core.app.NotificationManagerCompat; | ||||
| import androidx.work.Worker; | ||||
| @@ -28,13 +30,11 @@ import javax.inject.Named; | ||||
| import eu.toldi.infinityforlemmy.account.Account; | ||||
| import eu.toldi.infinityforlemmy.activities.InboxActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.LinkResolverActivity; | ||||
| import eu.toldi.infinityforlemmy.apis.RedditAPI; | ||||
| import eu.toldi.infinityforlemmy.apis.LemmyAPI; | ||||
| import eu.toldi.infinityforlemmy.comment.Comment; | ||||
| import eu.toldi.infinityforlemmy.comment.ParseComment; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.message.FetchMessage; | ||||
| import eu.toldi.infinityforlemmy.message.Message; | ||||
| import eu.toldi.infinityforlemmy.message.ParseMessage; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.JSONUtils; | ||||
| import eu.toldi.infinityforlemmy.message.CommentInteraction; | ||||
| import eu.toldi.infinityforlemmy.utils.NotificationUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import retrofit2.Call; | ||||
| @@ -88,9 +88,16 @@ public class PullNotificationWorker extends Worker { | ||||
|  | ||||
|                 if (response != null && response.isSuccessful() && response.body() != null) { | ||||
|                     String responseBody = response.body(); | ||||
|                     JSONArray messageArray = new JSONObject(responseBody).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); | ||||
|                     ArrayList<Message> messages = ParseMessage.parseMessages(messageArray, | ||||
|                             context.getResources().getConfiguration().locale, FetchMessage.MESSAGE_TYPE_NOTIFICATION); | ||||
|                     JSONArray messageArray = new JSONObject(responseBody).getJSONArray("replies"); | ||||
|                     List<CommentInteraction> messages = new ArrayList<>(); | ||||
|                     for (int i = 0; i < messageArray.length(); i++) { | ||||
|                         JSONObject commentInteractionObject = messageArray.getJSONObject(i); | ||||
|                         Comment comment = ParseComment.parseSingleComment(commentInteractionObject); | ||||
|                         boolean isRead = !commentInteractionObject.getJSONObject("comment_reply").getBoolean("read"); | ||||
|                         int id = commentInteractionObject.getJSONObject("comment_reply").getInt("id"); | ||||
|                         messages.add(new CommentInteraction(id, comment, isRead)); | ||||
|                     } | ||||
|  | ||||
|  | ||||
|                     if (!messages.isEmpty()) { | ||||
|                         NotificationCompat.Builder summaryBuilder = NotificationUtils.buildSummaryNotification(context, | ||||
| @@ -110,77 +117,36 @@ public class PullNotificationWorker extends Worker { | ||||
|  | ||||
|                         int pendingIntentFlags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT; | ||||
|                         for (int messageIndex = messageSize - 1; messageIndex >= 0; messageIndex--) { | ||||
|                             Message message = messages.get(messageIndex); | ||||
|                             if (message.getTimeUTC() <= lastNotificationTime) { | ||||
|                             CommentInteraction message = messages.get(messageIndex); | ||||
|                             if (message.getComment().getCommentTimeMillis() <= lastNotificationTime) { | ||||
|                                 continue; | ||||
|                             } | ||||
|  | ||||
|                             hasValidMessage = true; | ||||
|  | ||||
|                             inboxStyle.addLine(message.getAuthor() + " " + message.getBody()); | ||||
|                             inboxStyle.addLine(message.getComment().getAuthorQualifiedName() + " " + message.getComment().getCommentMarkdown()); | ||||
|  | ||||
|  | ||||
|                             String title = message.getComment().getAuthorQualifiedName(); | ||||
|                             String summary = message.getComment().getCommunityQualifiedName(); | ||||
|  | ||||
|                             String kind = message.getKind(); | ||||
|                             String title; | ||||
|                             String summary; | ||||
|                             if (kind.equals(Message.TYPE_COMMENT) || kind.equals(Message.TYPE_LINK)) { | ||||
|                                 title = message.getAuthor(); | ||||
|                                 summary = message.getSubject().substring(0, 1).toUpperCase() + message.getSubject().substring(1); | ||||
|                             } else { | ||||
|                                 title = message.getTitle() == null || message.getTitle().equals("") ? message.getSubject() : message.getTitle(); | ||||
|                                 if (kind.equals(Message.TYPE_ACCOUNT)) { | ||||
|                                     summary = context.getString(R.string.notification_summary_account); | ||||
|                                 } else if (kind.equals(Message.TYPE_MESSAGE)) { | ||||
|                                     summary = context.getString(R.string.notification_summary_message); | ||||
|                                 } else if (kind.equals(Message.TYPE_SUBREDDIT)) { | ||||
|                                     summary = context.getString(R.string.notification_summary_community); | ||||
|                                 } else { | ||||
|                                     summary = context.getString(R.string.notification_summary_award); | ||||
|                                 } | ||||
|                             } | ||||
|  | ||||
|                             NotificationCompat.Builder builder = NotificationUtils.buildNotification(notificationManager, | ||||
|                                     context, title, message.getBody(), summary, | ||||
|                                     context, title, message.getComment().getCommentMarkdown(), summary, | ||||
|                                     NotificationUtils.CHANNEL_ID_NEW_MESSAGES, | ||||
|                                     NotificationUtils.CHANNEL_NEW_MESSAGES, | ||||
|                                     NotificationUtils.getAccountGroupName(accountName), color); | ||||
|  | ||||
|                             if (kind.equals(Message.TYPE_COMMENT)) { | ||||
|                                 Intent intent = new Intent(context, LinkResolverActivity.class); | ||||
|                                 Uri uri = Uri.parse(message.getContext()); | ||||
|                                 intent.setData(uri); | ||||
|                                 intent.putExtra(LinkResolverActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); | ||||
|                                 intent.putExtra(LinkResolverActivity.EXTRA_MESSAGE_FULLNAME, message.getFullname()); | ||||
|                                 PendingIntent pendingIntent = PendingIntent.getActivity(context, accountIndex * 6, intent, pendingIntentFlags); | ||||
|                                 builder.setContentIntent(pendingIntent); | ||||
|                             } else if (kind.equals(Message.TYPE_ACCOUNT)) { | ||||
|                                 Intent intent = new Intent(context, InboxActivity.class); | ||||
|                                 intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); | ||||
|                                 PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 1, intent, pendingIntentFlags); | ||||
|                                 builder.setContentIntent(summaryPendingIntent); | ||||
|                             } else if (kind.equals(Message.TYPE_LINK)) { | ||||
|                                 Intent intent = new Intent(context, LinkResolverActivity.class); | ||||
|                                 Uri uri = Uri.parse(message.getContext()); | ||||
|                                 intent.setData(uri); | ||||
|                                 intent.putExtra(LinkResolverActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); | ||||
|                                 intent.putExtra(LinkResolverActivity.EXTRA_MESSAGE_FULLNAME, message.getFullname()); | ||||
|                                 PendingIntent pendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 2, intent, pendingIntentFlags); | ||||
|                                 builder.setContentIntent(pendingIntent); | ||||
|                             } else if (kind.equals(Message.TYPE_MESSAGE)) { | ||||
|                                 Intent intent = new Intent(context, InboxActivity.class); | ||||
|                                 intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); | ||||
|                                 intent.putExtra(InboxActivity.EXTRA_VIEW_MESSAGE, true); | ||||
|                                 PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 3, intent, pendingIntentFlags); | ||||
|                                 builder.setContentIntent(summaryPendingIntent); | ||||
|                             } else if (kind.equals(Message.TYPE_SUBREDDIT)) { | ||||
|                                 Intent intent = new Intent(context, InboxActivity.class); | ||||
|                                 intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); | ||||
|                                 PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 4, intent, pendingIntentFlags); | ||||
|                                 builder.setContentIntent(summaryPendingIntent); | ||||
|                             } else { | ||||
|                                 Intent intent = new Intent(context, InboxActivity.class); | ||||
|                                 intent.putExtra(InboxActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); | ||||
|                                 PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, accountIndex * 6 + 5, intent, pendingIntentFlags); | ||||
|                                 builder.setContentIntent(summaryPendingIntent); | ||||
|                             Intent intent = new Intent(context, LinkResolverActivity.class); | ||||
|                             Uri uri = Uri.parse(message.getComment().getPermalink()); | ||||
|                             intent.setData(uri); | ||||
|                             intent.putExtra(LinkResolverActivity.EXTRA_NEW_ACCOUNT_NAME, accountName); | ||||
|                             intent.putExtra(LinkResolverActivity.EXTRA_MESSAGE_FULLNAME, message.getId()); | ||||
|                             PendingIntent pendingIntent = PendingIntent.getActivity(context, accountIndex * 6, intent, pendingIntentFlags); | ||||
|                             builder.setContentIntent(pendingIntent); | ||||
|  | ||||
|                             if (ActivityCompat.checkSelfPermission(this.getApplicationContext(), android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { | ||||
|                                 return Result.failure(); | ||||
|                             } | ||||
|                             notificationManager.notify(NotificationUtils.getNotificationIdUnreadMessage(accountIndex, messageIndex), builder.build()); | ||||
|                         } | ||||
| @@ -216,10 +182,7 @@ public class PullNotificationWorker extends Worker { | ||||
|         if (retryCount < 0) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         Call<String> call = mOauthWithoutAuthenticatorRetrofit.create(RedditAPI.class) | ||||
|                 .getMessages(APIUtils.getOAuthHeader(account.getAccessToken()), | ||||
|                         FetchMessage.WHERE_UNREAD, null); | ||||
|         Call<String> call = mRetrofit.getRetrofit().create(LemmyAPI.class).userReplies("New", 1, 25, true, account.getAccessToken()); | ||||
|         Response<String> response = call.execute(); | ||||
|  | ||||
|         if (response.isSuccessful()) { | ||||
|   | ||||
| @@ -13,6 +13,14 @@ import androidx.sqlite.db.SupportSQLiteDatabase; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.account.Account; | ||||
| import eu.toldi.infinityforlemmy.account.AccountDao; | ||||
| import eu.toldi.infinityforlemmy.blockedcommunity.BlockedCommunityDao; | ||||
| import eu.toldi.infinityforlemmy.blockedcommunity.BlockedCommunityData; | ||||
| import eu.toldi.infinityforlemmy.blockeduser.BlockedUserDao; | ||||
| import eu.toldi.infinityforlemmy.blockeduser.BlockedUserData; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.CommentFilter; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.CommentFilterDao; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsage; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsageDao; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomTheme; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeDao; | ||||
| import eu.toldi.infinityforlemmy.multireddit.AnonymousMultiredditSubreddit; | ||||
| @@ -38,7 +46,8 @@ import eu.toldi.infinityforlemmy.user.UserData; | ||||
|  | ||||
| @Database(entities = {Account.class, SubredditData.class, SubscribedSubredditData.class, UserData.class, | ||||
|         SubscribedUserData.class, MultiReddit.class, CustomTheme.class, RecentSearchQuery.class, | ||||
|         ReadPost.class, PostFilter.class, PostFilterUsage.class, AnonymousMultiredditSubreddit.class}, version = 23) | ||||
|         ReadPost.class, PostFilter.class, PostFilterUsage.class, AnonymousMultiredditSubreddit.class, | ||||
|         BlockedUserData.class, BlockedCommunityData.class, CommentFilter.class, CommentFilterUsage.class}, version = 28) | ||||
| public abstract class RedditDataRoomDatabase extends RoomDatabase { | ||||
|  | ||||
|     public static RedditDataRoomDatabase create(final Context context) { | ||||
| @@ -49,7 +58,7 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase { | ||||
|                         MIGRATION_9_10, MIGRATION_10_11, MIGRATION_11_12, MIGRATION_12_13, | ||||
|                         MIGRATION_13_14, MIGRATION_14_15, MIGRATION_15_16, MIGRATION_16_17, | ||||
|                         MIGRATION_17_18, MIGRATION_18_19, MIGRATION_19_20, MIGRATION_20_21, | ||||
|                         MIGRATION_21_22, MIGRATION_22_23) | ||||
|                         MIGRATION_21_22, MIGRATION_22_23, MIGRATION_23_24, MIGRATION_24_25, MIGRATION_25_26, MIGRATION_26_27, MIGRATION_27_28) | ||||
|                 .build(); | ||||
|     } | ||||
|  | ||||
| @@ -59,6 +68,10 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase { | ||||
|  | ||||
|     public abstract SubscribedSubredditDao subscribedSubredditDao(); | ||||
|  | ||||
|     public abstract BlockedUserDao blockedUserDao(); | ||||
|  | ||||
|     public abstract BlockedCommunityDao blockedCommunityDao(); | ||||
|  | ||||
|     public abstract UserDao userDao(); | ||||
|  | ||||
|     public abstract SubscribedUserDao subscribedUserDao(); | ||||
| @@ -77,6 +90,10 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase { | ||||
|  | ||||
|     public abstract AnonymousMultiredditSubredditDao anonymousMultiredditSubredditDao(); | ||||
|  | ||||
|     public abstract CommentFilterDao commentFilterDao(); | ||||
|  | ||||
|     public abstract CommentFilterUsageDao commentFilterUsageDao(); | ||||
|  | ||||
|     private static final Migration MIGRATION_1_2 = new Migration(1, 2) { | ||||
|         @Override | ||||
|         public void migrate(SupportSQLiteDatabase database) { | ||||
| @@ -383,4 +400,49 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase { | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     private static final Migration MIGRATION_23_24 = new Migration(23, 24) { | ||||
|         @Override | ||||
|         public void migrate(@NonNull SupportSQLiteDatabase database) { | ||||
|             database.execSQL("ALTER TABLE accounts ADD COLUMN can_downvote INTEGER DEFAULT 1 NOT NULL"); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     private static final Migration MIGRATION_24_25 = new Migration(24, 25) { | ||||
|         @Override | ||||
|         public void migrate(@NonNull SupportSQLiteDatabase database) { | ||||
|             database.execSQL("ALTER TABLE subreddits ADD COLUMN blocked INTEGER DEFAULT 1 NOT NULL"); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     private static final Migration MIGRATION_25_26 = new Migration(25, 26) { | ||||
|         @Override | ||||
|         public void migrate(@NonNull SupportSQLiteDatabase database) { | ||||
|             database.execSQL("CREATE TABLE blocked_users" + | ||||
|                     "(name TEXT, id INTEGER NOT NULL, avatar TEXT, qualified_name TEXT, account_name TEXT NOT NULL, PRIMARY KEY( id, account_name))"); | ||||
|             database.execSQL("CREATE TABLE blocked_communities" + | ||||
|                     "(name TEXT, icon TEXT, id INTEGER NOT NULL, qualified_name TEXT, account_name TEXT NOT NULL, PRIMARY KEY( id, account_name))"); | ||||
|  | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     private static final Migration MIGRATION_26_27 = new Migration(26, 27) { | ||||
|         @Override | ||||
|         public void migrate(@NonNull SupportSQLiteDatabase database) { | ||||
|             database.execSQL("ALTER TABLE subscribed_subreddits" | ||||
|                     + " ADD COLUMN is_favorite INTEGER DEFAULT 0 NOT NULL"); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     private static final Migration MIGRATION_27_28 = new Migration(27, 28) { | ||||
|         @Override | ||||
|         public void migrate(@NonNull SupportSQLiteDatabase database) { | ||||
|             database.execSQL("ALTER TABLE custom_themes ADD COLUMN filled_card_view_background_color INTEGER DEFAULT " + Color.parseColor("#E6F4FF") + " NOT NULL"); | ||||
|             database.execSQL("ALTER TABLE custom_themes ADD COLUMN read_post_filled_card_view_background_color INTEGER DEFAULT " + Color.parseColor("#F5F5F5") + " NOT NULL"); | ||||
|             database.execSQL("CREATE TABLE comment_filter " + | ||||
|                     "(name TEXT NOT NULL PRIMARY KEY, max_vote INTEGER NOT NULL, min_vote INTEGER NOT NULL, exclude_strings TEXT, exclude_users TEXT)"); | ||||
|             database.execSQL("CREATE TABLE comment_filter_usage (name TEXT NOT NULL, usage INTEGER NOT NULL, " + | ||||
|                     "name_of_usage TEXT NOT NULL, PRIMARY KEY(name, usage, name_of_usage), FOREIGN KEY(name) REFERENCES comment_filter(name) ON DELETE CASCADE)"); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
|   | ||||
| @@ -14,7 +14,6 @@ import java.util.Map; | ||||
| import eu.toldi.infinityforlemmy.apis.RedgifsAPI; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import okhttp3.Headers; | ||||
| import okhttp3.Interceptor; | ||||
| import okhttp3.Response; | ||||
| import retrofit2.Call; | ||||
| @@ -22,6 +21,8 @@ import retrofit2.Retrofit; | ||||
| import retrofit2.converter.scalars.ScalarsConverterFactory; | ||||
|  | ||||
| public class RedgifsAccessTokenAuthenticator implements Interceptor { | ||||
|     private static final String REDGIFS_HOST = "redgifs.com"; | ||||
|  | ||||
|     private SharedPreferences mCurrentAccountSharedPreferences; | ||||
|  | ||||
|     public RedgifsAccessTokenAuthenticator(SharedPreferences currentAccountSharedPreferences) { | ||||
| @@ -60,7 +61,17 @@ public class RedgifsAccessTokenAuthenticator implements Interceptor { | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public Response intercept(@NonNull Chain chain) throws IOException { | ||||
|         Response response = chain.proceed(chain.request()); | ||||
|         if (!chain.request().url().host().endsWith(REDGIFS_HOST)) { | ||||
|             return chain.proceed(chain.request()); | ||||
|         } | ||||
|  | ||||
|         String currentAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.REDGIFS_ACCESS_TOKEN, ""); | ||||
|         Response response = chain.proceed( | ||||
|                 chain.request().newBuilder() | ||||
|                         .addHeader(APIUtils.AUTHORIZATION_KEY, APIUtils.AUTHORIZATION_BASE + currentAccessToken) | ||||
|                         .build() | ||||
|         ); | ||||
|  | ||||
|         if (response.code() == 401 || response.code() == 400) { | ||||
|             String accessTokenHeader = response.request().header(APIUtils.AUTHORIZATION_KEY); | ||||
|             if (accessTokenHeader == null) { | ||||
| @@ -74,13 +85,21 @@ public class RedgifsAccessTokenAuthenticator implements Interceptor { | ||||
|                     String newAccessToken = refreshAccessToken(); | ||||
|                     if (!newAccessToken.equals("")) { | ||||
|                         response.close(); | ||||
|                         return chain.proceed(response.request().newBuilder().headers(Headers.of(APIUtils.getRedgifsOAuthHeader(newAccessToken))).build()); | ||||
|                         return chain.proceed( | ||||
|                                 chain.request().newBuilder() | ||||
|                                         .addHeader(APIUtils.AUTHORIZATION_KEY, APIUtils.AUTHORIZATION_BASE + newAccessToken) | ||||
|                                         .build() | ||||
|                         ); | ||||
|                     } else { | ||||
|                         return response; | ||||
|                     } | ||||
|                 } else { | ||||
|                     response.close(); | ||||
|                     return chain.proceed(response.request().newBuilder().headers(Headers.of(APIUtils.getRedgifsOAuthHeader(accessTokenFromSharedPreferences))).build()); | ||||
|                     return chain.proceed( | ||||
|                             chain.request().newBuilder() | ||||
|                                     .addHeader(APIUtils.AUTHORIZATION_KEY, APIUtils.AUTHORIZATION_BASE + accessTokenFromSharedPreferences) | ||||
|                                     .build() | ||||
|                     ); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -1,7 +1,10 @@ | ||||
| package eu.toldi.infinityforlemmy; | ||||
|  | ||||
| import android.util.Log; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.network.SortTypeConverterFactory; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| import okhttp3.Interceptor; | ||||
| import okhttp3.OkHttpClient; | ||||
| import retrofit2.Retrofit; | ||||
| import retrofit2.adapter.guava.GuavaCallAdapterFactory; | ||||
| @@ -12,8 +15,14 @@ public class RetrofitHolder { | ||||
|  | ||||
|     private Retrofit retrofit; | ||||
|     private OkHttpClient okHttpClient; | ||||
|  | ||||
|     private OkHttpClient okHttpClientBase; | ||||
|     private String baseURL = APIUtils.API_BASE_URI; | ||||
|  | ||||
|     private String accessToken = null; | ||||
|  | ||||
|     private Interceptor oAuthInterceptor; | ||||
|  | ||||
|     public Retrofit getRetrofit() { | ||||
|         return retrofit; | ||||
|     } | ||||
| @@ -24,11 +33,16 @@ public class RetrofitHolder { | ||||
|     } | ||||
|  | ||||
|     public String getBaseURL() { | ||||
|         return baseURL; | ||||
|         String result = baseURL; | ||||
|         if (baseURL.endsWith("/")) { | ||||
|             result = baseURL.substring(0, baseURL.length() - 1); | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     public RetrofitHolder(OkHttpClient okHttpClient) { | ||||
|         this.okHttpClient = okHttpClient; | ||||
|         this.okHttpClientBase = okHttpClient; | ||||
|         this.retrofit = createRetrofit(okHttpClient, APIUtils.API_BASE_URI); | ||||
|     } | ||||
|  | ||||
| @@ -42,4 +56,18 @@ public class RetrofitHolder { | ||||
|                 .addConverterFactory(GsonConverterFactory.create()) | ||||
|                 .build(); | ||||
|     } | ||||
|  | ||||
|     public void setAccessToken(String accessToken) { | ||||
|         this.accessToken = accessToken; | ||||
|         OkHttpClient.Builder builder = okHttpClientBase.newBuilder(); | ||||
|         Log.d("RetrofitHolder", "Access token changed"); | ||||
|         if (accessToken != null && !accessToken.equals("")) { | ||||
|             Log.i("RetrofitHolder", "Setting access token interceptor"); | ||||
|             oAuthInterceptor = APIUtils.getOAuthInterceptor(accessToken); | ||||
|             builder.addInterceptor(oAuthInterceptor); | ||||
|         } | ||||
|         okHttpClient = builder.build(); | ||||
|         retrofit = createRetrofit(okHttpClient, baseURL); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -43,12 +43,15 @@ public class SortType { | ||||
|         TOP_TWELVE_HOURS("TopTwelveHour", "Top"), | ||||
|         TOP_DAY("TopDay", "Top"), | ||||
|         TOP_WEEK("TopWeek", "Top"), | ||||
|         TOP_MONTH("month", "Top"), | ||||
|         TOP_MONTH("TopMonth", "Top"), | ||||
|         TOP_THREE_MONTHS("TopThreeMonths", "Top"), | ||||
|         TOP_SIX_MONTHS("TopSixMonths", "Top"), | ||||
|         TOP_NINE_MONTHS("TopNineMonths", "Top"), | ||||
|         TOP_YEAR("TopYear", "Top"), | ||||
|         TOP_ALL("TopAll", "Top"); | ||||
|         TOP_ALL("TopAll", "Top"), | ||||
|  | ||||
|         SCALED("Scaled", "Scaled"), | ||||
|         CONTROVERSIAL("Controversial", "Controversial"); | ||||
|  | ||||
|         public final String value; | ||||
|         public final String fullName; | ||||
| @@ -69,15 +72,15 @@ public class SortType { | ||||
|     } | ||||
|  | ||||
|     public enum Time { | ||||
|         HOUR("TopHour", "Top Hour"), | ||||
|         SIX_HOURS("TopSixHour", "Top Six Hours"), | ||||
|         TWELVE_HOURS("TopTwelveHour", "Top Twelve Hours"), | ||||
|         HOUR("hour", "Hour"), | ||||
|         SIX_HOURS("SixHour", "Six Hours"), | ||||
|         TWELVE_HOURS("TwelveHour", "Twelve Hours"), | ||||
|         DAY("day", "Day"), | ||||
|         WEEK("week", "Week"), | ||||
|         MONTH("month", "Month"), | ||||
|         THREE_MONTHS("TopThreeMonth", "Top Three Months"), | ||||
|         SIX_MONTHS("TopSixMonth", "Top Six Months"), | ||||
|         NINE_MONTHS("TopNineMonth", "Top Nine Months"), | ||||
|         THREE_MONTHS("ThreeMonths", "Three Months"), | ||||
|         SIX_MONTHS("SixMonths", "Six Months"), | ||||
|         NINE_MONTHS("NineMonths", "Nine Months"), | ||||
|         YEAR("year", "Year"), | ||||
|         ALL("all", "All Time"); | ||||
|  | ||||
| @@ -88,5 +91,14 @@ public class SortType { | ||||
|             this.value = value; | ||||
|             this.fullName = fullName; | ||||
|         } | ||||
|  | ||||
|         public static Time fromValue(String value) { | ||||
|             for (Time time : values()) { | ||||
|                 if (time.value.equalsIgnoreCase(value)) { | ||||
|                     return time; | ||||
|                 } | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -32,6 +32,9 @@ public class Account implements Parcelable { | ||||
|     @ColumnInfo(name = "instance_url") | ||||
|     private String instance_url; | ||||
|  | ||||
|     @ColumnInfo(name = "can_downvote") | ||||
|     private boolean canDownvote = true; | ||||
|  | ||||
|     @Ignore | ||||
|     protected Account(Parcel in) { | ||||
|         accountName = in.readString(); | ||||
| @@ -42,6 +45,7 @@ public class Account implements Parcelable { | ||||
|         code = in.readString(); | ||||
|         isCurrentUser = in.readByte() != 0; | ||||
|         instance_url = in.readString(); | ||||
|         canDownvote = in.readByte() != 0; | ||||
|     } | ||||
|  | ||||
|     public static final Creator<Account> CREATOR = new Creator<Account>() { | ||||
| @@ -58,11 +62,11 @@ public class Account implements Parcelable { | ||||
|  | ||||
|     @Ignore | ||||
|     public static Account getAnonymousAccount() { | ||||
|         return new Account("-",null, null, null, null, null, false,null); | ||||
|         return new Account("-",null, null, null, null, null, false,null,true); | ||||
|     } | ||||
|  | ||||
|     public Account(@NonNull String accountName, String display_name, String accessToken, String code, | ||||
|                    String profileImageUrl, String bannerImageUrl, boolean isCurrentUser,String instance_url) { | ||||
|                    String profileImageUrl, String bannerImageUrl, boolean isCurrentUser,String instance_url, boolean canDownvote) { | ||||
|         this.accountName = accountName; | ||||
|         this.display_name = display_name; | ||||
|         this.accessToken = accessToken; | ||||
| @@ -71,6 +75,7 @@ public class Account implements Parcelable { | ||||
|         this.bannerImageUrl = bannerImageUrl; | ||||
|         this.isCurrentUser = isCurrentUser; | ||||
|         this.instance_url = instance_url; | ||||
|         this.canDownvote = canDownvote; | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
| @@ -116,6 +121,10 @@ public class Account implements Parcelable { | ||||
|         return instance_url; | ||||
|     } | ||||
|  | ||||
|     public boolean canDownvote() { | ||||
|         return canDownvote; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void writeToParcel(Parcel dest, int flags) { | ||||
|         dest.writeString(accountName); | ||||
| @@ -126,5 +135,6 @@ public class Account implements Parcelable { | ||||
|         dest.writeString(code); | ||||
|         dest.writeByte((byte) (isCurrentUser ? 1 : 0)); | ||||
|         dest.writeString(instance_url); | ||||
|         dest.writeByte((byte) (canDownvote ? 1 : 0)); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,85 @@ | ||||
| package eu.toldi.infinityforlemmy.account; | ||||
|  | ||||
| import org.json.JSONArray; | ||||
| import org.json.JSONException; | ||||
| import org.json.JSONObject; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.apis.LemmyAPI; | ||||
| import eu.toldi.infinityforlemmy.blockedcommunity.BlockedCommunityData; | ||||
| import eu.toldi.infinityforlemmy.blockeduser.BlockedUserData; | ||||
| import eu.toldi.infinityforlemmy.subreddit.ParseSubredditData; | ||||
| import eu.toldi.infinityforlemmy.subreddit.SubredditData; | ||||
| import eu.toldi.infinityforlemmy.utils.LemmyUtils; | ||||
| import retrofit2.Call; | ||||
| import retrofit2.Callback; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
| public class FetchBlockedThings { | ||||
|  | ||||
|     public static void fetchBlockedThings(Retrofit mRetrofit, String accessToken, String accountName, FetchBlockedThingsListener fetchBlockedThingsListener) { | ||||
|         LemmyAPI lemmyAPI = mRetrofit.create(LemmyAPI.class); | ||||
|  | ||||
|         Call<String> call = lemmyAPI.getSiteInfo(accessToken); | ||||
|         call.enqueue(new Callback<String>() { | ||||
|             @Override | ||||
|             public void onResponse(Call<String> call, retrofit2.Response<String> response) { | ||||
|                 if (response.isSuccessful()) { | ||||
|                     String siteInfo = response.body(); | ||||
|                     if (siteInfo != null) { | ||||
|                         List<BlockedUserData> blockedUsers = new ArrayList<>(); | ||||
|                         List<BlockedCommunityData> blockedCommunities = new ArrayList<>(); | ||||
|                         try { | ||||
|                             JSONObject siteInfoJson = new JSONObject(siteInfo).getJSONObject("my_user"); | ||||
|                             JSONArray blockedUsersJson = (siteInfoJson.has("person_blocks")) ? siteInfoJson.getJSONArray("person_blocks") : null; | ||||
|                             JSONArray blockedCommunitiesJson = (siteInfoJson.has("community_blocks")) ? siteInfoJson.getJSONArray("community_blocks") : null; | ||||
|                             if (blockedUsersJson != null) { | ||||
|                                 for (int i = 0; i < blockedUsersJson.length(); i++) { | ||||
|                                     JSONObject blockedUserJson = blockedUsersJson.getJSONObject(i).getJSONObject("target"); | ||||
|                                     int id = blockedUserJson.getInt("id"); | ||||
|                                     String name = blockedUserJson.getString("name"); | ||||
|                                     String avatar = ""; | ||||
|                                     if (blockedUserJson.has("avatar")) | ||||
|                                         avatar = blockedUserJson.getString("avatar"); | ||||
|  | ||||
|                                     String qualifiedName = LemmyUtils.actorID2FullName(blockedUserJson.getString("actor_id")); | ||||
|                                     BlockedUserData blockedUserData = new BlockedUserData(id, name, avatar, qualifiedName, accountName); | ||||
|  | ||||
|                                     blockedUsers.add(blockedUserData); | ||||
|                                 } | ||||
|                             } | ||||
|                             if (blockedCommunitiesJson != null) { | ||||
|                                 for (int i = 0; i < blockedCommunitiesJson.length(); i++) { | ||||
|                                     JSONObject blockedCommunityJson = blockedCommunitiesJson.getJSONObject(i); | ||||
|                                     SubredditData blockedCommunityData = ParseSubredditData.parseSubredditData(blockedCommunityJson, true); | ||||
|                                     blockedCommunities.add(new BlockedCommunityData(blockedCommunityData, accountName)); | ||||
|                                 } | ||||
|                             } | ||||
|                             fetchBlockedThingsListener.onFetchBlockedThingsSuccess(blockedUsers, blockedCommunities); | ||||
|                         } catch (JSONException e) { | ||||
|                             e.printStackTrace(); | ||||
|                             fetchBlockedThingsListener.onFetchBlockedThingsFailure(); | ||||
|                         } | ||||
|                     } else { | ||||
|                         fetchBlockedThingsListener.onFetchBlockedThingsFailure(); | ||||
|                     } | ||||
|                 } else { | ||||
|                     fetchBlockedThingsListener.onFetchBlockedThingsFailure(); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onFailure(Call<String> call, Throwable t) { | ||||
|                 fetchBlockedThingsListener.onFetchBlockedThingsFailure(); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public interface FetchBlockedThingsListener { | ||||
|         void onFetchBlockedThingsSuccess(List<BlockedUserData> blockedUsers, List<BlockedCommunityData> blockedCommunities); | ||||
|  | ||||
|         void onFetchBlockedThingsFailure(); | ||||
|     } | ||||
| } | ||||
| @@ -8,6 +8,7 @@ import android.view.Menu; | ||||
| import android.view.MenuItem; | ||||
| import android.view.Window; | ||||
| import android.view.WindowManager; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| @@ -40,6 +41,7 @@ import eu.toldi.infinityforlemmy.events.ChangeNSFWEvent; | ||||
| import eu.toldi.infinityforlemmy.events.SwitchAccountEvent; | ||||
| import eu.toldi.infinityforlemmy.fragments.CommentsListingFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.PostFragment; | ||||
| import eu.toldi.infinityforlemmy.post.MarkPostAsRead; | ||||
| import eu.toldi.infinityforlemmy.post.Post; | ||||
| import eu.toldi.infinityforlemmy.post.PostPagingSource; | ||||
| import eu.toldi.infinityforlemmy.readpost.InsertReadPost; | ||||
| @@ -64,10 +66,15 @@ public class AccountSavedThingActivity extends BaseActivity implements ActivityT | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     @Inject | ||||
|     Executor mExecutor; | ||||
|  | ||||
|     @Inject | ||||
|     MarkPostAsRead markPostAsRead; | ||||
|     private FragmentManager fragmentManager; | ||||
|     private SectionsPagerAdapter sectionsPagerAdapter; | ||||
|     private String mAccessToken; | ||||
|     private String mAccountName; | ||||
|  | ||||
|     private String mAccountQualifiedName; | ||||
|     private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; | ||||
|     private ActivityAccountSavedThingBinding binding; | ||||
|  | ||||
| @@ -116,6 +123,7 @@ public class AccountSavedThingActivity extends BaseActivity implements ActivityT | ||||
|  | ||||
|         mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); | ||||
|         mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); | ||||
|         mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null); | ||||
|  | ||||
|         initializeViewPager(); | ||||
|     } | ||||
| @@ -249,7 +257,17 @@ public class AccountSavedThingActivity extends BaseActivity implements ActivityT | ||||
|  | ||||
|     @Override | ||||
|     public void markPostAsRead(Post post) { | ||||
|         InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountName, post.getId()); | ||||
|         markPostAsRead.markPostAsRead(post.getId(), mAccessToken, new MarkPostAsRead.MarkPostAsReadListener() { | ||||
|             @Override | ||||
|             public void onMarkPostAsReadSuccess() { | ||||
|                 InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountQualifiedName, post.getId()); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onMarkPostAsReadFailed() { | ||||
|                 Toast.makeText(AccountSavedThingActivity.this, R.string.mark_post_as_read_failed, Toast.LENGTH_SHORT).show(); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private class SectionsPagerAdapter extends FragmentStateAdapter { | ||||
| @@ -265,7 +283,7 @@ public class AccountSavedThingActivity extends BaseActivity implements ActivityT | ||||
|                 PostFragment fragment = new PostFragment(); | ||||
|                 Bundle bundle = new Bundle(); | ||||
|                 bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostPagingSource.TYPE_USER); | ||||
|                 bundle.putString(PostFragment.EXTRA_USER_NAME, mAccountName); | ||||
|                 bundle.putString(PostFragment.EXTRA_USER_NAME, mAccountQualifiedName); | ||||
|                 bundle.putString(PostFragment.EXTRA_USER_WHERE, PostPagingSource.USER_WHERE_SAVED); | ||||
|                 bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
|                 bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); | ||||
| @@ -275,7 +293,7 @@ public class AccountSavedThingActivity extends BaseActivity implements ActivityT | ||||
|             } | ||||
|             CommentsListingFragment fragment = new CommentsListingFragment(); | ||||
|             Bundle bundle = new Bundle(); | ||||
|             bundle.putString(CommentsListingFragment.EXTRA_USERNAME, mAccountName); | ||||
|             bundle.putString(CommentsListingFragment.EXTRA_USERNAME, mAccountQualifiedName); | ||||
|             bundle.putString(CommentsListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
|             bundle.putString(CommentsListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); | ||||
|             bundle.putBoolean(CommentsListingFragment.EXTRA_ARE_SAVED_COMMENTS, true); | ||||
|   | ||||
| @@ -39,6 +39,9 @@ import androidx.viewpager2.widget.ViewPager2; | ||||
| import com.google.android.material.appbar.AppBarLayout; | ||||
| import com.google.android.material.appbar.CollapsingToolbarLayout; | ||||
| import com.google.android.material.floatingactionbutton.FloatingActionButton; | ||||
| import com.google.android.material.shape.CornerFamily; | ||||
| import com.google.android.material.shape.MaterialShapeDrawable; | ||||
| import com.google.android.material.shape.ShapeAppearanceModel; | ||||
| import com.google.android.material.tabs.TabLayout; | ||||
|  | ||||
| import java.lang.reflect.Field; | ||||
| @@ -377,9 +380,18 @@ public abstract class BaseActivity extends AppCompatActivity implements CustomFo | ||||
|         button.setTextColor(customThemeWrapper.getFABIconColor()); | ||||
|     } | ||||
|  | ||||
|     protected void applyFABTheme(FloatingActionButton fab) { | ||||
|     protected void applyFABTheme(FloatingActionButton fab, boolean isCircular) { | ||||
|         fab.setBackgroundTintList(ColorStateList.valueOf(customThemeWrapper.getColorAccent())); | ||||
|         fab.setImageTintList(ColorStateList.valueOf(customThemeWrapper.getFABIconColor())); | ||||
|         if (isCircular) { | ||||
|             ShapeAppearanceModel shapeAppearanceModel = ShapeAppearanceModel.builder() | ||||
|                     .setAllCorners(CornerFamily.ROUNDED, 100) // Adjust the radius value to control the roundness | ||||
|                     .build(); | ||||
|  | ||||
|             // Apply the circular shape to the FAB | ||||
|             MaterialShapeDrawable shapeDrawable = new MaterialShapeDrawable(shapeAppearanceModel); | ||||
|             fab.setShapeAppearanceModel(shapeAppearanceModel); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     protected void fixViewPager2Sensitivity(ViewPager2 viewPager2) { | ||||
|   | ||||
| @@ -0,0 +1,462 @@ | ||||
| package eu.toldi.infinityforlemmy.activities; | ||||
|  | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.text.Editable; | ||||
| import android.text.TextWatcher; | ||||
| import android.view.Menu; | ||||
| import android.view.MenuItem; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.view.Window; | ||||
| import android.view.WindowManager; | ||||
| import android.view.inputmethod.InputMethodManager; | ||||
| import android.widget.EditText; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.appcompat.widget.Toolbar; | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout; | ||||
| import androidx.core.view.inputmethod.EditorInfoCompat; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentManager; | ||||
| import androidx.fragment.app.FragmentPagerAdapter; | ||||
| import androidx.viewpager.widget.ViewPager; | ||||
|  | ||||
| import com.google.android.material.appbar.AppBarLayout; | ||||
| import com.google.android.material.appbar.CollapsingToolbarLayout; | ||||
| import com.google.android.material.floatingactionbutton.FloatingActionButton; | ||||
| import com.google.android.material.tabs.TabLayout; | ||||
|  | ||||
| import org.greenrobot.eventbus.EventBus; | ||||
| import org.greenrobot.eventbus.Subscribe; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
|  | ||||
| import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
| import eu.toldi.infinityforlemmy.ActivityToolbarInterface; | ||||
| import eu.toldi.infinityforlemmy.FragmentCommunicator; | ||||
| import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| import eu.toldi.infinityforlemmy.RetrofitHolder; | ||||
| import eu.toldi.infinityforlemmy.account.FetchBlockedThings; | ||||
| import eu.toldi.infinityforlemmy.asynctasks.InsertBlockedThings; | ||||
| import eu.toldi.infinityforlemmy.blockedcommunity.BlockedCommunityData; | ||||
| import eu.toldi.infinityforlemmy.blockeduser.BlockedUserData; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.customviews.ViewPagerBugFixed; | ||||
| import eu.toldi.infinityforlemmy.customviews.slidr.Slidr; | ||||
| import eu.toldi.infinityforlemmy.events.GoBackToMainPageEvent; | ||||
| import eu.toldi.infinityforlemmy.events.SwitchAccountEvent; | ||||
| import eu.toldi.infinityforlemmy.fragments.BlockedCommunitiesListingFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.BlockedUsersListingFragment; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
|  | ||||
| public class BlockedThingListingActivity extends BaseActivity implements ActivityToolbarInterface { | ||||
|  | ||||
|     public static final String EXTRA_SHOW_MULTIREDDITS = "ESM"; | ||||
|     private static final String INSERT_SUBSCRIBED_SUBREDDIT_STATE = "ISSS"; | ||||
|     private static final String INSERT_MULTIREDDIT_STATE = "IMS"; | ||||
|  | ||||
|     @BindView(R.id.coordinator_layout_subscribed_thing_listing_activity) | ||||
|     CoordinatorLayout coordinatorLayout; | ||||
|     @BindView(R.id.appbar_layout_subscribed_thing_listing_activity) | ||||
|     AppBarLayout appBarLayout; | ||||
|     @BindView(R.id.collapsing_toolbar_layout_subscribed_thing_listing_activity) | ||||
|     CollapsingToolbarLayout collapsingToolbarLayout; | ||||
|     @BindView(R.id.toolbar_subscribed_thing_listing_activity) | ||||
|     Toolbar toolbar; | ||||
|     @BindView(R.id.search_edit_text_subscribed_thing_listing_activity) | ||||
|     EditText searchEditText; | ||||
|     @BindView(R.id.tab_layout_subscribed_thing_listing_activity) | ||||
|     TabLayout tabLayout; | ||||
|     @BindView(R.id.view_pager_subscribed_thing_listing_activity) | ||||
|     ViewPagerBugFixed viewPager; | ||||
|     @BindView(R.id.fab_subscribed_thing_listing_activity) | ||||
|     FloatingActionButton fab; | ||||
|     @Inject | ||||
|     @Named("oauth") | ||||
|     Retrofit mOauthRetrofit; | ||||
|  | ||||
|     @Inject | ||||
|     @Named("no_oauth") | ||||
|     RetrofitHolder mRetrofit; | ||||
|     @Inject | ||||
|     RedditDataRoomDatabase mRedditDataRoomDatabase; | ||||
|     @Inject | ||||
|     @Named("default") | ||||
|     SharedPreferences mSharedPreferences; | ||||
|     @Inject | ||||
|     @Named("current_account") | ||||
|     SharedPreferences mCurrentAccountSharedPreferences; | ||||
|     @Inject | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     @Inject | ||||
|     Executor mExecutor; | ||||
|     private String mAccessToken; | ||||
|     private String mAccountName; | ||||
|  | ||||
|     private String mAccountQualifiedName; | ||||
|     private boolean mInsertSuccess = false; | ||||
|     private boolean mInsertMultiredditSuccess = false; | ||||
|     private boolean showMultiReddits = false; | ||||
|     private SectionsPagerAdapter sectionsPagerAdapter; | ||||
|     private Menu mMenu; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         ((Infinity) getApplication()).getAppComponent().inject(this); | ||||
|  | ||||
|         super.onCreate(savedInstanceState); | ||||
|  | ||||
|         setContentView(R.layout.activity_subscribed_thing_listing); | ||||
|  | ||||
|         ButterKnife.bind(this); | ||||
|  | ||||
|         EventBus.getDefault().register(this); | ||||
|  | ||||
|         applyCustomTheme(); | ||||
|  | ||||
|         if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { | ||||
|             mSliderPanel = Slidr.attach(this); | ||||
|         } | ||||
|  | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | ||||
|             Window window = getWindow(); | ||||
|  | ||||
|             if (isChangeStatusBarIconColor()) { | ||||
|                 addOnOffsetChangedListener(appBarLayout); | ||||
|             } | ||||
|  | ||||
|             if (isImmersiveInterface()) { | ||||
|                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { | ||||
|                     window.setDecorFitsSystemWindows(false); | ||||
|                 } else { | ||||
|                     window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); | ||||
|                 } | ||||
|                 adjustToolbar(toolbar); | ||||
|  | ||||
|                 int navBarHeight = getNavBarHeight(); | ||||
|                 if (navBarHeight > 0) { | ||||
|                     CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); | ||||
|                     params.bottomMargin += navBarHeight; | ||||
|                     fab.setLayoutParams(params); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         setSupportActionBar(toolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|         setToolbarGoToTop(toolbar); | ||||
|  | ||||
|         mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); | ||||
|         mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, "-"); | ||||
|         mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, "-"); | ||||
|  | ||||
|         if (savedInstanceState != null) { | ||||
|             mInsertSuccess = savedInstanceState.getBoolean(INSERT_SUBSCRIBED_SUBREDDIT_STATE); | ||||
|             mInsertMultiredditSuccess = savedInstanceState.getBoolean(INSERT_MULTIREDDIT_STATE); | ||||
|         } else { | ||||
|             showMultiReddits = getIntent().getBooleanExtra(EXTRA_SHOW_MULTIREDDITS, false); | ||||
|         } | ||||
|  | ||||
|         if (mAccessToken == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|             searchEditText.setImeOptions(searchEditText.getImeOptions() | EditorInfoCompat.IME_FLAG_NO_PERSONALIZED_LEARNING); | ||||
|         } | ||||
|  | ||||
|         searchEditText.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) { | ||||
|                 sectionsPagerAdapter.changeSearchQuery(editable.toString()); | ||||
|             } | ||||
|         }); | ||||
|         initializeViewPagerAndLoadSubscriptions(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public SharedPreferences getDefaultSharedPreferences() { | ||||
|         return mSharedPreferences; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected CustomThemeWrapper getCustomThemeWrapper() { | ||||
|         return mCustomThemeWrapper; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void applyCustomTheme() { | ||||
|         coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar); | ||||
|         applyTabLayoutTheme(tabLayout); | ||||
|         applyFABTheme(fab, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|         searchEditText.setTextColor(mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor()); | ||||
|         searchEditText.setHintTextColor(mCustomThemeWrapper.getToolbarSecondaryTextColor()); | ||||
|     } | ||||
|  | ||||
|     private void initializeViewPagerAndLoadSubscriptions() { | ||||
|         fab.setOnClickListener(view -> { | ||||
|             Intent intent = new Intent(this, CreateMultiRedditActivity.class); | ||||
|             startActivity(intent); | ||||
|         }); | ||||
|         sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); | ||||
|         viewPager.setAdapter(sectionsPagerAdapter); | ||||
|         viewPager.setOffscreenPageLimit(2); | ||||
|         if (viewPager.getCurrentItem() != 2) { | ||||
|             fab.hide(); | ||||
|         } | ||||
|         viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { | ||||
|             @Override | ||||
|             public void onPageSelected(int position) { | ||||
|                 if (position == 0) { | ||||
|                     unlockSwipeRightToGoBack(); | ||||
|                     fab.hide(); | ||||
|                 } else { | ||||
|                     lockSwipeRightToGoBack(); | ||||
|                     if (position != 2) { | ||||
|                         fab.hide(); | ||||
|                     } else { | ||||
|                         fab.show(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|         tabLayout.setupWithViewPager(viewPager); | ||||
|  | ||||
|         if (showMultiReddits) { | ||||
|             viewPager.setCurrentItem(2, false); | ||||
|         } | ||||
|  | ||||
|         loadBlocks(false); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onCreateOptionsMenu(Menu menu) { | ||||
|         getMenuInflater().inflate(R.menu.subscribed_thing_listing_activity, menu); | ||||
|         mMenu = menu; | ||||
|         applyMenuItemTheme(menu); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(@NonNull MenuItem item) { | ||||
|         if (item.getItemId() == R.id.action_search_subscribed_thing_listing_activity) { | ||||
|             item.setVisible(false); | ||||
|             searchEditText.setVisibility(View.VISIBLE); | ||||
|             searchEditText.requestFocus(); | ||||
|             if (searchEditText.requestFocus()) { | ||||
|                 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); | ||||
|                 imm.showSoftInput(searchEditText, InputMethodManager.SHOW_IMPLICIT); | ||||
|             } | ||||
|             return true; | ||||
|         } else if (item.getItemId() == android.R.id.home) { | ||||
|             if (searchEditText.getVisibility() == View.VISIBLE) { | ||||
|                 Utils.hideKeyboard(this); | ||||
|                 searchEditText.setVisibility(View.GONE); | ||||
|                 searchEditText.setText(""); | ||||
|                 mMenu.findItem(R.id.action_search_subscribed_thing_listing_activity).setVisible(true); | ||||
|                 sectionsPagerAdapter.changeSearchQuery(""); | ||||
|                 return true; | ||||
|             } | ||||
|             finish(); | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onBackPressed() { | ||||
|         if (searchEditText.getVisibility() == View.VISIBLE) { | ||||
|             Utils.hideKeyboard(this); | ||||
|             searchEditText.setVisibility(View.GONE); | ||||
|             searchEditText.setText(""); | ||||
|             mMenu.findItem(R.id.action_search_subscribed_thing_listing_activity).setVisible(true); | ||||
|             sectionsPagerAdapter.changeSearchQuery(""); | ||||
|         } else { | ||||
|             super.onBackPressed(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onSaveInstanceState(@NonNull Bundle outState) { | ||||
|         super.onSaveInstanceState(outState); | ||||
|         outState.putBoolean(INSERT_SUBSCRIBED_SUBREDDIT_STATE, mInsertSuccess); | ||||
|         outState.putBoolean(INSERT_MULTIREDDIT_STATE, mInsertMultiredditSuccess); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onDestroy() { | ||||
|         super.onDestroy(); | ||||
|         EventBus.getDefault().unregister(this); | ||||
|     } | ||||
|  | ||||
|     public void loadBlocks(boolean forceLoad) { | ||||
|         if (mAccessToken != null && !(!forceLoad && mInsertSuccess)) { | ||||
|             FetchBlockedThings.fetchBlockedThings(mRetrofit.getRetrofit(), mAccessToken, mAccountQualifiedName, new FetchBlockedThings.FetchBlockedThingsListener() { | ||||
|                 @Override | ||||
|                 public void onFetchBlockedThingsSuccess(List<BlockedUserData> blockedUsers, List<BlockedCommunityData> blockedCommunities) { | ||||
|                     InsertBlockedThings.insertBlockedThings(mExecutor, new Handler(), mRedditDataRoomDatabase, mAccountQualifiedName, | ||||
|                             blockedCommunities, blockedUsers, () -> { | ||||
|                                 mInsertSuccess = true; | ||||
|                                 sectionsPagerAdapter.stopRefreshProgressbar(); | ||||
|                             }); | ||||
|                 } | ||||
|  | ||||
|                 @Override | ||||
|                 public void onFetchBlockedThingsFailure() { | ||||
|  | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Subscribe | ||||
|     public void onAccountSwitchEvent(SwitchAccountEvent event) { | ||||
|         finish(); | ||||
|     } | ||||
|  | ||||
|     @Subscribe | ||||
|     public void goBackToMainPageEvent(GoBackToMainPageEvent event) { | ||||
|         finish(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onLongPress() { | ||||
|         if (sectionsPagerAdapter != null) { | ||||
|             sectionsPagerAdapter.goBackToTop(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void lockSwipeRightToGoBack() { | ||||
|         if (mSliderPanel != null) { | ||||
|             mSliderPanel.lock(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void unlockSwipeRightToGoBack() { | ||||
|         if (mSliderPanel != null) { | ||||
|             mSliderPanel.unlock(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private class SectionsPagerAdapter extends FragmentPagerAdapter { | ||||
|  | ||||
|         private BlockedCommunitiesListingFragment blockedCommunitiesListingFragment; | ||||
|         private BlockedUsersListingFragment followedUsersListingFragment; | ||||
|  | ||||
|         public SectionsPagerAdapter(FragmentManager fm) { | ||||
|             super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); | ||||
|         } | ||||
|  | ||||
|         @NonNull | ||||
|         @Override | ||||
|         public Fragment getItem(int position) { | ||||
|             switch (position) { | ||||
|                 default: | ||||
|                 case 0: { | ||||
|                     BlockedCommunitiesListingFragment fragment = new BlockedCommunitiesListingFragment(); | ||||
|                     Bundle bundle = new Bundle(); | ||||
|                     bundle.putBoolean(BlockedCommunitiesListingFragment.EXTRA_IS_SUBREDDIT_SELECTION, false); | ||||
|                     bundle.putString(BlockedCommunitiesListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); | ||||
|                     bundle.putString(BlockedCommunitiesListingFragment.EXTRA_ACCOUNT_QUALIFIED_NAME, mAccountQualifiedName); | ||||
|                     bundle.putString(BlockedCommunitiesListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
|                     fragment.setArguments(bundle); | ||||
|                     return fragment; | ||||
|                 } | ||||
|                 case 1: { | ||||
|                     BlockedUsersListingFragment fragment = new BlockedUsersListingFragment(); | ||||
|                     Bundle bundle = new Bundle(); | ||||
|                     bundle.putString(BlockedUsersListingFragment.EXTRA_ACCOUNT_NAME, mAccountQualifiedName); | ||||
|                     bundle.putString(BlockedUsersListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
|                     fragment.setArguments(bundle); | ||||
|                     return fragment; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public int getCount() { | ||||
|             return 2; | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public CharSequence getPageTitle(int position) { | ||||
|             switch (position) { | ||||
|                 case 0: | ||||
|                     return Utils.getTabTextWithCustomFont(typeface, getString(R.string.communities)); | ||||
|                 case 1: | ||||
|                     return Utils.getTabTextWithCustomFont(typeface, getString(R.string.users)); | ||||
|                 case 2: | ||||
|                     return Utils.getTabTextWithCustomFont(typeface, getString(R.string.multi_reddits)); | ||||
|             } | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         @NonNull | ||||
|         @Override | ||||
|         public Object instantiateItem(@NonNull ViewGroup container, int position) { | ||||
|             Fragment fragment = (Fragment) super.instantiateItem(container, position); | ||||
|             if (position == 0) { | ||||
|                 blockedCommunitiesListingFragment = (BlockedCommunitiesListingFragment) fragment; | ||||
|             } else if (position == 1) { | ||||
|                 followedUsersListingFragment = (BlockedUsersListingFragment) fragment; | ||||
|             } | ||||
|  | ||||
|             return fragment; | ||||
|         } | ||||
|  | ||||
|         void stopRefreshProgressbar() { | ||||
|             if (blockedCommunitiesListingFragment != null) { | ||||
|                 ((FragmentCommunicator) blockedCommunitiesListingFragment).stopRefreshProgressbar(); | ||||
|             } | ||||
|             if (followedUsersListingFragment != null) { | ||||
|                 ((FragmentCommunicator) followedUsersListingFragment).stopRefreshProgressbar(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         void goBackToTop() { | ||||
|             if (viewPager.getCurrentItem() == 0) { | ||||
|                 blockedCommunitiesListingFragment.goBackToTop(); | ||||
|             } else if (viewPager.getCurrentItem() == 1) { | ||||
|                 followedUsersListingFragment.goBackToTop(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         void changeSearchQuery(String searchQuery) { | ||||
|             if (blockedCommunitiesListingFragment != null) { | ||||
|                 blockedCommunitiesListingFragment.changeSearchQuery(searchQuery); | ||||
|             } | ||||
|             if (followedUsersListingFragment != null) { | ||||
|                 followedUsersListingFragment.changeSearchQuery(searchQuery); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -205,7 +205,7 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA | ||||
|                 } | ||||
|             }; | ||||
|             Markwon postBodyMarkwon = MarkdownUtils.createFullRedditMarkwon(this, | ||||
|                     miscPlugin, parentTextColor, parentSpoilerBackgroundColor, null); | ||||
|                     miscPlugin, parentTextColor, parentSpoilerBackgroundColor, null, mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false)); | ||||
|             MarkwonAdapter markwonAdapter = MarkdownUtils.createTablesAdapter(); | ||||
|             binding.commentContentMarkdownView.setLayoutManager(new LinearLayoutManagerBugFixed(this)); | ||||
|             binding.commentContentMarkdownView.setAdapter(markwonAdapter); | ||||
| @@ -226,7 +226,7 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA | ||||
|  | ||||
|         setSupportActionBar(binding.commentToolbar); | ||||
|  | ||||
|         mGlide = Glide.with(this); | ||||
|         mGlide = Glide.with(getApplication()); | ||||
|  | ||||
|         if (savedInstanceState != null) { | ||||
|             selectedAccount = savedInstanceState.getParcelable(SELECTED_ACCOUNT_STATE); | ||||
| @@ -513,8 +513,8 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA | ||||
|         int start = Math.max(binding.commentCommentEditText.getSelectionStart(), 0); | ||||
|         int end = Math.max(binding.commentCommentEditText.getSelectionEnd(), 0); | ||||
|         binding.commentCommentEditText.getText().replace(Math.min(start, end), Math.max(start, end), | ||||
|                 "[" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")", | ||||
|                 0, "[]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); | ||||
|                 "", | ||||
|                 0, "![]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -0,0 +1,126 @@ | ||||
| package eu.toldi.infinityforlemmy.activities; | ||||
|  | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.os.Bundle; | ||||
| import android.view.MenuItem; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.lifecycle.ViewModelProvider; | ||||
|  | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
|  | ||||
| import butterknife.ButterKnife; | ||||
| import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| import eu.toldi.infinityforlemmy.adapters.CommentFilterWithUsageRecyclerViewAdapter; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.CommentFilterOptionsBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.CommentFilter; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.DeleteCommentFilter; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.databinding.ActivityCommentFilterPreferenceBinding; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.CommentFilterWithUsageViewModel; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
|  | ||||
| public class CommentFilterPreferenceActivity extends BaseActivity { | ||||
|  | ||||
|     private ActivityCommentFilterPreferenceBinding binding; | ||||
|  | ||||
|     @Inject | ||||
|     @Named("default") | ||||
|     SharedPreferences sharedPreferences; | ||||
|     @Inject | ||||
|     RedditDataRoomDatabase redditDataRoomDatabase; | ||||
|     @Inject | ||||
|     CustomThemeWrapper customThemeWrapper; | ||||
|     @Inject | ||||
|     Executor executor; | ||||
|     public CommentFilterWithUsageViewModel commentFilterWithUsageViewModel; | ||||
|     private CommentFilterWithUsageRecyclerViewAdapter adapter; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         ((Infinity) getApplication()).getAppComponent().inject(this); | ||||
|  | ||||
|         setImmersiveModeNotApplicable(); | ||||
|  | ||||
|         super.onCreate(savedInstanceState); | ||||
|         binding = ActivityCommentFilterPreferenceBinding.inflate(getLayoutInflater()); | ||||
|  | ||||
|         setContentView(binding.getRoot()); | ||||
|  | ||||
|         ButterKnife.bind(this); | ||||
|  | ||||
|         applyCustomTheme(); | ||||
|  | ||||
|         setSupportActionBar(binding.toolbarCommentFilterPreferenceActivity); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|  | ||||
|         binding.fabCommentFilterPreferenceActivity.setOnClickListener(view -> { | ||||
|             Intent intent = new Intent(this, CustomizeCommentFilterActivity.class); | ||||
|             intent.putExtra(CustomizeCommentFilterActivity.EXTRA_FROM_SETTINGS, true); | ||||
|             startActivity(intent); | ||||
|         }); | ||||
|  | ||||
|         adapter = new CommentFilterWithUsageRecyclerViewAdapter(this, commentFilter -> { | ||||
|             CommentFilterOptionsBottomSheetFragment commentFilterOptionsBottomSheetFragment = new CommentFilterOptionsBottomSheetFragment(); | ||||
|             Bundle bundle = new Bundle(); | ||||
|             bundle.putParcelable(CommentFilterOptionsBottomSheetFragment.EXTRA_POST_FILTER, commentFilter); | ||||
|             commentFilterOptionsBottomSheetFragment.setArguments(bundle); | ||||
|             commentFilterOptionsBottomSheetFragment.show(getSupportFragmentManager(), commentFilterOptionsBottomSheetFragment.getTag()); | ||||
|         }); | ||||
|  | ||||
|         binding.recyclerViewCommentFilterPreferenceActivity.setAdapter(adapter); | ||||
|  | ||||
|         commentFilterWithUsageViewModel = new ViewModelProvider(this, | ||||
|                 new CommentFilterWithUsageViewModel.Factory(redditDataRoomDatabase)).get(CommentFilterWithUsageViewModel.class); | ||||
|  | ||||
|         commentFilterWithUsageViewModel.getCommentFilterWithUsageListLiveData().observe(this, commentFilterWithUsages -> adapter.setCommentFilterWithUsageList(commentFilterWithUsages)); | ||||
|     } | ||||
|  | ||||
|     public void editCommentFilter(CommentFilter commentFilter) { | ||||
|         Intent intent = new Intent(this, CustomizeCommentFilterActivity.class); | ||||
|         intent.putExtra(CustomizeCommentFilterActivity.EXTRA_COMMENT_FILTER, commentFilter); | ||||
|         intent.putExtra(CustomizeCommentFilterActivity.EXTRA_FROM_SETTINGS, true); | ||||
|         startActivity(intent); | ||||
|     } | ||||
|  | ||||
|     public void applyCommentFilterTo(CommentFilter commentFilter) { | ||||
|         Intent intent = new Intent(this, CommentFilterUsageListingActivity.class); | ||||
|         intent.putExtra(CommentFilterUsageListingActivity.EXTRA_COMMENT_FILTER, commentFilter); | ||||
|         startActivity(intent); | ||||
|     } | ||||
|  | ||||
|     public void deleteCommentFilter(CommentFilter commentFilter) { | ||||
|         DeleteCommentFilter.deleteCommentFilter(redditDataRoomDatabase, executor, commentFilter); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected SharedPreferences getDefaultSharedPreferences() { | ||||
|         return sharedPreferences; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected CustomThemeWrapper getCustomThemeWrapper() { | ||||
|         return customThemeWrapper; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void applyCustomTheme() { | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(binding.appbarLayoutCommentFilterPreferenceActivity, binding.collapsingToolbarLayoutCommentFilterPreferenceActivity, binding.toolbarCommentFilterPreferenceActivity); | ||||
|         applyFABTheme(binding.fabCommentFilterPreferenceActivity, sharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|         binding.getRoot().setBackgroundColor(customThemeWrapper.getBackgroundColor()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(@NonNull MenuItem item) { | ||||
|         if (item.getItemId() == android.R.id.home) { | ||||
|             finish(); | ||||
|             return true; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,181 @@ | ||||
| package eu.toldi.infinityforlemmy.activities; | ||||
|  | ||||
| import android.app.Activity; | ||||
|  | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.res.ColorStateList; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.view.MenuItem; | ||||
| import android.view.View; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.lifecycle.ViewModelProvider; | ||||
|  | ||||
| import com.google.android.material.dialog.MaterialAlertDialogBuilder; | ||||
| import com.google.android.material.textfield.TextInputEditText; | ||||
| import com.google.android.material.textfield.TextInputLayout; | ||||
|  | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.CommentFilterUsageOptionsBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.NewCommentFilterUsageBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.CommentFilter; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsage; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsageViewModel; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.DeleteCommentFilterUsage; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.SaveCommentFilterUsage; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.databinding.ActivityCommentFilterUsageListingBinding; | ||||
| import eu.toldi.infinityforlemmy.adapters.CommentFilterUsageRecyclerViewAdapter; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
|  | ||||
| public class CommentFilterUsageListingActivity extends BaseActivity { | ||||
|  | ||||
|     public static final String EXTRA_COMMENT_FILTER = "ECF"; | ||||
|     @Inject | ||||
|     @Named("default") | ||||
|     SharedPreferences sharedPreferences; | ||||
|     @Inject | ||||
|     RedditDataRoomDatabase redditDataRoomDatabase; | ||||
|     @Inject | ||||
|     CustomThemeWrapper customThemeWrapper; | ||||
|     @Inject | ||||
|     Executor executor; | ||||
|     private ActivityCommentFilterUsageListingBinding binding; | ||||
|     public CommentFilterUsageViewModel commentFilterUsageViewModel; | ||||
|     private CommentFilterUsageRecyclerViewAdapter adapter; | ||||
|     private CommentFilter commentFilter; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         ((Infinity) getApplication()).getAppComponent().inject(this); | ||||
|  | ||||
|         setImmersiveModeNotApplicable(); | ||||
|  | ||||
|         super.onCreate(savedInstanceState); | ||||
|         binding = ActivityCommentFilterUsageListingBinding.inflate(getLayoutInflater()); | ||||
|         setContentView(binding.getRoot()); | ||||
|  | ||||
|         applyCustomTheme(); | ||||
|  | ||||
|         setSupportActionBar(binding.toolbarCommentFilterUsageListingActivity); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|  | ||||
|         commentFilter = getIntent().getParcelableExtra(EXTRA_COMMENT_FILTER); | ||||
|  | ||||
|         setTitle(commentFilter.name); | ||||
|  | ||||
|         binding.fabCommentFilterUsageListingActivity.setOnClickListener(view -> { | ||||
|             NewCommentFilterUsageBottomSheetFragment newCommentFilterUsageBottomSheetFragment = new NewCommentFilterUsageBottomSheetFragment(); | ||||
|             newCommentFilterUsageBottomSheetFragment.show(getSupportFragmentManager(), newCommentFilterUsageBottomSheetFragment.getTag()); | ||||
|         }); | ||||
|  | ||||
|         adapter = new CommentFilterUsageRecyclerViewAdapter(this, customThemeWrapper, commentFilterUsage -> { | ||||
|             CommentFilterUsageOptionsBottomSheetFragment commentFilterUsageOptionsBottomSheetFragment = new CommentFilterUsageOptionsBottomSheetFragment(); | ||||
|             Bundle bundle = new Bundle(); | ||||
|             bundle.putParcelable(CommentFilterUsageOptionsBottomSheetFragment.EXTRA_COMMENT_FILTER_USAGE, commentFilterUsage); | ||||
|             commentFilterUsageOptionsBottomSheetFragment.setArguments(bundle); | ||||
|             commentFilterUsageOptionsBottomSheetFragment.show(getSupportFragmentManager(), commentFilterUsageOptionsBottomSheetFragment.getTag()); | ||||
|         }); | ||||
|         binding.recyclerViewCommentFilterUsageListingActivity.setAdapter(adapter); | ||||
|  | ||||
|         commentFilterUsageViewModel = new ViewModelProvider(this, | ||||
|                 new CommentFilterUsageViewModel.Factory(redditDataRoomDatabase, commentFilter.name)).get(CommentFilterUsageViewModel.class); | ||||
|  | ||||
|         commentFilterUsageViewModel.getCommentFilterUsageListLiveData().observe(this, commentFilterUsages -> adapter.setCommentFilterUsages(commentFilterUsages)); | ||||
|     } | ||||
|  | ||||
|     public void newCommentFilterUsage(int type) { | ||||
|         switch (type) { | ||||
|             case CommentFilterUsage.SUBREDDIT_TYPE: | ||||
|                 editAndCommentFilterUsageNameOfUsage(type, null); | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void editAndCommentFilterUsageNameOfUsage(int type, String nameOfUsage) { | ||||
|         View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_post_or_comment_filter_name_of_usage, null); | ||||
|         TextView messageTextView = dialogView.findViewById(R.id.message_text_view_edit_post_or_comment_filter_name_of_usage_dialog); | ||||
|         messageTextView.setVisibility(View.GONE); | ||||
|         TextInputLayout textInputLayout = dialogView.findViewById(R.id.text_input_layout_edit_post_or_comment_filter_name_of_usage_dialog); | ||||
|         TextInputEditText textInputEditText = dialogView.findViewById(R.id.text_input_edit_text_edit_post_or_comment_filter_name_of_usage_dialog); | ||||
|         int primaryTextColor = customThemeWrapper.getPrimaryTextColor(); | ||||
|         textInputLayout.setBoxStrokeColor(primaryTextColor); | ||||
|         textInputLayout.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); | ||||
|         textInputEditText.setTextColor(primaryTextColor); | ||||
|         if (nameOfUsage != null) { | ||||
|             textInputEditText.setText(nameOfUsage); | ||||
|         } | ||||
|         textInputEditText.requestFocus(); | ||||
|         int titleStringId = R.string.community; | ||||
|         switch (type) { | ||||
|             case CommentFilterUsage.SUBREDDIT_TYPE: | ||||
|                 textInputEditText.setHint(R.string.settings_tab_community_name); | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         Utils.showKeyboard(this, new Handler(), textInputEditText); | ||||
|         new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) | ||||
|                 .setTitle(titleStringId) | ||||
|                 .setView(dialogView) | ||||
|                 .setPositiveButton(R.string.ok, (editTextDialogInterface, i1) | ||||
|                         -> { | ||||
|                     Utils.hideKeyboard(this); | ||||
|  | ||||
|                     CommentFilterUsage commentFilterUsage; | ||||
|                     if (!textInputEditText.getText().toString().equals("")) { | ||||
|                         commentFilterUsage = new CommentFilterUsage(commentFilter.name, type, textInputEditText.getText().toString()); | ||||
|                         SaveCommentFilterUsage.saveCommentFilterUsage(redditDataRoomDatabase, executor, commentFilterUsage); | ||||
|                     } | ||||
|                 }) | ||||
|                 .setNegativeButton(R.string.cancel, null) | ||||
|                 .setOnDismissListener(editTextDialogInterface -> { | ||||
|                     Utils.hideKeyboard(this); | ||||
|                 }) | ||||
|                 .show(); | ||||
|     } | ||||
|  | ||||
|     public void editCommentFilterUsage(CommentFilterUsage commentFilterUsage) { | ||||
|         editAndCommentFilterUsageNameOfUsage(commentFilterUsage.usage, commentFilterUsage.nameOfUsage); | ||||
|     } | ||||
|  | ||||
|     public void deleteCommentFilterUsage(CommentFilterUsage commentFilterUsage) { | ||||
|         DeleteCommentFilterUsage.deleteCommentFilterUsage(redditDataRoomDatabase, executor, commentFilterUsage); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(@NonNull MenuItem item) { | ||||
|         if (item.getItemId() == android.R.id.home) { | ||||
|             finish(); | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected SharedPreferences getDefaultSharedPreferences() { | ||||
|         return sharedPreferences; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected CustomThemeWrapper getCustomThemeWrapper() { | ||||
|         return customThemeWrapper; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void applyCustomTheme() { | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(binding.appbarLayoutCommentFilterUsageListingActivity, binding.collapsingToolbarLayoutCommentFilterUsageListingActivity, binding.toolbarCommentFilterUsageListingActivity); | ||||
|         applyFABTheme(binding.fabCommentFilterUsageListingActivity, sharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|         binding.getRoot().setBackgroundColor(customThemeWrapper.getBackgroundColor()); | ||||
|     } | ||||
| } | ||||
| @@ -51,6 +51,7 @@ import eu.toldi.infinityforlemmy.customtheme.CustomThemeViewModel; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.events.RecreateActivityEvent; | ||||
| import eu.toldi.infinityforlemmy.utils.CustomThemeSharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
|  | ||||
| public class CustomThemeListingActivity extends BaseActivity implements | ||||
| @@ -154,7 +155,7 @@ public class CustomThemeListingActivity extends BaseActivity implements | ||||
|     @Override | ||||
|     protected void applyCustomTheme() { | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar); | ||||
|         applyFABTheme(fab); | ||||
|         applyFABTheme(fab, sharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -0,0 +1,302 @@ | ||||
| package eu.toldi.infinityforlemmy.activities; | ||||
|  | ||||
| import android.app.Activity; | ||||
|  | ||||
| import android.Manifest; | ||||
| import android.app.Activity; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.pm.PackageManager; | ||||
| import android.content.res.ColorStateList; | ||||
| import android.graphics.PorterDuff; | ||||
| import android.graphics.drawable.Drawable; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.view.Menu; | ||||
| import android.view.MenuItem; | ||||
| import android.widget.EditText; | ||||
| import android.widget.TextView; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.activity.result.ActivityResultLauncher; | ||||
| import androidx.activity.result.contract.ActivityResultContracts; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.core.content.ContextCompat; | ||||
|  | ||||
| import com.google.android.material.dialog.MaterialAlertDialogBuilder; | ||||
|  | ||||
| import java.lang.reflect.Field; | ||||
| import java.util.ArrayList; | ||||
| import java.util.concurrent.Executor; | ||||
| import java.util.regex.PatternSyntaxException; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.CommentFilter; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.SaveCommentFilter; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.databinding.ActivityCustomizeCommentFilterBinding; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
|  | ||||
|  | ||||
| public class CustomizeCommentFilterActivity extends BaseActivity { | ||||
|  | ||||
|     public static final String EXTRA_COMMENT_FILTER = "ECF"; | ||||
|     public static final String EXTRA_FROM_SETTINGS = "EFS"; | ||||
|     public static final String RETURN_EXTRA_COMMENT_FILTER = "RECF"; | ||||
|     private static final String COMMENT_FILTER_STATE = "CFS"; | ||||
|     private static final String ORIGINAL_NAME_STATE = "ONS"; | ||||
|     @Inject | ||||
|     RedditDataRoomDatabase mRedditDataRoomDatabase; | ||||
|     @Inject | ||||
|     @Named("default") | ||||
|     SharedPreferences mSharedPreferences; | ||||
|     @Inject | ||||
|     @Named("current_account") | ||||
|     SharedPreferences currentAccountSharedPreferences; | ||||
|     @Inject | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     @Inject | ||||
|     Executor mExecutor; | ||||
|     private CommentFilter commentFilter; | ||||
|     private boolean fromSettings; | ||||
|     private String originalName; | ||||
|     private ActivityCustomizeCommentFilterBinding binding; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         ((Infinity) getApplication()).getAppComponent().inject(this); | ||||
|  | ||||
|         setImmersiveModeNotApplicable(); | ||||
|  | ||||
|         super.onCreate(savedInstanceState); | ||||
|         binding = ActivityCustomizeCommentFilterBinding.inflate(getLayoutInflater()); | ||||
|         setContentView(binding.getRoot()); | ||||
|  | ||||
|         applyCustomTheme(); | ||||
|  | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { | ||||
|             addOnOffsetChangedListener(binding.appbarLayoutCustomizeCommentFilterActivity); | ||||
|         } | ||||
|  | ||||
|         setSupportActionBar(binding.toolbarCustomizeCommentFilterActivity); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|         setToolbarGoToTop(binding.toolbarCustomizeCommentFilterActivity); | ||||
|  | ||||
|         ActivityResultLauncher<Intent> requestAddUsersLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { | ||||
|             Intent data = result.getData(); | ||||
|             if (data == null) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             ArrayList<String> usernames = data.getStringArrayListExtra(SearchActivity.RETURN_EXTRA_SELECTED_USERNAMES); | ||||
|             String currentUsers = binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.getText().toString().trim(); | ||||
|             if (usernames != null && !usernames.isEmpty()) { | ||||
|                 if (!currentUsers.isEmpty() && currentUsers.charAt(currentUsers.length() - 1) != ',') { | ||||
|                     String newString = currentUsers + ","; | ||||
|                     binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.setText(newString); | ||||
|                 } | ||||
|                 StringBuilder stringBuilder = new StringBuilder(); | ||||
|                 for (String s : usernames) { | ||||
|                     stringBuilder.append(s).append(","); | ||||
|                 } | ||||
|                 stringBuilder.deleteCharAt(stringBuilder.length() - 1); | ||||
|                 binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.append(stringBuilder.toString()); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         binding.addUsersImageViewCustomizeCommentFilterActivity.setOnClickListener(view -> { | ||||
|             Intent intent = new Intent(this, SearchActivity.class); | ||||
|             intent.putExtra(SearchActivity.EXTRA_SEARCH_ONLY_USERS, true); | ||||
|             intent.putExtra(SearchActivity.EXTRA_IS_MULTI_SELECTION, true); | ||||
|             requestAddUsersLauncher.launch(intent); | ||||
|         }); | ||||
|  | ||||
|         fromSettings = getIntent().getBooleanExtra(EXTRA_FROM_SETTINGS, false); | ||||
|  | ||||
|         if (savedInstanceState != null) { | ||||
|             commentFilter = savedInstanceState.getParcelable(COMMENT_FILTER_STATE); | ||||
|             originalName = savedInstanceState.getString(ORIGINAL_NAME_STATE); | ||||
|         } else { | ||||
|             commentFilter = getIntent().getParcelableExtra(EXTRA_COMMENT_FILTER); | ||||
|             if (commentFilter == null) { | ||||
|                 commentFilter = new CommentFilter(); | ||||
|                 originalName = ""; | ||||
|             } else { | ||||
|                 if (!fromSettings) { | ||||
|                     originalName = ""; | ||||
|                 } else { | ||||
|                     originalName = commentFilter.name; | ||||
|                 } | ||||
|             } | ||||
|             bindView(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void bindView() { | ||||
|         binding.nameTextInputEditTextCustomizeCommentFilterActivity.setText(commentFilter.name); | ||||
|         binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.setText(commentFilter.excludeStrings); | ||||
|         binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.setText(commentFilter.excludeUsers); | ||||
|         binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.setText(Integer.toString(commentFilter.minVote)); | ||||
|         binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.setText(Integer.toString(commentFilter.maxVote)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected SharedPreferences getDefaultSharedPreferences() { | ||||
|         return mSharedPreferences; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected CustomThemeWrapper getCustomThemeWrapper() { | ||||
|         return mCustomThemeWrapper; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void applyCustomTheme() { | ||||
|         binding.getRoot().setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(binding.appbarLayoutCustomizeCommentFilterActivity, binding.collapsingToolbarLayoutCustomizeCommentFilterActivity, binding.toolbarCustomizeCommentFilterActivity); | ||||
|         int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); | ||||
|         int primaryIconColor = mCustomThemeWrapper.getPrimaryIconColor(); | ||||
|         Drawable cursorDrawable = Utils.getTintedDrawable(this, R.drawable.edit_text_cursor, primaryTextColor); | ||||
|         binding.nameTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor); | ||||
|         binding.nameTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); | ||||
|         binding.nameTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor); | ||||
|         binding.excludeStringsTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor); | ||||
|         binding.excludeStringsTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); | ||||
|         binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor); | ||||
|         binding.excludeUsersTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); | ||||
|         binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor); | ||||
|         binding.addUsersImageViewCustomizeCommentFilterActivity.setImageDrawable(Utils.getTintedDrawable(this, R.drawable.ic_add_24dp, primaryIconColor)); | ||||
|         binding.minVoteTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor); | ||||
|         binding.minVoteTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); | ||||
|         binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor); | ||||
|         binding.maxVoteTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor); | ||||
|         binding.maxVoteTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); | ||||
|         binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor); | ||||
|  | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { | ||||
|             binding.nameTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable); | ||||
|             binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable); | ||||
|             binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable); | ||||
|             binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable); | ||||
|             binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable); | ||||
|         } else { | ||||
|             setCursorDrawableColor(binding.nameTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor); | ||||
|             setCursorDrawableColor(binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor); | ||||
|             setCursorDrawableColor(binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor); | ||||
|             setCursorDrawableColor(binding.minVoteTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor); | ||||
|             setCursorDrawableColor(binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor); | ||||
|         } | ||||
|  | ||||
|         if (typeface != null) { | ||||
|             Utils.setFontToAllTextViews(binding.getRoot(), typeface); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void setCursorDrawableColor(EditText editText, int color) { | ||||
|         try { | ||||
|             Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes"); | ||||
|             fCursorDrawableRes.setAccessible(true); | ||||
|             int mCursorDrawableRes = fCursorDrawableRes.getInt(editText); | ||||
|             Field fEditor = TextView.class.getDeclaredField("mEditor"); | ||||
|             fEditor.setAccessible(true); | ||||
|             Object editor = fEditor.get(editText); | ||||
|             Class<?> clazz = editor.getClass(); | ||||
|             Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable"); | ||||
|             fCursorDrawable.setAccessible(true); | ||||
|             Drawable[] drawables = new Drawable[2]; | ||||
|             drawables[0] = editText.getContext().getResources().getDrawable(mCursorDrawableRes); | ||||
|             drawables[1] = editText.getContext().getResources().getDrawable(mCursorDrawableRes); | ||||
|             drawables[0].setColorFilter(color, PorterDuff.Mode.SRC_IN); | ||||
|             drawables[1].setColorFilter(color, PorterDuff.Mode.SRC_IN); | ||||
|             fCursorDrawable.set(editor, drawables); | ||||
|         } catch (Throwable ignored) { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onCreateOptionsMenu(Menu menu) { | ||||
|         getMenuInflater().inflate(R.menu.customize_comment_filter_activity, menu); | ||||
|         if (fromSettings) { | ||||
|             menu.findItem(R.id.action_save_customize_comment_filter_activity).setVisible(false); | ||||
|         } | ||||
|         applyMenuItemTheme(menu); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(@NonNull MenuItem item) { | ||||
|         if (item.getItemId() == android.R.id.home) { | ||||
|             finish(); | ||||
|             return true; | ||||
|         } else if (item.getItemId() == R.id.action_save_customize_comment_filter_activity) { | ||||
|             try { | ||||
|                 constructCommentFilter(); | ||||
|                 Intent returnIntent = new Intent(); | ||||
|                 returnIntent.putExtra(RETURN_EXTRA_COMMENT_FILTER, commentFilter); | ||||
|                 setResult(Activity.RESULT_OK, returnIntent); | ||||
|                 finish(); | ||||
|             } catch (PatternSyntaxException e) { | ||||
|                 Toast.makeText(this, R.string.invalid_regex, Toast.LENGTH_SHORT).show(); | ||||
|             } | ||||
|  | ||||
|             return true; | ||||
|         } else if (item.getItemId() == R.id.action_save_to_database_customize_comment_filter_activity) { | ||||
|             try { | ||||
|                 constructCommentFilter(); | ||||
|  | ||||
|                 if (!commentFilter.name.equals("")) { | ||||
|                     saveCommentFilter(originalName); | ||||
|                 } else { | ||||
|                     Toast.makeText(CustomizeCommentFilterActivity.this, R.string.comment_filter_requires_a_name, Toast.LENGTH_LONG).show(); | ||||
|                 } | ||||
|             } catch (PatternSyntaxException e) { | ||||
|                 Toast.makeText(this, R.string.invalid_regex, Toast.LENGTH_SHORT).show(); | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     private void saveCommentFilter(String originalName) { | ||||
|         SaveCommentFilter.saveCommentFilter(mExecutor, new Handler(), mRedditDataRoomDatabase, commentFilter, originalName, | ||||
|                 new SaveCommentFilter.SaveCommentFilterListener() { | ||||
|                     @Override | ||||
|                     public void success() { | ||||
|                         Intent returnIntent = new Intent(); | ||||
|                         returnIntent.putExtra(RETURN_EXTRA_COMMENT_FILTER, commentFilter); | ||||
|                         setResult(Activity.RESULT_OK, returnIntent); | ||||
|                         finish(); | ||||
|                     } | ||||
|  | ||||
|                     @Override | ||||
|                     public void duplicate() { | ||||
|                         new MaterialAlertDialogBuilder(CustomizeCommentFilterActivity.this, R.style.MaterialAlertDialogTheme) | ||||
|                                 .setTitle(getString(R.string.duplicate_comment_filter_dialog_title, commentFilter.name)) | ||||
|                                 .setMessage(R.string.duplicate_comment_filter_dialog_message) | ||||
|                                 .setPositiveButton(R.string.override, (dialogInterface, i) -> saveCommentFilter(commentFilter.name)) | ||||
|                                 .setNegativeButton(R.string.cancel, null) | ||||
|                                 .show(); | ||||
|                     } | ||||
|                 }); | ||||
|     } | ||||
|  | ||||
|     private void constructCommentFilter() throws PatternSyntaxException { | ||||
|         commentFilter.name = binding.nameTextInputEditTextCustomizeCommentFilterActivity.getText().toString(); | ||||
|         commentFilter.excludeStrings = binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.getText().toString(); | ||||
|         commentFilter.excludeUsers = binding.excludeUsersTextInputEditTextCustomizeCommentFilterActivity.getText().toString(); | ||||
|         commentFilter.maxVote = binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.getText() == null || binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString().equals("") ? -1 : Integer.parseInt(binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString()); | ||||
|         commentFilter.minVote = binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.getText() == null || binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString().equals("") ? -1 : Integer.parseInt(binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onSaveInstanceState(@NonNull Bundle outState) { | ||||
|         super.onSaveInstanceState(outState); | ||||
|         outState.putParcelable(COMMENT_FILTER_STATE, commentFilter); | ||||
|         outState.putString(ORIGINAL_NAME_STATE, originalName); | ||||
|     } | ||||
| } | ||||
| @@ -226,10 +226,6 @@ public class CustomizePostFilterActivity extends BaseActivity { | ||||
|  | ||||
|         applyCustomTheme(); | ||||
|  | ||||
|         if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { | ||||
|             Slidr.attach(this); | ||||
|         } | ||||
|  | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { | ||||
|             addOnOffsetChangedListener(appBarLayout); | ||||
|         } | ||||
|   | ||||
| @@ -345,7 +345,7 @@ public class EditCommentActivity extends BaseActivity implements UploadImageEnab | ||||
|         int start = Math.max(contentEditText.getSelectionStart(), 0); | ||||
|         int end = Math.max(contentEditText.getSelectionEnd(), 0); | ||||
|         contentEditText.getText().replace(Math.min(start, end), Math.max(start, end), | ||||
|                 "[" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")", | ||||
|                 0, "[]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); | ||||
|                 "", | ||||
|                 0, "![]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -3,17 +3,20 @@ package eu.toldi.infinityforlemmy.activities; | ||||
| import android.content.ActivityNotFoundException; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.graphics.Bitmap; | ||||
| import android.net.Uri; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| import android.os.Environment; | ||||
| import android.os.Handler; | ||||
| import android.provider.MediaStore; | ||||
| import android.text.Editable; | ||||
| import android.text.TextWatcher; | ||||
| import android.view.Menu; | ||||
| import android.view.MenuItem; | ||||
| import android.view.View; | ||||
| import android.widget.EditText; | ||||
| import android.widget.TextView; | ||||
| import android.widget.ImageView; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| @@ -23,18 +26,22 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout; | ||||
| import androidx.core.content.FileProvider; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| import com.bumptech.glide.Glide; | ||||
| import com.bumptech.glide.RequestManager; | ||||
| import com.google.android.material.appbar.AppBarLayout; | ||||
| import com.google.android.material.button.MaterialButton; | ||||
| import com.google.android.material.dialog.MaterialAlertDialogBuilder; | ||||
| import com.google.android.material.snackbar.Snackbar; | ||||
|  | ||||
| import org.greenrobot.eventbus.EventBus; | ||||
| import org.greenrobot.eventbus.Subscribe; | ||||
| import org.json.JSONException; | ||||
| import org.xmlpull.v1.XmlPullParserException; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.ExecutionException; | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| @@ -48,14 +55,16 @@ import eu.toldi.infinityforlemmy.RetrofitHolder; | ||||
| import eu.toldi.infinityforlemmy.UploadImageEnabledActivity; | ||||
| import eu.toldi.infinityforlemmy.UploadedImage; | ||||
| import eu.toldi.infinityforlemmy.adapters.MarkdownBottomBarRecyclerViewAdapter; | ||||
| import eu.toldi.infinityforlemmy.apis.RedditAPI; | ||||
| import eu.toldi.infinityforlemmy.apis.LemmyAPI; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.UploadedImagesBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; | ||||
| import eu.toldi.infinityforlemmy.customviews.slidr.Slidr; | ||||
| import eu.toldi.infinityforlemmy.dto.EditPostDTO; | ||||
| import eu.toldi.infinityforlemmy.events.SwitchAccountEvent; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| import eu.toldi.infinityforlemmy.post.Post; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.UploadImageUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
| import retrofit2.Call; | ||||
| import retrofit2.Callback; | ||||
| @@ -64,16 +73,19 @@ import retrofit2.Retrofit; | ||||
|  | ||||
| public class EditPostActivity extends BaseActivity implements UploadImageEnabledActivity { | ||||
|  | ||||
|     public static final String EXTRA_TITLE = "ET"; | ||||
|     public static final String EXTRA_CONTENT = "EC"; | ||||
|     public static final String EXTRA_FULLNAME = "EF"; | ||||
|     public static final String EXTRA_DATA = "ED"; | ||||
|  | ||||
|  | ||||
|     private static final int UPLOAD_IMAGE_REQUEST_CODE = 1; | ||||
|     private static final int PICK_IMAGE_REQUEST_CODE = 100; | ||||
|     private static final int CAPTURE_IMAGE_REQUEST_CODE = 200; | ||||
|     private static final int MARKDOWN_PREVIEW_REQUEST_CODE = 300; | ||||
|  | ||||
|     private static final String UPLOADED_IMAGES_STATE = "UIS"; | ||||
|  | ||||
|     private static final String picturePattern = "https:\\/\\/[^\\/]+\\/pictrs\\/image\\/([a-f\\d-]+\\.jpeg)"; | ||||
|  | ||||
|  | ||||
|     @BindView(R.id.coordinator_layout_edit_post_activity) | ||||
|     CoordinatorLayout coordinatorLayout; | ||||
|     @BindView(R.id.appbar_layout_edit_post_activity) | ||||
| @@ -81,13 +93,22 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled | ||||
|     @BindView(R.id.toolbar_edit_post_activity) | ||||
|     Toolbar toolbar; | ||||
|     @BindView(R.id.post_title_text_view_edit_post_activity) | ||||
|     TextView titleTextView; | ||||
|     EditText titleEditText; | ||||
|     @BindView(R.id.divider_edit_post_activity) | ||||
|     View divider; | ||||
|     @BindView(R.id.post_text_content_edit_text_edit_post_activity) | ||||
|     EditText contentEditText; | ||||
|     @BindView(R.id.markdown_bottom_bar_recycler_view_edit_post_activity) | ||||
|     RecyclerView markdownBottomBarRecyclerView; | ||||
|     @BindView(R.id.post_link_edit_text_post_edit_activity) | ||||
|     EditText linkEditText; | ||||
|  | ||||
|     @BindView(R.id.upload_image_button_post_edit_activity) | ||||
|     MaterialButton uploadImageButton; | ||||
|  | ||||
|     @BindView(R.id.image_view_post_edit_activity) | ||||
|     ImageView imageView; | ||||
|  | ||||
|     @Inject | ||||
|     @Named("no_oauth") | ||||
|     RetrofitHolder mRetrofit; | ||||
| @@ -104,13 +125,16 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     @Inject | ||||
|     Executor mExecutor; | ||||
|     private String mFullName; | ||||
|     private Post mPost; | ||||
|  | ||||
|     private String mAccessToken; | ||||
|     private String mPostContent; | ||||
|     private boolean isSubmitting = false; | ||||
|     private Uri capturedImageUri; | ||||
|     private ArrayList<UploadedImage> uploadedImages = new ArrayList<>(); | ||||
|  | ||||
|  | ||||
|     private RequestManager mGlide; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         ((Infinity) getApplication()).getAppComponent().inject(this); | ||||
| @@ -138,11 +162,49 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled | ||||
|         setSupportActionBar(toolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|  | ||||
|         mFullName = getIntent().getStringExtra(EXTRA_FULLNAME); | ||||
|         mPost = getIntent().getParcelableExtra(EXTRA_DATA); | ||||
|         if (mPost == null) { | ||||
|             finish(); | ||||
|         } | ||||
|  | ||||
|         mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); | ||||
|         titleTextView.setText(getIntent().getStringExtra(EXTRA_TITLE)); | ||||
|         mPostContent = getIntent().getStringExtra(EXTRA_CONTENT); | ||||
|         contentEditText.setText(mPostContent); | ||||
|         titleEditText.setText(mPost.getTitle()); | ||||
|         contentEditText.setText(mPost.getSelfText()); | ||||
|         linkEditText.setText(mPost.getUrl()); | ||||
|  | ||||
|         mGlide = Glide.with(getApplication()); | ||||
|  | ||||
|         if (mPost.getUrl() != null && mPost.getUrl().matches(picturePattern)) { | ||||
|             loadImage(); | ||||
|         } | ||||
|  | ||||
|         linkEditText.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) { | ||||
|                 if (charSequence.toString().matches(picturePattern)) { | ||||
|                     loadImage(); | ||||
|                 } else { | ||||
|                     uploadImageButton.setVisibility(View.VISIBLE); | ||||
|                     imageView.setVisibility(View.GONE); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void afterTextChanged(Editable editable) { | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         uploadImageButton.setOnClickListener(view -> { | ||||
|             Intent intent = new Intent(); | ||||
|             intent.setType("image/*"); | ||||
|             intent.setAction(Intent.ACTION_GET_CONTENT); | ||||
|             startActivityForResult(Intent.createChooser(intent, getString(R.string.select_from_gallery)), UPLOAD_IMAGE_REQUEST_CODE); | ||||
|         }); | ||||
|  | ||||
|  | ||||
|         if (savedInstanceState != null) { | ||||
|             uploadedImages = savedInstanceState.getParcelableArrayList(UPLOADED_IMAGES_STATE); | ||||
| @@ -190,18 +252,27 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled | ||||
|     protected void applyCustomTheme() { | ||||
|         coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, null, toolbar); | ||||
|         titleTextView.setTextColor(mCustomThemeWrapper.getPostTitleColor()); | ||||
|         titleEditText.setTextColor(mCustomThemeWrapper.getPostTitleColor()); | ||||
|         divider.setBackgroundColor(mCustomThemeWrapper.getPostTitleColor()); | ||||
|         contentEditText.setTextColor(mCustomThemeWrapper.getPostContentColor()); | ||||
|         linkEditText.setTextColor(mCustomThemeWrapper.getPostContentColor()); | ||||
|  | ||||
|         uploadImageButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); | ||||
|         uploadImageButton.setBackgroundColor(mCustomThemeWrapper.getColorPrimaryLightTheme()); | ||||
|         if (titleTypeface != null) { | ||||
|             titleTextView.setTypeface(titleTypeface); | ||||
|             titleEditText.setTypeface(titleTypeface); | ||||
|         } | ||||
|         if (contentTypeface != null) { | ||||
|             contentEditText.setTypeface(contentTypeface); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void loadImage() { | ||||
|         uploadImageButton.setVisibility(View.GONE); | ||||
|         imageView.setVisibility(View.VISIBLE); | ||||
|         mGlide.load(mPost.getUrl()).into(imageView); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onPause() { | ||||
|         super.onPause(); | ||||
| @@ -237,21 +308,19 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled | ||||
|             isSubmitting = true; | ||||
|  | ||||
|             Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_SHORT).show(); | ||||
|  | ||||
|             Map<String, String> params = new HashMap<>(); | ||||
|             params.put(APIUtils.THING_ID_KEY, mFullName); | ||||
|             params.put(APIUtils.TEXT_KEY, contentEditText.getText().toString()); | ||||
|  | ||||
|             mRetrofit.getRetrofit().create(RedditAPI.class) | ||||
|                     .editPostOrComment(APIUtils.getOAuthHeader(mAccessToken), params) | ||||
|             mRetrofit.getRetrofit().create(LemmyAPI.class).postUpdate(new EditPostDTO(mPost.getId(), titleEditText.getText().toString(), (linkEditText.getText().toString().isEmpty()) ? null : linkEditText.getText().toString(), contentEditText.getText().toString(), mPost.isNSFW(), null, mAccessToken)) | ||||
|                     .enqueue(new Callback<String>() { | ||||
|                         @Override | ||||
|                         public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { | ||||
|                             isSubmitting = false; | ||||
|                             Toast.makeText(EditPostActivity.this, R.string.edit_success, Toast.LENGTH_SHORT).show(); | ||||
|                             Intent returnIntent = new Intent(); | ||||
|                             setResult(RESULT_OK, returnIntent); | ||||
|                             finish(); | ||||
|                             if (response.isSuccessful()) { | ||||
|                                 Toast.makeText(EditPostActivity.this, R.string.edit_success, Toast.LENGTH_SHORT).show(); | ||||
|                                 Intent returnIntent = new Intent(); | ||||
|                                 setResult(RESULT_OK, returnIntent); | ||||
|                                 finish(); | ||||
|                             } else { | ||||
|                                 Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); | ||||
|                             } | ||||
|                         } | ||||
|  | ||||
|                         @Override | ||||
| @@ -275,6 +344,39 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled | ||||
|                 } | ||||
|                 Utils.uploadImageToReddit(this, mExecutor, mRetrofit, | ||||
|                         mAccessToken, contentEditText, coordinatorLayout, data.getData(), uploadedImages); | ||||
|             } else if (requestCode == UPLOAD_IMAGE_REQUEST_CODE) { | ||||
|                 if (data == null) { | ||||
|                     Snackbar.make(coordinatorLayout, R.string.error_getting_image, Snackbar.LENGTH_SHORT).show(); | ||||
|                     return; | ||||
|                 } | ||||
|                 Toast.makeText(this, R.string.uploading_image, Toast.LENGTH_SHORT).show(); | ||||
|                 Handler handler = new Handler(); | ||||
|                 Uri imageUri = data.getData(); | ||||
|                 mExecutor.execute(() -> { | ||||
|                     try { | ||||
|                         Bitmap bitmap = Glide.with(getApplication()).asBitmap().load(imageUri).submit().get(); | ||||
|                         String imageUrlOrError = UploadImageUtils.uploadImage(mRetrofit, mAccessToken, bitmap); | ||||
|                         handler.post(() -> { | ||||
|                             if (imageUrlOrError != null && !imageUrlOrError.startsWith("Error: ")) { | ||||
|                                 String fileName = Utils.getFileName(this, imageUri); | ||||
|                                 if (fileName == null) { | ||||
|                                     fileName = imageUrlOrError; | ||||
|                                 } | ||||
|                                 mPost.setUrl(imageUrlOrError); | ||||
|                                 linkEditText.setText(imageUrlOrError); | ||||
|                                 Snackbar.make(coordinatorLayout, R.string.upload_image_success, Snackbar.LENGTH_LONG).show(); | ||||
|                             } else { | ||||
|                                 Toast.makeText(this, R.string.upload_image_failed, Toast.LENGTH_LONG).show(); | ||||
|                             } | ||||
|                         }); | ||||
|                     } catch (ExecutionException | InterruptedException e) { | ||||
|                         e.printStackTrace(); | ||||
|                         handler.post(() -> Toast.makeText(this, R.string.get_image_bitmap_failed, Toast.LENGTH_LONG).show()); | ||||
|                     } catch (XmlPullParserException | JSONException | IOException e) { | ||||
|                         e.printStackTrace(); | ||||
|                         handler.post(() -> Toast.makeText(this, R.string.error_processing_image, Toast.LENGTH_LONG).show()); | ||||
|                     } | ||||
|                 }); | ||||
|             } else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE) { | ||||
|                 Utils.uploadImageToReddit(this, mExecutor, mRetrofit, | ||||
|                         mAccessToken, contentEditText, coordinatorLayout, capturedImageUri, uploadedImages); | ||||
| @@ -282,6 +384,7 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled | ||||
|                 editPost(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -305,7 +408,7 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled | ||||
|         if (isSubmitting) { | ||||
|             promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_edit_post_detail); | ||||
|         } else { | ||||
|             if (contentEditText.getText().toString().equals(mPostContent)) { | ||||
|             if (contentEditText.getText().toString().equals(mPost.getSelfText())) { | ||||
|                 finish(); | ||||
|             } else { | ||||
|                 promptAlertDialog(R.string.discard, R.string.discard_detail); | ||||
| @@ -353,7 +456,7 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled | ||||
|         int start = Math.max(contentEditText.getSelectionStart(), 0); | ||||
|         int end = Math.max(contentEditText.getSelectionEnd(), 0); | ||||
|         contentEditText.getText().replace(Math.min(start, end), Math.max(start, end), | ||||
|                 "[" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")", | ||||
|                 0, "[]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); | ||||
|                 "", | ||||
|                 0, "![]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -38,7 +38,6 @@ import javax.inject.Named; | ||||
|  | ||||
| import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
| import jp.wasabeef.glide.transformations.RoundedCornersTransformation; | ||||
| import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| @@ -52,6 +51,7 @@ import eu.toldi.infinityforlemmy.user.UserViewModel; | ||||
| import eu.toldi.infinityforlemmy.utils.EditProfileUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
| import jp.wasabeef.glide.transformations.RoundedCornersTransformation; | ||||
| import pl.droidsonroids.gif.GifImageView; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
| @@ -135,7 +135,7 @@ public class EditProfileActivity extends BaseActivity { | ||||
|             startPickImage(PICK_IMAGE_AVATAR_REQUEST_CODE); | ||||
|         }); | ||||
|  | ||||
|         final RequestManager glide = Glide.with(this); | ||||
|         final RequestManager glide = Glide.with(getApplication()); | ||||
|         final UserViewModel.Factory userViewModelFactory = | ||||
|                 new UserViewModel.Factory(getApplication(), mRedditDataRoomDatabase, mAccountName); | ||||
|         final UserViewModel userViewModel = | ||||
|   | ||||
| @@ -103,6 +103,8 @@ public class FilteredPostsActivity extends BaseActivity implements SortTypeSelec | ||||
|     public SubredditViewModel mSubredditViewModel; | ||||
|     private String mAccessToken; | ||||
|     private String mAccountName; | ||||
|  | ||||
|     private String mAccountQualifiedName; | ||||
|     private String name; | ||||
|     private String userWhere; | ||||
|     private int postType; | ||||
| @@ -158,6 +160,7 @@ public class FilteredPostsActivity extends BaseActivity implements SortTypeSelec | ||||
|  | ||||
|         mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); | ||||
|         mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); | ||||
|         mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null); | ||||
|         name = getIntent().getStringExtra(EXTRA_NAME); | ||||
|         postType = getIntent().getIntExtra(EXTRA_POST_TYPE, PostPagingSource.TYPE_FRONT_PAGE); | ||||
|  | ||||
| @@ -262,14 +265,14 @@ public class FilteredPostsActivity extends BaseActivity implements SortTypeSelec | ||||
|     protected void applyCustomTheme() { | ||||
|         coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar); | ||||
|         applyFABTheme(fab); | ||||
|         applyFABTheme(fab, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|     } | ||||
|  | ||||
|     private void bindView(PostFilter postFilter, boolean initializeFragment) { | ||||
|         switch (postType) { | ||||
|             case PostPagingSource.TYPE_FRONT_PAGE: | ||||
|             case PostPagingSource.TYPE_ANONYMOUS_FRONT_PAGE: | ||||
|                 getSupportActionBar().setTitle(R.string.home); | ||||
|                 getSupportActionBar().setTitle(R.string.subscribed_feed); | ||||
|                 break; | ||||
|             case PostPagingSource.TYPE_SEARCH: | ||||
|                 getSupportActionBar().setTitle(R.string.search); | ||||
| @@ -470,7 +473,7 @@ public class FilteredPostsActivity extends BaseActivity implements SortTypeSelec | ||||
|  | ||||
|     @Override | ||||
|     public void markPostAsRead(Post post) { | ||||
|         InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountName, post.getId()); | ||||
|         InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountQualifiedName, post.getId()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -29,12 +29,6 @@ import javax.inject.Named; | ||||
|  | ||||
| import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
| import io.noties.markwon.AbstractMarkwonPlugin; | ||||
| import io.noties.markwon.Markwon; | ||||
| import io.noties.markwon.MarkwonConfiguration; | ||||
| import io.noties.markwon.MarkwonPlugin; | ||||
| import io.noties.markwon.core.MarkwonTheme; | ||||
| import io.noties.markwon.recycler.MarkwonAdapter; | ||||
| import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| @@ -45,6 +39,12 @@ import eu.toldi.infinityforlemmy.customviews.slidr.Slidr; | ||||
| import eu.toldi.infinityforlemmy.events.SwitchAccountEvent; | ||||
| import eu.toldi.infinityforlemmy.markdown.MarkdownUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import io.noties.markwon.AbstractMarkwonPlugin; | ||||
| import io.noties.markwon.Markwon; | ||||
| import io.noties.markwon.MarkwonConfiguration; | ||||
| import io.noties.markwon.MarkwonPlugin; | ||||
| import io.noties.markwon.core.MarkwonTheme; | ||||
| import io.noties.markwon.recycler.MarkwonAdapter; | ||||
|  | ||||
| public class FullMarkdownActivity extends BaseActivity { | ||||
|  | ||||
| @@ -139,7 +139,7 @@ public class FullMarkdownActivity extends BaseActivity { | ||||
|             } | ||||
|         }; | ||||
|         Markwon markwon = MarkdownUtils.createFullRedditMarkwon(this, | ||||
|                 miscPlugin, markdownColor, spoilerBackgroundColor, null); | ||||
|                 miscPlugin, markdownColor, spoilerBackgroundColor, null, mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false)); | ||||
|  | ||||
|         MarkwonAdapter markwonAdapter = MarkdownUtils.createTablesAdapter(); | ||||
|         LinearLayoutManagerBugFixed linearLayoutManager = new SwipeLockLinearLayoutManager(this, new SwipeLockInterface() { | ||||
|   | ||||
| @@ -1,336 +0,0 @@ | ||||
| package eu.toldi.infinityforlemmy.activities; | ||||
|  | ||||
| import android.content.SharedPreferences; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| import android.view.KeyEvent; | ||||
| import android.view.Menu; | ||||
| import android.view.MenuItem; | ||||
| import android.view.View; | ||||
| import android.view.Window; | ||||
| import android.view.WindowManager; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.appcompat.widget.Toolbar; | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentActivity; | ||||
| import androidx.fragment.app.FragmentManager; | ||||
| import androidx.viewpager2.adapter.FragmentStateAdapter; | ||||
| import androidx.viewpager2.widget.ViewPager2; | ||||
|  | ||||
| import com.google.android.material.appbar.AppBarLayout; | ||||
| import com.google.android.material.appbar.CollapsingToolbarLayout; | ||||
| import com.google.android.material.tabs.TabLayout; | ||||
|  | ||||
| import org.greenrobot.eventbus.EventBus; | ||||
| import org.greenrobot.eventbus.Subscribe; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
|  | ||||
| import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
| import eu.toldi.infinityforlemmy.ActivityToolbarInterface; | ||||
| import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.PostLayoutBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.customviews.slidr.Slidr; | ||||
| import eu.toldi.infinityforlemmy.events.ChangeNSFWEvent; | ||||
| import eu.toldi.infinityforlemmy.events.SwitchAccountEvent; | ||||
| import eu.toldi.infinityforlemmy.fragments.CommentsListingFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.HistoryPostFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.PostFragment; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
|  | ||||
| public class HistoryActivity extends BaseActivity implements ActivityToolbarInterface, | ||||
|         PostLayoutBottomSheetFragment.PostLayoutSelectionCallback { | ||||
|  | ||||
|     @BindView(R.id.coordinator_layout_history_activity) | ||||
|     CoordinatorLayout coordinatorLayout; | ||||
|     @BindView(R.id.appbar_layout_history_activity) | ||||
|     AppBarLayout appBarLayout; | ||||
|     @BindView(R.id.collapsing_toolbar_layout_history_activity) | ||||
|     CollapsingToolbarLayout collapsingToolbarLayout; | ||||
|     @BindView(R.id.toolbar_history_activity) | ||||
|     Toolbar toolbar; | ||||
|     @BindView(R.id.tab_layout_tab_layout_history_activity_activity) | ||||
|     TabLayout tabLayout; | ||||
|     @BindView(R.id.view_pager_history_activity) | ||||
|     ViewPager2 viewPager2; | ||||
|     @Inject | ||||
|     @Named("default") | ||||
|     SharedPreferences mSharedPreferences; | ||||
|     @Inject | ||||
|     @Named("post_layout") | ||||
|     SharedPreferences mPostLayoutSharedPreferences; | ||||
|     @Inject | ||||
|     @Named("current_account") | ||||
|     SharedPreferences mCurrentAccountSharedPreferences; | ||||
|     @Inject | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     private FragmentManager fragmentManager; | ||||
|     private SectionsPagerAdapter sectionsPagerAdapter; | ||||
|     private String mAccessToken; | ||||
|     private String mAccountName; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         ((Infinity) getApplication()).getAppComponent().inject(this); | ||||
|  | ||||
|         super.onCreate(savedInstanceState); | ||||
|  | ||||
|         setContentView(R.layout.activity_history); | ||||
|  | ||||
|         ButterKnife.bind(this); | ||||
|  | ||||
|         EventBus.getDefault().register(this); | ||||
|  | ||||
|         applyCustomTheme(); | ||||
|  | ||||
|         if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { | ||||
|             mSliderPanel = Slidr.attach(this); | ||||
|         } | ||||
|  | ||||
|         //mViewPager2 = viewPager2; | ||||
|  | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | ||||
|             Window window = getWindow(); | ||||
|  | ||||
|             if (isChangeStatusBarIconColor()) { | ||||
|                 addOnOffsetChangedListener(appBarLayout); | ||||
|             } | ||||
|  | ||||
|             if (isImmersiveInterface()) { | ||||
|                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { | ||||
|                     window.setDecorFitsSystemWindows(false); | ||||
|                 } else { | ||||
|                     window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); | ||||
|                 } | ||||
|                 adjustToolbar(toolbar); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         setSupportActionBar(toolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|         setToolbarGoToTop(toolbar); | ||||
|  | ||||
|         fragmentManager = getSupportFragmentManager(); | ||||
|  | ||||
|         mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); | ||||
|         mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); | ||||
|  | ||||
|         initializeViewPager(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onKeyDown(int keyCode, KeyEvent event) { | ||||
|         if (sectionsPagerAdapter != null) { | ||||
|             return sectionsPagerAdapter.handleKeyDown(keyCode) || super.onKeyDown(keyCode, event); | ||||
|         } | ||||
|  | ||||
|         return super.onKeyDown(keyCode, event); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public SharedPreferences getDefaultSharedPreferences() { | ||||
|         return mSharedPreferences; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected CustomThemeWrapper getCustomThemeWrapper() { | ||||
|         return mCustomThemeWrapper; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void applyCustomTheme() { | ||||
|         coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar); | ||||
|         applyTabLayoutTheme(tabLayout); | ||||
|     } | ||||
|  | ||||
|     private void initializeViewPager() { | ||||
|         sectionsPagerAdapter = new SectionsPagerAdapter(this); | ||||
|         tabLayout.setVisibility(View.GONE); | ||||
|         viewPager2.setAdapter(sectionsPagerAdapter); | ||||
|         viewPager2.setOffscreenPageLimit(2); | ||||
|         //viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); | ||||
|         viewPager2.setUserInputEnabled(false); | ||||
|         /*new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { | ||||
|             switch (position) { | ||||
|                 case 0: | ||||
|                     Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.posts)); | ||||
|                     break; | ||||
|             } | ||||
|         }).attach();*/ | ||||
|  | ||||
|         viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { | ||||
|             @Override | ||||
|             public void onPageSelected(int position) { | ||||
|                 if (position == 0) { | ||||
|                     unlockSwipeRightToGoBack(); | ||||
|                 } else { | ||||
|                     lockSwipeRightToGoBack(); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         fixViewPager2Sensitivity(viewPager2); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onCreateOptionsMenu(Menu menu) { | ||||
|         getMenuInflater().inflate(R.menu.history_activity, menu); | ||||
|         applyMenuItemTheme(menu); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(@NonNull MenuItem item) { | ||||
|         int itemId = item.getItemId(); | ||||
|         if (itemId == android.R.id.home) { | ||||
|             finish(); | ||||
|             return true; | ||||
|         } else if (itemId == R.id.action_refresh_history_activity) { | ||||
|             sectionsPagerAdapter.refresh(); | ||||
|             return true; | ||||
|         } else if (itemId == R.id.action_change_post_layout_history_activity) { | ||||
|             PostLayoutBottomSheetFragment postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); | ||||
|             postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); | ||||
|             return true; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onDestroy() { | ||||
|         super.onDestroy(); | ||||
|         EventBus.getDefault().unregister(this); | ||||
|     } | ||||
|  | ||||
|     @Subscribe | ||||
|     public void onAccountSwitchEvent(SwitchAccountEvent event) { | ||||
|         finish(); | ||||
|     } | ||||
|  | ||||
|     @Subscribe | ||||
|     public void onChangeNSFWEvent(ChangeNSFWEvent changeNSFWEvent) { | ||||
|         sectionsPagerAdapter.changeNSFW(changeNSFWEvent.nsfw); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onLongPress() { | ||||
|         if (sectionsPagerAdapter != null) { | ||||
|             sectionsPagerAdapter.goBackToTop(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void lockSwipeRightToGoBack() { | ||||
|         if (mSliderPanel != null) { | ||||
|             mSliderPanel.lock(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void unlockSwipeRightToGoBack() { | ||||
|         if (mSliderPanel != null) { | ||||
|             mSliderPanel.unlock(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void postLayoutSelected(int postLayout) { | ||||
|         if (sectionsPagerAdapter != null) { | ||||
|             mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.HISTORY_POST_LAYOUT_READ_POST, postLayout).apply(); | ||||
|             sectionsPagerAdapter.changePostLayout(postLayout); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private class SectionsPagerAdapter extends FragmentStateAdapter { | ||||
|  | ||||
|         SectionsPagerAdapter(FragmentActivity fa) { | ||||
|             super(fa); | ||||
|         } | ||||
|  | ||||
|         @NonNull | ||||
|         @Override | ||||
|         public Fragment createFragment(int position) { | ||||
|             if (position == 0) { | ||||
|                 HistoryPostFragment fragment = new HistoryPostFragment(); | ||||
|                 Bundle bundle = new Bundle(); | ||||
|                 bundle.putInt(HistoryPostFragment.EXTRA_HISTORY_TYPE, HistoryPostFragment.HISTORY_TYPE_READ_POSTS); | ||||
|                 bundle.putString(HistoryPostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
|                 bundle.putString(HistoryPostFragment.EXTRA_ACCOUNT_NAME, mAccountName); | ||||
|                 fragment.setArguments(bundle); | ||||
|                 return fragment; | ||||
|             } else { | ||||
|                 HistoryPostFragment fragment = new HistoryPostFragment(); | ||||
|                 Bundle bundle = new Bundle(); | ||||
|                 bundle.putInt(HistoryPostFragment.EXTRA_HISTORY_TYPE, HistoryPostFragment.HISTORY_TYPE_READ_POSTS); | ||||
|                 bundle.putString(HistoryPostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
|                 bundle.putString(HistoryPostFragment.EXTRA_ACCOUNT_NAME, mAccountName); | ||||
|                 fragment.setArguments(bundle); | ||||
|                 return fragment; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         @Nullable | ||||
|         private Fragment getCurrentFragment() { | ||||
|             if (viewPager2 == null || fragmentManager == null) { | ||||
|                 return null; | ||||
|             } | ||||
|             return fragmentManager.findFragmentByTag("f" + viewPager2.getCurrentItem()); | ||||
|         } | ||||
|  | ||||
|         public boolean handleKeyDown(int keyCode) { | ||||
|             if (viewPager2.getCurrentItem() == 0) { | ||||
|                 Fragment fragment = getCurrentFragment(); | ||||
|                 if (fragment instanceof PostFragment) { | ||||
|                     return ((PostFragment) fragment).handleKeyDown(keyCode); | ||||
|                 } | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         public void refresh() { | ||||
|             Fragment fragment = getCurrentFragment(); | ||||
|             if (fragment instanceof PostFragment) { | ||||
|                 ((PostFragment) fragment).refresh(); | ||||
|             } else if (fragment instanceof CommentsListingFragment) { | ||||
|                 ((CommentsListingFragment) fragment).refresh(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void changeNSFW(boolean nsfw) { | ||||
|             Fragment fragment = getCurrentFragment(); | ||||
|             if (fragment instanceof PostFragment) { | ||||
|                 ((PostFragment) fragment).changeNSFW(nsfw); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void changePostLayout(int postLayout) { | ||||
|             Fragment fragment = getCurrentFragment(); | ||||
|             if (fragment instanceof HistoryPostFragment) { | ||||
|                 ((HistoryPostFragment) fragment).changePostLayout(postLayout); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         public void goBackToTop() { | ||||
|             Fragment fragment = getCurrentFragment(); | ||||
|             if (fragment instanceof PostFragment) { | ||||
|                 ((PostFragment) fragment).goBackToTop(); | ||||
|             } else if (fragment instanceof CommentsListingFragment) { | ||||
|                 ((CommentsListingFragment) fragment).goBackToTop(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public int getItemCount() { | ||||
|             return 1; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -47,7 +47,6 @@ import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RecyclerViewContentScrollingInterface; | ||||
| import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| import eu.toldi.infinityforlemmy.RetrofitHolder; | ||||
| import eu.toldi.infinityforlemmy.apis.RedditAPI; | ||||
| import eu.toldi.infinityforlemmy.asynctasks.SwitchAccount; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.customviews.slidr.Slidr; | ||||
| @@ -56,14 +55,12 @@ import eu.toldi.infinityforlemmy.events.PassPrivateMessageEvent; | ||||
| import eu.toldi.infinityforlemmy.events.PassPrivateMessageIndexEvent; | ||||
| import eu.toldi.infinityforlemmy.events.SwitchAccountEvent; | ||||
| import eu.toldi.infinityforlemmy.fragments.InboxFragment; | ||||
| import eu.toldi.infinityforlemmy.fragments.PrivateMessageFragment; | ||||
| import eu.toldi.infinityforlemmy.message.CommentInteraction; | ||||
| import eu.toldi.infinityforlemmy.message.FetchMessage; | ||||
| import eu.toldi.infinityforlemmy.message.Message; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| import eu.toldi.infinityforlemmy.message.ReadMessage; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
| import retrofit2.Call; | ||||
| import retrofit2.Callback; | ||||
| import retrofit2.Response; | ||||
|  | ||||
| public class InboxActivity extends BaseActivity implements ActivityToolbarInterface, RecyclerViewContentScrollingInterface { | ||||
|  | ||||
| @@ -184,7 +181,7 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf | ||||
|                 if (i == EditorInfo.IME_ACTION_DONE) { | ||||
|                     Utils.hideKeyboard(this); | ||||
|                     Intent pmIntent = new Intent(this, SendPrivateMessageActivity.class); | ||||
|                     pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, thingEditText.getText().toString()); | ||||
|                     //pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, thingEditText.getText().toString()); | ||||
|                     startActivity(pmIntent); | ||||
|                     return true; | ||||
|                 } | ||||
| @@ -197,7 +194,7 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf | ||||
|                             -> { | ||||
|                         Utils.hideKeyboard(this); | ||||
|                         Intent pmIntent = new Intent(this, SendPrivateMessageActivity.class); | ||||
|                         pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, thingEditText.getText().toString()); | ||||
|                         //pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, thingEditText.getText().toString()); | ||||
|                         startActivity(pmIntent); | ||||
|                     }) | ||||
|                     .setNegativeButton(R.string.cancel, null) | ||||
| @@ -229,7 +226,7 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf | ||||
|         mCoordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(mAppBarLayout, mCollapsingToolbarLayout, mToolbar); | ||||
|         applyTabLayoutTheme(tabLayout); | ||||
|         applyFABTheme(fab); | ||||
|         applyFABTheme(fab, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|     } | ||||
|  | ||||
|     private void getCurrentAccountAndFetchMessage(Bundle savedInstanceState) { | ||||
| @@ -268,13 +265,16 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf | ||||
|             } | ||||
|         }); | ||||
|         viewPager2.setAdapter(sectionsPagerAdapter); | ||||
|         viewPager2.setOffscreenPageLimit(2); | ||||
|         viewPager2.setOffscreenPageLimit(3); | ||||
|         new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { | ||||
|             switch (position) { | ||||
|                 case 0: | ||||
|                     Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.notifications)); | ||||
|                     Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.replies)); | ||||
|                     break; | ||||
|                 case 1: | ||||
|                     Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.mentions)); | ||||
|                     break; | ||||
|                 case 2: | ||||
|                     Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.messages)); | ||||
|                     break; | ||||
|             } | ||||
| @@ -302,31 +302,21 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf | ||||
|             return true; | ||||
|         } else if (item.getItemId() == R.id.action_read_all_messages_inbox_activity) { | ||||
|             if (mAccessToken != null) { | ||||
|                 Toast.makeText(this, R.string.please_wait, Toast.LENGTH_SHORT).show(); | ||||
|                 mRetrofit.getRetrofit().create(RedditAPI.class).readAllMessages(APIUtils.getOAuthHeader(mAccessToken)) | ||||
|                         .enqueue(new Callback<>() { | ||||
|                             @Override | ||||
|                             public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { | ||||
|                                 if (response.isSuccessful()) { | ||||
|                                     Toast.makeText(InboxActivity.this, R.string.read_all_messages_success, Toast.LENGTH_SHORT).show(); | ||||
|                                     if (sectionsPagerAdapter != null) { | ||||
|                                         sectionsPagerAdapter.readAllMessages(); | ||||
|                                     } | ||||
|                                     EventBus.getDefault().post(new ChangeInboxCountEvent(0)); | ||||
|                                 } else { | ||||
|                                     if (response.code() == 429) { | ||||
|                                         Toast.makeText(InboxActivity.this, R.string.read_all_messages_time_limit, Toast.LENGTH_LONG).show(); | ||||
|                                     } else { | ||||
|                                         Toast.makeText(InboxActivity.this, R.string.read_all_messages_failed, Toast.LENGTH_LONG).show(); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 ReadMessage.readAllMessages(mRetrofit.getRetrofit(), mAccessToken, new ReadMessage.ReadMessageListener() { | ||||
|                     @Override | ||||
|                     public void readSuccess() { | ||||
|                         Toast.makeText(InboxActivity.this, R.string.read_all_messages_success, Toast.LENGTH_SHORT).show(); | ||||
|                         if (sectionsPagerAdapter != null) { | ||||
|                             sectionsPagerAdapter.readAllMessages(); | ||||
|                         } | ||||
|                         EventBus.getDefault().post(new ChangeInboxCountEvent(0)); | ||||
|                     } | ||||
|  | ||||
|                             @Override | ||||
|                             public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { | ||||
|                                 Toast.makeText(InboxActivity.this, R.string.read_all_messages_failed, Toast.LENGTH_LONG).show(); | ||||
|                             } | ||||
|                         }); | ||||
|                     @Override | ||||
|                     public void readFailed() { | ||||
|  | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } else if (item.getItemId() == android.R.id.home) { | ||||
|             finish(); | ||||
| @@ -341,7 +331,7 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf | ||||
|         if (resultCode == RESULT_OK && requestCode == SEARCH_USER_REQUEST_CODE && data != null) { | ||||
|             String username = data.getStringExtra(SearchActivity.EXTRA_RETURN_USER_NAME); | ||||
|             Intent intent = new Intent(this, SendPrivateMessageActivity.class); | ||||
|             intent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, username); | ||||
|             //intent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, username); | ||||
|             startActivity(intent); | ||||
|         } | ||||
|     } | ||||
| @@ -438,7 +428,7 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         Message getPrivateMessage(int index) { | ||||
|         CommentInteraction getPrivateMessage(int index) { | ||||
|             if (viewPager2 == null || fragmentManager == null) { | ||||
|                 return null; | ||||
|             } | ||||
| @@ -452,26 +442,27 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf | ||||
|         @NonNull | ||||
|         @Override | ||||
|         public Fragment createFragment(int position) { | ||||
|             if (position == 0) { | ||||
|                 InboxFragment fragment = new InboxFragment(); | ||||
|                 Bundle bundle = new Bundle(); | ||||
|                 bundle.putString(InboxFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
|                 bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_INBOX); | ||||
|                 fragment.setArguments(bundle); | ||||
|                 return fragment; | ||||
|             } else { | ||||
|                 InboxFragment fragment = new InboxFragment(); | ||||
|                 Bundle bundle = new Bundle(); | ||||
|                 bundle.putString(InboxFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
|                 bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_MESSAGES); | ||||
|                 fragment.setArguments(bundle); | ||||
|                 return fragment; | ||||
|             Fragment fragment = new InboxFragment(); | ||||
|             Bundle bundle = new Bundle(); | ||||
|             bundle.putString(InboxFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
|             switch (position) { | ||||
|                 case 0: | ||||
|                     bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_REPLIES); | ||||
|                     break; | ||||
|                 case 1: | ||||
|                     bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_MENTIONS); | ||||
|                     break; | ||||
|                 case 2: | ||||
|                     fragment = new PrivateMessageFragment(); | ||||
|                     break; | ||||
|             } | ||||
|             fragment.setArguments(bundle); | ||||
|             return fragment; | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public int getItemCount() { | ||||
|             return 2; | ||||
|             return 3; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,266 @@ | ||||
| package eu.toldi.infinityforlemmy.activities; | ||||
|  | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.graphics.Color; | ||||
| import android.graphics.PorterDuff; | ||||
| import android.net.Uri; | ||||
| import android.os.Bundle; | ||||
| import android.text.Spanned; | ||||
| import android.util.Log; | ||||
| import android.view.MenuItem; | ||||
| import android.view.View; | ||||
| import android.widget.ImageView; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.appcompat.widget.Toolbar; | ||||
| import androidx.constraintlayout.widget.ConstraintLayout; | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout; | ||||
| import androidx.recyclerview.widget.LinearLayoutManager; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| import com.google.android.material.appbar.AppBarLayout; | ||||
| import com.google.android.material.card.MaterialCardView; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RetrofitHolder; | ||||
| import eu.toldi.infinityforlemmy.adapters.AdminRecyclerViewAdapter; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; | ||||
| import eu.toldi.infinityforlemmy.customviews.slidr.Slidr; | ||||
| import eu.toldi.infinityforlemmy.databinding.ActivityInstanceInfoBinding; | ||||
| import eu.toldi.infinityforlemmy.markdown.MarkdownUtils; | ||||
| import eu.toldi.infinityforlemmy.site.FetchSiteInfo; | ||||
| import eu.toldi.infinityforlemmy.site.SiteInfo; | ||||
| import eu.toldi.infinityforlemmy.site.SiteStatistics; | ||||
| import eu.toldi.infinityforlemmy.user.BasicUserInfo; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import io.noties.markwon.AbstractMarkwonPlugin; | ||||
| import io.noties.markwon.Markwon; | ||||
| import io.noties.markwon.MarkwonConfiguration; | ||||
| import io.noties.markwon.MarkwonPlugin; | ||||
| import io.noties.markwon.core.MarkwonTheme; | ||||
| import io.noties.markwon.recycler.MarkwonAdapter; | ||||
|  | ||||
| public class InstanceInfoActivity extends BaseActivity { | ||||
|  | ||||
|     @Inject | ||||
|     @Named("default") | ||||
|     SharedPreferences mSharedPreferences; | ||||
|  | ||||
|     @Inject | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|  | ||||
|     @Inject | ||||
|     @Named("no_oauth") | ||||
|     RetrofitHolder mRetorifitHolder; | ||||
|  | ||||
|     ActivityInstanceInfoBinding mInstanceInfoActivityViewBinding; | ||||
|     private CoordinatorLayout coordinatorLayout; | ||||
|     private Toolbar toolbar; | ||||
|     private AppBarLayout appBarLayout; | ||||
|  | ||||
|     private ConstraintLayout mLoadingConstraintLayout; | ||||
|  | ||||
|     private MaterialCardView mStatisticsCardView; | ||||
|  | ||||
|     private TextView mUsersTextView; | ||||
|     private TextView mCommunitiesTextView; | ||||
|     private TextView mPostsTextView; | ||||
|     private TextView mCommentsTextView; | ||||
|     private TextView mActiveUsersTextView; | ||||
|     private ImageView mUsersImageView; | ||||
|     private ImageView mCommunitiesImageView; | ||||
|     private ImageView mPostsImageView; | ||||
|     private ImageView mCommentsImageView; | ||||
|     private ImageView mActiveUsersImageView; | ||||
|  | ||||
|     private MaterialCardView mDescriptionCardView; | ||||
|  | ||||
|     private RecyclerView mContentMarkdownView; | ||||
|     private RecyclerView mAdminsRecyclerView; | ||||
|  | ||||
|     private MaterialCardView mAdminsCardView; | ||||
|     private MarkwonAdapter mMarkwonAdapter; | ||||
|     private Markwon mPostDetailMarkwon; | ||||
|     private AdminRecyclerViewAdapter mAdminAdapter; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(@Nullable Bundle savedInstanceState) { | ||||
|         ((Infinity) getApplication()).getAppComponent().inject(this); | ||||
|         super.onCreate(savedInstanceState); | ||||
|         mInstanceInfoActivityViewBinding = ActivityInstanceInfoBinding.inflate(getLayoutInflater()); | ||||
|         View view = mInstanceInfoActivityViewBinding.getRoot(); | ||||
|         setImmersiveModeNotApplicable(); | ||||
|  | ||||
|         setContentView(view); | ||||
|         setSupportActionBar(mInstanceInfoActivityViewBinding.toolbarInstanceInfoActivity); | ||||
|  | ||||
|         setUpBindings(); | ||||
|         applyCustomTheme(); | ||||
|  | ||||
|         if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { | ||||
|             Slidr.attach(this); | ||||
|         } | ||||
|  | ||||
|         setSupportActionBar(toolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|  | ||||
|         // Remove transparency from navigation bar | ||||
|         getWindow().setNavigationBarColor(mCustomThemeWrapper.getBackgroundColor()); | ||||
|  | ||||
|         int markdownColor = customThemeWrapper.getPostContentColor(); | ||||
|         int postSpoilerBackgroundColor = markdownColor | 0xFF000000; | ||||
|         int linkColor = customThemeWrapper.getLinkColor(); | ||||
|  | ||||
|  | ||||
|         MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() { | ||||
|             @Override | ||||
|             public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { | ||||
|                 if (InstanceInfoActivity.this.contentTypeface != null) { | ||||
|                     textView.setTypeface(InstanceInfoActivity.this.contentTypeface); | ||||
|                 } | ||||
|                 textView.setTextColor(markdownColor); | ||||
|                 textView.setHighlightColor(Color.TRANSPARENT); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { | ||||
|                 builder.linkResolver((view, link) -> { | ||||
|                     Intent intent = new Intent(InstanceInfoActivity.this, LinkResolverActivity.class); | ||||
|                     Uri uri = Uri.parse(link); | ||||
|                     intent.setData(uri); | ||||
|                     InstanceInfoActivity.this.startActivity(intent); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void configureTheme(@NonNull MarkwonTheme.Builder builder) { | ||||
|                 builder.linkColor(linkColor); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         mPostDetailMarkwon = MarkdownUtils.createFullRedditMarkwon(this, | ||||
|                 miscPlugin, markdownColor, postSpoilerBackgroundColor, null, mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false)); | ||||
|         mMarkwonAdapter = MarkdownUtils.createTablesAdapter(); | ||||
|         mContentMarkdownView.setAdapter(mMarkwonAdapter); | ||||
|         LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); | ||||
|         mContentMarkdownView.setLayoutManager(linearLayoutManager); | ||||
|         mAdminAdapter = new AdminRecyclerViewAdapter(InstanceInfoActivity.this, customThemeWrapper); | ||||
|         mAdminsRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(InstanceInfoActivity.this)); | ||||
|         mAdminsRecyclerView.setAdapter(mAdminAdapter); | ||||
|  | ||||
|         fetchInstanceInfo(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onStart() { | ||||
|         super.onStart(); | ||||
|         fetchInstanceInfo(); | ||||
|     } | ||||
|  | ||||
|     private void fetchInstanceInfo() { | ||||
|         FetchSiteInfo.fetchSiteInfo(mRetorifitHolder.getRetrofit(), null, new FetchSiteInfo.FetchSiteInfoListener() { | ||||
|             @Override | ||||
|             public void onFetchSiteInfoSuccess(SiteInfo siteInfo) { | ||||
|                 mLoadingConstraintLayout.setVisibility(View.GONE); | ||||
|                 toolbar.setTitle(siteInfo.getName()); | ||||
|                 if (siteInfo.getSidebar() != null) { | ||||
|                     mMarkwonAdapter.setMarkdown(mPostDetailMarkwon, siteInfo.getSidebar()); | ||||
|                     Log.i("SiteInfo", "onFetchSiteInfoSuccess: " + siteInfo.getSidebar()); | ||||
|                     // noinspection NotifyDataSetChanged | ||||
|                     mMarkwonAdapter.notifyDataSetChanged(); | ||||
|                     mDescriptionCardView.setVisibility(View.VISIBLE); | ||||
|                 } | ||||
|                 List<BasicUserInfo> admins = siteInfo.getAdmins(); | ||||
|                 if (admins != null && !admins.isEmpty()) { | ||||
|                     mAdminsCardView.setVisibility(View.VISIBLE); | ||||
|                     mAdminAdapter.setUsers(admins); | ||||
|                 } | ||||
|                 SiteStatistics siteStatistics = siteInfo.getSiteStatistics(); | ||||
|                 if (siteStatistics != null) { | ||||
|                     mStatisticsCardView.setVisibility(View.VISIBLE); | ||||
|                     mUsersTextView.setText(getString(R.string.user_number_detail, siteStatistics.getUsers())); | ||||
|                     mCommunitiesTextView.setText(getString(R.string.community_number_detail, siteStatistics.getCommunities())); | ||||
|                     mPostsTextView.setText(getString(R.string.post_count_detail, siteStatistics.getPosts())); | ||||
|                     mCommentsTextView.setText(getString(R.string.comment_count_detail, siteStatistics.getComments())); | ||||
|                     mActiveUsersTextView.setText(getString(R.string.active_users_number_detail, siteStatistics.getUsers_active())); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onFetchSiteInfoFailed() { | ||||
|  | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     protected void setUpBindings() { | ||||
|         coordinatorLayout = mInstanceInfoActivityViewBinding.coordinatorLayoutInstanceInfoActivity; | ||||
|         toolbar = mInstanceInfoActivityViewBinding.toolbarInstanceInfoActivity; | ||||
|         appBarLayout = mInstanceInfoActivityViewBinding.appbarLayoutInstanceInfoActivity; | ||||
|         mStatisticsCardView = mInstanceInfoActivityViewBinding.statisticsCardInstanceInfoActivity; | ||||
|         mDescriptionCardView = mInstanceInfoActivityViewBinding.descriptionCardInstanceInfoActivity; | ||||
|         mContentMarkdownView = mInstanceInfoActivityViewBinding.markdownRecyclerViewInstanceInfoActivity; | ||||
|         mAdminsCardView = mInstanceInfoActivityViewBinding.moderatorsCardInstanceInfoActivity; | ||||
|         mLoadingConstraintLayout = mInstanceInfoActivityViewBinding.loadingLayoutInstanceInfoActivity; | ||||
|         mAdminsRecyclerView = mInstanceInfoActivityViewBinding.recyclerViewAdminsInstanceInfoActivity; | ||||
|         mUsersTextView = mInstanceInfoActivityViewBinding.registeredUserCountTextViewInstanceInfoActivity; | ||||
|         mCommunitiesTextView = mInstanceInfoActivityViewBinding.communityCountInstanceInfoActivity; | ||||
|         mPostsTextView = mInstanceInfoActivityViewBinding.postCountTextViewInstanceInfoActivity; | ||||
|         mCommentsTextView = mInstanceInfoActivityViewBinding.commentCountTextViewInstanceInfoActivity; | ||||
|         mActiveUsersTextView = mInstanceInfoActivityViewBinding.activeUserCountTextViewInstanceInfoActivity; | ||||
|         mUsersImageView = mInstanceInfoActivityViewBinding.registeredUserCountImageViewInstanceInfoActivity; | ||||
|         mCommunitiesImageView = mInstanceInfoActivityViewBinding.communitiesIconImageViewInstanceInfoActivity; | ||||
|         mPostsImageView = mInstanceInfoActivityViewBinding.postCountImageViewInstanceInfoActivity; | ||||
|         mCommentsImageView = mInstanceInfoActivityViewBinding.commentCountImageViewInstanceInfoActivity; | ||||
|         mActiveUsersImageView = mInstanceInfoActivityViewBinding.activeUserCountImageViewInstanceInfoActivity; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected SharedPreferences getDefaultSharedPreferences() { | ||||
|         return mSharedPreferences; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected CustomThemeWrapper getCustomThemeWrapper() { | ||||
|         return mCustomThemeWrapper; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void applyCustomTheme() { | ||||
|         coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, null, toolbar); | ||||
|         mStatisticsCardView.setCardBackgroundColor(mCustomThemeWrapper.getCardViewBackgroundColor()); | ||||
|         mDescriptionCardView.setCardBackgroundColor(mCustomThemeWrapper.getCardViewBackgroundColor()); | ||||
|         mAdminsCardView.setCardBackgroundColor(mCustomThemeWrapper.getCardViewBackgroundColor()); | ||||
|         mUsersImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN); | ||||
|         mCommunitiesImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN); | ||||
|         mPostsImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN); | ||||
|         mCommentsImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN); | ||||
|         mActiveUsersImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN); | ||||
|         mUsersTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|         mCommunitiesTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|         mPostsTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|         mCommentsTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|         mActiveUsersTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(MenuItem item) { | ||||
|         if (item.getItemId() == android.R.id.home) { | ||||
|             finish(); | ||||
|             return true; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
| @@ -7,6 +7,7 @@ import android.content.pm.PackageManager; | ||||
| import android.content.pm.ResolveInfo; | ||||
| import android.net.Uri; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.webkit.URLUtil; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| @@ -17,15 +18,25 @@ import androidx.browser.customtabs.CustomTabsService; | ||||
|  | ||||
| import org.apache.commons.io.FilenameUtils; | ||||
|  | ||||
| import java.net.MalformedURLException; | ||||
| import java.net.URL; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RetrofitHolder; | ||||
| import eu.toldi.infinityforlemmy.comment.Comment; | ||||
| import eu.toldi.infinityforlemmy.comment.FetchComment; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.post.FetchPost; | ||||
| import eu.toldi.infinityforlemmy.post.ObjectResolver; | ||||
| import eu.toldi.infinityforlemmy.post.Post; | ||||
| import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; | ||||
| import eu.toldi.infinityforlemmy.utils.LemmyUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
|  | ||||
| @@ -35,10 +46,9 @@ public class LinkResolverActivity extends AppCompatActivity { | ||||
|     public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; | ||||
|     public static final String EXTRA_IS_NSFW = "EIN"; | ||||
|  | ||||
|     private static final String POST_PATTERN = "/r/[\\w-]+/comments/\\w+/?\\w+/?"; | ||||
|     private static final String POST_PATTERN_2 = "/(u|U|user)/[\\w-]+/comments/\\w+/?\\w+/?"; | ||||
|     private static final String POST_PATTERN = "https?:\\/\\/\\S+\\/post\\/\\d+"; | ||||
|     private static final String POST_PATTERN_3 = "/[\\w-]+$"; | ||||
|     private static final String COMMENT_PATTERN = "/(r|u|U|user)/[\\w-]+/comments/\\w+/?[\\w-]+/\\w+/?"; | ||||
|     private static final String COMMENT_PATTERN = "https?:\\/\\/\\S+\\/comment\\/\\d+"; | ||||
|     private static final String SUBREDDIT_PATTERN = "(?:https?://[\\w.-]+)?/c/[\\w-]+(@[\\w.-]+)?"; | ||||
|     private static final String USER_PATTERN = "(?:https?://[\\w.-]+)?/u(sers)?/[\\w-]+(@[\\w.-]+)?"; | ||||
|     private static final String SIDEBAR_PATTERN = "/[rR]/[\\w-]+/about/sidebar"; | ||||
| @@ -60,11 +70,30 @@ public class LinkResolverActivity extends AppCompatActivity { | ||||
|     @Inject | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|  | ||||
|     @Inject | ||||
|     ObjectResolver mObjectResolver; | ||||
|  | ||||
|     @Inject | ||||
|     @Named("current_account") | ||||
|     SharedPreferences mCurrentAccountSharedPreferences; | ||||
|  | ||||
|     @Inject | ||||
|     @Named("no_oauth") | ||||
|     RetrofitHolder mRetrofit; | ||||
|  | ||||
|     @Inject | ||||
|     Executor mExecutor; | ||||
|  | ||||
|     @Inject | ||||
|     PostEnricher postEnricher; | ||||
|  | ||||
|     private String mAccessToken; | ||||
|  | ||||
|     private Uri getRedditUriByPath(String path) { | ||||
|         if (path.charAt(0) != '/') { | ||||
|             return Uri.parse("https://www.reddit.com/" + path); | ||||
|             return Uri.parse(mRetrofit.getBaseURL() + path); | ||||
|         } else { | ||||
|             return Uri.parse("https://www.reddit.com" + path); | ||||
|             return Uri.parse(mRetrofit.getBaseURL() + path); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -73,19 +102,27 @@ public class LinkResolverActivity extends AppCompatActivity { | ||||
|         super.onCreate(savedInstanceState); | ||||
|  | ||||
|         ((Infinity) getApplication()).getAppComponent().inject(this); | ||||
|         mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); | ||||
|         if (mAccessToken != null) { | ||||
|             String instance = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_INSTANCE, null); | ||||
|             mRetrofit.setBaseURL(instance); | ||||
|             if (mCurrentAccountSharedPreferences.getBoolean(SharedPreferencesUtils.BEARER_TOKEN_AUTH, true)) { | ||||
|                 mRetrofit.setAccessToken(mAccessToken); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         Uri uri = getIntent().getData(); | ||||
|         if (uri == null) { | ||||
|             String url = getIntent().getStringExtra(Intent.EXTRA_TEXT); | ||||
|             if (!URLUtil.isValidUrl(url)) { | ||||
|                 Toast.makeText(this, R.string.invalid_link, Toast.LENGTH_SHORT).show(); | ||||
|                 Toast.makeText(getApplicationContext(), R.string.invalid_link, Toast.LENGTH_SHORT).show(); | ||||
|                 finish(); | ||||
|                 return; | ||||
|             } | ||||
|             try { | ||||
|                 uri = Uri.parse(url); | ||||
|             } catch (NullPointerException e) { | ||||
|                 Toast.makeText(this, R.string.invalid_link, Toast.LENGTH_SHORT).show(); | ||||
|                 Toast.makeText(getApplicationContext(), R.string.invalid_link, Toast.LENGTH_SHORT).show(); | ||||
|                 finish(); | ||||
|                 return; | ||||
|             } | ||||
| @@ -93,7 +130,7 @@ public class LinkResolverActivity extends AppCompatActivity { | ||||
|  | ||||
|         if (uri.getScheme() == null && uri.getHost() == null) { | ||||
|             if (uri.toString().isEmpty()) { | ||||
|                 Toast.makeText(this, R.string.invalid_link, Toast.LENGTH_SHORT).show(); | ||||
|                 Toast.makeText(getApplicationContext(), R.string.invalid_link, Toast.LENGTH_SHORT).show(); | ||||
|                 finish(); | ||||
|                 return; | ||||
|             } | ||||
| @@ -105,7 +142,7 @@ public class LinkResolverActivity extends AppCompatActivity { | ||||
|  | ||||
|     private void handleUri(Uri uri) { | ||||
|         if (uri == null) { | ||||
|             Toast.makeText(this, R.string.no_link_available, Toast.LENGTH_SHORT).show(); | ||||
|             Toast.makeText(getApplicationContext(), R.string.no_link_available, Toast.LENGTH_SHORT).show(); | ||||
|         } else { | ||||
|             String path = uri.getPath(); | ||||
|             if (path == null) { | ||||
| @@ -169,92 +206,142 @@ public class LinkResolverActivity extends AppCompatActivity { | ||||
|                             intent.putExtra(ViewUserDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); | ||||
|                             intent.putExtra(ViewUserDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); | ||||
|                             startActivity(intent); | ||||
|                         } else if (uri.toString().matches(POST_PATTERN)) { | ||||
|                             if (mAccessToken == null) { | ||||
|                                 // switch retrofit to use the current instance for anonymous requests | ||||
|                                 mRetrofit.setBaseURL(uri.getScheme() + "://" + uri.getHost() + "/"); | ||||
|                                 Intent intent = new Intent(LinkResolverActivity.this, ViewPostDetailActivity.class); | ||||
|                                 intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, Integer.parseInt(segments.get(segments.size() - 1))); | ||||
|                                 intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); | ||||
|                                 intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); | ||||
|                                 startActivity(intent); | ||||
|                             } else { | ||||
|                                 boolean local = false; | ||||
|                                 try { | ||||
|                                     URL baseURL = new URL(mRetrofit.getBaseURL()); | ||||
|                                     if (baseURL.getHost().equalsIgnoreCase(uri.getHost())) { | ||||
|                                         local = true; | ||||
|                                         FetchPost.fetchPost(mExecutor, new Handler(), mRetrofit.getRetrofit(), segments.get(segments.size() - 1), mAccessToken, postEnricher, new FetchPost.FetchPostListener() { | ||||
|                                             @Override | ||||
|                                             public void fetchPostSuccess(Post post) { | ||||
|  | ||||
|                                                 Intent intent = new Intent(LinkResolverActivity.this, ViewPostDetailActivity.class); | ||||
|                                                 intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, post.getId()); | ||||
|                                                 intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); | ||||
|                                                 intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); | ||||
|                                                 startActivity(intent); | ||||
|                                             } | ||||
|  | ||||
|                                             @Override | ||||
|                                             public void fetchPostFailed() { | ||||
|                                                 Toast.makeText(getApplicationContext(), R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show(); | ||||
|                                                 finish(); | ||||
|                                             } | ||||
|                                         }); | ||||
|                                     } | ||||
|                                 } catch (MalformedURLException e) { | ||||
|                                     Toast.makeText(getApplicationContext(), R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show(); | ||||
|                                     finish(); | ||||
|                                 } | ||||
|                                 if (!local) { | ||||
|                                     mObjectResolver.resolvePost(uri.toString(), mAccessToken, new ObjectResolver.ObjectResolverListener() { | ||||
|                                         @Override | ||||
|                                         public void onResolveObjectSuccess(Object p) { | ||||
|                                             Post post = (Post) p; | ||||
|                                             Intent intent = new Intent(LinkResolverActivity.this, ViewPostDetailActivity.class); | ||||
|                                             intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, post.getId()); | ||||
|                                             intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); | ||||
|                                             intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); | ||||
|                                             startActivity(intent); | ||||
|                                         } | ||||
|  | ||||
|                                         @Override | ||||
|                                         public void onResolveObjectFailed() { | ||||
|                                             Toast.makeText(getApplicationContext(), R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show(); | ||||
|                                             finish(); | ||||
|                                         } | ||||
|                                     }); | ||||
|                                 } | ||||
|                             } | ||||
|                         } else if (uri.toString().matches(COMMENT_PATTERN)) { | ||||
|                             if (mAccessToken == null) { | ||||
|                                 mRetrofit.setBaseURL(uri.getScheme() + "://" + uri.getHost() + "/"); | ||||
|                                 FetchComment.fetchSingleComment(mRetrofit.getRetrofit(), null, Integer.parseInt(segments.get(segments.size() - 1)), new FetchComment.FetchCommentListener() { | ||||
|                                     @Override | ||||
|                                     public void onFetchCommentSuccess(ArrayList<Comment> comments, Integer parentId, ArrayList<Integer> moreChildrenIds) { | ||||
|                                         Intent intent = new Intent(LinkResolverActivity.this, ViewPostDetailActivity.class); | ||||
|                                         Comment comment = comments.get(0); | ||||
|                                         intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, comment.getPostId()); | ||||
|                                         intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); | ||||
|                                         intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); | ||||
|                                         intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, comment.getId()); | ||||
|                                         intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_PARENT_ID, comment.getParentId()); | ||||
|                                         startActivity(intent); | ||||
|                                     } | ||||
|  | ||||
|                                     @Override | ||||
|                                     public void onFetchCommentFailed() { | ||||
|                                         Toast.makeText(getApplicationContext(), R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show(); | ||||
|                                         finish(); | ||||
|                                     } | ||||
|                                 }); | ||||
|                             } else { | ||||
|                                 boolean local = false; | ||||
|                                 try { | ||||
|                                     URL baseURL = new URL(mRetrofit.getBaseURL()); | ||||
|                                     if (baseURL.getHost().equalsIgnoreCase(uri.getHost())) { | ||||
|                                         local = true; | ||||
|                                         FetchComment.fetchSingleComment(mRetrofit.getRetrofit(), mAccessToken, Integer.parseInt(segments.get(segments.size() - 1)), new FetchComment.FetchCommentListener() { | ||||
|                                             @Override | ||||
|                                             public void onFetchCommentSuccess(ArrayList<Comment> comments, Integer parentId, ArrayList<Integer> moreChildrenIds) { | ||||
|                                                 Intent intent = new Intent(LinkResolverActivity.this, ViewPostDetailActivity.class); | ||||
|                                                 Comment comment = comments.get(0); | ||||
|                                                 intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, comment.getPostId()); | ||||
|                                                 intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); | ||||
|                                                 intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); | ||||
|                                                 intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, comment.getId()); | ||||
|                                                 intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_PARENT_ID, comment.getParentId()); | ||||
|                                                 startActivity(intent); | ||||
|                                             } | ||||
|  | ||||
|                                             @Override | ||||
|                                             public void onFetchCommentFailed() { | ||||
|                                                 Toast.makeText(getApplicationContext(), R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show(); | ||||
|                                                 finish(); | ||||
|                                             } | ||||
|                                         }); | ||||
|                                     } | ||||
|                                 } catch (MalformedURLException e) { | ||||
|                                     Toast.makeText(getApplicationContext(), R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show(); | ||||
|                                     finish(); | ||||
|                                 } | ||||
|                                 if (!local) { | ||||
|                                     mObjectResolver.resolveComment(uri.toString(), mAccessToken, new ObjectResolver.ObjectResolverListener() { | ||||
|                                         @Override | ||||
|                                         public void onResolveObjectSuccess(Object c) { | ||||
|                                             Comment comment = (Comment) c; | ||||
|                                             Intent intent = new Intent(LinkResolverActivity.this, ViewPostDetailActivity.class); | ||||
|                                             intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, comment.getPostId()); | ||||
|                                             intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); | ||||
|                                             intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); | ||||
|                                             intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, comment.getId()); | ||||
|                                             intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_PARENT_ID, comment.getParentId()); | ||||
|                                             startActivity(intent); | ||||
|                                         } | ||||
|  | ||||
|                                         @Override | ||||
|                                         public void onResolveObjectFailed() { | ||||
|                                             Toast.makeText(getApplicationContext(), R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show(); | ||||
|                                             finish(); | ||||
|                                         } | ||||
|                                     }); | ||||
|                                 } | ||||
|                             } | ||||
|                         } else if (authority.equals("v.redd.it")) { | ||||
|                             Intent intent = new Intent(this, ViewVideoActivity.class); | ||||
|                             intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_V_REDD_IT); | ||||
|                             intent.putExtra(ViewVideoActivity.EXTRA_V_REDD_IT_URL, uri.toString()); | ||||
|                             startActivity(intent); | ||||
|                         } else if (authority.contains("reddit.com") || authority.contains("redd.it") || authority.contains("reddit.app")) { | ||||
|                             if (authority.equals("reddit.app.link") && path.isEmpty()) { | ||||
|                                 String redirect = uri.getQueryParameter("$og_redirect"); | ||||
|                                 if (redirect != null) { | ||||
|                                     handleUri(Uri.parse(redirect)); | ||||
|                                 } else { | ||||
|                                     deepLinkError(uri); | ||||
|                                 } | ||||
|                             } else if (path.isEmpty()) { | ||||
|                                 Intent intent = new Intent(this, MainActivity.class); | ||||
|                                 startActivity(intent); | ||||
|                             } else if (path.equals("/report")) { | ||||
|                                 openInWebView(uri); | ||||
|                             } else if (path.matches(POST_PATTERN) || path.matches(POST_PATTERN_2)) { | ||||
|                                 int commentsIndex = segments.lastIndexOf("comments"); | ||||
|                                 if (commentsIndex >= 0 && commentsIndex < segments.size() - 1) { | ||||
|                                     Intent intent = new Intent(this, ViewPostDetailActivity.class); | ||||
|                                     intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, segments.get(commentsIndex + 1)); | ||||
|                                     intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); | ||||
|                                     intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); | ||||
|                                     startActivity(intent); | ||||
|                                 } else { | ||||
|                                     deepLinkError(uri); | ||||
|                                 } | ||||
|                             } else if (path.matches(POST_PATTERN_3)) { | ||||
|                                 Intent intent = new Intent(this, ViewPostDetailActivity.class); | ||||
|                                 intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, path.substring(1)); | ||||
|                                 intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); | ||||
|                                 intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); | ||||
|                                 startActivity(intent); | ||||
|                             } else if (path.matches(COMMENT_PATTERN)) { | ||||
|                                 int commentsIndex = segments.lastIndexOf("comments"); | ||||
|                                 if (commentsIndex >= 0 && commentsIndex < segments.size() - 1) { | ||||
|                                     Intent intent = new Intent(this, ViewPostDetailActivity.class); | ||||
|                                     intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, segments.get(commentsIndex + 1)); | ||||
|                                     intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, segments.get(segments.size() - 1)); | ||||
|                                     intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); | ||||
|                                     intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); | ||||
|                                     startActivity(intent); | ||||
|                                 } else { | ||||
|                                     deepLinkError(uri); | ||||
|                                 } | ||||
|                             } else if (path.matches(WIKI_PATTERN)) { | ||||
|                                 String[] pathSegments = path.split("/"); | ||||
|                                 String wikiPage; | ||||
|                                 if (pathSegments.length == 4) { | ||||
|                                     wikiPage = "index"; | ||||
|                                 } else { | ||||
|                                     int lengthThroughWiki = 0; | ||||
|                                     for (int i = 1; i <= 3; ++i) { | ||||
|                                         lengthThroughWiki += pathSegments[i].length() + 1; | ||||
|                                     } | ||||
|                                     wikiPage = path.substring(lengthThroughWiki); | ||||
|                                 } | ||||
|                                 Intent intent = new Intent(this, WikiActivity.class); | ||||
|                                 intent.putExtra(WikiActivity.EXTRA_SUBREDDIT_NAME, segments.get(1)); | ||||
|                                 intent.putExtra(WikiActivity.EXTRA_WIKI_PATH, wikiPage); | ||||
|                                 startActivity(intent); | ||||
|                             } else if (path.matches(SIDEBAR_PATTERN)) { | ||||
|                                 Intent intent = new Intent(this, ViewSubredditDetailActivity.class); | ||||
|                                 intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, path.substring(3, path.length() - 14)); | ||||
|                                 intent.putExtra(ViewSubredditDetailActivity.EXTRA_VIEW_SIDEBAR, true); | ||||
|                                 startActivity(intent); | ||||
|                             } else if (path.matches(MULTIREDDIT_PATTERN)) { | ||||
|                                 Intent intent = new Intent(this, ViewMultiRedditDetailActivity.class); | ||||
|                                 intent.putExtra(ViewMultiRedditDetailActivity.EXTRA_MULTIREDDIT_PATH, path); | ||||
|                                 startActivity(intent); | ||||
|                             } else if (path.matches(MULTIREDDIT_PATTERN_2)) { | ||||
|                                 String subredditName = path.substring(3); | ||||
|                                 Intent intent = new Intent(this, ViewSubredditDetailActivity.class); | ||||
|                                 intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditName); | ||||
|                                 intent.putExtra(ViewSubredditDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); | ||||
|                                 intent.putExtra(ViewSubredditDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); | ||||
|                                 startActivity(intent); | ||||
|                             } else if (authority.equals("redd.it") && path.matches(REDD_IT_POST_PATTERN)) { | ||||
|                                 Intent intent = new Intent(this, ViewPostDetailActivity.class); | ||||
|                                 intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, path.substring(1)); | ||||
|                                 startActivity(intent); | ||||
|                             } else { | ||||
|                                 deepLinkError(uri); | ||||
|                             } | ||||
|                         } else if (authority.equals("click.redditmail.com")) { | ||||
|                             if (path.startsWith("/CL0/")) { | ||||
|                                 handleUri(Uri.parse(path.substring("/CL0/".length()))); | ||||
| @@ -343,7 +430,7 @@ public class LinkResolverActivity extends AppCompatActivity { | ||||
|  | ||||
|         String authority = uri.getAuthority(); | ||||
|         if(authority != null && (authority.contains("reddit.com") || authority.contains("redd.it") || authority.contains("reddit.app.link"))) { | ||||
|             openInCustomTabs(uri, pm, false); | ||||
|             openInBrowser(uri, pm, false); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -6,16 +6,18 @@ import android.content.SharedPreferences; | ||||
| import android.graphics.drawable.Drawable; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.text.Editable; | ||||
| import android.util.Log; | ||||
| import android.util.Patterns; | ||||
| import android.view.InflateException; | ||||
| import android.view.MenuItem; | ||||
| import android.widget.ArrayAdapter; | ||||
| import android.widget.Button; | ||||
| import android.widget.ProgressBar; | ||||
| import android.widget.TextView; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.appcompat.widget.AppCompatAutoCompleteTextView; | ||||
| import androidx.appcompat.widget.Toolbar; | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout; | ||||
|  | ||||
| @@ -26,6 +28,10 @@ import org.json.JSONException; | ||||
| import org.json.JSONObject; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.net.MalformedURLException; | ||||
| import java.net.URL; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| @@ -38,11 +44,17 @@ import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| import eu.toldi.infinityforlemmy.RetrofitHolder; | ||||
| import eu.toldi.infinityforlemmy.adapters.CustomArrayAdapter; | ||||
| import eu.toldi.infinityforlemmy.apis.LemmyAPI; | ||||
| import eu.toldi.infinityforlemmy.asynctasks.ParseAndInsertNewAccount; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.customviews.slidr.Slidr; | ||||
| import eu.toldi.infinityforlemmy.dto.AccountLoginDTO; | ||||
| import eu.toldi.infinityforlemmy.lemmyverse.FetchInstancesListener; | ||||
| import eu.toldi.infinityforlemmy.lemmyverse.LemmyInstance; | ||||
| import eu.toldi.infinityforlemmy.lemmyverse.LemmyVerseFetchInstances; | ||||
| import eu.toldi.infinityforlemmy.site.FetchSiteInfo; | ||||
| import eu.toldi.infinityforlemmy.site.SiteInfo; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
| import retrofit2.Call; | ||||
| @@ -55,6 +67,9 @@ public class LoginActivity extends BaseActivity { | ||||
|     private static final String ENABLE_DOM_STATE = "EDS"; | ||||
|     private static final String IS_AGREE_TO_USER_AGGREMENT_STATE = "IATUAS"; | ||||
|  | ||||
|     public static final String EXTRA_INPUT_USERNAME = "INPUT_USERNAME"; | ||||
|     public static final String EXTRA_INPUT_INSTANCE = "INPUT_INSTANCE"; | ||||
|  | ||||
|     @BindView(R.id.coordinator_layout_login_activity) | ||||
|     CoordinatorLayout coordinatorLayout; | ||||
|     @BindView(R.id.appbar_layout_login_activity) | ||||
| @@ -65,7 +80,7 @@ public class LoginActivity extends BaseActivity { | ||||
|     TextView twoFAInfoTextView; | ||||
|  | ||||
|     @BindView(R.id.instance_url_input) | ||||
|     TextInputEditText instance_input; | ||||
|     AppCompatAutoCompleteTextView instance_input; | ||||
|     @BindView(R.id.username_input) | ||||
|     TextInputEditText username_input; | ||||
|     @BindView(R.id.user_password_input) | ||||
| @@ -82,9 +97,11 @@ public class LoginActivity extends BaseActivity { | ||||
|     @Inject | ||||
|     @Named("no_oauth") | ||||
|     RetrofitHolder mRetrofit; | ||||
|  | ||||
|     @Inject | ||||
|     @Named("oauth") | ||||
|     Retrofit mOauthRetrofit; | ||||
|     @Named("lemmyVerse") | ||||
|     Retrofit mLemmyVerseRetrofit; | ||||
|  | ||||
|     @Inject | ||||
|     RedditDataRoomDatabase mRedditDataRoomDatabase; | ||||
|     @Inject | ||||
| @@ -135,17 +152,45 @@ public class LoginActivity extends BaseActivity { | ||||
|             isAgreeToUserAgreement = savedInstanceState.getBoolean(IS_AGREE_TO_USER_AGGREMENT_STATE); | ||||
|         } | ||||
|  | ||||
|         // Get username and instance from intent | ||||
|         Intent intent = getIntent(); | ||||
|         String username_intent = intent.getStringExtra(EXTRA_INPUT_USERNAME); | ||||
|         String instance_intent = intent.getStringExtra(EXTRA_INPUT_INSTANCE); | ||||
|         if (username_intent != null) { | ||||
|             username_input.setText(username_intent); | ||||
|         } | ||||
|         if (instance_intent != null) { | ||||
|             instance_input.setText(instance_intent); | ||||
|         } | ||||
|  | ||||
|         LemmyVerseFetchInstances.INSTANCE.fetchInstances(mLemmyVerseRetrofit, new FetchInstancesListener() { | ||||
|  | ||||
|             @Override | ||||
|             public void onFetchInstancesSuccess(@NonNull List<LemmyInstance> instances) { | ||||
|                 ArrayList<String> instanceNames = new ArrayList<>(); | ||||
|                 for (LemmyInstance instance : instances) { | ||||
|                     instanceNames.add(instance.getFqdn()); | ||||
|                 } | ||||
|                 ArrayAdapter<String> adapter = new CustomArrayAdapter(LoginActivity.this, android.R.layout.simple_dropdown_item_1line, instanceNames, mCustomThemeWrapper); | ||||
|                 instance_input.setAdapter(adapter); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|  | ||||
|         loginButton.setOnClickListener(view -> { | ||||
|             Log.i("LoginActivity", "Login button clicked"); | ||||
|             if (!checkFields()) | ||||
|                 return; | ||||
|             loginButton.setEnabled(false); | ||||
|             progressBar.setVisibility(ProgressBar.VISIBLE); | ||||
|             String username = username_input.getText().toString().trim(); | ||||
|             String instance = correctURL(instance_input.getText().toString().trim()); | ||||
|             if (!Patterns.WEB_URL.matcher(instance).matches()) { | ||||
|                 instance_input.setError("Invalid instance URL"); | ||||
|             try { | ||||
|                 URL urlObj = new URL(instance); | ||||
|                 instance = urlObj.getProtocol() + "://" + urlObj.getHost() + "/"; | ||||
|             } catch (MalformedURLException e) { | ||||
|                 instance_input.setError("Invalid URL"); | ||||
|                 Toast.makeText(LoginActivity.this, "Invalid instance URL", Toast.LENGTH_SHORT).show(); | ||||
|                 loginButton.setEnabled(true); | ||||
|                 progressBar.setVisibility(ProgressBar.GONE); | ||||
|                 return; | ||||
|             } | ||||
|             Log.i("LoginActivity", "Instance: " + instance); | ||||
| @@ -153,6 +198,7 @@ public class LoginActivity extends BaseActivity { | ||||
|             mRetrofit.setBaseURL(instance); | ||||
|             LemmyAPI api = mRetrofit.getRetrofit().create(LemmyAPI.class); | ||||
|             Call<String> accessTokenCall = api.userLogin(accountLoginDTO); | ||||
|             String finalInstance = instance; | ||||
|             accessTokenCall.enqueue(new Callback<String>() { | ||||
|                 @Override | ||||
|                 public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { | ||||
| @@ -171,22 +217,51 @@ public class LoginActivity extends BaseActivity { | ||||
|                         try { | ||||
|                             JSONObject responseJSON = new JSONObject(accountResponse); | ||||
|                             String accessToken = responseJSON.getString("jwt"); | ||||
|                             mRetrofit.setAccessToken(null); | ||||
|  | ||||
|                             FetchMyInfo.fetchAccountInfo(mRetrofit.getRetrofit(), mRedditDataRoomDatabase, username, | ||||
|                                     accessToken, new FetchMyInfo.FetchMyInfoListener() { | ||||
|                                         @Override | ||||
|                                         public void onFetchMyInfoSuccess(String name, String display_name, String profileImageUrl, String bannerImageUrl) { | ||||
|                                             FetchSiteInfo.fetchSiteInfo(mRetrofit.getRetrofit(), accessToken, new FetchSiteInfo.FetchSiteInfoListener() { | ||||
|                                                 @Override | ||||
|                                                 public void onFetchSiteInfoSuccess(SiteInfo siteInfo) { | ||||
|                                                     boolean canDownvote = siteInfo.isEnable_downvotes(); | ||||
|                                                     ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), name, display_name, accessToken, profileImageUrl, bannerImageUrl, authCode, finalInstance, canDownvote, mRedditDataRoomDatabase.accountDao(), | ||||
|                                                             () -> { | ||||
|                                                                 Intent resultIntent = new Intent(); | ||||
|                                                                 setResult(Activity.RESULT_OK, resultIntent); | ||||
|                                                                 finish(); | ||||
|                                                             }); | ||||
|                                                     mCurrentAccountSharedPreferences.edit().putBoolean(SharedPreferencesUtils.CAN_DOWNVOTE, canDownvote).apply(); | ||||
|                                                     String[] version = siteInfo.getVersion().split("\\."); | ||||
|                                                     if (version.length > 0) { | ||||
|                                                         Log.d("SwitchAccount", "Lemmy Version: " + version[0] + "." + version[1]); | ||||
|                                                         int majorVersion = Integer.parseInt(version[0]); | ||||
|                                                         int minorVersion = Integer.parseInt(version[1]); | ||||
|                                                         if (majorVersion > 0 || (majorVersion == 0 && minorVersion >= 19)) { | ||||
|                                                             mRetrofit.setAccessToken(accessToken); | ||||
|                                                             mCurrentAccountSharedPreferences.edit().putBoolean(SharedPreferencesUtils.BEARER_TOKEN_AUTH, true).apply(); | ||||
|                                                         } | ||||
|                                                     } | ||||
|                                                 } | ||||
|  | ||||
|                                                 @Override | ||||
|                                                 public void onFetchSiteInfoFailed() { | ||||
|                                                     ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), name,display_name, accessToken,  profileImageUrl, bannerImageUrl, authCode, finalInstance,true, mRedditDataRoomDatabase.accountDao(), | ||||
|                                                             () -> { | ||||
|                                                                 Intent resultIntent = new Intent(); | ||||
|                                                                 setResult(Activity.RESULT_OK, resultIntent); | ||||
|                                                                 finish(); | ||||
|                                                             }); | ||||
|                                                     mCurrentAccountSharedPreferences.edit().putBoolean(SharedPreferencesUtils.CAN_DOWNVOTE, true).apply(); | ||||
|                                                 } | ||||
|                                             }); | ||||
|                                             mCurrentAccountSharedPreferences.edit().putString(SharedPreferencesUtils.ACCESS_TOKEN, accessToken) | ||||
|                                                     .putString(SharedPreferencesUtils.ACCOUNT_NAME, display_name) | ||||
|                                                     .putString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, name) | ||||
|                                                     .putString(SharedPreferencesUtils.ACCOUNT_INSTANCE,instance) | ||||
|                                                     .putString(SharedPreferencesUtils.ACCOUNT_INSTANCE,finalInstance) | ||||
|                                                     .putString(SharedPreferencesUtils.ACCOUNT_IMAGE_URL, profileImageUrl).apply(); | ||||
|                                             ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), name,display_name, accessToken,  profileImageUrl, bannerImageUrl, authCode,instance, mRedditDataRoomDatabase.accountDao(), | ||||
|                                                     () -> { | ||||
|                                                         Intent resultIntent = new Intent(); | ||||
|                                                         setResult(Activity.RESULT_OK, resultIntent); | ||||
|                                                         finish(); | ||||
|                                                     }); | ||||
|                                         } | ||||
|  | ||||
|                                         @Override | ||||
| @@ -240,6 +315,26 @@ public class LoginActivity extends BaseActivity { | ||||
|         }); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     private boolean checkFields() { | ||||
|         boolean result = true; | ||||
|         Editable username = username_input.getText(); | ||||
|         Editable password = password_input.getText(); | ||||
|         Editable instance = instance_input.getText(); | ||||
|         if(instance == null || instance.toString().isEmpty()) { | ||||
|             instance_input.setError(getString(R.string.instance_cannot_be_empty)); | ||||
|             result = false; | ||||
|         } | ||||
|         if(username == null || username.toString().isEmpty()) { | ||||
|             username_input.setError(getString(R.string.username_cannot_be_empty)); | ||||
|             result = false; | ||||
|         } | ||||
|         if(password == null || password.toString().isEmpty()) { | ||||
|             password_input.setError(getString(R.string.password_cannot_be_empty)); | ||||
|             result = false; | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|     private static String correctURL(String url) { | ||||
|         if (url == null || url.isEmpty()) { | ||||
|             throw new IllegalArgumentException("URL cannot be null or empty"); | ||||
| @@ -281,6 +376,7 @@ public class LoginActivity extends BaseActivity { | ||||
|         if (typeface != null) { | ||||
|             twoFAInfoTextView.setTypeface(typeface); | ||||
|         } | ||||
|         instance_input.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -33,6 +33,7 @@ import androidx.appcompat.app.AppCompatDelegate; | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout; | ||||
| import androidx.core.app.ActivityCompat; | ||||
| import androidx.core.content.ContextCompat; | ||||
| import androidx.core.splashscreen.SplashScreen; | ||||
| import androidx.drawerlayout.widget.DrawerLayout; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentActivity; | ||||
| @@ -107,12 +108,14 @@ import eu.toldi.infinityforlemmy.events.ChangeLockBottomAppBarEvent; | ||||
| import eu.toldi.infinityforlemmy.events.ChangeNSFWEvent; | ||||
| import eu.toldi.infinityforlemmy.events.ChangeRequireAuthToAccountSectionEvent; | ||||
| import eu.toldi.infinityforlemmy.events.ChangeShowAvatarOnTheRightInTheNavigationDrawerEvent; | ||||
| import eu.toldi.infinityforlemmy.events.ChangeUseCircularFabEvent; | ||||
| import eu.toldi.infinityforlemmy.events.RecreateActivityEvent; | ||||
| import eu.toldi.infinityforlemmy.events.SwitchAccountEvent; | ||||
| import eu.toldi.infinityforlemmy.fragments.PostFragment; | ||||
| import eu.toldi.infinityforlemmy.message.ReadMessage; | ||||
| import eu.toldi.infinityforlemmy.multireddit.MultiReddit; | ||||
| import eu.toldi.infinityforlemmy.multireddit.MultiRedditViewModel; | ||||
| import eu.toldi.infinityforlemmy.post.MarkPostAsRead; | ||||
| import eu.toldi.infinityforlemmy.post.Post; | ||||
| import eu.toldi.infinityforlemmy.post.PostPagingSource; | ||||
| import eu.toldi.infinityforlemmy.readpost.InsertReadPost; | ||||
| @@ -213,6 +216,10 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     @Inject | ||||
|     Executor mExecutor; | ||||
|  | ||||
|     @Inject | ||||
|     MarkPostAsRead markPostAsRead; | ||||
|  | ||||
|     private FragmentManager fragmentManager; | ||||
|     private SectionsPagerAdapter sectionsPagerAdapter; | ||||
|     private NavigationDrawerRecyclerViewMergedAdapter adapter; | ||||
| @@ -225,9 +232,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|     private boolean mFetchUserInfoSuccess = false; | ||||
|     private boolean mFetchSubscriptionsSuccess = false; | ||||
|     private boolean mDrawerOnAccountSwitch = false; | ||||
|     private String mMessageFullname; | ||||
|     private int mMessageFullname; | ||||
|     private String mNewAccountName; | ||||
|     private boolean hideFab; | ||||
|  | ||||
|     private boolean useCircularFab; | ||||
|     private boolean showBottomAppBar; | ||||
|     private int mBackButtonAction; | ||||
|     private boolean mLockBottomAppBar; | ||||
| @@ -239,8 +248,12 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|     private int fabOption; | ||||
|     private int inboxCount; | ||||
|  | ||||
|     private boolean mBearerTokenUsed = true; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         SplashScreen.installSplashScreen(this); | ||||
|  | ||||
|         ((Infinity) getApplication()).getAppComponent().inject(this); | ||||
|  | ||||
|         setTheme(R.style.AppTheme_NoActionBarWithTransparentStatusBar); | ||||
| @@ -254,6 +267,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|         ButterKnife.bind(this); | ||||
|  | ||||
|         hideFab = mSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_FAB_IN_POST_FEED, false); | ||||
|         useCircularFab = mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false); | ||||
|         showBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, false); | ||||
|  | ||||
|         navigationWrapper = new NavigationWrapper(findViewById(R.id.bottom_app_bar_bottom_app_bar), findViewById(R.id.linear_layout_bottom_app_bar), | ||||
| @@ -327,11 +341,13 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|         fragmentManager = getSupportFragmentManager(); | ||||
|  | ||||
|         mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); | ||||
|         mRetrofit.setAccessToken(mAccessToken); | ||||
|         mBearerTokenUsed = mCurrentAccountSharedPreferences.getBoolean(SharedPreferencesUtils.BEARER_TOKEN_AUTH, true); | ||||
|  | ||||
|         mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); | ||||
|         mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null); | ||||
|         String instance = (mAccessToken == null) ? mSharedPreferences.getString(SharedPreferencesUtils.ANONYMOUS_ACCOUNT_INSTANCE, APIUtils.API_BASE_URI) : mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_INSTANCE, null); | ||||
|         if(instance != null) { | ||||
|         if (instance != null) { | ||||
|             mRetrofit.setBaseURL(instance); | ||||
|         } | ||||
|  | ||||
| @@ -339,11 +355,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|             mFetchUserInfoSuccess = savedInstanceState.getBoolean(FETCH_USER_INFO_STATE); | ||||
|             mFetchSubscriptionsSuccess = savedInstanceState.getBoolean(FETCH_SUBSCRIPTIONS_STATE); | ||||
|             mDrawerOnAccountSwitch = savedInstanceState.getBoolean(DRAWER_ON_ACCOUNT_SWITCH_STATE); | ||||
|             mMessageFullname = savedInstanceState.getString(MESSAGE_FULLNAME_STATE); | ||||
|             mMessageFullname = savedInstanceState.getInt(MESSAGE_FULLNAME_STATE); | ||||
|             mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE); | ||||
|             inboxCount = savedInstanceState.getInt(INBOX_COUNT_STATE); | ||||
|         } else { | ||||
|             mMessageFullname = getIntent().getStringExtra(EXTRA_MESSSAGE_FULLNAME); | ||||
|             mMessageFullname = getIntent().getIntExtra(EXTRA_MESSSAGE_FULLNAME, 0); | ||||
|             mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); | ||||
|         } | ||||
|  | ||||
| @@ -356,9 +372,12 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|         super.onResume(); | ||||
|         if (mAccessToken == null) { | ||||
|             String instancePreference = mSharedPreferences.getString(SharedPreferencesUtils.ANONYMOUS_ACCOUNT_INSTANCE, APIUtils.API_BASE_URI); | ||||
|             if (!mRetrofit.getBaseURL().equalsIgnoreCase(instancePreference)) { | ||||
|             if (!instancePreference.startsWith(mRetrofit.getBaseURL())) { | ||||
|                 mRetrofit.setBaseURL(instancePreference); | ||||
|                 this.recreate(); | ||||
|             } | ||||
|         } else { | ||||
|             checkUserToken(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -380,7 +399,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|         navigationView.setBackgroundColor(backgroundColor); | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar); | ||||
|         applyTabLayoutTheme(tabLayout); | ||||
|         applyFABTheme(navigationWrapper.floatingActionButton); | ||||
|         applyFABTheme(navigationWrapper.floatingActionButton, useCircularFab); | ||||
|     } | ||||
|  | ||||
|     private void initializeNotificationAndBindView() { | ||||
| @@ -472,7 +491,6 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|                 Intent intent = new Intent(this, ViewUserDetailActivity.class); | ||||
|                 intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName); | ||||
|                 intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, mAccountQualifiedName); | ||||
|                 intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, mAccountName); | ||||
|                 startActivity(intent); | ||||
|                 break; | ||||
|             } | ||||
| @@ -799,21 +817,19 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|  | ||||
|         adapter = new NavigationDrawerRecyclerViewMergedAdapter(this, mSharedPreferences, | ||||
|                 mNsfwAndSpoilerSharedPreferences, mNavigationDrawerSharedPreferences, mSecuritySharedPreferences, | ||||
|                 mCustomThemeWrapper, mAccountName, new NavigationDrawerRecyclerViewMergedAdapter.ItemClickListener() { | ||||
|                     @Override | ||||
|                     public void onMenuClick(int stringId) { | ||||
|                         Intent intent = null; | ||||
|                         if (stringId == R.string.profile) { | ||||
|                             intent = new Intent(MainActivity.this, ViewUserDetailActivity.class); | ||||
|                             intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName); | ||||
|                             intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, mAccountQualifiedName); | ||||
|                         } else if (stringId == R.string.subscriptions) { | ||||
|                             intent = new Intent(MainActivity.this, SubscribedThingListingActivity.class); | ||||
|                         } else if (stringId == R.string.multi_reddit) { | ||||
|                 mCustomThemeWrapper, mAccountName, mAccountQualifiedName, new NavigationDrawerRecyclerViewMergedAdapter.ItemClickListener() { | ||||
|             @Override | ||||
|             public void onMenuClick(int stringId) { | ||||
|                 Intent intent = null; | ||||
|                 if (stringId == R.string.profile) { | ||||
|                     intent = new Intent(MainActivity.this, ViewUserDetailActivity.class); | ||||
|                     intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName); | ||||
|                     intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, mAccountQualifiedName); | ||||
|                 } else if (stringId == R.string.subscriptions) { | ||||
|                     intent = new Intent(MainActivity.this, SubscribedThingListingActivity.class); | ||||
|                 } else if (stringId == R.string.multi_reddit) { | ||||
|                             intent = new Intent(MainActivity.this, SubscribedThingListingActivity.class); | ||||
|                             intent.putExtra(SubscribedThingListingActivity.EXTRA_SHOW_MULTIREDDITS, true); | ||||
|                         } else if (stringId == R.string.history) { | ||||
|                             intent = new Intent(MainActivity.this, HistoryActivity.class); | ||||
|                         } else if (stringId == R.string.trending) { | ||||
|                             intent = new Intent(MainActivity.this, TrendingActivity.class); | ||||
|                         } else if (stringId == R.string.upvoted) { | ||||
| @@ -874,7 +890,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|                                     }); | ||||
|                         } else if (stringId == R.string.anonymous_account_instance) { | ||||
|                             changeAnonymousAccountInstance(); | ||||
|                         } | ||||
|                 } else if (stringId == R.string.blocks) { | ||||
|                     intent = new Intent(MainActivity.this, BlockedThingListingActivity.class); | ||||
|                 } else if (stringId == R.string.instance_info) { | ||||
|                     intent = new Intent(MainActivity.this, InstanceInfoActivity.class); | ||||
|                 } | ||||
|                         if (intent != null) { | ||||
|                             startActivity(intent); | ||||
|                         } | ||||
| @@ -911,7 +931,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|         sectionsPagerAdapter = new SectionsPagerAdapter(this, tabCount, mShowFavoriteMultiReddits, | ||||
|                 mShowMultiReddits, mShowFavoriteSubscribedSubreddits, mShowSubscribedSubreddits); | ||||
|         viewPager2.setAdapter(sectionsPagerAdapter); | ||||
|         viewPager2.setOffscreenPageLimit(1); | ||||
|         viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT); | ||||
|         viewPager2.setUserInputEnabled(!mDisableSwipingBetweenTabs); | ||||
|         if (mMainActivityTabsSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_TAB_NAMES, true)) { | ||||
|             if (mShowFavoriteMultiReddits || mShowMultiReddits || mShowFavoriteSubscribedSubreddits || mShowSubscribedSubreddits) { | ||||
| @@ -922,7 +942,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|             new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { | ||||
|                 switch (position) { | ||||
|                     case 0: | ||||
|                         Utils.setTitleWithCustomFontToTab(typeface, tab, mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_TITLE, getString(R.string.home))); | ||||
|                         Utils.setTitleWithCustomFontToTab(typeface, tab, mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_TITLE, getString(R.string.subscribed_feed))); | ||||
|                         break; | ||||
|                     case 1: | ||||
|                         Utils.setTitleWithCustomFontToTab(typeface, tab, mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_TITLE, getString(R.string.local))); | ||||
| @@ -1001,12 +1021,12 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|                         sectionsPagerAdapter.setSubscribedSubreddits(subscribedSubredditData); | ||||
|                     } | ||||
|                 }); | ||||
|         /*subscribedSubredditViewModel.getAllFavoriteSubscribedSubreddits().observe(this, subscribedSubredditData -> { | ||||
|         subscribedSubredditViewModel.getAllFavoriteSubscribedSubreddits().observe(this, subscribedSubredditData -> { | ||||
|             adapter.setFavoriteSubscribedSubreddits(subscribedSubredditData); | ||||
|             if (mShowFavoriteSubscribedSubreddits && sectionsPagerAdapter != null) { | ||||
|                 sectionsPagerAdapter.setFavoriteSubscribedSubreddits(subscribedSubredditData); | ||||
|             } | ||||
|         });*/ | ||||
|         }); | ||||
|  | ||||
|         accountViewModel = new ViewModelProvider(this, | ||||
|                 new AccountViewModel.Factory(mRedditDataRoomDatabase)).get(AccountViewModel.class); | ||||
| @@ -1020,11 +1040,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|         loadUserData(); | ||||
|  | ||||
|         if (mAccessToken != null) { | ||||
|             if (mMessageFullname != null) { | ||||
|             if (mMessageFullname != 0) { | ||||
|                 ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() { | ||||
|                     @Override | ||||
|                     public void readSuccess() { | ||||
|                         mMessageFullname = null; | ||||
|                         mMessageFullname = 0; | ||||
|                     } | ||||
|  | ||||
|                     @Override | ||||
| @@ -1065,22 +1085,59 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void checkUserToken() { | ||||
|         if (mBearerTokenUsed) { | ||||
|             FetchUserData.validateAuthToken(mRetrofit.getRetrofit(), new FetchUserData.ValidateAuthTokenListener() { | ||||
|                 @Override | ||||
|                 public void onValidateAuthTokenSuccess() { | ||||
|                 } | ||||
|  | ||||
|                 @Override | ||||
|                 public void onValidateAuthTokenFailed() { | ||||
|                     // Alert user that the token is invalid and they need to re-login | ||||
|                     new MaterialAlertDialogBuilder(MainActivity.this, R.style.MaterialAlertDialogTheme) | ||||
|                             .setTitle(R.string.token_expired) | ||||
|                             .setMessage(R.string.token_expired_message) | ||||
|                             .setPositiveButton(R.string.ok, (dialogInterface, i) -> { | ||||
|                                 Intent intent = new Intent(MainActivity.this, LoginActivity.class); | ||||
|                                 // Username without instance | ||||
|                                 String username = mAccountName.substring(0, mAccountQualifiedName.indexOf("@")); | ||||
|                                 intent.putExtra(LoginActivity.EXTRA_INPUT_USERNAME, username); | ||||
|                                 intent.putExtra(LoginActivity.EXTRA_INPUT_INSTANCE, mRetrofit.getBaseURL()); | ||||
|                                 startActivity(intent); | ||||
|                             }) | ||||
|                             .setCancelable(false) | ||||
|                             .show(); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void loadUserData() { | ||||
|         if (!mFetchUserInfoSuccess) { | ||||
|             FetchUserData.fetchUserData(mRedditDataRoomDatabase, mRetrofit.getRetrofit(), mAccessToken, | ||||
|                     mAccountName, new FetchUserData.FetchUserDataListener() { | ||||
|             FetchUserData.fetchUnreadCount(mRetrofit.getRetrofit(), mAccessToken, new FetchUserData.FetchUserUnreadCountListener() { | ||||
|                 @Override | ||||
|                 public void onFetchUserDataSuccess(UserData userData, int inboxCount) { | ||||
|                 public void onFetchUserUnreadCountSuccess(int inboxCount) { | ||||
|                     MainActivity.this.inboxCount = inboxCount; | ||||
|                     mAccountName = userData.getName(); | ||||
|                     mFetchUserInfoSuccess = true; | ||||
|                     if (adapter != null) { | ||||
|                         adapter.setInboxCount(inboxCount); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 @Override | ||||
|                 public void onFetchUserDataFailed() { | ||||
|                 public void onFetchUserUnreadCountFailed() { | ||||
|                 } | ||||
|             }); | ||||
|             FetchUserData.fetchUserData(mRedditDataRoomDatabase, mRetrofit.getRetrofit(), mAccessToken, | ||||
|                     mAccountName, new FetchUserData.FetchUserDataListener() { | ||||
|                         @Override | ||||
|                         public void onFetchUserDataSuccess(UserData userData, int inboxCount) { | ||||
|                             mAccountName = userData.getName(); | ||||
|                             mFetchUserInfoSuccess = true; | ||||
|                         } | ||||
|  | ||||
|                         @Override | ||||
|                         public void onFetchUserDataFailed() { | ||||
|                     mFetchUserInfoSuccess = false; | ||||
|                 } | ||||
|             }); | ||||
| @@ -1172,7 +1229,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|         outState.putBoolean(FETCH_USER_INFO_STATE, mFetchUserInfoSuccess); | ||||
|         outState.putBoolean(FETCH_SUBSCRIPTIONS_STATE, mFetchSubscriptionsSuccess); | ||||
|         outState.putBoolean(DRAWER_ON_ACCOUNT_SWITCH_STATE, mDrawerOnAccountSwitch); | ||||
|         outState.putString(MESSAGE_FULLNAME_STATE, mMessageFullname); | ||||
|         outState.putInt(MESSAGE_FULLNAME_STATE, mMessageFullname); | ||||
|         outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName); | ||||
|         outState.putInt(INBOX_COUNT_STATE, inboxCount); | ||||
|     } | ||||
| @@ -1331,6 +1388,12 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|         navigationWrapper.floatingActionButton.setVisibility(hideFab ? View.GONE : View.VISIBLE); | ||||
|     } | ||||
|  | ||||
|     @Subscribe | ||||
|     public void onChangeUseCircularFab(ChangeUseCircularFabEvent event) { | ||||
|         useCircularFab = event.isUseCircularFab(); | ||||
|         applyFABTheme(navigationWrapper.floatingActionButton, useCircularFab); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onLongPress() { | ||||
|         if (sectionsPagerAdapter != null) { | ||||
| @@ -1376,10 +1439,6 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|                 goToUser(); | ||||
|                 break; | ||||
|             } | ||||
|             case FABMoreOptionsBottomSheetFragment.FAB_RANDOM: { | ||||
|                 randomThing(); | ||||
|                 break; | ||||
|             } | ||||
|             case FABMoreOptionsBottomSheetFragment.FAB_HIDE_READ_POSTS: { | ||||
|                 if (sectionsPagerAdapter != null) { | ||||
|                     sectionsPagerAdapter.hideReadPosts(); | ||||
| @@ -1487,7 +1546,12 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|             if (i == EditorInfo.IME_ACTION_DONE) { | ||||
|                 Utils.hideKeyboard(this); | ||||
|                 Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class); | ||||
|                 subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, thingEditText.getText().toString()); | ||||
|                 String communityName = thingEditText.getText().toString(); | ||||
|                 if (communityName.startsWith("!")) { | ||||
|                     communityName = communityName.substring(1); | ||||
|                 } | ||||
|                 subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, communityName); | ||||
|  | ||||
|                 startActivity(subredditIntent); | ||||
|                 return true; | ||||
|             } | ||||
| @@ -1545,7 +1609,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|                         -> { | ||||
|                     Utils.hideKeyboard(this); | ||||
|                     Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class); | ||||
|                     subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, thingEditText.getText().toString()); | ||||
|                     String communityName = thingEditText.getText().toString(); | ||||
|                     if (communityName.startsWith("!")) { | ||||
|                         communityName = communityName.substring(1); | ||||
|                     } | ||||
|                     subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, communityName); | ||||
|                     startActivity(subredditIntent); | ||||
|                 }) | ||||
|                 .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { | ||||
| @@ -1566,7 +1634,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|             if (i == EditorInfo.IME_ACTION_DONE) { | ||||
|                 Utils.hideKeyboard(this); | ||||
|                 Intent userIntent = new Intent(this, ViewUserDetailActivity.class); | ||||
|                 userIntent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, thingEditText.getText().toString()); | ||||
|                 String qualifiedName = thingEditText.getText().toString(); | ||||
|                 if (qualifiedName.startsWith("@")) { | ||||
|                     qualifiedName = qualifiedName.substring(1); | ||||
|                 } | ||||
|                 userIntent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, qualifiedName); | ||||
|                 startActivity(userIntent); | ||||
|                 return true; | ||||
|             } | ||||
| @@ -1579,7 +1651,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|                         -> { | ||||
|                     Utils.hideKeyboard(this); | ||||
|                     Intent userIntent = new Intent(this, ViewUserDetailActivity.class); | ||||
|                     userIntent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, thingEditText.getText().toString()); | ||||
|                     String qualifiedName = thingEditText.getText().toString(); | ||||
|                     if (qualifiedName.startsWith("@")) { | ||||
|                         qualifiedName = qualifiedName.substring(1); | ||||
|                     } | ||||
|                     userIntent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, qualifiedName); | ||||
|                     startActivity(userIntent); | ||||
|                 }) | ||||
|                 .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { | ||||
| @@ -1608,11 +1684,21 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|  | ||||
|     @Override | ||||
|     public void markPostAsRead(Post post) { | ||||
|         InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountName, post.getId()); | ||||
|         markPostAsRead.markPostAsRead(post.getId(), mAccessToken, new MarkPostAsRead.MarkPostAsReadListener() { | ||||
|             @Override | ||||
|             public void onMarkPostAsReadSuccess() { | ||||
|                 InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountQualifiedName, post.getId()); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onMarkPostAsReadFailed() { | ||||
|                 Toast.makeText(MainActivity.this, R.string.mark_post_as_read_failed, Toast.LENGTH_SHORT).show(); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public void doNotShowRedditAPIInfoAgain() { | ||||
|         mInternalSharedPreferences.edit().putBoolean(SharedPreferencesUtils.DO_NOT_SHOW_REDDIT_API_INFO_AGAIN, true).apply(); | ||||
|         mInternalSharedPreferences.edit().putBoolean(SharedPreferencesUtils.DO_NOT_SHOW_REDDIT_API_INFO_V2_AGAIN, true).apply(); | ||||
|     } | ||||
|  | ||||
|     private class SectionsPagerAdapter extends FragmentStateAdapter { | ||||
|   | ||||
| @@ -8,6 +8,7 @@ import android.view.MenuItem; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.appcompat.widget.Toolbar; | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout; | ||||
| import androidx.lifecycle.Observer; | ||||
| import androidx.lifecycle.ViewModelProvider; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| @@ -16,6 +17,7 @@ import com.google.android.material.appbar.CollapsingToolbarLayout; | ||||
| import com.google.android.material.dialog.MaterialAlertDialogBuilder; | ||||
| import com.google.android.material.floatingactionbutton.FloatingActionButton; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| @@ -26,13 +28,15 @@ import butterknife.ButterKnife; | ||||
| import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| import eu.toldi.infinityforlemmy.adapters.PostFilterRecyclerViewAdapter; | ||||
| import eu.toldi.infinityforlemmy.adapters.PostFilterWithUsageRecyclerViewAdapter; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.PostFilterOptionsBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.post.Post; | ||||
| import eu.toldi.infinityforlemmy.postfilter.DeletePostFilter; | ||||
| import eu.toldi.infinityforlemmy.postfilter.PostFilter; | ||||
| import eu.toldi.infinityforlemmy.postfilter.PostFilterViewModel; | ||||
| import eu.toldi.infinityforlemmy.postfilter.PostFilterWithUsageViewModel; | ||||
| import eu.toldi.infinityforlemmy.postfilter.PostFilterWithUsage; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
|  | ||||
| public class PostFilterPreferenceActivity extends BaseActivity { | ||||
|  | ||||
| @@ -61,8 +65,8 @@ public class PostFilterPreferenceActivity extends BaseActivity { | ||||
|     CustomThemeWrapper customThemeWrapper; | ||||
|     @Inject | ||||
|     Executor executor; | ||||
|     public PostFilterViewModel postFilterViewModel; | ||||
|     private PostFilterRecyclerViewAdapter adapter; | ||||
|     public PostFilterWithUsageViewModel postFilterWithUsageViewModel; | ||||
|     private PostFilterWithUsageRecyclerViewAdapter adapter; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
| @@ -98,7 +102,7 @@ public class PostFilterPreferenceActivity extends BaseActivity { | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         adapter = new PostFilterRecyclerViewAdapter(this, customThemeWrapper, postFilter -> { | ||||
|         adapter = new PostFilterWithUsageRecyclerViewAdapter(this, customThemeWrapper, postFilter -> { | ||||
|             if (post != null) { | ||||
|                 showPostFilterOptions(post, postFilter); | ||||
|             } else if (subredditName != null) { | ||||
| @@ -116,10 +120,15 @@ public class PostFilterPreferenceActivity extends BaseActivity { | ||||
|  | ||||
|         recyclerView.setAdapter(adapter); | ||||
|  | ||||
|         postFilterViewModel = new ViewModelProvider(this, | ||||
|                 new PostFilterViewModel.Factory(redditDataRoomDatabase)).get(PostFilterViewModel.class); | ||||
|         postFilterWithUsageViewModel = new ViewModelProvider(this, | ||||
|                 new PostFilterWithUsageViewModel.Factory(redditDataRoomDatabase)).get(PostFilterWithUsageViewModel.class); | ||||
|  | ||||
|         postFilterViewModel.getPostFilterListLiveData().observe(this, postFilters -> adapter.setPostFilterList(postFilters)); | ||||
|         postFilterWithUsageViewModel.getPostFilterWithUsageListLiveData().observe(this, new Observer<List<PostFilterWithUsage>>() { | ||||
|             @Override | ||||
|             public void onChanged(List<PostFilterWithUsage> postFilterWithUsages) { | ||||
|                 adapter.setPostFilterWithUsageList(postFilterWithUsages); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public void showPostFilterOptions(Post post, PostFilter postFilter) { | ||||
| @@ -205,7 +214,7 @@ public class PostFilterPreferenceActivity extends BaseActivity { | ||||
|     @Override | ||||
|     protected void applyCustomTheme() { | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar); | ||||
|         applyFABTheme(fab); | ||||
|         applyFABTheme(fab, sharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|         coordinatorLayout.setBackgroundColor(customThemeWrapper.getBackgroundColor()); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -39,6 +39,7 @@ import eu.toldi.infinityforlemmy.postfilter.PostFilter; | ||||
| import eu.toldi.infinityforlemmy.postfilter.PostFilterUsage; | ||||
| import eu.toldi.infinityforlemmy.postfilter.PostFilterUsageViewModel; | ||||
| import eu.toldi.infinityforlemmy.postfilter.SavePostFilterUsage; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
|  | ||||
| public class PostFilterUsageListingActivity extends BaseActivity { | ||||
| @@ -125,9 +126,9 @@ public class PostFilterUsageListingActivity extends BaseActivity { | ||||
|     } | ||||
|  | ||||
|     private void editAndPostFilterUsageNameOfUsage(int type, String nameOfUsage) { | ||||
|         View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_post_filter_name_of_usage, null); | ||||
|         TextInputLayout textInputLayout = dialogView.findViewById(R.id.text_input_layout_edit_post_filter_name_of_usage_dialog); | ||||
|         TextInputEditText textInputEditText = dialogView.findViewById(R.id.text_input_edit_text_edit_post_filter_name_of_usage_dialog); | ||||
|         View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_post_or_comment_filter_name_of_usage, null); | ||||
|         TextInputLayout textInputLayout = dialogView.findViewById(R.id.text_input_layout_edit_post_or_comment_filter_name_of_usage_dialog); | ||||
|         TextInputEditText textInputEditText = dialogView.findViewById(R.id.text_input_edit_text_edit_post_or_comment_filter_name_of_usage_dialog); | ||||
|         int primaryTextColor = customThemeWrapper.getPrimaryTextColor(); | ||||
|         textInputLayout.setBoxStrokeColor(primaryTextColor); | ||||
|         textInputLayout.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); | ||||
| @@ -206,7 +207,7 @@ public class PostFilterUsageListingActivity extends BaseActivity { | ||||
|     @Override | ||||
|     protected void applyCustomTheme() { | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar); | ||||
|         applyFABTheme(fab); | ||||
|         applyFABTheme(fab, sharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|         coordinatorLayout.setBackgroundColor(customThemeWrapper.getBackgroundColor()); | ||||
|     } | ||||
| } | ||||
| @@ -214,7 +214,7 @@ public class PostGalleryActivity extends BaseActivity implements FlairBottomShee | ||||
|         setSupportActionBar(toolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|  | ||||
|         mGlide = Glide.with(this); | ||||
|         mGlide = Glide.with(getApplication()); | ||||
|  | ||||
|         mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); | ||||
|  | ||||
| @@ -504,7 +504,7 @@ public class PostGalleryActivity extends BaseActivity implements FlairBottomShee | ||||
|     } | ||||
|  | ||||
|     private void loadSubredditIcon() { | ||||
|         LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, mAccessToken, mOauthRetrofit, mRetrofit.getRetrofit(), iconImageUrl -> { | ||||
|         LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, mAccessToken, mRetrofit.getRetrofit(), iconImageUrl -> { | ||||
|             iconUrl = iconImageUrl; | ||||
|             displaySubredditIcon(); | ||||
|             loadSubredditIconSuccessful = true; | ||||
|   | ||||
| @@ -17,6 +17,7 @@ import android.widget.EditText; | ||||
| import android.widget.ImageView; | ||||
| import android.widget.LinearLayout; | ||||
| import android.widget.TextView; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| @@ -25,6 +26,8 @@ import androidx.constraintlayout.widget.ConstraintLayout; | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout; | ||||
| import androidx.core.content.ContextCompat; | ||||
| import androidx.core.content.FileProvider; | ||||
| import androidx.recyclerview.widget.LinearLayoutManager; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| import com.bumptech.glide.Glide; | ||||
| import com.bumptech.glide.RequestManager; | ||||
| @@ -43,6 +46,7 @@ import org.greenrobot.eventbus.Subscribe; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| @@ -55,11 +59,16 @@ import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| import eu.toldi.infinityforlemmy.RetrofitHolder; | ||||
| import eu.toldi.infinityforlemmy.UploadImageEnabledActivity; | ||||
| import eu.toldi.infinityforlemmy.UploadedImage; | ||||
| import eu.toldi.infinityforlemmy.account.Account; | ||||
| import eu.toldi.infinityforlemmy.adapters.MarkdownBottomBarRecyclerViewAdapter; | ||||
| import eu.toldi.infinityforlemmy.asynctasks.LoadSubredditIcon; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.AccountChooserBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.FlairBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.UploadedImagesBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; | ||||
| import eu.toldi.infinityforlemmy.events.SubmitImagePostEvent; | ||||
| import eu.toldi.infinityforlemmy.events.SubmitVideoOrGifPostEvent; | ||||
| import eu.toldi.infinityforlemmy.events.SwitchAccountEvent; | ||||
| @@ -68,12 +77,13 @@ import eu.toldi.infinityforlemmy.subreddit.FetchSubredditData; | ||||
| import eu.toldi.infinityforlemmy.subreddit.SubredditData; | ||||
| import eu.toldi.infinityforlemmy.subscribedsubreddit.SubscribedSubredditData; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
| import jp.wasabeef.glide.transformations.RoundedCornersTransformation; | ||||
| import pl.droidsonroids.gif.GifImageView; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
| public class PostImageActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback, | ||||
|         AccountChooserBottomSheetFragment.AccountChooserListener { | ||||
|         UploadImageEnabledActivity, AccountChooserBottomSheetFragment.AccountChooserListener { | ||||
|  | ||||
|     static final String EXTRA_SUBREDDIT_NAME = "ESN"; | ||||
|  | ||||
| @@ -92,6 +102,9 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF | ||||
|     private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; | ||||
|     private static final int PICK_IMAGE_REQUEST_CODE = 1; | ||||
|     private static final int CAPTURE_IMAGE_REQUEST_CODE = 2; | ||||
|  | ||||
|     private static final int PICK_IMAGE_REQUEST_CODE_2 = 100; | ||||
|     private static final int CAPTURE_IMAGE_REQUEST_CODE_2 = 200; | ||||
|     private static final String COMMUNITY_DATA_STATE = "CDS"; | ||||
|  | ||||
|     @BindView(R.id.coordinator_layout_post_image_activity) | ||||
| @@ -153,6 +166,11 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF | ||||
|     @Inject | ||||
|     @Named("current_account") | ||||
|     SharedPreferences mCurrentAccountSharedPreferences; | ||||
|  | ||||
|     @BindView(R.id.post_text_content_edit_text_post_text_activity) | ||||
|     EditText contentEditText; | ||||
|     @BindView(R.id.markdown_bottom_bar_recycler_view_post_text_activity) | ||||
|     RecyclerView markdownBottomBarRecyclerView; | ||||
|     @Inject | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     @Inject | ||||
| @@ -184,6 +202,9 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF | ||||
|     private FlairBottomSheetFragment flairSelectionBottomSheetFragment; | ||||
|     private Snackbar mPostingSnackbar; | ||||
|  | ||||
|     private Uri capturedImageUri; | ||||
|     private ArrayList<UploadedImage> uploadedImages = new ArrayList<>(); | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         ((Infinity) getApplication()).getAppComponent().inject(this); | ||||
| @@ -207,7 +228,7 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF | ||||
|         setSupportActionBar(toolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|  | ||||
|         mGlide = Glide.with(this); | ||||
|         mGlide = Glide.with(getApplication()); | ||||
|  | ||||
|         mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); | ||||
|  | ||||
| @@ -376,6 +397,30 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF | ||||
|             imageView.setVisibility(View.GONE); | ||||
|             constraintLayout.setVisibility(View.VISIBLE); | ||||
|         }); | ||||
|  | ||||
|         MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter( | ||||
|                 mCustomThemeWrapper, new MarkdownBottomBarRecyclerViewAdapter.ItemClickListener() { | ||||
|             @Override | ||||
|             public void onClick(int item) { | ||||
|                 MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener( | ||||
|                         PostImageActivity.this, contentEditText, item); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onUploadImage() { | ||||
|                 Utils.hideKeyboard(PostImageActivity.this); | ||||
|                 UploadedImagesBottomSheetFragment fragment = new UploadedImagesBottomSheetFragment(); | ||||
|                 Bundle arguments = new Bundle(); | ||||
|                 arguments.putParcelableArrayList(UploadedImagesBottomSheetFragment.EXTRA_UPLOADED_IMAGES, | ||||
|                         uploadedImages); | ||||
|                 fragment.setArguments(arguments); | ||||
|                 fragment.show(getSupportFragmentManager(), fragment.getTag()); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this, | ||||
|                 LinearLayoutManager.HORIZONTAL, false)); | ||||
|         markdownBottomBarRecyclerView.setAdapter(adapter); | ||||
|     } | ||||
|  | ||||
|     private void loadCurrentAccount() { | ||||
| @@ -430,8 +475,11 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF | ||||
|         nsfwTextView.setTextColor(primaryTextColor); | ||||
|         titleEditText.setTextColor(primaryTextColor); | ||||
|         titleEditText.setHintTextColor(secondaryTextColor); | ||||
|         applyFABTheme(captureFab); | ||||
|         applyFABTheme(selectFromLibraryFab); | ||||
|         contentEditText.setTextColor(primaryTextColor); | ||||
|         contentEditText.setHintTextColor(secondaryTextColor); | ||||
|         boolean circleFab = mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false); | ||||
|         applyFABTheme(captureFab, circleFab); | ||||
|         applyFABTheme(selectFromLibraryFab, circleFab); | ||||
|         selectAgainTextView.setTextColor(mCustomThemeWrapper.getColorAccent()); | ||||
|         if (typeface != null) { | ||||
|             subredditNameTextView.setTypeface(typeface); | ||||
| @@ -441,6 +489,10 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF | ||||
|             titleEditText.setTypeface(typeface); | ||||
|             selectAgainTextView.setTypeface(typeface); | ||||
|         } | ||||
|  | ||||
|         if (contentTypeface != null) { | ||||
|             contentEditText.setTypeface(contentTypeface); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void loadImage() { | ||||
| @@ -465,7 +517,7 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF | ||||
|     } | ||||
|  | ||||
|     private void loadSubredditIcon() { | ||||
|         LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, mAccessToken, mOauthRetrofit, mRetrofit.getRetrofit(), iconImageUrl -> { | ||||
|         LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, communityData.getQualified_name(), mAccessToken, mRetrofit.getRetrofit(), iconImageUrl -> { | ||||
|             iconUrl = iconImageUrl; | ||||
|             displaySubredditIcon(); | ||||
|             loadSubredditIconSuccessful = true; | ||||
| @@ -544,6 +596,7 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF | ||||
|             intent.putExtra(SubmitPostService.EXTRA_ACCOUNT, selectedAccount); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, communityData.getId()); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_BODY, contentEditText.getText().toString()); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); | ||||
| @@ -626,6 +679,16 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF | ||||
|             if (resultCode == RESULT_OK) { | ||||
|                 loadImage(); | ||||
|             } | ||||
|         } else if (requestCode == PICK_IMAGE_REQUEST_CODE_2) { | ||||
|             if (data == null) { | ||||
|                 Toast.makeText(PostImageActivity.this, R.string.error_getting_image, Toast.LENGTH_LONG).show(); | ||||
|                 return; | ||||
|             } | ||||
|             Utils.uploadImageToReddit(this, mExecutor, mRetrofit, | ||||
|                     mAccessToken, contentEditText, coordinatorLayout, data.getData(), uploadedImages); | ||||
|         } else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE_2) { | ||||
|             Utils.uploadImageToReddit(this, mExecutor, mRetrofit, | ||||
|                     mAccessToken, contentEditText, coordinatorLayout, capturedImageUri, uploadedImages); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -705,4 +768,37 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void uploadImage() { | ||||
|         Intent intent = new Intent(); | ||||
|         intent.setType("image/*"); | ||||
|         intent.setAction(Intent.ACTION_GET_CONTENT); | ||||
|         startActivityForResult(Intent.createChooser(intent, | ||||
|                 getResources().getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE_2); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void captureImage() { | ||||
|         Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); | ||||
|         try { | ||||
|             capturedImageUri = FileProvider.getUriForFile(this, "eu.toldi.infinityforlemmy.provider", | ||||
|                     File.createTempFile("captured_image", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES))); | ||||
|             pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri); | ||||
|             startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE_2); | ||||
|         } catch (IOException ex) { | ||||
|             Toast.makeText(this, R.string.error_creating_temp_file, Toast.LENGTH_SHORT).show(); | ||||
|         } catch (ActivityNotFoundException e) { | ||||
|             Toast.makeText(this, R.string.no_camera_available, Toast.LENGTH_SHORT).show(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void insertImageUrl(UploadedImage uploadedImage) { | ||||
|         int start = Math.max(contentEditText.getSelectionStart(), 0); | ||||
|         int end = Math.max(contentEditText.getSelectionEnd(), 0); | ||||
|         contentEditText.getText().replace(Math.min(start, end), Math.max(start, end), | ||||
|                 "", | ||||
|                 0, "![]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,11 +1,15 @@ | ||||
| package eu.toldi.infinityforlemmy.activities; | ||||
|  | ||||
| import android.content.ActivityNotFoundException; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.res.Resources; | ||||
| import android.net.Uri; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| import android.os.Environment; | ||||
| import android.os.Handler; | ||||
| import android.provider.MediaStore; | ||||
| import android.view.Menu; | ||||
| import android.view.MenuItem; | ||||
| import android.webkit.URLUtil; | ||||
| @@ -19,6 +23,9 @@ import androidx.annotation.Nullable; | ||||
| import androidx.appcompat.widget.Toolbar; | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout; | ||||
| import androidx.core.content.ContextCompat; | ||||
| import androidx.core.content.FileProvider; | ||||
| import androidx.recyclerview.widget.LinearLayoutManager; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| import com.bumptech.glide.Glide; | ||||
| import com.bumptech.glide.RequestManager; | ||||
| @@ -34,6 +41,9 @@ import com.libRG.CustomTextView; | ||||
| import org.greenrobot.eventbus.EventBus; | ||||
| import org.greenrobot.eventbus.Subscribe; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| @@ -46,12 +56,17 @@ import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| import eu.toldi.infinityforlemmy.RetrofitHolder; | ||||
| import eu.toldi.infinityforlemmy.UploadImageEnabledActivity; | ||||
| import eu.toldi.infinityforlemmy.UploadedImage; | ||||
| import eu.toldi.infinityforlemmy.account.Account; | ||||
| import eu.toldi.infinityforlemmy.adapters.MarkdownBottomBarRecyclerViewAdapter; | ||||
| import eu.toldi.infinityforlemmy.apis.TitleSuggestion; | ||||
| import eu.toldi.infinityforlemmy.asynctasks.LoadSubredditIcon; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.AccountChooserBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.FlairBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.UploadedImagesBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; | ||||
| import eu.toldi.infinityforlemmy.events.SubmitTextOrLinkPostEvent; | ||||
| import eu.toldi.infinityforlemmy.events.SwitchAccountEvent; | ||||
| import eu.toldi.infinityforlemmy.services.SubmitPostService; | ||||
| @@ -60,6 +75,7 @@ import eu.toldi.infinityforlemmy.subreddit.SubredditData; | ||||
| import eu.toldi.infinityforlemmy.subscribedsubreddit.SubscribedSubredditData; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
| import jp.wasabeef.glide.transformations.RoundedCornersTransformation; | ||||
| import pl.droidsonroids.gif.GifImageView; | ||||
| import retrofit2.Call; | ||||
| @@ -69,7 +85,7 @@ import retrofit2.Retrofit; | ||||
| import retrofit2.converter.scalars.ScalarsConverterFactory; | ||||
|  | ||||
| public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback, | ||||
|         AccountChooserBottomSheetFragment.AccountChooserListener { | ||||
|         UploadImageEnabledActivity, AccountChooserBottomSheetFragment.AccountChooserListener { | ||||
|  | ||||
|     static final String EXTRA_SUBREDDIT_NAME = "ESN"; | ||||
|     static final String EXTRA_LINK = "EL"; | ||||
| @@ -87,6 +103,9 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|     private static final String IS_NSFW_STATE = "INS"; | ||||
|  | ||||
|     private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; | ||||
|     private static final int PICK_IMAGE_REQUEST_CODE = 100; | ||||
|     private static final int CAPTURE_IMAGE_REQUEST_CODE = 200; | ||||
|     private static final int MARKDOWN_PREVIEW_REQUEST_CODE = 300; | ||||
|  | ||||
|     @BindView(R.id.coordinator_layout_post_link_activity) | ||||
|     CoordinatorLayout coordinatorLayout; | ||||
| @@ -124,6 +143,11 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|     MaterialButton suggestTitleButton; | ||||
|     @BindView(R.id.post_link_edit_text_post_link_activity) | ||||
|     EditText linkEditText; | ||||
|  | ||||
|     @BindView(R.id.post_text_content_edit_text_post_text_activity) | ||||
|     EditText contentEditText; | ||||
|     @BindView(R.id.markdown_bottom_bar_recycler_view_post_text_activity) | ||||
|     RecyclerView markdownBottomBarRecyclerView; | ||||
|     @Inject | ||||
|     @Named("no_oauth") | ||||
|     RetrofitHolder mRetrofit; | ||||
| @@ -167,6 +191,9 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|     private FlairBottomSheetFragment flairSelectionBottomSheetFragment; | ||||
|     private Snackbar mPostingSnackbar; | ||||
|  | ||||
|     private Uri capturedImageUri; | ||||
|     private ArrayList<UploadedImage> uploadedImages = new ArrayList<>(); | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         ((Infinity) getApplication()).getAppComponent().inject(this); | ||||
| @@ -190,7 +217,7 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|         setSupportActionBar(toolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|  | ||||
|         mGlide = Glide.with(this); | ||||
|         mGlide = Glide.with(getApplication()); | ||||
|  | ||||
|         mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); | ||||
|  | ||||
| @@ -335,21 +362,46 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|                     .baseUrl("http://localhost/") | ||||
|                     .addConverterFactory(ScalarsConverterFactory.create()) | ||||
|                     .build().create(TitleSuggestion.class).getHtml(url).enqueue(new Callback<String>() { | ||||
|                 @Override | ||||
|                 public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { | ||||
|                     if (response.isSuccessful()) { | ||||
|                         titleEditText.setText(response.body().substring(response.body().indexOf("<title>") + 7, response.body().indexOf("</title>"))); | ||||
|                     } else { | ||||
|                         Toast.makeText(PostLinkActivity.this, R.string.suggest_title_failed, Toast.LENGTH_SHORT).show(); | ||||
|                     } | ||||
|                 } | ||||
|                         @Override | ||||
|                         public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { | ||||
|                             if (response.isSuccessful()) { | ||||
|                                 titleEditText.setText(response.body().substring(response.body().indexOf("<title>") + 7, response.body().indexOf("</title>"))); | ||||
|                             } else { | ||||
|                                 Toast.makeText(PostLinkActivity.this, R.string.suggest_title_failed, Toast.LENGTH_SHORT).show(); | ||||
|                             } | ||||
|                         } | ||||
|  | ||||
|                 @Override | ||||
|                 public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { | ||||
|                     Toast.makeText(PostLinkActivity.this, R.string.suggest_title_failed, Toast.LENGTH_SHORT).show(); | ||||
|                 } | ||||
|             }); | ||||
|                         @Override | ||||
|                         public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { | ||||
|                             Toast.makeText(PostLinkActivity.this, R.string.suggest_title_failed, Toast.LENGTH_SHORT).show(); | ||||
|                         } | ||||
|                     }); | ||||
|         }); | ||||
|  | ||||
|  | ||||
|         MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter( | ||||
|                 mCustomThemeWrapper, new MarkdownBottomBarRecyclerViewAdapter.ItemClickListener() { | ||||
|             @Override | ||||
|             public void onClick(int item) { | ||||
|                 MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener( | ||||
|                         PostLinkActivity.this, contentEditText, item); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onUploadImage() { | ||||
|                 Utils.hideKeyboard(PostLinkActivity.this); | ||||
|                 UploadedImagesBottomSheetFragment fragment = new UploadedImagesBottomSheetFragment(); | ||||
|                 Bundle arguments = new Bundle(); | ||||
|                 arguments.putParcelableArrayList(UploadedImagesBottomSheetFragment.EXTRA_UPLOADED_IMAGES, | ||||
|                         uploadedImages); | ||||
|                 fragment.setArguments(arguments); | ||||
|                 fragment.show(getSupportFragmentManager(), fragment.getTag()); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this, | ||||
|                 LinearLayoutManager.HORIZONTAL, false)); | ||||
|         markdownBottomBarRecyclerView.setAdapter(adapter); | ||||
|     } | ||||
|  | ||||
|     private void loadCurrentAccount() { | ||||
| @@ -406,6 +458,8 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|         titleEditText.setHintTextColor(secondaryTextColor); | ||||
|         suggestTitleButton.setBackgroundColor(mCustomThemeWrapper.getColorPrimaryLightTheme()); | ||||
|         suggestTitleButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); | ||||
|         contentEditText.setTextColor(primaryTextColor); | ||||
|         contentEditText.setHintTextColor(secondaryTextColor); | ||||
|         linkEditText.setTextColor(primaryTextColor); | ||||
|         linkEditText.setHintTextColor(secondaryTextColor); | ||||
|         if (typeface != null) { | ||||
| @@ -418,6 +472,7 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|         } | ||||
|         if (contentTypeface != null) { | ||||
|             linkEditText.setTypeface(contentTypeface); | ||||
|             contentEditText.setTypeface(contentTypeface); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -436,12 +491,12 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|     } | ||||
|  | ||||
|     private void loadSubredditIcon() { | ||||
|         LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, | ||||
|                 mAccessToken, mOauthRetrofit, mRetrofit.getRetrofit(), iconImageUrl -> { | ||||
|             iconUrl = iconImageUrl; | ||||
|             displaySubredditIcon(); | ||||
|             loadSubredditIconSuccessful = true; | ||||
|         }); | ||||
|         LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, communityData.getQualified_name(), | ||||
|                 mAccessToken, mRetrofit.getRetrofit(), iconImageUrl -> { | ||||
|                     iconUrl = iconImageUrl; | ||||
|                     displaySubredditIcon(); | ||||
|                     loadSubredditIconSuccessful = true; | ||||
|                 }); | ||||
|     } | ||||
|  | ||||
|     private void promptAlertDialog(int titleResId, int messageResId) { | ||||
| @@ -514,7 +569,8 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|             intent.putExtra(SubmitPostService.EXTRA_ACCOUNT, selectedAccount); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, communityData.getId()); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_CONTENT, linkEditText.getText().toString()); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_BODY, contentEditText.getText().toString()); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_URL, linkEditText.getText().toString()); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_LINK); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); | ||||
| @@ -561,8 +617,8 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|     @Override | ||||
|     protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { | ||||
|         super.onActivityResult(requestCode, resultCode, data); | ||||
|         if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { | ||||
|             if (resultCode == RESULT_OK) { | ||||
|         if (resultCode == RESULT_OK) { | ||||
|             if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { | ||||
|                 communityData = data.getExtras().getParcelable(SubredditSelectionActivity.EXTRA_RETURN_COMMUNITY_DATA); | ||||
|                 subredditName = communityData.getName(); | ||||
|                 iconUrl = communityData.getIconUrl(); | ||||
| @@ -574,6 +630,16 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|                 displaySubredditIcon(); | ||||
|  | ||||
|                 flair = null; | ||||
|             } else if (requestCode == PICK_IMAGE_REQUEST_CODE) { | ||||
|                 if (data == null) { | ||||
|                     Toast.makeText(PostLinkActivity.this, R.string.error_getting_image, Toast.LENGTH_LONG).show(); | ||||
|                     return; | ||||
|                 } | ||||
|                 Utils.uploadImageToReddit(this, mExecutor, mRetrofit, | ||||
|                         mAccessToken, contentEditText, coordinatorLayout, data.getData(), uploadedImages); | ||||
|             } else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE) { | ||||
|                 Utils.uploadImageToReddit(this, mExecutor, mRetrofit, | ||||
|                         mAccessToken, contentEditText, coordinatorLayout, capturedImageUri, uploadedImages); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -629,4 +695,37 @@ public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void uploadImage() { | ||||
|         Intent intent = new Intent(); | ||||
|         intent.setType("image/*"); | ||||
|         intent.setAction(Intent.ACTION_GET_CONTENT); | ||||
|         startActivityForResult(Intent.createChooser(intent, | ||||
|                 getResources().getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void captureImage() { | ||||
|         Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); | ||||
|         try { | ||||
|             capturedImageUri = FileProvider.getUriForFile(this, "eu.toldi.infinityforlemmy.provider", | ||||
|                     File.createTempFile("captured_image", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES))); | ||||
|             pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri); | ||||
|             startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE); | ||||
|         } catch (IOException ex) { | ||||
|             Toast.makeText(this, R.string.error_creating_temp_file, Toast.LENGTH_SHORT).show(); | ||||
|         } catch (ActivityNotFoundException e) { | ||||
|             Toast.makeText(this, R.string.no_camera_available, Toast.LENGTH_SHORT).show(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void insertImageUrl(UploadedImage uploadedImage) { | ||||
|         int start = Math.max(contentEditText.getSelectionStart(), 0); | ||||
|         int end = Math.max(contentEditText.getSelectionEnd(), 0); | ||||
|         contentEditText.getText().replace(Math.min(start, end), Math.max(start, end), | ||||
|                 "", | ||||
|                 0, "![]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -219,7 +219,7 @@ public class PostPollActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|         setSupportActionBar(toolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|  | ||||
|         mGlide = Glide.with(this); | ||||
|         mGlide = Glide.with(getApplication()); | ||||
|  | ||||
|         mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); | ||||
|  | ||||
| @@ -500,7 +500,7 @@ public class PostPollActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|     } | ||||
|  | ||||
|     private void loadSubredditIcon() { | ||||
|         LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, mAccessToken, mOauthRetrofit, mRetrofit.getRetrofit(), iconImageUrl -> { | ||||
|         LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, mAccessToken, mRetrofit.getRetrofit(), iconImageUrl -> { | ||||
|             iconUrl = iconImageUrl; | ||||
|             displaySubredditIcon(); | ||||
|             loadSubredditIconSuccessful = true; | ||||
|   | ||||
| @@ -208,7 +208,7 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|         setSupportActionBar(toolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|  | ||||
|         mGlide = Glide.with(this); | ||||
|         mGlide = Glide.with(getApplication()); | ||||
|  | ||||
|         mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); | ||||
|  | ||||
| @@ -450,12 +450,12 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|     } | ||||
|  | ||||
|     private void loadSubredditIcon() { | ||||
|         LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, | ||||
|                 mAccessToken, mOauthRetrofit, mRetrofit.getRetrofit(), iconImageUrl -> { | ||||
|             iconUrl = iconImageUrl; | ||||
|             displaySubredditIcon(); | ||||
|             loadSubredditIconSuccessful = true; | ||||
|         }); | ||||
|         LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, communityData.getQualified_name(), | ||||
|                 mAccessToken, mRetrofit.getRetrofit(), iconImageUrl -> { | ||||
|                     iconUrl = iconImageUrl; | ||||
|                     displaySubredditIcon(); | ||||
|                     loadSubredditIconSuccessful = true; | ||||
|                 }); | ||||
|     } | ||||
|  | ||||
|     private void promptAlertDialog(int titleResId, int messageResId) { | ||||
| @@ -533,7 +533,7 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|         intent.putExtra(SubmitPostService.EXTRA_ACCOUNT, selectedAccount); | ||||
|         intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, communityData.getId()); | ||||
|         intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); | ||||
|         intent.putExtra(SubmitPostService.EXTRA_CONTENT, contentEditText.getText().toString()); | ||||
|         intent.putExtra(SubmitPostService.EXTRA_BODY, contentEditText.getText().toString()); | ||||
|         intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_SELF); | ||||
|         intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); | ||||
|         intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); | ||||
| @@ -673,8 +673,8 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr | ||||
|         int start = Math.max(contentEditText.getSelectionStart(), 0); | ||||
|         int end = Math.max(contentEditText.getSelectionEnd(), 0); | ||||
|         contentEditText.getText().replace(Math.min(start, end), Math.max(start, end), | ||||
|                 "[" + uploadedImage.imageName + "](" + uploadedImage.imageUrl + ")", | ||||
|                 0, "[]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); | ||||
|                 "", | ||||
|                 0, "![]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -216,7 +216,7 @@ public class PostVideoActivity extends BaseActivity implements FlairBottomSheetF | ||||
|         setSupportActionBar(toolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|  | ||||
|         mGlide = Glide.with(this); | ||||
|         mGlide = Glide.with(getApplication()); | ||||
|  | ||||
|         player = new ExoPlayer.Builder(this).build(); | ||||
|         videoPlayerView.setPlayer(player); | ||||
| @@ -447,8 +447,9 @@ public class PostVideoActivity extends BaseActivity implements FlairBottomSheetF | ||||
|         nsfwTextView.setTextColor(primaryTextColor); | ||||
|         titleEditText.setTextColor(primaryTextColor); | ||||
|         titleEditText.setHintTextColor(secondaryTextColor); | ||||
|         applyFABTheme(captureFab); | ||||
|         applyFABTheme(selectFromLibraryFab); | ||||
|         boolean circularFab = mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false); | ||||
|         applyFABTheme(captureFab, circularFab); | ||||
|         applyFABTheme(selectFromLibraryFab, circularFab); | ||||
|         selectAgainTextView.setTextColor(mCustomThemeWrapper.getColorAccent()); | ||||
|         if (typeface != null) { | ||||
|             subredditNameTextView.setTypeface(typeface); | ||||
| @@ -485,11 +486,11 @@ public class PostVideoActivity extends BaseActivity implements FlairBottomSheetF | ||||
|  | ||||
|     private void loadSubredditIcon() { | ||||
|         LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, | ||||
|                 mAccessToken, mOauthRetrofit, mRetrofit.getRetrofit(), iconImageUrl -> { | ||||
|             iconUrl = iconImageUrl; | ||||
|             displaySubredditIcon(); | ||||
|             loadSubredditIconSuccessful = true; | ||||
|         }); | ||||
|                 mAccessToken, mRetrofit.getRetrofit(), iconImageUrl -> { | ||||
|                     iconUrl = iconImageUrl; | ||||
|                     displaySubredditIcon(); | ||||
|                     loadSubredditIconSuccessful = true; | ||||
|                 }); | ||||
|     } | ||||
|  | ||||
|     private void promptAlertDialog(int titleResId, int messageResId) { | ||||
|   | ||||
| @@ -132,7 +132,7 @@ public class RulesActivity extends BaseActivity { | ||||
|  | ||||
|         mSubredditName = getIntent().getExtras().getString(EXTRA_SUBREDDIT_NAME); | ||||
|  | ||||
|         mAdapter = new RulesRecyclerViewAdapter(this, mCustomThemeWrapper, sliderPanel); | ||||
|         mAdapter = new RulesRecyclerViewAdapter(this, mCustomThemeWrapper, sliderPanel, mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false)); | ||||
|         recyclerView.setAdapter(mAdapter); | ||||
|         FetchSubredditData.fetchSubredditData(mRetrofit.getRetrofit(), mSubredditName, mAccessToken, new FetchSubredditData.FetchSubredditDataListener() { | ||||
|             @Override | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package eu.toldi.infinityforlemmy.activities; | ||||
| import android.app.Activity; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.res.ColorStateList; | ||||
| import android.net.Uri; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| @@ -27,11 +28,14 @@ import androidx.lifecycle.ViewModelProvider; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| import com.google.android.material.appbar.AppBarLayout; | ||||
| import com.google.android.material.button.MaterialButton; | ||||
| import com.google.android.material.dialog.MaterialAlertDialogBuilder; | ||||
|  | ||||
| import org.greenrobot.eventbus.EventBus; | ||||
| import org.greenrobot.eventbus.Subscribe; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
| @@ -47,7 +51,6 @@ import eu.toldi.infinityforlemmy.apis.RedditAPI; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.customviews.slidr.Slidr; | ||||
| import eu.toldi.infinityforlemmy.events.SwitchAccountEvent; | ||||
| import eu.toldi.infinityforlemmy.recentsearchquery.DeleteRecentSearchQuery; | ||||
| import eu.toldi.infinityforlemmy.recentsearchquery.RecentSearchQuery; | ||||
| import eu.toldi.infinityforlemmy.recentsearchquery.RecentSearchQueryViewModel; | ||||
| import eu.toldi.infinityforlemmy.subreddit.ParseSubredditData; | ||||
| @@ -98,6 +101,8 @@ public class SearchActivity extends BaseActivity { | ||||
|     ImageView clearSearchTextImageView; | ||||
|     @BindView(R.id.link_handler_image_view_search_activity) | ||||
|     ImageView linkHandlerImageView; | ||||
|     @BindView(R.id.delete_all_recent_searches_button_search_activity) | ||||
|     MaterialButton deleteAllSearchesButton; | ||||
|     @BindView(R.id.subreddit_name_relative_layout_search_activity) | ||||
|     RelativeLayout subredditNameRelativeLayout; | ||||
|     @BindView(R.id.search_in_text_view_search_activity) | ||||
| @@ -124,6 +129,8 @@ public class SearchActivity extends BaseActivity { | ||||
|     SharedPreferences mNsfwAndSpoilerSharedPreferences; | ||||
|     @Inject | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     @Inject | ||||
|     Executor executor; | ||||
|     private String mAccountName; | ||||
|     private String mAccessToken; | ||||
|     private String query; | ||||
| @@ -163,6 +170,7 @@ public class SearchActivity extends BaseActivity { | ||||
|         setSupportActionBar(toolbar); | ||||
|  | ||||
|         clearSearchTextImageView.setVisibility(View.GONE); | ||||
|         deleteAllSearchesButton.setVisibility(View.GONE); | ||||
|  | ||||
|         searchOnlySubreddits = getIntent().getBooleanExtra(EXTRA_SEARCH_ONLY_SUBREDDITS, false); | ||||
|         searchOnlyUsers = getIntent().getBooleanExtra(EXTRA_SEARCH_ONLY_USERS, false); | ||||
| @@ -276,6 +284,17 @@ public class SearchActivity extends BaseActivity { | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         deleteAllSearchesButton.setOnClickListener(view -> { | ||||
|             new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) | ||||
|                     .setTitle(R.string.confirm) | ||||
|                     .setMessage(R.string.confirm_delete_all_recent_searches) | ||||
|                     .setPositiveButton(R.string.yes, (dialogInterface, i) -> { | ||||
|                         executor.execute(() -> mRedditDataRoomDatabase.recentSearchQueryDao().deleteAllRecentSearchQueries(mAccountName)); | ||||
|                     }) | ||||
|                     .setNegativeButton(R.string.no, null) | ||||
|                     .show(); | ||||
|         }); | ||||
|  | ||||
|         if (savedInstanceState != null) { | ||||
|             subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); | ||||
|             subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); | ||||
| @@ -319,7 +338,7 @@ public class SearchActivity extends BaseActivity { | ||||
|  | ||||
|                 @Override | ||||
|                 public void onDelete(RecentSearchQuery recentSearchQuery) { | ||||
|                     DeleteRecentSearchQuery.deleteRecentSearchQueryListener(mRedditDataRoomDatabase, recentSearchQuery, () -> {}); | ||||
|                     executor.execute(() -> mRedditDataRoomDatabase.recentSearchQueryDao().deleteRecentSearchQueries(recentSearchQuery)); | ||||
|                 } | ||||
|             }); | ||||
|             recyclerView.setVisibility(View.VISIBLE); | ||||
| @@ -334,8 +353,10 @@ public class SearchActivity extends BaseActivity { | ||||
|                 mRecentSearchQueryViewModel.getAllRecentSearchQueries().observe(this, recentSearchQueries -> { | ||||
|                     if (recentSearchQueries != null && !recentSearchQueries.isEmpty()) { | ||||
|                         divider.setVisibility(View.VISIBLE); | ||||
|                         deleteAllSearchesButton.setVisibility(View.VISIBLE); | ||||
|                     } else { | ||||
|                         divider.setVisibility(View.GONE); | ||||
|                         deleteAllSearchesButton.setVisibility(View.GONE); | ||||
|                     } | ||||
|                     adapter.setRecentSearchQueries(recentSearchQueries); | ||||
|                 }); | ||||
| @@ -401,6 +422,7 @@ public class SearchActivity extends BaseActivity { | ||||
|         linkHandlerImageView.setColorFilter(mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor(), android.graphics.PorterDuff.Mode.SRC_IN); | ||||
|         int colorAccent = mCustomThemeWrapper.getColorAccent(); | ||||
|         searchInTextView.setTextColor(colorAccent); | ||||
|         deleteAllSearchesButton.setIconTint(ColorStateList.valueOf(mCustomThemeWrapper.getPrimaryIconColor())); | ||||
|         subredditNameTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|         divider.setBackgroundColor(mCustomThemeWrapper.getDividerColor()); | ||||
|         if (typeface != null) { | ||||
| @@ -433,12 +455,14 @@ public class SearchActivity extends BaseActivity { | ||||
|         if (resultCode == RESULT_OK && data != null) { | ||||
|             if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { | ||||
|                 communityData = data.getParcelableExtra(SubredditSelectionActivity.EXTRA_RETURN_COMMUNITY_DATA); | ||||
|                 subredditName = communityData.getName(); | ||||
|  | ||||
|                 subredditIsUser = false; | ||||
|  | ||||
|                 if (subredditName == null) { | ||||
|                 if (communityData == null) { | ||||
|                     subredditNameTextView.setText(R.string.all_communities); | ||||
|                 } else { | ||||
|                     subredditName = communityData.getName(); | ||||
|                     communityQualifiedName = communityData.getQualified_name(); | ||||
|                     subredditNameTextView.setText(subredditName); | ||||
|                 } | ||||
|             } else if (requestCode == SUBREDDIT_SEARCH_REQUEST_CODE) { | ||||
|   | ||||
| @@ -38,6 +38,7 @@ import org.greenrobot.eventbus.EventBus; | ||||
| import org.greenrobot.eventbus.Subscribe; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
| @@ -130,10 +131,11 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect | ||||
|     SharedPreferences mCurrentAccountSharedPreferences; | ||||
|     @Inject | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     @Inject | ||||
|     Executor executor; | ||||
|     private Call<String> subredditAutocompleteCall; | ||||
|     private String mAccessToken; | ||||
|     private String mAccountName; | ||||
|  | ||||
|     private String mAccountQualifiedName; | ||||
|     private String mQuery; | ||||
|     private String mSubredditName; | ||||
| @@ -238,13 +240,13 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect | ||||
|         coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar); | ||||
|         applyTabLayoutTheme(tabLayout); | ||||
|         applyFABTheme(fab); | ||||
|         applyFABTheme(fab, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|     } | ||||
|  | ||||
|     private void bindView(Bundle savedInstanceState) { | ||||
|         sectionsPagerAdapter = new SectionsPagerAdapter(this); | ||||
|         viewPager2.setAdapter(sectionsPagerAdapter); | ||||
|         viewPager2.setOffscreenPageLimit(3); | ||||
|         viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT); | ||||
|         viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); | ||||
|         viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { | ||||
|             @Override | ||||
| @@ -392,8 +394,8 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect | ||||
|         }); | ||||
|  | ||||
|         if (mAccountName != null && mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_SEARCH_HISTORY, true) && !mInsertSearchQuerySuccess && mQuery != null) { | ||||
|             InsertRecentSearchQuery.insertRecentSearchQueryListener(mRedditDataRoomDatabase, mAccountQualifiedName, | ||||
|                     mQuery, () -> mInsertSearchQuerySuccess = true); | ||||
|             InsertRecentSearchQuery.insertRecentSearchQueryListener(executor, new Handler(getMainLooper()), | ||||
|                     mRedditDataRoomDatabase, mAccountQualifiedName, mQuery, () -> mInsertSearchQuerySuccess = true); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -558,10 +560,6 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect | ||||
|                 goToUser(); | ||||
|                 break; | ||||
|             } | ||||
|             case FABMoreOptionsBottomSheetFragment.FAB_RANDOM: { | ||||
|                 random(); | ||||
|                 break; | ||||
|             } | ||||
|             case FABMoreOptionsBottomSheetFragment.FAB_HIDE_READ_POSTS: { | ||||
|                 if (sectionsPagerAdapter != null) { | ||||
|                     sectionsPagerAdapter.hideReadPosts(); | ||||
| @@ -788,7 +786,8 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect | ||||
|                     bundle.putString(SubredditListingFragment.EXTRA_QUERY, mQuery); | ||||
|                     bundle.putBoolean(SubredditListingFragment.EXTRA_IS_GETTING_SUBREDDIT_INFO, false); | ||||
|                     bundle.putString(SubredditListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
|                     bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_NAME, mAccountQualifiedName); | ||||
|                     bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); | ||||
|                     bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_QUALIFIED_NAME, mAccountQualifiedName); | ||||
|                     mFragment.setArguments(bundle); | ||||
|                     return mFragment; | ||||
|                 } | ||||
|   | ||||
| @@ -119,7 +119,8 @@ public class SearchSubredditsResultActivity extends BaseActivity implements Acti | ||||
|             bundle.putString(SubredditListingFragment.EXTRA_QUERY, query); | ||||
|             bundle.putBoolean(SubredditListingFragment.EXTRA_IS_GETTING_SUBREDDIT_INFO, true); | ||||
|             bundle.putString(SubredditListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
|             bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_NAME, mAccountQualifiedName); | ||||
|             bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); | ||||
|             bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_QUALIFIED_NAME, mAccountQualifiedName); | ||||
|             bundle.putBoolean(SubredditListingFragment.EXTRA_IS_MULTI_SELECTION, getIntent().getBooleanExtra(EXTRA_IS_MULTI_SELECTION, false)); | ||||
|             mFragment.setArguments(bundle); | ||||
|         } else { | ||||
|   | ||||
| @@ -194,7 +194,7 @@ public class SelectedSubredditsAndUsersActivity extends BaseActivity implements | ||||
|     protected void applyCustomTheme() { | ||||
|         coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar); | ||||
|         applyFABTheme(fab); | ||||
|         applyFABTheme(fab, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -1,8 +1,13 @@ | ||||
| package eu.toldi.infinityforlemmy.activities; | ||||
|  | ||||
| import android.content.ActivityNotFoundException; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.net.Uri; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| import android.os.Environment; | ||||
| import android.provider.MediaStore; | ||||
| import android.view.Menu; | ||||
| import android.view.MenuItem; | ||||
| import android.view.View; | ||||
| @@ -10,12 +15,20 @@ import android.widget.EditText; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.appcompat.widget.Toolbar; | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout; | ||||
| import androidx.core.content.FileProvider; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| import com.google.android.material.appbar.AppBarLayout; | ||||
| import com.google.android.material.snackbar.Snackbar; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
|  | ||||
| @@ -23,13 +36,24 @@ import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
| import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RetrofitHolder; | ||||
| import eu.toldi.infinityforlemmy.UploadImageEnabledActivity; | ||||
| import eu.toldi.infinityforlemmy.UploadedImage; | ||||
| import eu.toldi.infinityforlemmy.adapters.MarkdownBottomBarRecyclerViewAdapter; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.UploadedImagesBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.message.ComposeMessage; | ||||
| import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; | ||||
| import eu.toldi.infinityforlemmy.privatemessage.LemmyPrivateMessageAPI; | ||||
| import eu.toldi.infinityforlemmy.privatemessage.PrivateMessage; | ||||
| import eu.toldi.infinityforlemmy.user.BasicUserInfo; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import retrofit2.Retrofit; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
|  | ||||
| public class SendPrivateMessageActivity extends BaseActivity { | ||||
|     public static final String EXTRA_RECIPIENT_USERNAME = "ERU"; | ||||
| public class SendPrivateMessageActivity extends BaseActivity implements UploadImageEnabledActivity { | ||||
|     public static final String EXTRA_RECIPIENT_USER_INFO = "ERUI"; | ||||
|  | ||||
|     private static final int PICK_IMAGE_REQUEST_CODE = 100; | ||||
|     private static final int CAPTURE_IMAGE_REQUEST_CODE = 200; | ||||
|     @BindView(R.id.coordinator_layout_send_private_message_activity) | ||||
|     CoordinatorLayout coordinatorLayout; | ||||
|     @BindView(R.id.appbar_layout_send_private_message_activity) | ||||
| @@ -40,15 +64,20 @@ public class SendPrivateMessageActivity extends BaseActivity { | ||||
|     EditText usernameEditText; | ||||
|     @BindView(R.id.divider_1_send_private_message_activity) | ||||
|     View divider1; | ||||
|     @BindView(R.id.subjet_edit_text_send_private_message_activity) | ||||
|     EditText subjectEditText; | ||||
|     @BindView(R.id.divider_2_send_private_message_activity) | ||||
|     View divider2; | ||||
|     @BindView(R.id.content_edit_text_send_private_message_activity) | ||||
|     EditText messageEditText; | ||||
|  | ||||
|     @BindView(R.id.markdown_bottom_bar_recycler_view_send_private_message_activity) | ||||
|     RecyclerView markdownBottomBarRecyclerView; | ||||
|     @Inject | ||||
|     @Named("oauth") | ||||
|     Retrofit mOauthRetrofit; | ||||
|     @Named("no_oauth") | ||||
|     RetrofitHolder mRetrofit; | ||||
|  | ||||
|     @Inject | ||||
|     Executor mExecutor; | ||||
|  | ||||
|     @Inject | ||||
|     @Named("default") | ||||
|     SharedPreferences mSharedPreferences; | ||||
| @@ -57,15 +86,24 @@ public class SendPrivateMessageActivity extends BaseActivity { | ||||
|     SharedPreferences mCurrentAccountSharedPreferences; | ||||
|     @Inject | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|  | ||||
|     @Inject | ||||
|     LemmyPrivateMessageAPI mLemmyPrivateMessageAPI; | ||||
|     private String mAccessToken; | ||||
|  | ||||
|     private BasicUserInfo mRecipientBasicUserInfo; | ||||
|     private boolean isSubmitting = false; | ||||
|  | ||||
|     private ArrayList<UploadedImage> uploadedImages = new ArrayList<>(); | ||||
|  | ||||
|     private Uri capturedImageUri; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         ((Infinity) getApplication()).getAppComponent().inject(this); | ||||
|  | ||||
|         setImmersiveModeNotApplicable(); | ||||
|          | ||||
|  | ||||
|         super.onCreate(savedInstanceState); | ||||
|         setContentView(R.layout.activity_send_private_message); | ||||
|  | ||||
| @@ -77,14 +115,66 @@ public class SendPrivateMessageActivity extends BaseActivity { | ||||
|             addOnOffsetChangedListener(appBarLayout); | ||||
|         } | ||||
|  | ||||
|         MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter( | ||||
|                 mCustomThemeWrapper, new MarkdownBottomBarRecyclerViewAdapter.ItemClickListener() { | ||||
|             @Override | ||||
|             public void onClick(int item) { | ||||
|                 MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener( | ||||
|                         SendPrivateMessageActivity.this, messageEditText, item); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onUploadImage() { | ||||
|                 Utils.hideKeyboard(SendPrivateMessageActivity.this); | ||||
|                 UploadedImagesBottomSheetFragment fragment = new UploadedImagesBottomSheetFragment(); | ||||
|                 Bundle arguments = new Bundle(); | ||||
|                 arguments.putParcelableArrayList(UploadedImagesBottomSheetFragment.EXTRA_UPLOADED_IMAGES, | ||||
|                         uploadedImages); | ||||
|                 fragment.setArguments(arguments); | ||||
|                 fragment.show(getSupportFragmentManager(), fragment.getTag()); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this, | ||||
|                 LinearLayoutManagerBugFixed.HORIZONTAL, false)); | ||||
|         markdownBottomBarRecyclerView.setAdapter(adapter); | ||||
|  | ||||
|         mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); | ||||
|  | ||||
|         setSupportActionBar(toolbar); | ||||
|  | ||||
|         String username = getIntent().getStringExtra(EXTRA_RECIPIENT_USERNAME); | ||||
|         if (username != null) { | ||||
|             usernameEditText.setText(username); | ||||
|         if (savedInstanceState != null) { | ||||
|             mRecipientBasicUserInfo = savedInstanceState.getParcelable(EXTRA_RECIPIENT_USER_INFO); | ||||
|         } else { | ||||
|             mRecipientBasicUserInfo = getIntent().getParcelableExtra(EXTRA_RECIPIENT_USER_INFO); | ||||
|         } | ||||
|  | ||||
|         if (mRecipientBasicUserInfo != null) { | ||||
|             usernameEditText.setText(mRecipientBasicUserInfo.getQualifiedName()); | ||||
|             usernameEditText.setEnabled(false); | ||||
|         } else { | ||||
|             finish(); | ||||
|         } | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { | ||||
|         super.onActivityResult(requestCode, resultCode, data); | ||||
|         if (resultCode == RESULT_OK) { | ||||
|             if (requestCode == PICK_IMAGE_REQUEST_CODE) { | ||||
|                 if (data == null) { | ||||
|                     Toast.makeText(SendPrivateMessageActivity.this, R.string.error_getting_image, Toast.LENGTH_LONG).show(); | ||||
|                     return; | ||||
|                 } | ||||
|                 Utils.uploadImageToReddit(this, mExecutor, mRetrofit, | ||||
|                         mAccessToken, messageEditText, coordinatorLayout, data.getData(), uploadedImages); | ||||
|             } else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE) { | ||||
|                 Utils.uploadImageToReddit(this, mExecutor, mRetrofit, | ||||
|                         mAccessToken, messageEditText, coordinatorLayout, capturedImageUri, uploadedImages); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -108,12 +198,6 @@ public class SendPrivateMessageActivity extends BaseActivity { | ||||
|                     return true; | ||||
|                 } | ||||
|  | ||||
|                 if (subjectEditText.getText() == null || subjectEditText.getText().toString().equals("")) { | ||||
|                     isSubmitting = false; | ||||
|                     Snackbar.make(coordinatorLayout, R.string.message_subject_required, Snackbar.LENGTH_LONG).show(); | ||||
|                     return true; | ||||
|                 } | ||||
|  | ||||
|                 if (messageEditText.getText() == null || messageEditText.getText().toString().equals("")) { | ||||
|                     isSubmitting = false; | ||||
|                     Snackbar.make(coordinatorLayout, R.string.message_content_required, Snackbar.LENGTH_LONG).show(); | ||||
| @@ -125,32 +209,26 @@ public class SendPrivateMessageActivity extends BaseActivity { | ||||
|                 Snackbar sendingSnackbar = Snackbar.make(coordinatorLayout, R.string.sending_message, Snackbar.LENGTH_INDEFINITE); | ||||
|                 sendingSnackbar.show(); | ||||
|  | ||||
|                 ComposeMessage.composeMessage(mOauthRetrofit, mAccessToken, getResources().getConfiguration().locale, | ||||
|                         usernameEditText.getText().toString(), subjectEditText.getText().toString(), | ||||
|                         messageEditText.getText().toString(), new ComposeMessage.ComposeMessageListener() { | ||||
|                             @Override | ||||
|                             public void composeMessageSuccess() { | ||||
|                                 isSubmitting = false; | ||||
|                                 item.setEnabled(true); | ||||
|                                 item.getIcon().setAlpha(255); | ||||
|                                 Toast.makeText(SendPrivateMessageActivity.this, R.string.send_message_success, Toast.LENGTH_SHORT).show(); | ||||
|                                 finish(); | ||||
|                             } | ||||
|                 mLemmyPrivateMessageAPI.sendPrivateMessage(mAccessToken, mRecipientBasicUserInfo.getId(), messageEditText.getText().toString(), new LemmyPrivateMessageAPI.PrivateMessageSentListener() { | ||||
|                     @Override | ||||
|                     public void onPrivateMessageSentSuccess(@NonNull PrivateMessage privateMessage) { | ||||
|                         isSubmitting = false; | ||||
|                         item.setEnabled(true); | ||||
|                         item.getIcon().setAlpha(255); | ||||
|                         Toast.makeText(SendPrivateMessageActivity.this, R.string.send_message_success, Toast.LENGTH_SHORT).show(); | ||||
|                         finish(); | ||||
|                     } | ||||
|  | ||||
|                             @Override | ||||
|                             public void composeMessageFailed(String errorMessage) { | ||||
|                                 isSubmitting = false; | ||||
|                                 sendingSnackbar.dismiss(); | ||||
|                                 item.setEnabled(true); | ||||
|                                 item.getIcon().setAlpha(255); | ||||
|                     @Override | ||||
|                     public void onPrivateMessageSentError() { | ||||
|                         isSubmitting = false; | ||||
|                         sendingSnackbar.dismiss(); | ||||
|                         item.setEnabled(true); | ||||
|                         item.getIcon().setAlpha(255); | ||||
|  | ||||
|                                 if (errorMessage == null || errorMessage.equals("")) { | ||||
|                                     Snackbar.make(coordinatorLayout, R.string.send_message_failed, Snackbar.LENGTH_LONG).show(); | ||||
|                                 } else { | ||||
|                                     Snackbar.make(coordinatorLayout, errorMessage, Snackbar.LENGTH_LONG).show(); | ||||
|                                 } | ||||
|                             } | ||||
|                         }); | ||||
|                         Snackbar.make(coordinatorLayout, R.string.send_message_failed, Snackbar.LENGTH_LONG).show(); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
| @@ -159,6 +237,7 @@ public class SendPrivateMessageActivity extends BaseActivity { | ||||
|     @Override | ||||
|     protected void onSaveInstanceState(@NonNull Bundle outState) { | ||||
|         super.onSaveInstanceState(outState); | ||||
|         outState.putParcelable(EXTRA_RECIPIENT_USER_INFO, mRecipientBasicUserInfo); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -177,19 +256,49 @@ public class SendPrivateMessageActivity extends BaseActivity { | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, null, toolbar); | ||||
|         int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); | ||||
|         usernameEditText.setTextColor(primaryTextColor); | ||||
|         subjectEditText.setTextColor(primaryTextColor); | ||||
|         messageEditText.setTextColor(primaryTextColor); | ||||
|         int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); | ||||
|         usernameEditText.setHintTextColor(secondaryTextColor); | ||||
|         subjectEditText.setHintTextColor(secondaryTextColor); | ||||
|         messageEditText.setHintTextColor(secondaryTextColor); | ||||
|         int dividerColor = mCustomThemeWrapper.getDividerColor(); | ||||
|         divider1.setBackgroundColor(dividerColor); | ||||
|         divider2.setBackgroundColor(dividerColor); | ||||
|         if (typeface != null) { | ||||
|             usernameEditText.setTypeface(typeface); | ||||
|             subjectEditText.setTypeface(typeface); | ||||
|             messageEditText.setTypeface(typeface); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void uploadImage() { | ||||
|         Intent intent = new Intent(); | ||||
|         intent.setType("image/*"); | ||||
|         intent.setAction(Intent.ACTION_GET_CONTENT); | ||||
|         startActivityForResult(Intent.createChooser(intent, | ||||
|                 getResources().getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void captureImage() { | ||||
|         Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); | ||||
|         try { | ||||
|             capturedImageUri = FileProvider.getUriForFile(this, "eu.toldi.infinityforlemmy.provider", | ||||
|                     File.createTempFile("captured_image", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES))); | ||||
|             pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri); | ||||
|             startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE); | ||||
|         } catch (IOException ex) { | ||||
|             Toast.makeText(this, R.string.error_creating_temp_file, Toast.LENGTH_SHORT).show(); | ||||
|         } catch (ActivityNotFoundException e) { | ||||
|             Toast.makeText(this, R.string.no_camera_available, Toast.LENGTH_SHORT).show(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void insertImageUrl(UploadedImage uploadedImage) { | ||||
|         int start = Math.max(messageEditText.getSelectionStart(), 0); | ||||
|         int end = Math.max(messageEditText.getSelectionEnd(), 0); | ||||
|         messageEditText.getText().replace(Math.min(start, end), Math.max(start, end), | ||||
|                 "", | ||||
|                 0, "![]()".length() + uploadedImage.imageName.length() + uploadedImage.imageUrl.length()); | ||||
|     } | ||||
| } | ||||
| @@ -112,8 +112,6 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom | ||||
|     View divider1; | ||||
|     @BindView(R.id.flair_custom_text_view_submit_crosspost_activity) | ||||
|     CustomTextView flairTextView; | ||||
|     @BindView(R.id.spoiler_custom_text_view_submit_crosspost_activity) | ||||
|     CustomTextView spoilerTextView; | ||||
|     @BindView(R.id.nsfw_custom_text_view_submit_crosspost_activity) | ||||
|     CustomTextView nsfwTextView; | ||||
|     @BindView(R.id.divider_2_submit_crosspost_activity) | ||||
| @@ -204,7 +202,7 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom | ||||
|         setSupportActionBar(toolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|  | ||||
|         mGlide = Glide.with(this); | ||||
|         mGlide = Glide.with(getApplication()); | ||||
|  | ||||
|         mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); | ||||
|  | ||||
| @@ -259,11 +257,6 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom | ||||
|                 flairTextView.setBorderColor(flairBackgroundColor); | ||||
|                 flairTextView.setTextColor(flairTextColor); | ||||
|             } | ||||
|             if (isSpoiler) { | ||||
|                 spoilerTextView.setBackgroundColor(spoilerBackgroundColor); | ||||
|                 spoilerTextView.setBorderColor(spoilerBackgroundColor); | ||||
|                 spoilerTextView.setTextColor(spoilerTextColor); | ||||
|             } | ||||
|             if (isNSFW) { | ||||
|                 nsfwTextView.setBackgroundColor(nsfwBackgroundColor); | ||||
|                 nsfwTextView.setBorderColor(nsfwBackgroundColor); | ||||
| @@ -287,13 +280,14 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom | ||||
|             titleEditText.setText(post.getTitle()); | ||||
|         } | ||||
|  | ||||
|         if (post.getPostType() == Post.TEXT_TYPE) { | ||||
|         if (post.getPostType() == Post.TEXT_TYPE || post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { | ||||
|             contentTextView.setVisibility(View.VISIBLE); | ||||
|             contentTextView.setText(post.getSelfTextPlain()); | ||||
|         } else if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { | ||||
|             contentTextView.setVisibility(View.VISIBLE); | ||||
|             contentTextView.setText(post.getUrl()); | ||||
|             contentTextView.setText(generateCrossPostText(post)); | ||||
|         } else { | ||||
|             if (post.getSelfTextPlain() != null && !post.getSelfTextPlain().equals("")) { | ||||
|                 contentTextView.setVisibility(View.VISIBLE); | ||||
|                 contentTextView.setText(generateCrossPostText(post)); | ||||
|             } | ||||
|             Post.Preview preview = getPreview(post); | ||||
|             if (preview != null) { | ||||
|                 frameLayout.setVisibility(View.VISIBLE); | ||||
| @@ -368,18 +362,6 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         spoilerTextView.setOnClickListener(view -> { | ||||
|             if (!isSpoiler) { | ||||
|                 spoilerTextView.setBackgroundColor(spoilerBackgroundColor); | ||||
|                 spoilerTextView.setBorderColor(spoilerBackgroundColor); | ||||
|                 spoilerTextView.setTextColor(spoilerTextColor); | ||||
|                 isSpoiler = true; | ||||
|             } else { | ||||
|                 spoilerTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); | ||||
|                 spoilerTextView.setTextColor(primaryTextColor); | ||||
|                 isSpoiler = false; | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         nsfwTextView.setOnClickListener(view -> { | ||||
|             if (!isNSFW) { | ||||
| @@ -461,7 +443,6 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom | ||||
|         nsfwBackgroundColor = mCustomThemeWrapper.getNsfwBackgroundColor(); | ||||
|         nsfwTextColor = mCustomThemeWrapper.getNsfwTextColor(); | ||||
|         flairTextView.setTextColor(primaryTextColor); | ||||
|         spoilerTextView.setTextColor(primaryTextColor); | ||||
|         nsfwTextView.setTextColor(primaryTextColor); | ||||
|         titleEditText.setTextColor(primaryTextColor); | ||||
|         titleEditText.setHintTextColor(secondaryTextColor); | ||||
| @@ -474,7 +455,6 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom | ||||
|             rulesButton.setTypeface(typeface); | ||||
|             receivePostReplyNotificationsTextView.setTypeface(typeface); | ||||
|             flairTextView.setTypeface(typeface); | ||||
|             spoilerTextView.setTypeface(typeface); | ||||
|             nsfwTextView.setTypeface(typeface); | ||||
|             titleEditText.setTypeface(typeface); | ||||
|         } | ||||
| @@ -499,11 +479,11 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom | ||||
|  | ||||
|     private void loadSubredditIcon() { | ||||
|         LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, | ||||
|                 mAccessToken, mOauthRetrofit, mRetrofit.getRetrofit(), iconImageUrl -> { | ||||
|             iconUrl = iconImageUrl; | ||||
|             displaySubredditIcon(); | ||||
|             loadSubredditIconSuccessful = true; | ||||
|         }); | ||||
|                 mAccessToken, mRetrofit.getRetrofit(), iconImageUrl -> { | ||||
|                     iconUrl = iconImageUrl; | ||||
|                     displaySubredditIcon(); | ||||
|                     loadSubredditIconSuccessful = true; | ||||
|                 }); | ||||
|     } | ||||
|  | ||||
|     private void promptAlertDialog(int titleResId, int messageResId) { | ||||
| @@ -561,22 +541,19 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom | ||||
|  | ||||
|             mPostingSnackbar.show(); | ||||
|  | ||||
|             String subredditName; | ||||
|             if (subredditIsUser) { | ||||
|                 subredditName = "u_" + subredditNameTextView.getText().toString(); | ||||
|             } else { | ||||
|                 subredditName = subredditNameTextView.getText().toString(); | ||||
|             } | ||||
|             String subredditName = subredditNameTextView.getText().toString(); | ||||
|  | ||||
|  | ||||
|             Intent intent = new Intent(this, SubmitPostService.class); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_ACCOUNT, selectedAccount); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, communityData.getId()); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); | ||||
|             if (post.isCrosspost()) { | ||||
|                 intent.putExtra(SubmitPostService.EXTRA_CONTENT, "t3_" + post.getCrosspostParentId()); | ||||
|             } else { | ||||
|                 intent.putExtra(SubmitPostService.EXTRA_CONTENT, post.getFullName()); | ||||
|  | ||||
|             intent.putExtra(SubmitPostService.EXTRA_BODY, generateCrossPostText(post)); | ||||
|             if (post.getUrl() != null && !post.getUrl().equals("")) { | ||||
|                 intent.putExtra(SubmitPostService.EXTRA_URL, post.getUrl()); | ||||
|             } | ||||
|  | ||||
|             intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_CROSSPOST); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); | ||||
|             intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); | ||||
| @@ -699,4 +676,15 @@ public class SubmitCrosspostActivity extends BaseActivity implements FlairBottom | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static String generateCrossPostText(Post post) { | ||||
|         StringBuilder stringBuilder = new StringBuilder(); | ||||
|         stringBuilder.append("cross-posted from: ").append(post.getPermalink()).append("\n"); | ||||
|         String[] lines = post.getSelfTextPlain().split("\n"); | ||||
|         for (String line : lines) { | ||||
|             stringBuilder.append("> ").append(line).append("\n"); | ||||
|         } | ||||
|  | ||||
|         return stringBuilder.toString(); | ||||
|     } | ||||
| } | ||||
| @@ -127,7 +127,7 @@ public class SubredditMultiselectionActivity extends BaseActivity implements Act | ||||
|         setSupportActionBar(mToolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|  | ||||
|         mGlide = Glide.with(this); | ||||
|         mGlide = Glide.with(getApplication()); | ||||
|  | ||||
|         mSwipeRefreshLayout.setEnabled(false); | ||||
|  | ||||
|   | ||||
| @@ -73,7 +73,6 @@ import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
| ; | ||||
|  | ||||
| public class SubscribedThingListingActivity extends BaseActivity implements ActivityToolbarInterface { | ||||
|  | ||||
| @@ -113,6 +112,9 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti | ||||
|     @Named("current_account") | ||||
|     SharedPreferences mCurrentAccountSharedPreferences; | ||||
|     @Inject | ||||
|     @Named("internal") | ||||
|     SharedPreferences mInternalSharedPreferences; | ||||
|     @Inject | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     @Inject | ||||
|     Executor mExecutor; | ||||
| @@ -221,7 +223,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti | ||||
|         coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar); | ||||
|         applyTabLayoutTheme(tabLayout); | ||||
|         applyFABTheme(fab); | ||||
|         applyFABTheme(fab, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|         searchEditText.setTextColor(mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor()); | ||||
|         searchEditText.setHintTextColor(mCustomThemeWrapper.getToolbarSecondaryTextColor()); | ||||
|     } | ||||
| @@ -233,7 +235,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti | ||||
|         }); | ||||
|         sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); | ||||
|         viewPager.setAdapter(sectionsPagerAdapter); | ||||
|         viewPager.setOffscreenPageLimit(3); | ||||
|         viewPager.setOffscreenPageLimit(1); | ||||
|         if (viewPager.getCurrentItem() != 2) { | ||||
|             fab.hide(); | ||||
|         } | ||||
| @@ -324,6 +326,10 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti | ||||
|     } | ||||
|  | ||||
|     public void loadSubscriptions(boolean forceLoad) { | ||||
|         if (!forceLoad && System.currentTimeMillis() - mInternalSharedPreferences.getLong(SharedPreferencesUtils.SUBSCRIBED_THINGS_SYNC_TIME, 0L) < 24 * 60 * 60 * 1000) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (mAccessToken != null && !(!forceLoad && mInsertSuccess)) { | ||||
|             FetchSubscribedThing.fetchSubscribedThing(mRetrofit.getRetrofit(), mAccessToken, mAccountQualifiedName, null, | ||||
|                     new ArrayList<>(), new ArrayList<>(), | ||||
| @@ -333,6 +339,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti | ||||
|                         public void onFetchSubscribedThingSuccess(ArrayList<SubscribedSubredditData> subscribedSubredditData, | ||||
|                                                                   ArrayList<SubscribedUserData> subscribedUserData, | ||||
|                                                                   ArrayList<SubredditData> subredditData) { | ||||
|                             mInternalSharedPreferences.edit().putLong(SharedPreferencesUtils.SUBSCRIBED_THINGS_SYNC_TIME, System.currentTimeMillis()).apply(); | ||||
|                             InsertSubscribedThings.insertSubscribedThings( | ||||
|                                     mExecutor, | ||||
|                                     new Handler(), | ||||
| @@ -358,7 +365,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti | ||||
|         } | ||||
|  | ||||
|         if (!(!forceLoad && mInsertMultiredditSuccess)) { | ||||
|             loadMultiReddits(); | ||||
|             //loadMultiReddits(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -412,7 +419,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti | ||||
|                                     public void success() { | ||||
|                                         Toast.makeText(SubscribedThingListingActivity.this, | ||||
|                                                 R.string.delete_multi_reddit_success, Toast.LENGTH_SHORT).show(); | ||||
|                                         loadMultiReddits(); | ||||
|                                         //loadMultiReddits(); | ||||
|                                     } | ||||
|  | ||||
|                                     @Override | ||||
| @@ -439,7 +446,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti | ||||
|  | ||||
|     @Subscribe | ||||
|     public void onRefreshMultiRedditsEvent(RefreshMultiRedditsEvent event) { | ||||
|         loadMultiReddits(); | ||||
|         //loadMultiReddits(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -477,6 +484,7 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti | ||||
|         @Override | ||||
|         public Fragment getItem(int position) { | ||||
|             switch (position) { | ||||
|                 default: | ||||
|                 case 0: { | ||||
|                     SubscribedSubredditsListingFragment fragment = new SubscribedSubredditsListingFragment(); | ||||
|                     Bundle bundle = new Bundle(); | ||||
| @@ -487,28 +495,12 @@ public class SubscribedThingListingActivity extends BaseActivity implements Acti | ||||
|                     fragment.setArguments(bundle); | ||||
|                     return fragment; | ||||
|                 } | ||||
|                 case 1: { | ||||
|                     FollowedUsersListingFragment fragment = new FollowedUsersListingFragment(); | ||||
|                     Bundle bundle = new Bundle(); | ||||
|                     bundle.putString(FollowedUsersListingFragment.EXTRA_ACCOUNT_NAME, mAccountName == null ? "-" : mAccountName); | ||||
|                     bundle.putString(FollowedUsersListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
|                     fragment.setArguments(bundle); | ||||
|                     return fragment; | ||||
|                 } | ||||
|                 default: { | ||||
|                     MultiRedditListingFragment fragment = new MultiRedditListingFragment(); | ||||
|                     Bundle bundle = new Bundle(); | ||||
|                     bundle.putString(MultiRedditListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
|                     bundle.putString(MultiRedditListingFragment.EXTRA_ACCOUNT_NAME, mAccountName == null ? "-" : mAccountName); | ||||
|                     fragment.setArguments(bundle); | ||||
|                     return fragment; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public int getCount() { | ||||
|             return 3; | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|   | ||||
| @@ -152,7 +152,7 @@ public class TrendingActivity extends BaseActivity { | ||||
|  | ||||
|         mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); | ||||
|  | ||||
|         mGlide = Glide.with(this); | ||||
|         mGlide = Glide.with(getApplication()); | ||||
|  | ||||
|         DisplayMetrics displayMetrics = new DisplayMetrics(); | ||||
|         getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); | ||||
| @@ -201,7 +201,7 @@ public class TrendingActivity extends BaseActivity { | ||||
|         isRefreshing = true; | ||||
|  | ||||
|         errorLinearLayout.setVisibility(View.GONE); | ||||
|         Glide.with(this).clear(errorImageView); | ||||
|         Glide.with(getApplication()).clear(errorImageView); | ||||
|         swipeRefreshLayout.setRefreshing(true); | ||||
|         trendingSearches = null; | ||||
|         adapter.setTrendingSearches(null); | ||||
|   | ||||
| @@ -78,6 +78,7 @@ import eu.toldi.infinityforlemmy.font.TitleFontStyle; | ||||
| import eu.toldi.infinityforlemmy.services.DownloadMediaService; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
| import okhttp3.OkHttpClient; | ||||
|  | ||||
| public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWallpaperCallback, CustomFontReceiver { | ||||
|  | ||||
| @@ -108,6 +109,9 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa | ||||
|     @Named("default") | ||||
|     SharedPreferences mSharedPreferences; | ||||
|     @Inject | ||||
|     @Named("glide") | ||||
|     OkHttpClient okHttpClient; | ||||
|     @Inject | ||||
|     Executor mExecutor; | ||||
|     private boolean isActionBarHidden = false; | ||||
|     private boolean isDownloading = false; | ||||
| @@ -146,7 +150,7 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa | ||||
|         getTheme().applyStyle(ContentFontFamily.valueOf(mSharedPreferences | ||||
|                 .getString(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY, ContentFontFamily.Default.name())).getResId(), true); | ||||
|  | ||||
|         BigImageViewer.initialize(GlideImageLoader.with(this.getApplicationContext())); | ||||
|         BigImageViewer.initialize(GlideImageLoader.with(this.getApplicationContext(), okHttpClient)); | ||||
|  | ||||
|         setContentView(R.layout.activity_view_image_or_gif); | ||||
|  | ||||
| @@ -161,7 +165,7 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa | ||||
|             Slidr.attach(this, new SlidrConfig.Builder().position(SlidrPosition.VERTICAL).distanceThreshold(0.125f).build()); | ||||
|         } | ||||
|  | ||||
|         glide = Glide.with(this); | ||||
|         glide = Glide.with(getApplication()); | ||||
|  | ||||
|         handler = new Handler(); | ||||
|  | ||||
|   | ||||
| @@ -67,6 +67,7 @@ import eu.toldi.infinityforlemmy.events.SwitchAccountEvent; | ||||
| import eu.toldi.infinityforlemmy.fragments.PostFragment; | ||||
| import eu.toldi.infinityforlemmy.multireddit.DeleteMultiReddit; | ||||
| import eu.toldi.infinityforlemmy.multireddit.MultiReddit; | ||||
| import eu.toldi.infinityforlemmy.post.MarkPostAsRead; | ||||
| import eu.toldi.infinityforlemmy.post.Post; | ||||
| import eu.toldi.infinityforlemmy.post.PostPagingSource; | ||||
| import eu.toldi.infinityforlemmy.readpost.InsertReadPost; | ||||
| @@ -131,8 +132,11 @@ public class ViewMultiRedditDetailActivity extends BaseActivity implements SortT | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     @Inject | ||||
|     Executor mExecutor; | ||||
|     @Inject | ||||
|     MarkPostAsRead markPostAsRead; | ||||
|     private String mAccessToken; | ||||
|     private String mAccountName; | ||||
|     private String mAccountQualifiedName; | ||||
|     private String multiPath; | ||||
|     private Fragment mFragment; | ||||
|     private int fabOption; | ||||
| @@ -221,6 +225,7 @@ public class ViewMultiRedditDetailActivity extends BaseActivity implements SortT | ||||
|  | ||||
|         mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); | ||||
|         mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); | ||||
|         mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null); | ||||
|         lockBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_BOTTOM_APP_BAR, false); | ||||
|  | ||||
|         if (savedInstanceState != null) { | ||||
| @@ -848,7 +853,7 @@ public class ViewMultiRedditDetailActivity extends BaseActivity implements SortT | ||||
|         coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, collapsingToolbarLayout, toolbar); | ||||
|         navigationWrapper.applyCustomTheme(mCustomThemeWrapper.getBottomAppBarIconColor(), mCustomThemeWrapper.getBottomAppBarBackgroundColor()); | ||||
|         applyFABTheme(navigationWrapper.floatingActionButton); | ||||
|         applyFABTheme(navigationWrapper.floatingActionButton, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -868,7 +873,17 @@ public class ViewMultiRedditDetailActivity extends BaseActivity implements SortT | ||||
|  | ||||
|     @Override | ||||
|     public void markPostAsRead(Post post) { | ||||
|         InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountName, post.getId()); | ||||
|         markPostAsRead.markPostAsRead(post.getId(), mAccessToken, new MarkPostAsRead.MarkPostAsReadListener() { | ||||
|             @Override | ||||
|             public void onMarkPostAsReadSuccess() { | ||||
|                 InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountQualifiedName, post.getId()); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onMarkPostAsReadFailed() { | ||||
|                 Toast.makeText(ViewMultiRedditDetailActivity.this, R.string.mark_post_as_read_failed, Toast.LENGTH_SHORT).show(); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -931,10 +946,6 @@ public class ViewMultiRedditDetailActivity extends BaseActivity implements SortT | ||||
|                 goToUser(); | ||||
|                 break; | ||||
|             } | ||||
|             case FABMoreOptionsBottomSheetFragment.FAB_RANDOM: { | ||||
|                 random(); | ||||
|                 break; | ||||
|             } | ||||
|             case FABMoreOptionsBottomSheetFragment.FAB_HIDE_READ_POSTS: { | ||||
|                 if (mFragment instanceof PostFragment) { | ||||
|                     ((PostFragment) mFragment).hideReadPosts(); | ||||
|   | ||||
| @@ -67,6 +67,7 @@ import eu.toldi.infinityforlemmy.SaveComment; | ||||
| import eu.toldi.infinityforlemmy.SaveThing; | ||||
| import eu.toldi.infinityforlemmy.SortType; | ||||
| import eu.toldi.infinityforlemmy.SortTypeSelectionCallback; | ||||
| import eu.toldi.infinityforlemmy.apis.LemmyAPI; | ||||
| import eu.toldi.infinityforlemmy.apis.RedditAPI; | ||||
| import eu.toldi.infinityforlemmy.asynctasks.SwitchAccount; | ||||
| import eu.toldi.infinityforlemmy.comment.Comment; | ||||
| @@ -81,10 +82,12 @@ import eu.toldi.infinityforlemmy.post.HistoryPostPagingSource; | ||||
| import eu.toldi.infinityforlemmy.post.ParsePost; | ||||
| import eu.toldi.infinityforlemmy.post.Post; | ||||
| import eu.toldi.infinityforlemmy.post.PostPagingSource; | ||||
| import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; | ||||
| import eu.toldi.infinityforlemmy.postfilter.PostFilter; | ||||
| import eu.toldi.infinityforlemmy.readpost.ReadPost; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import okhttp3.OkHttpClient; | ||||
| import retrofit2.Call; | ||||
| import retrofit2.Response; | ||||
| import retrofit2.Retrofit; | ||||
| @@ -95,6 +98,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele | ||||
|     public static final String EXTRA_POST_ID = "EPI"; | ||||
|     public static final String EXTRA_POST_LIST_POSITION = "EPLP"; | ||||
|     public static final String EXTRA_SINGLE_COMMENT_ID = "ESCI"; | ||||
|     public static final String EXTRA_SINGLE_COMMENT_PARENT_ID = "ESCPI"; | ||||
|     public static final String EXTRA_CONTEXT_NUMBER = "ECN"; | ||||
|     public static final String EXTRA_MESSAGE_FULLNAME = "ENI"; | ||||
|     public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; | ||||
| @@ -146,6 +150,11 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     @Inject | ||||
|     Executor mExecutor; | ||||
|     @Inject | ||||
|     @Named("glide") | ||||
|     OkHttpClient okHttpClient; | ||||
|     @Inject | ||||
|     PostEnricher postEnricher; | ||||
|     @State | ||||
|     ArrayList<Post> posts; | ||||
|     @State | ||||
| @@ -180,6 +189,8 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele | ||||
|     private SectionsPagerAdapter sectionsPagerAdapter; | ||||
|     private String mAccessToken; | ||||
|     private String mAccountName; | ||||
|  | ||||
|     private String mAccountQalifiedName; | ||||
|     private long postFragmentId; | ||||
|     private int postListPosition; | ||||
|     private int orientation; | ||||
| @@ -192,7 +203,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele | ||||
|  | ||||
|         super.onCreate(savedInstanceState); | ||||
|  | ||||
|         BigImageViewer.initialize(GlideImageLoader.with(this.getApplicationContext())); | ||||
|         BigImageViewer.initialize(GlideImageLoader.with(this.getApplicationContext(), okHttpClient)); | ||||
|  | ||||
|         setContentView(R.layout.activity_view_post_detail); | ||||
|  | ||||
| @@ -268,6 +279,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele | ||||
|  | ||||
|         mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); | ||||
|         mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); | ||||
|         mAccountQalifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null); | ||||
|  | ||||
|         mVolumeKeysNavigateComments = mSharedPreferences.getBoolean(SharedPreferencesUtils.VOLUME_KEYS_NAVIGATE_COMMENTS, false); | ||||
|  | ||||
| @@ -335,7 +347,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele | ||||
|     protected void applyCustomTheme() { | ||||
|         mCoordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); | ||||
|         applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(mAppBarLayout, mCollapsingToolbarLayout, mToolbar); | ||||
|         applyFABTheme(fab); | ||||
|         applyFABTheme(fab, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|         searchPanelMaterialCardView.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimary())); | ||||
|         int searchPanelTextAndIconColor = mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor(); | ||||
|         searchTextInputLayout.setBoxStrokeColor(searchPanelTextAndIconColor); | ||||
| @@ -352,8 +364,8 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele | ||||
|  | ||||
|     private void checkNewAccountAndBindView(Bundle savedInstanceState) { | ||||
|         if (mNewAccountName != null) { | ||||
|             if (mAccountName == null || !mAccountName.equals(mNewAccountName)) { | ||||
|                 SwitchAccount.switchAccount(mRedditDataRoomDatabase,mRetrofit, mCurrentAccountSharedPreferences, | ||||
|             if (mAccountName == null || !mAccountQalifiedName.equals(mNewAccountName)) { | ||||
|                 SwitchAccount.switchAccount(mRedditDataRoomDatabase, mRetrofit, mCurrentAccountSharedPreferences, | ||||
|                         mExecutor, new Handler(), mNewAccountName, newAccount -> { | ||||
|                             EventBus.getDefault().post(new SwitchAccountEvent(getClass().getName())); | ||||
|                             Toast.makeText(this, R.string.account_switched, Toast.LENGTH_SHORT).show(); | ||||
| @@ -425,11 +437,11 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public void deleteComment(String fullName, int position) { | ||||
|     public void deleteComment(int comment_id, int position) { | ||||
|         if (sectionsPagerAdapter != null) { | ||||
|             ViewPostDetailFragment fragment = sectionsPagerAdapter.getCurrentFragment(); | ||||
|             if (fragment != null) { | ||||
|                 fragment.deleteComment(fullName, position); | ||||
|                 fragment.deleteComment(comment_id, position); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -522,69 +534,38 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele | ||||
|         Handler handler = new Handler(Looper.getMainLooper()); | ||||
|  | ||||
|         if (postType != HistoryPostPagingSource.TYPE_READ_POSTS) { | ||||
|             int nextPage = posts.size() / 25 + 1; | ||||
|  | ||||
|             mExecutor.execute(() -> { | ||||
|                 RedditAPI api = (mAccessToken == null ? mRetrofit.getRetrofit() : mOauthRetrofit).create(RedditAPI.class); | ||||
|                 LemmyAPI api = mRetrofit.getRetrofit().create(LemmyAPI.class); | ||||
|                 Call<String> call; | ||||
|                 String afterKey = posts.isEmpty() ? null : posts.get(posts.size() - 1).getFullName(); | ||||
|  | ||||
|                 switch (postType) { | ||||
|                     case PostPagingSource.TYPE_SUBREDDIT: | ||||
|                         if (mAccessToken == null) { | ||||
|                             call = api.getSubredditBestPosts(subredditName, sortType, sortTime, afterKey); | ||||
|                         } else { | ||||
|                             call = api.getSubredditBestPostsOauth(subredditName, sortType, | ||||
|                                    sortTime, afterKey, APIUtils.getOAuthHeader(mAccessToken)); | ||||
|                         } | ||||
|                         call = api.getPosts(null, sortType.value, nextPage, 25, null, post.getSubredditNamePrefixed(), false, mAccessToken); | ||||
|                         break; | ||||
|                     case PostPagingSource.TYPE_USER: | ||||
|                         if (mAccessToken == null) { | ||||
|                             call = api.getUserPosts(username, afterKey, sortType, sortTime); | ||||
|                         } else { | ||||
|                             call = api.getUserPostsOauth(username, userWhere, afterKey, sortType, | ||||
|                                     sortTime, APIUtils.getOAuthHeader(mAccessToken)); | ||||
|                         } | ||||
|                         call = api.getUserPosts(username, sortType.value, nextPage, 25, false, mAccessToken); | ||||
|                         break; | ||||
|                     case PostPagingSource.TYPE_SEARCH: | ||||
|                         if (subredditName == null) { | ||||
|                             if (mAccessToken == null) { | ||||
|                                 call = api.searchPosts(query, afterKey, sortType, sortTime, | ||||
|                                         trendingSource); | ||||
|                             } else { | ||||
|                                 call = api.searchPostsOauth(query, afterKey, sortType, | ||||
|                                         sortTime, trendingSource, APIUtils.getOAuthHeader(mAccessToken)); | ||||
|                             } | ||||
|                         } else { | ||||
|                             if (mAccessToken == null) { | ||||
|                                 call = api.searchPostsInSpecificSubreddit(subredditName, query, | ||||
|                                         sortType, sortTime, afterKey); | ||||
|                             } else { | ||||
|                                 call = api.searchPostsInSpecificSubredditOauth(subredditName, query, | ||||
|                                         sortType, sortTime, afterKey, | ||||
|                                         APIUtils.getOAuthHeader(mAccessToken)); | ||||
|                             } | ||||
|                         } | ||||
|                         call = api.search(query, null, subredditName, null, "Post", sortType.value, "All", nextPage, 25, mAccessToken); | ||||
|                         break; | ||||
|                     case PostPagingSource.TYPE_MULTI_REDDIT: | ||||
|                         if (mAccessToken == null) { | ||||
|                             call = api.getMultiRedditPosts(multiPath, afterKey, sortTime); | ||||
|                         } else { | ||||
|                             call = api.getMultiRedditPostsOauth(multiPath, afterKey, | ||||
|                                     sortTime, APIUtils.getOAuthHeader(mAccessToken)); | ||||
|                         } | ||||
|                         break; | ||||
|                         // TODO: Implement multi community | ||||
|  | ||||
|                     case PostPagingSource.TYPE_ANONYMOUS_FRONT_PAGE: | ||||
|                         //case PostPagingSource.TYPE_ANONYMOUS_MULTIREDDIT | ||||
|                         call = api.getSubredditBestPosts(subredditName, sortType, sortTime, afterKey); | ||||
|                         break; | ||||
|                         // TODO: Implement anonymous front page | ||||
|  | ||||
|                     default: | ||||
|                         call = api.getBestPosts(sortType, sortTime, afterKey, | ||||
|                                 APIUtils.getOAuthHeader(mAccessToken)); | ||||
|                         String type = (subredditName == null) ? "Subscribed" : (subredditName.equals("all")) ? "All" : "Local"; | ||||
|                         call = api.getPosts(type, sortType.value, nextPage, 25, null, null, false, mAccessToken); | ||||
|                 } | ||||
|  | ||||
|                 try { | ||||
|                     Response<String> response = call.execute(); | ||||
|                     if (response.isSuccessful()) { | ||||
|                         String responseString = response.body(); | ||||
|                         LinkedHashSet<Post> newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostList); | ||||
|                         LinkedHashSet<Post> newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostList, postEnricher); | ||||
|                         if (newPosts == null) { | ||||
|                             handler.post(() -> { | ||||
|                                 loadingMorePostsStatus = LoadingMorePostsStatus.NO_MORE_POSTS; | ||||
| @@ -666,7 +647,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele | ||||
|                     Response<String> response = historyPosts.execute(); | ||||
|                     if (response.isSuccessful()) { | ||||
|                         String responseString = response.body(); | ||||
|                         LinkedHashSet<Post> newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, null); | ||||
|                         LinkedHashSet<Post> newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, null, postEnricher); | ||||
|                         if (newPosts == null || newPosts.isEmpty()) { | ||||
|                             handler.post(() -> { | ||||
|                                 loadingMorePostsStatus = LoadingMorePostsStatus.NO_MORE_POSTS; | ||||
| @@ -870,6 +851,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele | ||||
|                     bundle.putParcelable(ViewPostDetailFragment.EXTRA_POST_DATA, post); | ||||
|                     bundle.putInt(ViewPostDetailFragment.EXTRA_POST_LIST_POSITION, position); | ||||
|                     bundle.putInt(ViewPostDetailFragment.EXTRA_SINGLE_COMMENT_ID, getIntent().getIntExtra(EXTRA_SINGLE_COMMENT_ID, 0)); | ||||
|                     bundle.putInt(ViewPostDetailFragment.EXTRA_SINGLE_COMMENT_PARENT_ID, getIntent().getIntExtra(EXTRA_SINGLE_COMMENT_PARENT_ID, 0)); | ||||
|                     bundle.putString(ViewPostDetailFragment.EXTRA_CONTEXT_NUMBER, getIntent().getStringExtra(EXTRA_CONTEXT_NUMBER)); | ||||
|                     bundle.putString(ViewPostDetailFragment.EXTRA_MESSAGE_FULLNAME, getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME)); | ||||
|                 } else { | ||||
| @@ -891,6 +873,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele | ||||
|                     bundle.putInt(ViewPostDetailFragment.EXTRA_POST_LIST_POSITION, postListPosition); | ||||
|                 } | ||||
|                 bundle.putInt(ViewPostDetailFragment.EXTRA_SINGLE_COMMENT_ID, getIntent().getIntExtra(EXTRA_SINGLE_COMMENT_ID, 0)); | ||||
|                 bundle.putInt(ViewPostDetailFragment.EXTRA_SINGLE_COMMENT_PARENT_ID, getIntent().getIntExtra(EXTRA_SINGLE_COMMENT_PARENT_ID, 0)); | ||||
|                 bundle.putString(ViewPostDetailFragment.EXTRA_CONTEXT_NUMBER, getIntent().getStringExtra(EXTRA_CONTEXT_NUMBER)); | ||||
|                 bundle.putString(ViewPostDetailFragment.EXTRA_MESSAGE_FULLNAME, getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME)); | ||||
|             } | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import android.content.SharedPreferences; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.util.Log; | ||||
| import android.view.MenuItem; | ||||
| import android.view.View; | ||||
| import android.widget.EditText; | ||||
| @@ -27,6 +28,7 @@ import org.greenrobot.eventbus.EventBus; | ||||
| import org.greenrobot.eventbus.Subscribe; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
| @@ -46,14 +48,15 @@ import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; | ||||
| import eu.toldi.infinityforlemmy.events.PassPrivateMessageEvent; | ||||
| import eu.toldi.infinityforlemmy.events.PassPrivateMessageIndexEvent; | ||||
| import eu.toldi.infinityforlemmy.events.RepliedToPrivateMessageEvent; | ||||
| import eu.toldi.infinityforlemmy.message.Message; | ||||
| import eu.toldi.infinityforlemmy.message.ReadMessage; | ||||
| import eu.toldi.infinityforlemmy.message.ReplyMessage; | ||||
| import eu.toldi.infinityforlemmy.privatemessage.LemmyPrivateMessageAPI; | ||||
| import eu.toldi.infinityforlemmy.privatemessage.PrivateMessage; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
| public class ViewPrivateMessagesActivity extends BaseActivity implements ActivityToolbarInterface { | ||||
|  | ||||
|     public static final String EXTRA_PRIVATE_MESSAGE = "EPM"; | ||||
|     public static final String EXTRA_PRIVATE_MESSAGE_INDEX = "EPM"; | ||||
|     public static final String EXTRA_MESSAGE_POSITION = "EMP"; | ||||
|     private static final String USER_AVATAR_STATE = "UAS"; | ||||
| @@ -91,14 +94,19 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     @Inject | ||||
|     Executor mExecutor; | ||||
|  | ||||
|     @Inject | ||||
|     LemmyPrivateMessageAPI mLemmyPrivateMessageAPI; | ||||
|     private LinearLayoutManagerBugFixed mLinearLayoutManager; | ||||
|     private PrivateMessagesDetailRecyclerViewAdapter mAdapter; | ||||
|     @State | ||||
|     Message privateMessage; | ||||
|     PrivateMessage privateMessage; | ||||
|     @State | ||||
|     Message replyTo; | ||||
|     PrivateMessage replyTo; | ||||
|     private String mAccessToken; | ||||
|     private String mAccountName; | ||||
|  | ||||
|     private String mAccountQualifiedName; | ||||
|     private String mUserAvatar; | ||||
|     private ArrayList<ProvideUserAvatarCallback> mProvideUserAvatarCallbacks; | ||||
|     private boolean isLoadingUserAvatar = false; | ||||
| @@ -128,6 +136,11 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit | ||||
|             addOnOffsetChangedListener(mAppBarLayout); | ||||
|         } | ||||
|  | ||||
|         Intent intent = getIntent(); | ||||
|         privateMessage = intent.getParcelableExtra(EXTRA_PRIVATE_MESSAGE); | ||||
|  | ||||
|         Log.i("ViewPrivate", "privateMessage: " + privateMessage); | ||||
|  | ||||
|         setSupportActionBar(mToolbar); | ||||
|         setToolbarGoToTop(mToolbar); | ||||
|  | ||||
| @@ -135,6 +148,7 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit | ||||
|  | ||||
|         mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); | ||||
|         mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); | ||||
|         mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null); | ||||
|  | ||||
|         if (savedInstanceState != null) { | ||||
|             mUserAvatar = savedInstanceState.getString(USER_AVATAR_STATE); | ||||
| @@ -144,36 +158,37 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit | ||||
|                 bindView(); | ||||
|             } | ||||
|         } else { | ||||
|             if (privateMessage != null) { | ||||
|                 bindView(); | ||||
|             } | ||||
|             EventBus.getDefault().post(new PassPrivateMessageIndexEvent(getIntent().getIntExtra(EXTRA_PRIVATE_MESSAGE_INDEX, -1))); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void bindView() { | ||||
|         if (privateMessage != null) { | ||||
|             if (privateMessage.getAuthor().equals(mAccountName)) { | ||||
|                 setTitle(privateMessage.getDestination()); | ||||
|             if (privateMessage.getCreatorQualifiedName().equals(mAccountQualifiedName)) { | ||||
|                 setTitle(privateMessage.getRecipientName()); | ||||
|                 mToolbar.setOnClickListener(view -> { | ||||
|                     if (privateMessage.isDestinationDeleted()) { | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     Intent intent = new Intent(this, ViewUserDetailActivity.class); | ||||
|                     intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, privateMessage.getDestination()); | ||||
|                     intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, privateMessage.getRecipientName()); | ||||
|                     intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, privateMessage.getRecipientQualifiedName()); | ||||
|                     startActivity(intent); | ||||
|                 }); | ||||
|             } else { | ||||
|                 setTitle(privateMessage.getAuthor()); | ||||
|                 setTitle(privateMessage.getCreatorName()); | ||||
|                 mToolbar.setOnClickListener(view -> { | ||||
|                     if (privateMessage.isAuthorDeleted()) { | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     Intent intent = new Intent(this, ViewUserDetailActivity.class); | ||||
|                     intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, privateMessage.getAuthor()); | ||||
|                     intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, privateMessage.getCreatorName()); | ||||
|                     intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, privateMessage.getCreatorQualifiedName()); | ||||
|                     startActivity(intent); | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|         mAdapter = new PrivateMessagesDetailRecyclerViewAdapter(this, mSharedPreferences, | ||||
|                 getResources().getConfiguration().locale, privateMessage, mAccountName, mCustomThemeWrapper); | ||||
|                 getResources().getConfiguration().locale, privateMessage, mAccountQualifiedName, mCustomThemeWrapper); | ||||
|         mLinearLayoutManager = new LinearLayoutManagerBugFixed(this); | ||||
|         mLinearLayoutManager.setStackFromEnd(true); | ||||
|         mRecyclerView.setLayoutManager(mLinearLayoutManager); | ||||
| @@ -184,58 +199,55 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit | ||||
|                 if (!mEditText.getText().toString().equals("")) { | ||||
|                     //Send Message | ||||
|                     if (privateMessage != null) { | ||||
|                         ArrayList<Message> replies = privateMessage.getReplies(); | ||||
|                         List<PrivateMessage> replies = privateMessage.getReplies(); | ||||
|                         if (replyTo == null) { | ||||
|                             replyTo = privateMessage; | ||||
|                         } | ||||
|                         isSendingMessage = true; | ||||
|                         mSendImageView.setColorFilter(mSecondaryTextColor, android.graphics.PorterDuff.Mode.SRC_IN); | ||||
|                         ReplyMessage.replyMessage(mEditText.getText().toString(), replyTo.getFullname(), | ||||
|                                 getResources().getConfiguration().locale, mOauthRetrofit, mAccessToken, | ||||
|                                 new ReplyMessage.ReplyMessageListener() { | ||||
|                                     @Override | ||||
|                                     public void replyMessageSuccess(Message message) { | ||||
|                                         if (mAdapter != null) { | ||||
|                                             mAdapter.addReply(message); | ||||
|                                         } | ||||
|                                         goToBottom(); | ||||
|                                         mEditText.setText(""); | ||||
|                                         mSendImageView.setColorFilter(mSendMessageIconColor, android.graphics.PorterDuff.Mode.SRC_IN); | ||||
|                                         isSendingMessage = false; | ||||
|                                         EventBus.getDefault().post(new RepliedToPrivateMessageEvent(message, getIntent().getIntExtra(EXTRA_MESSAGE_POSITION, -1))); | ||||
|                                     } | ||||
|  | ||||
|                                     @Override | ||||
|                                     public void replyMessageFailed(String errorMessage) { | ||||
|                                         if (errorMessage != null && !errorMessage.equals("")) { | ||||
|                                             Snackbar.make(mCoordinatorLayout, errorMessage, Snackbar.LENGTH_LONG).show(); | ||||
|                                         } else { | ||||
|                                             Snackbar.make(mCoordinatorLayout, R.string.reply_message_failed, Snackbar.LENGTH_LONG).show(); | ||||
|                                         } | ||||
|                                         mSendImageView.setColorFilter(mSendMessageIconColor, android.graphics.PorterDuff.Mode.SRC_IN); | ||||
|                                         isSendingMessage = false; | ||||
|                                     } | ||||
|                                 }); | ||||
|                         mLemmyPrivateMessageAPI.sendPrivateMessage(mAccessToken, replyTo.getCreatorId(), mEditText.getText().toString(), new LemmyPrivateMessageAPI.PrivateMessageSentListener() { | ||||
|  | ||||
|                             @Override | ||||
|                             public void onPrivateMessageSentSuccess(@NonNull PrivateMessage privateMessage) { | ||||
|                                 if (mAdapter != null) { | ||||
|                                     mAdapter.addReply(privateMessage); | ||||
|                                 } | ||||
|                                 goToBottom(); | ||||
|                                 mEditText.setText(""); | ||||
|                                 isSendingMessage = false; | ||||
|                                 EventBus.getDefault().post(new RepliedToPrivateMessageEvent(privateMessage, getIntent().getIntExtra(EXTRA_MESSAGE_POSITION, -1))); | ||||
|                             } | ||||
|  | ||||
|                             @Override | ||||
|                             public void onPrivateMessageSentError() { | ||||
|                                 Snackbar.make(mCoordinatorLayout, R.string.reply_message_failed, Snackbar.LENGTH_LONG).show(); | ||||
|                                 mSendImageView.setColorFilter(mSendMessageIconColor, android.graphics.PorterDuff.Mode.SRC_IN); | ||||
|                                 isSendingMessage = false; | ||||
|                             } | ||||
|                         }); | ||||
|  | ||||
|  | ||||
|                         StringBuilder fullnames = new StringBuilder(); | ||||
|                         if (privateMessage.isNew()) { | ||||
|                             fullnames.append(privateMessage.getFullname()).append(","); | ||||
|                         } | ||||
|  | ||||
|                         if (replies != null && !replies.isEmpty()) { | ||||
|                             for (Message m : replies) { | ||||
|                                 if (m.isNew()) { | ||||
|                             for (PrivateMessage m : replies) { | ||||
|                                 if (!m.getRead()) { | ||||
|                                     fullnames.append(m).append(","); | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                         if (fullnames.length() > 0) { | ||||
|                             fullnames.deleteCharAt(fullnames.length() - 1); | ||||
|                             ReadMessage.readMessage(mOauthRetrofit, mAccessToken, fullnames.toString(), | ||||
|                             ReadMessage.readMessage(mOauthRetrofit, mAccessToken, 0, | ||||
|                                     new ReadMessage.ReadMessageListener() { | ||||
|                                         @Override | ||||
|                                         public void readSuccess() {} | ||||
|                                         public void readSuccess() { | ||||
|                                         } | ||||
|  | ||||
|                                         @Override | ||||
|                                         public void readFailed() {} | ||||
|                                         public void readFailed() { | ||||
|                                         } | ||||
|                                     }); | ||||
|                         } | ||||
|                     } | ||||
| @@ -332,7 +344,7 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit | ||||
|  | ||||
|     @Subscribe | ||||
|     public void onPassPrivateMessageEvent(PassPrivateMessageEvent passPrivateMessageEvent) { | ||||
|         privateMessage = passPrivateMessageEvent.message; | ||||
|        /* privateMessage = passPrivateMessageEvent.message; | ||||
|         if (privateMessage != null) { | ||||
|             if (privateMessage.getAuthor().equals(mAccountName)) { | ||||
|                 if (privateMessage.getReplies() != null) { | ||||
| @@ -351,7 +363,7 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit | ||||
|             } | ||||
|  | ||||
|             bindView(); | ||||
|         } | ||||
|         }*/ | ||||
|     } | ||||
|  | ||||
|     public interface ProvideUserAvatarCallback { | ||||
|   | ||||
| @@ -1,14 +1,20 @@ | ||||
| package eu.toldi.infinityforlemmy.activities; | ||||
|  | ||||
| import static android.graphics.BitmapFactory.decodeResource; | ||||
|  | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.res.ColorStateList; | ||||
| import android.graphics.Bitmap; | ||||
| import android.graphics.PorterDuff; | ||||
| import android.graphics.drawable.Drawable; | ||||
| import android.net.Uri; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.text.Editable; | ||||
| import android.text.TextWatcher; | ||||
| import android.util.Log; | ||||
| import android.view.Gravity; | ||||
| import android.view.KeyEvent; | ||||
| import android.view.Menu; | ||||
| @@ -18,12 +24,14 @@ import android.view.ViewTreeObserver; | ||||
| import android.view.Window; | ||||
| import android.view.WindowManager; | ||||
| import android.view.inputmethod.EditorInfo; | ||||
| import android.widget.ImageView; | ||||
| import android.widget.LinearLayout; | ||||
| import android.widget.TextView; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.constraintlayout.widget.ConstraintLayout; | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentActivity; | ||||
| @@ -36,6 +44,9 @@ import androidx.viewpager2.widget.ViewPager2; | ||||
| import com.bumptech.glide.Glide; | ||||
| import com.bumptech.glide.RequestManager; | ||||
| import com.bumptech.glide.request.RequestOptions; | ||||
| import com.bumptech.glide.request.target.CustomTarget; | ||||
| import com.bumptech.glide.request.transition.Transition; | ||||
| import com.evernote.android.state.State; | ||||
| import com.google.android.material.appbar.AppBarLayout; | ||||
| import com.google.android.material.appbar.CollapsingToolbarLayout; | ||||
| import com.google.android.material.appbar.MaterialToolbar; | ||||
| @@ -82,6 +93,8 @@ import eu.toldi.infinityforlemmy.bottomsheetfragments.RandomBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.SortTimeBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.SortTypeBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.UrlMenuBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.community.BlockCommunity; | ||||
| import eu.toldi.infinityforlemmy.community.CommunityStats; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.customviews.NavigationWrapper; | ||||
| import eu.toldi.infinityforlemmy.customviews.slidr.Slidr; | ||||
| @@ -93,9 +106,11 @@ import eu.toldi.infinityforlemmy.fragments.SidebarFragment; | ||||
| import eu.toldi.infinityforlemmy.markdown.MarkdownUtils; | ||||
| import eu.toldi.infinityforlemmy.message.ReadMessage; | ||||
| import eu.toldi.infinityforlemmy.multireddit.MultiReddit; | ||||
| import eu.toldi.infinityforlemmy.post.MarkPostAsRead; | ||||
| import eu.toldi.infinityforlemmy.post.Post; | ||||
| import eu.toldi.infinityforlemmy.post.PostPagingSource; | ||||
| import eu.toldi.infinityforlemmy.readpost.InsertReadPost; | ||||
| import eu.toldi.infinityforlemmy.shortcut.ShortcutManager; | ||||
| import eu.toldi.infinityforlemmy.subreddit.CommunitySubscription; | ||||
| import eu.toldi.infinityforlemmy.subreddit.FetchSubredditData; | ||||
| import eu.toldi.infinityforlemmy.subreddit.ParseSubredditData; | ||||
| @@ -161,12 +176,26 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|     TextView communityFullNameTextView; | ||||
|     @BindView(R.id.subscriber_count_text_view_view_subreddit_detail_activity) | ||||
|     TextView nSubscribersTextView; | ||||
|     @BindView(R.id.online_subscriber_count_text_view_view_subreddit_detail_activity) | ||||
|     TextView nOnlineSubscribersTextView; | ||||
|     @BindView(R.id.since_text_view_view_subreddit_detail_activity) | ||||
|     TextView sinceTextView; | ||||
|     @BindView(R.id.creation_time_text_view_view_subreddit_detail_activity) | ||||
|     TextView creationTimeTextView; | ||||
|     @BindView(R.id.active_user_count_text_view_view_subreddit_detail_activity) | ||||
|     TextView nActiveUsersTextView; | ||||
|     @BindView(R.id.post_count_text_view_view_subreddit_detail_activity) | ||||
|     TextView nPostsTextView; | ||||
|     @BindView(R.id.comment_count_text_view_view_subreddit_detail_activity) | ||||
|     TextView nCommentsTextView; | ||||
|  | ||||
|     @BindView(R.id.subscriber_count_image_view_view_subreddit_detail_activity) | ||||
|     ImageView nSubscribersImageView; | ||||
|     @BindView(R.id.active_user_count_image_view_view_subreddit_detail_activity) | ||||
|     ImageView nActiveUsersImageView; | ||||
|     @BindView(R.id.post_count_image_view_view_subreddit_detail_activity) | ||||
|     ImageView nPostsImageView; | ||||
|     @BindView(R.id.comment_count_image_view_view_subreddit_detail_activity) | ||||
|     ImageView nCommentsImageView; | ||||
|  | ||||
|     @BindView(R.id.community_statistics_block_view_subreddit_detail_activity) | ||||
|     ConstraintLayout communityStatisticsBlock; | ||||
|  | ||||
|  | ||||
|     @BindView(R.id.description_text_view_view_subreddit_detail_activity) | ||||
|     TextView descriptionTextView; | ||||
|     @Inject | ||||
| @@ -196,6 +225,9 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     @Inject | ||||
|     Executor mExecutor; | ||||
|     @Inject | ||||
|     MarkPostAsRead markPostAsRead; | ||||
|  | ||||
|     private FragmentManager fragmentManager; | ||||
|     private SectionsPagerAdapter sectionsPagerAdapter; | ||||
|     private NavigationWrapper navigationWrapper; | ||||
| @@ -206,6 +238,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|     private String communityName; | ||||
|  | ||||
|     private int communityId; | ||||
|  | ||||
|     @State | ||||
|     SubredditData communityData; | ||||
|     @State | ||||
|     CommunityStats mCommunityStats; | ||||
|     private String description; | ||||
|  | ||||
|     private String qualifiedName; | ||||
| @@ -217,7 +254,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|     private boolean hideFab; | ||||
|     private boolean showBottomAppBar; | ||||
|     private boolean lockBottomAppBar; | ||||
|     private String mMessageFullname; | ||||
|     private int mMessageFullname; | ||||
|     private String mNewAccountName; | ||||
|     private RequestManager glide; | ||||
|     private int expandedTabTextColor; | ||||
| @@ -230,8 +267,14 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|     private int subscribedColor; | ||||
|     private int fabOption; | ||||
|     private MaterialAlertDialogBuilder nsfwWarningBuilder; | ||||
|     private Bitmap subredditIconBitmap; | ||||
|  | ||||
|     private boolean showStatistics; | ||||
|  | ||||
|     private boolean disableImagePreview; | ||||
|  | ||||
|     private boolean hideSubredditDescription; | ||||
|     private boolean isKbinMagazine = false; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
| @@ -244,6 +287,8 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|         ButterKnife.bind(this); | ||||
|  | ||||
|         hideFab = mSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_FAB_IN_POST_FEED, false); | ||||
|         showStatistics = mSharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_STATISTICS, true); | ||||
|         disableImagePreview = mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false); | ||||
|         showBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, false); | ||||
|         navigationWrapper = new NavigationWrapper(findViewById(R.id.bottom_app_bar_bottom_app_bar), findViewById(R.id.linear_layout_bottom_app_bar), | ||||
|                 findViewById(R.id.option_1_bottom_app_bar), findViewById(R.id.option_2_bottom_app_bar), | ||||
| @@ -348,27 +393,41 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|         mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null); | ||||
|  | ||||
|         if (savedInstanceState == null) { | ||||
|             mMessageFullname = getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME); | ||||
|             mMessageFullname = getIntent().getIntExtra(EXTRA_MESSAGE_FULLNAME, 0); | ||||
|             mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); | ||||
|         } else { | ||||
|             mFetchSubredditInfoSuccess = savedInstanceState.getBoolean(FETCH_SUBREDDIT_INFO_STATE); | ||||
|             mNCurrentOnlineSubscribers = savedInstanceState.getInt(CURRENT_ONLINE_SUBSCRIBERS_STATE); | ||||
|             mMessageFullname = savedInstanceState.getString(MESSAGE_FULLNAME_STATE); | ||||
|             mMessageFullname = savedInstanceState.getInt(MESSAGE_FULLNAME_STATE); | ||||
|             mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE); | ||||
|  | ||||
|             if (mFetchSubredditInfoSuccess) { | ||||
|                 nOnlineSubscribersTextView.setText(getString(R.string.online_subscribers_number_detail, mNCurrentOnlineSubscribers)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         checkNewAccountAndBindView(); | ||||
|  | ||||
|         fetchSubredditData(); | ||||
|         if (communityName != null) { | ||||
|         if (communityData != null) { | ||||
|             setupVisibleElements(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onStart() { | ||||
|         super.onStart(); | ||||
|         Log.e("ViewSubredditDetail", "onStart"); | ||||
|         if (communityData != null) { | ||||
|             setupVisibleElements(); | ||||
|         } else { | ||||
|             fetchSubredditData(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onStop() { | ||||
|         super.onStop(); | ||||
|         mFetchSubredditInfoSuccess = false; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onKeyDown(int keyCode, KeyEvent event) { | ||||
|         if (sectionsPagerAdapter != null) { | ||||
| @@ -410,20 +469,24 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|         subscribeSubredditChip.setTextColor(mCustomThemeWrapper.getChipTextColor()); | ||||
|         int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); | ||||
|         nSubscribersTextView.setTextColor(primaryTextColor); | ||||
|         nOnlineSubscribersTextView.setTextColor(primaryTextColor); | ||||
|         sinceTextView.setTextColor(primaryTextColor); | ||||
|         creationTimeTextView.setTextColor(primaryTextColor); | ||||
|         nActiveUsersTextView.setTextColor(primaryTextColor); | ||||
|         nPostsTextView.setTextColor(primaryTextColor); | ||||
|         nCommentsTextView.setTextColor(primaryTextColor); | ||||
|         nSubscribersImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN); | ||||
|         nActiveUsersImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN); | ||||
|         nPostsImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN); | ||||
|         nCommentsImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN); | ||||
|         descriptionTextView.setTextColor(primaryTextColor); | ||||
|         navigationWrapper.applyCustomTheme(mCustomThemeWrapper.getBottomAppBarIconColor(), mCustomThemeWrapper.getBottomAppBarBackgroundColor()); | ||||
|         applyTabLayoutTheme(tabLayout); | ||||
|         applyFABTheme(navigationWrapper.floatingActionButton); | ||||
|         applyFABTheme(navigationWrapper.floatingActionButton, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|         if (typeface != null) { | ||||
|             subredditNameTextView.setTypeface(typeface); | ||||
|             subscribeSubredditChip.setTypeface(typeface); | ||||
|             nSubscribersTextView.setTypeface(typeface); | ||||
|             nOnlineSubscribersTextView.setTypeface(typeface); | ||||
|             sinceTextView.setTypeface(typeface); | ||||
|             creationTimeTextView.setTypeface(typeface); | ||||
|             nActiveUsersTextView.setTypeface(typeface); | ||||
|             nPostsTextView.setTypeface(typeface); | ||||
|             nCommentsTextView.setTypeface(typeface); | ||||
|             descriptionTextView.setTypeface(typeface); | ||||
|         } | ||||
|         unsubscribedColor = mCustomThemeWrapper.getUnsubscribed(); | ||||
| @@ -462,7 +525,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|         setSupportActionBar(toolbar); | ||||
|         setToolbarGoToTop(toolbar); | ||||
|  | ||||
|         glide = Glide.with(this); | ||||
|         glide = Glide.with(getApplication()); | ||||
|         Locale locale = getResources().getConfiguration().locale; | ||||
|  | ||||
|         MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() { | ||||
| @@ -487,7 +550,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|             return true; | ||||
|         }; | ||||
|  | ||||
|         Markwon markwon = MarkdownUtils.createDescriptionMarkwon(this, miscPlugin, onLinkLongClickListener); | ||||
|         Markwon markwon = MarkdownUtils.createDescriptionMarkwon(this, miscPlugin, onLinkLongClickListener, mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false)); | ||||
|  | ||||
|         descriptionTextView.setOnLongClickListener(view -> { | ||||
|             if (description != null && !description.equals("") && descriptionTextView.getSelectionStart() == -1 && descriptionTextView.getSelectionEnd() == -1) { | ||||
| @@ -495,10 +558,14 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|             } | ||||
|             return true; | ||||
|         }); | ||||
|  | ||||
|         String actorID = (!isKbinMagazine) ? LemmyUtils.qualifiedCommunityName2ActorId(qualifiedName) : LemmyUtils.qualifiedMagazineName2ActorId(qualifiedName); | ||||
|         mSubredditViewModel = new ViewModelProvider(this, | ||||
|                 new SubredditViewModel.Factory(getApplication(), mRedditDataRoomDatabase, LemmyUtils.qualifiedCommunityName2ActorId(qualifiedName))) | ||||
|                 new SubredditViewModel.Factory(getApplication(), mRedditDataRoomDatabase, actorID)) | ||||
|                 .get(SubredditViewModel.class); | ||||
|         addObserverToLiveData(); | ||||
|     } | ||||
|  | ||||
|     private void addObserverToLiveData() { | ||||
|         mSubredditViewModel.getSubredditLiveData().observe(this, subredditData -> { | ||||
|             if (subredditData != null) { | ||||
|                 isNsfwSubreddit = subredditData.isNSFW(); | ||||
| @@ -524,11 +591,23 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|                             .into(iconGifImageView); | ||||
|                     iconGifImageView.setOnClickListener(null); | ||||
|                 } else { | ||||
|                     glide.load(subredditData.getIconUrl()) | ||||
|                     glide.asBitmap() | ||||
|                             .load(subredditData.getIconUrl()) | ||||
|                             .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(216, 0))) | ||||
|                             .error(glide.load(R.drawable.subreddit_default_icon) | ||||
|                                     .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(216, 0)))) | ||||
|                             .into(iconGifImageView); | ||||
|                             .into(new CustomTarget<Bitmap>() { | ||||
|                                 @Override | ||||
|                                 public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) { | ||||
|                                     subredditIconBitmap = resource; | ||||
|                                     iconGifImageView.setImageBitmap(resource); | ||||
|                                 } | ||||
|  | ||||
|                                 @Override | ||||
|                                 public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|                                     subredditIconBitmap = null; | ||||
|                                 } | ||||
|                             }); | ||||
|                     iconGifImageView.setOnClickListener(view -> { | ||||
|                         Intent intent = new Intent(ViewSubredditDetailActivity.this, ViewImageOrGifActivity.class); | ||||
|                         intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, subredditData.getIconUrl()); | ||||
| @@ -547,15 +626,18 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|                 communityFullNameTextView.setText(qualifiedName); | ||||
|                 String nSubscribers = getString(R.string.subscribers_number_detail, subredditData.getNSubscribers()); | ||||
|                 nSubscribersTextView.setText(nSubscribers); | ||||
|                 creationTimeTextView.setText(subredditData.getCreatedUTC()); | ||||
|  | ||||
|                 if (mCommunityStats != null && showStatistics) { | ||||
|                     communityStatisticsBlock.setVisibility(View.VISIBLE); | ||||
|                     nActiveUsersTextView.setText(getString(R.string.active_users_number_detail, mCommunityStats.getActiveUsers())); | ||||
|                     nPostsTextView.setText(getString(R.string.post_count_detail, mCommunityStats.getPosts())); | ||||
|                     nCommentsTextView.setText(getString(R.string.comment_count_detail, mCommunityStats.getComments())); | ||||
|                 } | ||||
|                 description = subredditData.getDescription(); | ||||
|  | ||||
|                 if (hideSubredditDescription || description.equals("")) { | ||||
|                     descriptionTextView.setVisibility(View.GONE); | ||||
|                 } else { | ||||
|                     descriptionTextView.setVisibility(View.VISIBLE); | ||||
|                     markwon.setMarkdown(descriptionTextView, description); | ||||
|                 } | ||||
|  | ||||
|                 descriptionTextView.setVisibility(View.GONE); | ||||
|  | ||||
|  | ||||
|                 if (subredditData.isNSFW()) { | ||||
|                     if (nsfwWarningBuilder == null | ||||
| @@ -689,14 +771,23 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|                     qualifiedName = LemmyUtils.actorID2FullName(communityData.getActorId()); | ||||
|                     if (communityName == null) { | ||||
|                         communityName = communityData.getTitle(); | ||||
|  | ||||
|                         setupVisibleElements(); | ||||
|                     } | ||||
|                     mCommunityStats = communityData.getCommunityStats(); | ||||
|                     if (communityData.getActorId().contains("/m/")) { | ||||
|                         isKbinMagazine = true; | ||||
|                         if (mSubredditViewModel != null) { | ||||
|                             // Remove current observer | ||||
|                             mSubredditViewModel.getSubredditLiveData().removeObservers(ViewSubredditDetailActivity.this); | ||||
|                             addObserverToLiveData(); | ||||
|                         } | ||||
|                     } | ||||
|                     setupVisibleElements(); | ||||
|                     communityId = communityData.getId(); | ||||
|                     ViewSubredditDetailActivity.this.communityData = communityData; | ||||
|                     setupSubscribeChip(); | ||||
|  | ||||
|                     mNCurrentOnlineSubscribers = nCurrentOnlineSubscribers; | ||||
|                     nOnlineSubscribersTextView.setText(getString(R.string.online_subscribers_number_detail, nCurrentOnlineSubscribers)); | ||||
|  | ||||
|                     InsertSubredditData.insertSubredditData(mExecutor, new Handler(), mRedditDataRoomDatabase, | ||||
|                             communityData, () -> mFetchSubredditInfoSuccess = true); | ||||
|                 } | ||||
| @@ -729,6 +820,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|             case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_PROFILE: { | ||||
|                 Intent intent = new Intent(this, ViewUserDetailActivity.class); | ||||
|                 intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName); | ||||
|                 intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, mAccountQualifiedName); | ||||
|                 startActivity(intent); | ||||
|                 break; | ||||
|             } | ||||
| @@ -868,11 +960,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|     } | ||||
|  | ||||
|     private void bindView() { | ||||
|         if (mMessageFullname != null) { | ||||
|         if (mMessageFullname != 0) { | ||||
|             ReadMessage.readMessage(mRetrofit.getRetrofit(), mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() { | ||||
|                 @Override | ||||
|                 public void readSuccess() { | ||||
|                     mMessageFullname = null; | ||||
|                     mMessageFullname = 0; | ||||
|                 } | ||||
|  | ||||
|                 @Override | ||||
| @@ -1092,7 +1184,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|             } | ||||
|         }); | ||||
|         viewPager2.setAdapter(sectionsPagerAdapter); | ||||
|         viewPager2.setOffscreenPageLimit(2); | ||||
|         viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT); | ||||
|         viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); | ||||
|         new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { | ||||
|             switch (position) { | ||||
| @@ -1122,6 +1214,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|     @Override | ||||
|     public boolean onCreateOptionsMenu(Menu menu) { | ||||
|         getMenuInflater().inflate(R.menu.view_subreddit_detail_activity, menu); | ||||
|         if (communityData != null && communityData.isBlocked()) { | ||||
|             menu.findItem(R.id.block_community_view_subreddit_detail_activity).setVisible(false); | ||||
|         } else { | ||||
|             menu.findItem(R.id.unblock_community_view_subreddit_detail_activity).setVisible(false); | ||||
|         } | ||||
|         applyMenuItemTheme(menu); | ||||
|         return true; | ||||
|     } | ||||
| @@ -1150,22 +1247,6 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|             PostLayoutBottomSheetFragment postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); | ||||
|             postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); | ||||
|             return true; | ||||
|         } else if (itemId == R.id.action_select_user_flair_view_subreddit_detail_activity) { | ||||
|             if (mAccessToken == null) { | ||||
|                 Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); | ||||
|                 return true; | ||||
|             } | ||||
|             Intent selectUserFlairIntent = new Intent(this, SelectUserFlairActivity.class); | ||||
|             selectUserFlairIntent.putExtra(SelectUserFlairActivity.EXTRA_SUBREDDIT_NAME, communityName); | ||||
|             startActivity(selectUserFlairIntent); | ||||
|             return true; | ||||
|         } else if (itemId == R.id.action_add_to_multireddit_view_subreddit_detail_activity) { | ||||
|             if (mAccessToken == null) { | ||||
|                 Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); | ||||
|                 return true; | ||||
|             } | ||||
|             Intent intent = new Intent(this, MultiredditSelectionActivity.class); | ||||
|             startActivityForResult(intent, ADD_TO_MULTIREDDIT_REQUEST_CODE); | ||||
|         } else if (itemId == R.id.action_add_to_post_filter_view_subreddit_detail_activity) { | ||||
|             Intent intent = new Intent(this, PostFilterPreferenceActivity.class); | ||||
|             intent.putExtra(PostFilterPreferenceActivity.EXTRA_SUBREDDIT_NAME, communityName); | ||||
| @@ -1175,24 +1256,63 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|             Intent shareIntent = new Intent(Intent.ACTION_SEND); | ||||
|             shareIntent.setType("text/plain"); | ||||
|             String baseURL = mRetrofit.getBaseURL().endsWith("/") ? mRetrofit.getBaseURL() : mRetrofit.getBaseURL() + "/"; | ||||
|             shareIntent.putExtra(Intent.EXTRA_TEXT, baseURL + "/" + qualifiedName); | ||||
|             shareIntent.putExtra(Intent.EXTRA_TEXT, baseURL + "c/" + qualifiedName); | ||||
|             if (shareIntent.resolveActivity(getPackageManager()) != null) { | ||||
|                 startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); | ||||
|             } else { | ||||
|                 Toast.makeText(this, R.string.no_app, Toast.LENGTH_SHORT).show(); | ||||
|             } | ||||
|             return true; | ||||
|         } else if (itemId == R.id.action_go_to_wiki_view_subreddit_detail_activity) { | ||||
|             Intent wikiIntent = new Intent(this, WikiActivity.class); | ||||
|             wikiIntent.putExtra(WikiActivity.EXTRA_SUBREDDIT_NAME, communityName); | ||||
|             wikiIntent.putExtra(WikiActivity.EXTRA_WIKI_PATH, "index"); | ||||
|             startActivity(wikiIntent); | ||||
|             return true; | ||||
|         } else if (itemId == R.id.action_contact_mods_view_subreddit_detail_activity) { | ||||
|             Intent intent = new Intent(this, SendPrivateMessageActivity.class); | ||||
|             intent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, "r/" + communityName); | ||||
|             startActivity(intent); | ||||
|            /* Intent intent = new Intent(this, SendPrivateMessageActivity.class); | ||||
|             intent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, "r/" + communityName);*/ | ||||
|             //startActivity(intent); | ||||
|             return true; | ||||
|         } else if (itemId == R.id.block_community_view_subreddit_detail_activity) { | ||||
|             if (mAccessToken == null) { | ||||
|                 Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); | ||||
|                 return true; | ||||
|             } | ||||
|             new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) | ||||
|                     .setTitle(R.string.block_community) | ||||
|                     .setMessage(R.string.are_you_sure) | ||||
|                     .setPositiveButton(R.string.yes, (dialogInterface, i) | ||||
|                             -> BlockCommunity.INSTANCE.blockCommunity(mRetrofit.getRetrofit(), communityId, mAccessToken, new BlockCommunity.BlockCommunityListener() { | ||||
|                         @Override | ||||
|                         public void onBlockCommunitySuccess() { | ||||
|                             communityData.setBlocked(true); | ||||
|                             Toast.makeText(ViewSubredditDetailActivity.this, R.string.block_community_success, Toast.LENGTH_SHORT).show(); | ||||
|                             ViewSubredditDetailActivity.this.invalidateOptionsMenu(); | ||||
|                             sectionsPagerAdapter.refresh(false); | ||||
|                         } | ||||
|  | ||||
|                         @Override | ||||
|                         public void onBlockCommunityError() { | ||||
|                             Toast.makeText(ViewSubredditDetailActivity.this, R.string.block_community_failed, Toast.LENGTH_SHORT).show(); | ||||
|                         } | ||||
|                     })) | ||||
|                     .setNegativeButton(R.string.no, null) | ||||
|                     .show(); | ||||
|             return true; | ||||
|         } else if (itemId == R.id.unblock_community_view_subreddit_detail_activity) { | ||||
|             BlockCommunity.INSTANCE.unBlockCommunity(mRetrofit.getRetrofit(), communityId, mAccessToken, new BlockCommunity.BlockCommunityListener() { | ||||
|                 @Override | ||||
|                 public void onBlockCommunitySuccess() { | ||||
|                     communityData.setBlocked(false); | ||||
|                     Toast.makeText(ViewSubredditDetailActivity.this, R.string.unblock_community_success, Toast.LENGTH_SHORT).show(); | ||||
|                     ViewSubredditDetailActivity.this.invalidateOptionsMenu(); | ||||
|                     sectionsPagerAdapter.refresh(false); | ||||
|                 } | ||||
|  | ||||
|                 @Override | ||||
|                 public void onBlockCommunityError() { | ||||
|                     Toast.makeText(ViewSubredditDetailActivity.this, R.string.unblock_community_failed, Toast.LENGTH_SHORT).show(); | ||||
|                 } | ||||
|             }); | ||||
|             return true; | ||||
|         } else if (itemId == R.id.action_add_to_home_screen_view_subreddit_detail_activity) { | ||||
|             Bitmap icon = subredditIconBitmap == null ? decodeResource(getResources(), R.drawable.subreddit_default_icon) : subredditIconBitmap; | ||||
|             return ShortcutManager.requestPinShortcut(this, qualifiedName, icon); | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| @@ -1230,7 +1350,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|         super.onSaveInstanceState(outState); | ||||
|         outState.putBoolean(FETCH_SUBREDDIT_INFO_STATE, mFetchSubredditInfoSuccess); | ||||
|         outState.putInt(CURRENT_ONLINE_SUBSCRIBERS_STATE, mNCurrentOnlineSubscribers); | ||||
|         outState.putString(MESSAGE_FULLNAME_STATE, mMessageFullname); | ||||
|         outState.putInt(MESSAGE_FULLNAME_STATE, mMessageFullname); | ||||
|         outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName); | ||||
|     } | ||||
|  | ||||
| @@ -1284,27 +1404,27 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|                 break; | ||||
|             case PostTypeBottomSheetFragment.TYPE_LINK: | ||||
|                 intent = new Intent(this, PostLinkActivity.class); | ||||
|                 intent.putExtra(PostLinkActivity.EXTRA_SUBREDDIT_NAME, communityName); | ||||
|                 intent.putExtra(PostLinkActivity.EXTRA_SUBREDDIT_NAME, qualifiedName); | ||||
|                 startActivity(intent); | ||||
|                 break; | ||||
|             case PostTypeBottomSheetFragment.TYPE_IMAGE: | ||||
|                 intent = new Intent(this, PostImageActivity.class); | ||||
|                 intent.putExtra(PostImageActivity.EXTRA_SUBREDDIT_NAME, communityName); | ||||
|                 intent.putExtra(PostImageActivity.EXTRA_SUBREDDIT_NAME, qualifiedName); | ||||
|                 startActivity(intent); | ||||
|                 break; | ||||
|             case PostTypeBottomSheetFragment.TYPE_VIDEO: | ||||
|                 intent = new Intent(this, PostVideoActivity.class); | ||||
|                 intent.putExtra(PostVideoActivity.EXTRA_SUBREDDIT_NAME, communityName); | ||||
|                 intent.putExtra(PostVideoActivity.EXTRA_SUBREDDIT_NAME, qualifiedName); | ||||
|                 startActivity(intent); | ||||
|                 break; | ||||
|             case PostTypeBottomSheetFragment.TYPE_GALLERY: | ||||
|                 intent = new Intent(this, PostGalleryActivity.class); | ||||
|                 intent.putExtra(PostGalleryActivity.EXTRA_SUBREDDIT_NAME, communityName); | ||||
|                 intent.putExtra(PostGalleryActivity.EXTRA_SUBREDDIT_NAME, qualifiedName); | ||||
|                 startActivity(intent); | ||||
|                 break; | ||||
|             case PostTypeBottomSheetFragment.TYPE_POLL: | ||||
|                 intent = new Intent(this, PostPollActivity.class); | ||||
|                 intent.putExtra(PostPollActivity.EXTRA_SUBREDDIT_NAME, communityName); | ||||
|                 intent.putExtra(PostPollActivity.EXTRA_SUBREDDIT_NAME, qualifiedName); | ||||
|                 startActivity(intent); | ||||
|         } | ||||
|     } | ||||
| @@ -1398,10 +1518,6 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|                 goToUser(); | ||||
|                 break; | ||||
|             } | ||||
|             case FABMoreOptionsBottomSheetFragment.FAB_RANDOM: { | ||||
|                 random(); | ||||
|                 break; | ||||
|             } | ||||
|             case FABMoreOptionsBottomSheetFragment.FAB_HIDE_READ_POSTS: { | ||||
|                 if (sectionsPagerAdapter != null) { | ||||
|                     sectionsPagerAdapter.hideReadPosts(); | ||||
| @@ -1441,7 +1557,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|             if (i == EditorInfo.IME_ACTION_DONE) { | ||||
|                 Utils.hideKeyboard(this); | ||||
|                 Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class); | ||||
|                 subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); | ||||
|                 String communityName = thingEditText.getText().toString(); | ||||
|                 if (communityName.startsWith("!")) { | ||||
|                     communityName = communityName.substring(1); | ||||
|                 } | ||||
|                 subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, communityName); | ||||
|                 startActivity(subredditIntent); | ||||
|                 return true; | ||||
|             } | ||||
| @@ -1499,7 +1619,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|                         -> { | ||||
|                     Utils.hideKeyboard(this); | ||||
|                     Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class); | ||||
|                     subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); | ||||
|                     String communityName = thingEditText.getText().toString(); | ||||
|                     if (communityName.startsWith("!")) { | ||||
|                         communityName = communityName.substring(1); | ||||
|                     } | ||||
|                     subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, communityName); | ||||
|                     startActivity(subredditIntent); | ||||
|                 }) | ||||
|                 .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { | ||||
| @@ -1520,7 +1644,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|             if (i == EditorInfo.IME_ACTION_DONE) { | ||||
|                 Utils.hideKeyboard(this); | ||||
|                 Intent userIntent = new Intent(this, ViewUserDetailActivity.class); | ||||
|                 userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); | ||||
|                 String qualifiedName = thingEditText.getText().toString(); | ||||
|                 if (qualifiedName.startsWith("@")) { | ||||
|                     qualifiedName = qualifiedName.substring(1); | ||||
|                 } | ||||
|                 userIntent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, qualifiedName); | ||||
|                 startActivity(userIntent); | ||||
|                 return true; | ||||
|             } | ||||
| @@ -1533,7 +1661,11 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|                         -> { | ||||
|                     Utils.hideKeyboard(this); | ||||
|                     Intent userIntent = new Intent(this, ViewUserDetailActivity.class); | ||||
|                     userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); | ||||
|                     String qualifiedName = thingEditText.getText().toString(); | ||||
|                     if (qualifiedName.startsWith("@")) { | ||||
|                         qualifiedName = qualifiedName.substring(1); | ||||
|                     } | ||||
|                     userIntent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, qualifiedName); | ||||
|                     startActivity(userIntent); | ||||
|                 }) | ||||
|                 .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { | ||||
| @@ -1562,7 +1694,18 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|  | ||||
|     @Override | ||||
|     public void markPostAsRead(Post post) { | ||||
|         InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountName, post.getId()); | ||||
|         markPostAsRead.markPostAsRead(post.getId(), mAccessToken, new MarkPostAsRead.MarkPostAsReadListener() { | ||||
|             @Override | ||||
|             public void onMarkPostAsReadSuccess() { | ||||
|                 InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountQualifiedName, post.getId()); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onMarkPostAsReadFailed() { | ||||
|                 Toast.makeText(ViewSubredditDetailActivity.this, R.string.mark_post_as_read_failed, Toast.LENGTH_SHORT).show(); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -1603,6 +1746,8 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|             bundle.putString(SidebarFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
|             bundle.putString(SidebarFragment.EXTRA_SUBREDDIT_NAME, communityName); | ||||
|             bundle.putString(SidebarFragment.EXTRA_COMMUNITY_QUALIFIED_NAME, qualifiedName); | ||||
|             bundle.putBoolean(SidebarFragment.EXTRA_SHOW_STATISTICS, !showStatistics); | ||||
|             bundle.putBoolean(SidebarFragment.EXTRA_DISABLE_IMAGE_PREVIEW, disableImagePreview); | ||||
|             fragment.setArguments(bundle); | ||||
|             return fragment; | ||||
|         } | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.res.ColorStateList; | ||||
| import android.content.res.Resources; | ||||
| import android.graphics.PorterDuff; | ||||
| import android.net.Uri; | ||||
| import android.os.AsyncTask; | ||||
| import android.os.Build; | ||||
| @@ -20,12 +21,15 @@ import android.view.ViewTreeObserver; | ||||
| import android.view.Window; | ||||
| import android.view.WindowManager; | ||||
| import android.view.inputmethod.EditorInfo; | ||||
| import android.widget.ImageView; | ||||
| import android.widget.LinearLayout; | ||||
| import android.widget.ProgressBar; | ||||
| import android.widget.TextView; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.constraintlayout.widget.ConstraintLayout; | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentActivity; | ||||
| @@ -52,6 +56,7 @@ import org.greenrobot.eventbus.EventBus; | ||||
| import org.greenrobot.eventbus.Subscribe; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Locale; | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| @@ -71,11 +76,14 @@ import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| import eu.toldi.infinityforlemmy.RetrofitHolder; | ||||
| import eu.toldi.infinityforlemmy.SortType; | ||||
| import eu.toldi.infinityforlemmy.SortTypeSelectionCallback; | ||||
| import eu.toldi.infinityforlemmy.account.FetchBlockedThings; | ||||
| import eu.toldi.infinityforlemmy.adapters.SubredditAutocompleteRecyclerViewAdapter; | ||||
| import eu.toldi.infinityforlemmy.apis.RedditAPI; | ||||
| import eu.toldi.infinityforlemmy.asynctasks.AddSubredditOrUserToMultiReddit; | ||||
| import eu.toldi.infinityforlemmy.asynctasks.CheckIsFollowingUser; | ||||
| import eu.toldi.infinityforlemmy.asynctasks.SwitchAccount; | ||||
| import eu.toldi.infinityforlemmy.blockedcommunity.BlockedCommunityData; | ||||
| import eu.toldi.infinityforlemmy.blockeduser.BlockedUserData; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.CopyTextBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.FABMoreOptionsBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.PostLayoutBottomSheetFragment; | ||||
| @@ -95,16 +103,19 @@ import eu.toldi.infinityforlemmy.fragments.PostFragment; | ||||
| import eu.toldi.infinityforlemmy.markdown.MarkdownUtils; | ||||
| import eu.toldi.infinityforlemmy.message.ReadMessage; | ||||
| import eu.toldi.infinityforlemmy.multireddit.MultiReddit; | ||||
| import eu.toldi.infinityforlemmy.post.MarkPostAsRead; | ||||
| import eu.toldi.infinityforlemmy.post.Post; | ||||
| import eu.toldi.infinityforlemmy.post.PostPagingSource; | ||||
| import eu.toldi.infinityforlemmy.readpost.InsertReadPost; | ||||
| import eu.toldi.infinityforlemmy.subreddit.ParseSubredditData; | ||||
| import eu.toldi.infinityforlemmy.subreddit.SubredditData; | ||||
| import eu.toldi.infinityforlemmy.user.BasicUserInfo; | ||||
| import eu.toldi.infinityforlemmy.user.BlockUser; | ||||
| import eu.toldi.infinityforlemmy.user.FetchUserData; | ||||
| import eu.toldi.infinityforlemmy.user.UserDao; | ||||
| import eu.toldi.infinityforlemmy.user.UserData; | ||||
| import eu.toldi.infinityforlemmy.user.UserFollowing; | ||||
| import eu.toldi.infinityforlemmy.user.UserStats; | ||||
| import eu.toldi.infinityforlemmy.user.UserViewModel; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.LemmyUtils; | ||||
| @@ -140,6 +151,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|     private static final String FETCH_USER_INFO_STATE = "FSIS"; | ||||
|     private static final String MESSAGE_FULLNAME_STATE = "MFS"; | ||||
|     private static final String NEW_ACCOUNT_NAME_STATE = "NANS"; | ||||
|     private static final String NEW_ACCOUNT_QUALIFIED_NAME_STATE = "NAQNS"; | ||||
|  | ||||
|     @BindView(R.id.coordinator_layout_view_user_detail_activity) | ||||
|     CoordinatorLayout coordinatorLayout; | ||||
| @@ -164,11 +176,40 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|  | ||||
|     @BindView(R.id.user_qualified_name_text_view_view_user_detail_activity) | ||||
|     TextView qualifiedNameTextView; | ||||
|  | ||||
|     @BindView(R.id.loading_user_progress_indicator_view_user_detail_activity) | ||||
|     ProgressBar progressBar; | ||||
|     @BindView(R.id.subscribe_user_chip_view_user_detail_activity) | ||||
|     Chip subscribeUserChip; | ||||
|     @BindView(R.id.karma_text_view_view_user_detail_activity) | ||||
|     TextView karmaTextView; | ||||
|     @BindView(R.id.cakeday_text_view_view_user_detail_activity) | ||||
|  | ||||
|     @BindView(R.id.post_count_text_view_view_user_detail_activity) | ||||
|     TextView postCountTextView; | ||||
|  | ||||
|     @BindView(R.id.comment_count_text_view_view_user_detail_activity) | ||||
|     TextView commentCountTextView; | ||||
|  | ||||
|     @BindView(R.id.upvote_count_post_text_view_view_user_detail_activity) | ||||
|     TextView upvoteCountPostTextView; | ||||
|  | ||||
|     @BindView(R.id.upvote_count_comment_text_view_view_user_detail_activity) | ||||
|     TextView upvoteCountCommentTextView; | ||||
|  | ||||
|     @BindView(R.id.posts_count_icon_image_view_view_user_detail_activity) | ||||
|     ImageView postsCountIconImageView; | ||||
|     @BindView(R.id.comments_count_icon_image_view_view_user_detail_activity) | ||||
|     ImageView commentsCountIconImageView; | ||||
|  | ||||
|     @BindView(R.id.upvote_count_posts_icon_image_view_view_user_detail_activity) | ||||
|     ImageView postUpvoteCountIconImageView; | ||||
|     @BindView(R.id.upvote_count_comments_icon_image_view_view_user_detail_activity) | ||||
|     ImageView commentUpvoteCountIconImageView; | ||||
|     @BindView(R.id.account_created_cake_icon_image_view_view_user_detail_activity) | ||||
|     ImageView accountCreatedCakeIconImageView; | ||||
|  | ||||
|     @BindView(R.id.user_statistics_block_view_user_detail_activity) | ||||
|     ConstraintLayout userStatisticsBlock; | ||||
|  | ||||
|     @BindView(R.id.cake_day_text_view_view_user_detail_activity) | ||||
|     TextView cakedayTextView; | ||||
|     @BindView(R.id.description_text_view_view_user_detail_activity) | ||||
|     TextView descriptionTextView; | ||||
| @@ -202,6 +243,9 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|     @Inject | ||||
|     Executor mExecutor; | ||||
|  | ||||
|     @Inject | ||||
|     MarkPostAsRead markPostAsRead; | ||||
|     public UserViewModel userViewModel; | ||||
|     private FragmentManager fragmentManager; | ||||
|     private SectionsPagerAdapter sectionsPagerAdapter; | ||||
| @@ -210,9 +254,14 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|     private Call<String> subredditAutocompleteCall; | ||||
|     private String mAccessToken; | ||||
|     private String mAccountName; | ||||
|     private String mAccountQualifiedName; | ||||
|     private String username; | ||||
|  | ||||
|     private String qualifiedName; | ||||
|     private String description; | ||||
|  | ||||
|     private boolean showStatistics; | ||||
|     private boolean showScore; | ||||
|     private boolean subscriptionReady = false; | ||||
|     private boolean mFetchUserInfoSuccess = false; | ||||
|     private int expandedTabTextColor; | ||||
| @@ -228,11 +277,13 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|     private boolean hideFab; | ||||
|     private boolean showBottomAppBar; | ||||
|     private boolean lockBottomAppBar; | ||||
|     private String mMessageFullname; | ||||
|     private int mMessageId; | ||||
|     private String mNewAccountName; | ||||
|  | ||||
|     private UserData mUserData; | ||||
|  | ||||
|     private boolean isBlocked; | ||||
|  | ||||
|     //private MaterialAlertDialogBuilder nsfwWarningBuilder; | ||||
|  | ||||
|     @Override | ||||
| @@ -272,16 +323,20 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|  | ||||
|         mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); | ||||
|         mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); | ||||
|         mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null); | ||||
|         lockBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_BOTTOM_APP_BAR, false); | ||||
|  | ||||
|         showStatistics = mSharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_STATISTICS, true); | ||||
|         showScore = mSharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_POST_AND_COMMENT_SCORE, true); | ||||
|  | ||||
|         if (savedInstanceState == null) { | ||||
|             mMessageFullname = getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME); | ||||
|             mMessageId = getIntent().getIntExtra(EXTRA_MESSAGE_FULLNAME, 0); | ||||
|             mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); | ||||
|         } else { | ||||
|             mFetchUserInfoSuccess = savedInstanceState.getBoolean(FETCH_USER_INFO_STATE); | ||||
|             mMessageFullname = savedInstanceState.getString(MESSAGE_FULLNAME_STATE); | ||||
|             mMessageId = savedInstanceState.getInt(MESSAGE_FULLNAME_STATE); | ||||
|             mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE); | ||||
|             qualifiedName = savedInstanceState.getString("qualified_name"); | ||||
|         } | ||||
|  | ||||
|         checkNewAccountAndInitializeViewPager(); | ||||
| @@ -293,9 +348,26 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onStart() { | ||||
|         super.onStart(); | ||||
|         if (mUserData != null) { | ||||
|             setupVisibleElements(); | ||||
|         } else { | ||||
|             fetchUserInfo(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onStop() { | ||||
|         super.onStop(); | ||||
|         mFetchUserInfoSuccess = false; | ||||
|     } | ||||
|  | ||||
|     private void setupVisibleElements() { | ||||
|         Resources resources = getResources(); | ||||
|         String title = username; | ||||
|         progressBar.setVisibility(View.GONE); | ||||
|         userNameTextView.setText(title); | ||||
|         qualifiedNameTextView.setText(qualifiedName); | ||||
|         toolbar.setTitle(title); | ||||
| @@ -376,7 +448,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         glide = Glide.with(this); | ||||
|         glide = Glide.with(getApplication()); | ||||
|         Locale locale = getResources().getConfiguration().locale; | ||||
|  | ||||
|         MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() { | ||||
| @@ -400,7 +472,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|             urlMenuBottomSheetFragment.show(getSupportFragmentManager(), null); | ||||
|             return true; | ||||
|         }; | ||||
|         Markwon markwon = MarkdownUtils.createDescriptionMarkwon(this, miscPlugin, onLinkLongClickListener); | ||||
|         Markwon markwon = MarkdownUtils.createDescriptionMarkwon(this, miscPlugin, onLinkLongClickListener, mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false)); | ||||
|  | ||||
|         descriptionTextView.setOnLongClickListener(view -> { | ||||
|             if (description != null && !description.equals("") && descriptionTextView.getSelectionStart() == -1 && descriptionTextView.getSelectionEnd() == -1) { | ||||
| @@ -553,8 +625,23 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|                     getSupportActionBar().setTitle(userFullName); | ||||
|                 } | ||||
|                 String karma = "";//getString(R.string.karma_info_user_detail, userData.getTotalKarma(), userData.getLinkKarma(), userData.getCommentKarma()); | ||||
|                 karmaTextView.setText(karma); | ||||
|                 cakedayTextView.setText(getString(R.string.cakeday_info, userData.getCakeday())); | ||||
|  | ||||
|                 cakedayTextView.setText((String) userData.getCakeday()); | ||||
|                 UserStats userStats = mUserData.getStats(); | ||||
|                 if (userStats != null && showStatistics) { | ||||
|                     userStatisticsBlock.setVisibility(View.VISIBLE); | ||||
|                     postCountTextView.setText(String.valueOf(userStats.getPostCount())); | ||||
|                     commentCountTextView.setText(String.valueOf(userStats.getCommentCount())); | ||||
|                     if (showScore) { | ||||
|                         upvoteCountPostTextView.setText(String.valueOf(userStats.getPostScore())); | ||||
|                         upvoteCountCommentTextView.setText(String.valueOf(userStats.getCommentScore())); | ||||
|                     } else { | ||||
|                         upvoteCountPostTextView.setVisibility(View.GONE); | ||||
|                         upvoteCountCommentTextView.setVisibility(View.GONE); | ||||
|                         postUpvoteCountIconImageView.setVisibility(View.GONE); | ||||
|                         commentUpvoteCountIconImageView.setVisibility(View.GONE); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if (userData.getDescription() == null || userData.getDescription().equals("")) { | ||||
|                     descriptionTextView.setVisibility(View.GONE); | ||||
| @@ -622,16 +709,25 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|         unsubscribedColor = mCustomThemeWrapper.getUnsubscribed(); | ||||
|         subscribedColor = mCustomThemeWrapper.getSubscribed(); | ||||
|         userNameTextView.setTextColor(mCustomThemeWrapper.getUsername()); | ||||
|         karmaTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|         postCountTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|         upvoteCountPostTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|         commentCountTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|         upvoteCountCommentTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|         postsCountIconImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN); | ||||
|         commentsCountIconImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN); | ||||
|         accountCreatedCakeIconImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN); | ||||
|         cakedayTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|         navigationWrapper.applyCustomTheme(mCustomThemeWrapper.getBottomAppBarIconColor(), mCustomThemeWrapper.getBottomAppBarBackgroundColor()); | ||||
|         applyFABTheme(navigationWrapper.floatingActionButton); | ||||
|         applyFABTheme(navigationWrapper.floatingActionButton, mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_CIRCULAR_FAB, false)); | ||||
|         descriptionTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|         subscribeUserChip.setTextColor(mCustomThemeWrapper.getChipTextColor()); | ||||
|         applyTabLayoutTheme(tabLayout); | ||||
|         if (typeface != null) { | ||||
|             userNameTextView.setTypeface(typeface); | ||||
|             karmaTextView.setTypeface(typeface); | ||||
|             postCountTextView.setTypeface(typeface); | ||||
|             upvoteCountPostTextView.setTypeface(typeface); | ||||
|             commentCountTextView.setTypeface(typeface); | ||||
|             upvoteCountCommentTextView.setTypeface(typeface); | ||||
|             cakedayTextView.setTypeface(typeface); | ||||
|             subscribeUserChip.setTypeface(typeface); | ||||
|             descriptionTextView.setTypeface(typeface); | ||||
| @@ -665,7 +761,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|     private void initializeViewPager() { | ||||
|         sectionsPagerAdapter = new SectionsPagerAdapter(this); | ||||
|         viewPager2.setAdapter(sectionsPagerAdapter); | ||||
|         viewPager2.setOffscreenPageLimit(2); | ||||
|         viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT); | ||||
|         viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); | ||||
|         new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { | ||||
|             switch (position) { | ||||
| @@ -700,11 +796,11 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|  | ||||
|         fixViewPager2Sensitivity(viewPager2); | ||||
|  | ||||
|         if (mMessageFullname != null) { | ||||
|             ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() { | ||||
|         if (mMessageId != 0) { | ||||
|             ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageId, new ReadMessage.ReadMessageListener() { | ||||
|                 @Override | ||||
|                 public void readSuccess() { | ||||
|                     mMessageFullname = null; | ||||
|                     mMessageId = 0; | ||||
|                 } | ||||
|  | ||||
|                 @Override | ||||
| @@ -923,6 +1019,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|             case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_PROFILE: { | ||||
|                 Intent intent = new Intent(this, ViewUserDetailActivity.class); | ||||
|                 intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName); | ||||
|                 intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY,mAccountQualifiedName); | ||||
|                 startActivity(intent); | ||||
|                 break; | ||||
|             } | ||||
| @@ -1077,8 +1174,27 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|                 @Override | ||||
|                 public void onFetchUserDataSuccess(UserData userData, int inboxCount) { | ||||
|                     mUserData = userData; | ||||
|                     username = userData.getName(); | ||||
|                     username = userData.getDisplayName(); | ||||
|                     setupVisibleElements(); | ||||
|                     FetchBlockedThings.fetchBlockedThings(mRetrofit.getRetrofit(), mAccessToken, mAccountQualifiedName, new FetchBlockedThings.FetchBlockedThingsListener() { | ||||
|  | ||||
|                         @Override | ||||
|                         public void onFetchBlockedThingsSuccess(List<BlockedUserData> blockedUsers, List<BlockedCommunityData> blockedCommunities) { | ||||
|                             for (BlockedUserData blockedUserData : blockedUsers) { | ||||
|                                 if (blockedUserData.getQualifiedName().equals(qualifiedName)) { | ||||
|                                     isBlocked = true; | ||||
|                                     invalidateOptionsMenu(); | ||||
|                                     return; | ||||
|                                 } | ||||
|                             } | ||||
|                             isBlocked = false; | ||||
|                             invalidateOptionsMenu(); | ||||
|                         } | ||||
|  | ||||
|                         @Override | ||||
|                         public void onFetchBlockedThingsFailure() { | ||||
|                         } | ||||
|                     }); | ||||
|                     new ViewUserDetailActivity.InsertUserDataAsyncTask(mRedditDataRoomDatabase.userDao(), userData, | ||||
|                             () -> mFetchUserInfoSuccess = true).execute(); | ||||
|                 } | ||||
| @@ -1092,12 +1208,12 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void deleteComment(String fullName) { | ||||
|     public void deleteComment(int commentId) { | ||||
|         new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) | ||||
|                 .setTitle(R.string.delete_this_comment) | ||||
|                 .setMessage(R.string.are_you_sure) | ||||
|                 .setPositiveButton(R.string.delete, (dialogInterface, i) | ||||
|                         -> DeleteThing.delete(mOauthRetrofit, fullName, mAccessToken, new DeleteThing.DeleteThingListener() { | ||||
|                         -> DeleteThing.deleteComment(mRetrofit.getRetrofit(), commentId, mAccessToken, new DeleteThing.DeleteThingListener() { | ||||
|                     @Override | ||||
|                     public void deleteSuccess() { | ||||
|                         Toast.makeText(ViewUserDetailActivity.this, R.string.delete_post_success, Toast.LENGTH_SHORT).show(); | ||||
| @@ -1121,6 +1237,12 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|             menu.findItem(R.id.action_block_user_view_user_detail_activity).setVisible(false); | ||||
|         } else { | ||||
|             menu.findItem(R.id.action_edit_profile_view_user_detail_activity).setVisible(false); | ||||
|             if (isBlocked) { | ||||
|                 menu.findItem(R.id.action_block_user_view_user_detail_activity).setVisible(false); | ||||
|                 menu.findItem(R.id.action_unblock_user_view_user_detail_activity).setVisible(true); | ||||
|             } else { | ||||
|                 menu.findItem(R.id.action_unblock_user_view_user_detail_activity).setVisible(false); | ||||
|             } | ||||
|         } | ||||
|         applyMenuItemTheme(menu); | ||||
|         return true; | ||||
| @@ -1155,7 +1277,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|             Intent shareIntent = new Intent(Intent.ACTION_SEND); | ||||
|             shareIntent.setType("text/plain"); | ||||
|             String baseURL = mRetrofit.getBaseURL().endsWith("/") ? mRetrofit.getBaseURL() : mRetrofit.getBaseURL() + "/"; | ||||
|             shareIntent.putExtra(Intent.EXTRA_TEXT, baseURL + qualifiedName); | ||||
|             shareIntent.putExtra(Intent.EXTRA_TEXT, baseURL + "u/" + qualifiedName); | ||||
|             if (shareIntent.resolveActivity(getPackageManager()) != null) { | ||||
|                 startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); | ||||
|             } else { | ||||
| @@ -1169,16 +1291,9 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|             } | ||||
|  | ||||
|             Intent pmIntent = new Intent(this, SendPrivateMessageActivity.class); | ||||
|             pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, username); | ||||
|             pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USER_INFO, new BasicUserInfo(mUserData.getId(), username, qualifiedName, mUserData.getAvatar(), mUserData.getDisplayName())); | ||||
|             startActivity(pmIntent); | ||||
|             return true; | ||||
|         } else if (itemId == R.id.action_add_to_multireddit_view_user_detail_activity) { | ||||
|             if (mAccessToken == null) { | ||||
|                 Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); | ||||
|                 return true; | ||||
|             } | ||||
|             Intent intent = new Intent(this, MultiredditSelectionActivity.class); | ||||
|             startActivityForResult(intent, ADD_TO_MULTIREDDIT_REQUEST_CODE); | ||||
|         } else if (itemId == R.id.action_add_to_post_filter_view_user_detail_activity) { | ||||
|             Intent intent = new Intent(this, PostFilterPreferenceActivity.class); | ||||
|             intent.putExtra(PostFilterPreferenceActivity.EXTRA_USER_NAME, username); | ||||
| @@ -1199,10 +1314,13 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|                     .setTitle(R.string.block_user) | ||||
|                     .setMessage(R.string.are_you_sure) | ||||
|                     .setPositiveButton(R.string.yes, (dialogInterface, i) | ||||
|                             -> BlockUser.blockUser(mOauthRetrofit, mAccessToken, username, new BlockUser.BlockUserListener() { | ||||
|                             -> BlockUser.blockUser(mRetrofit.getRetrofit(), mAccessToken, mUserData.getId(), true, new BlockUser.BlockUserListener() { | ||||
|                         @Override | ||||
|                         public void success() { | ||||
|                             Toast.makeText(ViewUserDetailActivity.this, R.string.block_user_success, Toast.LENGTH_SHORT).show(); | ||||
|                             isBlocked = true; | ||||
|                             sectionsPagerAdapter.refresh(); | ||||
|                             invalidateOptionsMenu(); | ||||
|                         } | ||||
|  | ||||
|                         @Override | ||||
| @@ -1216,6 +1334,25 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|         } else if (itemId == R.id.action_edit_profile_view_user_detail_activity) { | ||||
|             startActivity(new Intent(this, EditProfileActivity.class)); | ||||
|             return true; | ||||
|         } else if (itemId == R.id.action_unblock_user_view_user_detail_activity) { | ||||
|             if (mAccessToken == null) { | ||||
|                 Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); | ||||
|                 return true; | ||||
|             } | ||||
|             BlockUser.blockUser(mRetrofit.getRetrofit(), mAccessToken, mUserData.getId(), false, new BlockUser.BlockUserListener() { | ||||
|                 @Override | ||||
|                 public void success() { | ||||
|                     isBlocked = false; | ||||
|                     Toast.makeText(ViewUserDetailActivity.this, R.string.unblock_user_success, Toast.LENGTH_SHORT).show(); | ||||
|                     sectionsPagerAdapter.refresh(); | ||||
|                     invalidateOptionsMenu(); | ||||
|                 } | ||||
|  | ||||
|                 @Override | ||||
|                 public void failed() { | ||||
|                     Toast.makeText(ViewUserDetailActivity.this, R.string.unblock_user_failed, Toast.LENGTH_SHORT).show(); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| @@ -1262,8 +1399,10 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|     protected void onSaveInstanceState(@NonNull Bundle outState) { | ||||
|         super.onSaveInstanceState(outState); | ||||
|         outState.putBoolean(FETCH_USER_INFO_STATE, mFetchUserInfoSuccess); | ||||
|         outState.putString(MESSAGE_FULLNAME_STATE, mMessageFullname); | ||||
|         outState.putInt(MESSAGE_FULLNAME_STATE, mMessageId); | ||||
|         outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName); | ||||
|         outState.putString(NEW_ACCOUNT_QUALIFIED_NAME_STATE, mAccountQualifiedName); | ||||
|         outState.putString("qualified_name", qualifiedName); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -1335,10 +1474,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|                 goToUser(); | ||||
|                 break; | ||||
|             } | ||||
|             case FABMoreOptionsBottomSheetFragment.FAB_RANDOM: { | ||||
|                 random(); | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             case FABMoreOptionsBottomSheetFragment.FAB_HIDE_READ_POSTS: { | ||||
|                 if (sectionsPagerAdapter != null) { | ||||
|                     sectionsPagerAdapter.hideReadPosts(); | ||||
| @@ -1378,7 +1514,11 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|             if (i == EditorInfo.IME_ACTION_DONE) { | ||||
|                 Utils.hideKeyboard(this); | ||||
|                 Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class); | ||||
|                 subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); | ||||
|                 String communityName = thingEditText.getText().toString(); | ||||
|                 if (communityName.startsWith("!")) { | ||||
|                     communityName = communityName.substring(1); | ||||
|                 } | ||||
|                 subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, communityName); | ||||
|                 startActivity(subredditIntent); | ||||
|                 return true; | ||||
|             } | ||||
| @@ -1436,7 +1576,11 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|                         -> { | ||||
|                     Utils.hideKeyboard(this); | ||||
|                     Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class); | ||||
|                     subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); | ||||
|                     String communityName = thingEditText.getText().toString(); | ||||
|                     if (communityName.startsWith("!")) { | ||||
|                         communityName = communityName.substring(1); | ||||
|                     } | ||||
|                     subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, communityName); | ||||
|                     startActivity(subredditIntent); | ||||
|                 }) | ||||
|                 .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { | ||||
| @@ -1457,7 +1601,11 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|             if (i == EditorInfo.IME_ACTION_DONE) { | ||||
|                 Utils.hideKeyboard(this); | ||||
|                 Intent userIntent = new Intent(this, ViewUserDetailActivity.class); | ||||
|                 userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); | ||||
|                 String userName = thingEditText.getText().toString(); | ||||
|                 if (userName.startsWith("@")) { | ||||
|                     userName = userName.substring(1); | ||||
|                 } | ||||
|                 userIntent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, userName); | ||||
|                 startActivity(userIntent); | ||||
|                 return true; | ||||
|             } | ||||
| @@ -1470,7 +1618,11 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|                         -> { | ||||
|                     Utils.hideKeyboard(this); | ||||
|                     Intent userIntent = new Intent(this, ViewUserDetailActivity.class); | ||||
|                     userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); | ||||
|                     String userName = thingEditText.getText().toString(); | ||||
|                     if (userName.startsWith("@")) { | ||||
|                         userName = userName.substring(1); | ||||
|                     } | ||||
|                     userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, userName); | ||||
|                     startActivity(userIntent); | ||||
|                 }) | ||||
|                 .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { | ||||
| @@ -1550,7 +1702,17 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|  | ||||
|     @Override | ||||
|     public void markPostAsRead(Post post) { | ||||
|         InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountName, post.getId()); | ||||
|         markPostAsRead.markPostAsRead(post.getId(), mAccessToken, new MarkPostAsRead.MarkPostAsReadListener() { | ||||
|             @Override | ||||
|             public void onMarkPostAsReadSuccess() { | ||||
|                 InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, mAccountQualifiedName, post.getId()); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onMarkPostAsReadFailed() { | ||||
|                 Toast.makeText(ViewUserDetailActivity.this, R.string.mark_post_as_read_failed, Toast.LENGTH_SHORT).show(); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -23,14 +23,11 @@ import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.provider.Settings; | ||||
| import android.text.Html; | ||||
| import android.view.Menu; | ||||
| import android.view.MenuItem; | ||||
| import android.view.OrientationEventListener; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.ImageButton; | ||||
| import android.widget.ImageView; | ||||
| import android.widget.LinearLayout; | ||||
| import android.widget.ProgressBar; | ||||
| import android.widget.TextView; | ||||
| @@ -70,6 +67,7 @@ import com.google.android.exoplayer2.upstream.cache.SimpleCache; | ||||
| import com.google.android.exoplayer2.util.MimeTypes; | ||||
| import com.google.android.exoplayer2.video.VideoSize; | ||||
| import com.google.android.material.bottomappbar.BottomAppBar; | ||||
| import com.google.android.material.button.MaterialButton; | ||||
| import com.google.android.material.snackbar.Snackbar; | ||||
| import com.google.common.collect.ImmutableList; | ||||
| import com.otaliastudios.zoom.ZoomEngine; | ||||
| @@ -108,6 +106,7 @@ import eu.toldi.infinityforlemmy.font.TitleFontFamily; | ||||
| import eu.toldi.infinityforlemmy.font.TitleFontStyle; | ||||
| import eu.toldi.infinityforlemmy.post.FetchPost; | ||||
| import eu.toldi.infinityforlemmy.post.Post; | ||||
| import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; | ||||
| import eu.toldi.infinityforlemmy.services.DownloadMediaService; | ||||
| import eu.toldi.infinityforlemmy.services.DownloadRedditVideoService; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| @@ -131,7 +130,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|     public static final String EXTRA_VIDEO_DOWNLOAD_URL = "EVDU"; | ||||
|     public static final String EXTRA_SUBREDDIT = "ES"; | ||||
|     public static final String EXTRA_ID = "EI"; | ||||
|     public static final String EXTRA_POST_TITLE = "EPT"; | ||||
|     public static final String EXTRA_POST = "EP"; | ||||
|     public static final String EXTRA_PROGRESS_SECONDS = "EPS"; | ||||
|     public static final String EXTRA_VIDEO_TYPE = "EVT"; | ||||
|     public static final String EXTRA_GFYCAT_ID = "EGI"; | ||||
| @@ -162,17 +161,19 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|     @BindView(R.id.progress_bar_view_video_activity) | ||||
|     ProgressBar progressBar; | ||||
|     @BindView(R.id.mute_exo_playback_control_view) | ||||
|     ImageButton muteButton; | ||||
|     MaterialButton muteButton; | ||||
|     @BindView(R.id.hd_exo_playback_control_view) | ||||
|     ImageButton hdButton; | ||||
|     MaterialButton hdButton; | ||||
|     @BindView(R.id.bottom_navigation_exo_playback_control_view) | ||||
|     BottomAppBar bottomAppBar; | ||||
|     @BindView(R.id.title_text_view_exo_playback_control_view) | ||||
|     TextView titleTextView; | ||||
|     @BindView(R.id.back_button_exo_playback_control_view) | ||||
|     MaterialButton backButton; | ||||
|     @BindView(R.id.download_image_view_exo_playback_control_view) | ||||
|     ImageView downloadImageView; | ||||
|     MaterialButton downloadButton; | ||||
|     @BindView(R.id.playback_speed_image_view_exo_playback_control_view) | ||||
|     ImageView playbackSpeedImageView; | ||||
|     MaterialButton playbackSpeedButton; | ||||
|     @BindView(R.id.lockable_nested_scroll_view_view_video_activity) | ||||
|     LockableNestedScrollView nestedScrollView; | ||||
|  | ||||
| @@ -222,10 +223,6 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|     @Named("default") | ||||
|     SharedPreferences mSharedPreferences; | ||||
|  | ||||
|     @Inject | ||||
|     @Named("current_account") | ||||
|     SharedPreferences mCurrentAccountSharedPreferences; | ||||
|  | ||||
|     @Inject | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|  | ||||
| @@ -235,6 +232,9 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|     @Inject | ||||
|     SimpleCache mSimpleCache; | ||||
|  | ||||
|     @Inject | ||||
|     PostEnricher postEnricher; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
| @@ -301,6 +301,12 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|         ButterKnife.bind(this); | ||||
|         setVolumeControlStream(AudioManager.STREAM_MUSIC); | ||||
|  | ||||
|         setTitle(" "); | ||||
|  | ||||
|         if (typeface != null) { | ||||
|             titleTextView.setTypeface(typeface); | ||||
|         } | ||||
|  | ||||
|         Resources resources = getResources(); | ||||
|  | ||||
|         getWindow().getDecorView().setSystemUiVisibility( | ||||
| @@ -312,7 +318,11 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|         if (useBottomAppBar) { | ||||
|             getSupportActionBar().hide(); | ||||
|             bottomAppBar.setVisibility(View.VISIBLE); | ||||
|             downloadImageView.setOnClickListener(view -> { | ||||
|             backButton.setOnClickListener(view -> { | ||||
|                 finish(); | ||||
|             }); | ||||
|  | ||||
|             downloadButton.setOnClickListener(view -> { | ||||
|                 if (isDownloading) { | ||||
|                     return; | ||||
|                 } | ||||
| @@ -326,12 +336,8 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|                 requestPermissionAndDownload(); | ||||
|             }); | ||||
|  | ||||
|             playbackSpeedImageView.setOnClickListener(view -> { | ||||
|                 PlaybackSpeedBottomSheetFragment playbackSpeedBottomSheetFragment = new PlaybackSpeedBottomSheetFragment(); | ||||
|                 Bundle bundle = new Bundle(); | ||||
|                 bundle.putInt(PlaybackSpeedBottomSheetFragment.EXTRA_PLAYBACK_SPEED, playbackSpeed); | ||||
|                 playbackSpeedBottomSheetFragment.setArguments(bundle); | ||||
|                 playbackSpeedBottomSheetFragment.show(getSupportFragmentManager(), playbackSpeedBottomSheetFragment.getTag()); | ||||
|             playbackSpeedButton.setOnClickListener(view -> { | ||||
|                 changePlaybackSpeed(); | ||||
|             }); | ||||
|         } else { | ||||
|             ActionBar actionBar = getSupportActionBar(); | ||||
| @@ -402,12 +408,15 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|                         }; | ||||
|                         orientationEventListener.enable(); | ||||
|                     } | ||||
|                 } catch (Exception ignore) {} | ||||
|                 } catch (Exception ignore) { | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         String postTitle = intent.getStringExtra(EXTRA_POST_TITLE); | ||||
|         setSmallTitle(postTitle); | ||||
|         Post post = intent.getParcelableExtra(EXTRA_POST); | ||||
|         if (post != null) { | ||||
|             titleTextView.setText(post.getTitle()); | ||||
|         } | ||||
|  | ||||
|         trackSelector = new DefaultTrackSelector(this); | ||||
|         if (videoType == VIDEO_TYPE_NORMAL && isDataSavingMode && dataSavingModeDefaultResolution > 0) { | ||||
| @@ -598,20 +607,6 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void setSmallTitle(String title) { | ||||
|         if (title != null) { | ||||
|             if (useBottomAppBar) { | ||||
|                 titleTextView.setText(Html.fromHtml(String.format("<font color=\"#FFFFFF\"><small>%s</small></font>", title))); | ||||
|             } else { | ||||
|                 setTitle(Utils.getTabTextWithCustomFont(typeface, Html.fromHtml(String.format("<font color=\"#FFFFFF\"><small>%s</small></font>", title)))); | ||||
|             } | ||||
|         } else { | ||||
|             if (!useBottomAppBar) { | ||||
|                 setTitle(""); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void preparePlayer(Bundle savedInstanceState) { | ||||
|         if (mSharedPreferences.getBoolean(SharedPreferencesUtils.LOOP_VIDEO, true)) { | ||||
|             player.setRepeatMode(Player.REPEAT_MODE_ALL); | ||||
| @@ -631,17 +626,17 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|             isMute = savedInstanceState.getBoolean(IS_MUTE_STATE); | ||||
|             if (isMute) { | ||||
|                 player.setVolume(0f); | ||||
|                 muteButton.setImageResource(R.drawable.ic_mute_24dp); | ||||
|                 muteButton.setIconResource(R.drawable.ic_mute_24dp); | ||||
|             } else { | ||||
|                 player.setVolume(1f); | ||||
|                 muteButton.setImageResource(R.drawable.ic_unmute_24dp); | ||||
|                 muteButton.setIconResource(R.drawable.ic_unmute_24dp); | ||||
|             } | ||||
|         } else if (muteVideo) { | ||||
|             isMute = true; | ||||
|             player.setVolume(0f); | ||||
|             muteButton.setImageResource(R.drawable.ic_mute_24dp); | ||||
|             muteButton.setIconResource(R.drawable.ic_mute_24dp); | ||||
|         } else { | ||||
|             muteButton.setImageResource(R.drawable.ic_unmute_24dp); | ||||
|             muteButton.setIconResource(R.drawable.ic_unmute_24dp); | ||||
|         } | ||||
|  | ||||
|         player.addListener(new Player.Listener() { | ||||
| @@ -685,11 +680,11 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|                                     if (isMute) { | ||||
|                                         isMute = false; | ||||
|                                         player.setVolume(1f); | ||||
|                                         muteButton.setImageResource(R.drawable.ic_unmute_24dp); | ||||
|                                         muteButton.setIconResource(R.drawable.ic_unmute_24dp); | ||||
|                                     } else { | ||||
|                                         isMute = true; | ||||
|                                         player.setVolume(0f); | ||||
|                                         muteButton.setImageResource(R.drawable.ic_mute_24dp); | ||||
|                                         muteButton.setIconResource(R.drawable.ic_mute_24dp); | ||||
|                                     } | ||||
|                                 }); | ||||
|                             } | ||||
| @@ -702,6 +697,14 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private void changePlaybackSpeed() { | ||||
|         PlaybackSpeedBottomSheetFragment playbackSpeedBottomSheetFragment = new PlaybackSpeedBottomSheetFragment(); | ||||
|         Bundle bundle = new Bundle(); | ||||
|         bundle.putInt(PlaybackSpeedBottomSheetFragment.EXTRA_PLAYBACK_SPEED, playbackSpeed); | ||||
|         playbackSpeedBottomSheetFragment.setArguments(bundle); | ||||
|         playbackSpeedBottomSheetFragment.show(getSupportFragmentManager(), playbackSpeedBottomSheetFragment.getTag()); | ||||
|     } | ||||
|  | ||||
|     private int inferPrimaryTrackType(Format format) { | ||||
|         int trackType = MimeTypes.getTrackType(format.sampleMimeType); | ||||
|         if (trackType != C.TRACK_TYPE_UNKNOWN) { | ||||
| @@ -756,8 +759,8 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|                         } | ||||
|                     }); | ||||
|         } else { | ||||
|             FetchGfycatOrRedgifsVideoLinks.fetchRedgifsVideoLinks(this, mExecutor, new Handler(), redgifsRetrofit, | ||||
|                     mCurrentAccountSharedPreferences, gfycatId, new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() { | ||||
|             FetchGfycatOrRedgifsVideoLinks.fetchRedgifsVideoLinks(mExecutor, new Handler(), redgifsRetrofit, | ||||
|                     gfycatId, new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() { | ||||
|                         @Override | ||||
|                         public void success(String webm, String mp4) { | ||||
|                             progressBar.setVisibility(View.GONE); | ||||
| @@ -791,7 +794,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|                     int commentsIndex = segments.lastIndexOf("comments"); | ||||
|                     String postId = segments.get(commentsIndex + 1); | ||||
|                     FetchPost.fetchPost(mExecutor, new Handler(), retrofit.getRetrofit(), postId, null, | ||||
|                             new FetchPost.FetchPostListener() { | ||||
|                             postEnricher, new FetchPost.FetchPostListener() { | ||||
|                                 @Override | ||||
|                                 public void fetchPostSuccess(Post post) { | ||||
|                                     if (post.isGfycat()) { | ||||
| @@ -884,7 +887,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|                             Toast.makeText(ViewVideoActivity.this, R.string.fetch_streamable_video_failed, Toast.LENGTH_SHORT).show(); | ||||
|                             return; | ||||
|                         } | ||||
|                         setSmallTitle(streamableVideo.title); | ||||
|                         titleTextView.setText(streamableVideo.title); | ||||
|                         progressBar.setVisibility(View.GONE); | ||||
|                         videoDownloadUrl = streamableVideo.mp4 == null ? streamableVideo.mp4Mobile.url : streamableVideo.mp4.url; | ||||
|                         mVideoUri = Uri.parse(videoDownloadUrl); | ||||
| @@ -939,11 +942,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe | ||||
|             requestPermissionAndDownload(); | ||||
|             return true; | ||||
|         } else if (itemId == R.id.action_playback_speed_view_video_activity) { | ||||
|             PlaybackSpeedBottomSheetFragment playbackSpeedBottomSheetFragment = new PlaybackSpeedBottomSheetFragment(); | ||||
|             Bundle bundle = new Bundle(); | ||||
|             bundle.putInt(PlaybackSpeedBottomSheetFragment.EXTRA_PLAYBACK_SPEED, playbackSpeed); | ||||
|             playbackSpeedBottomSheetFragment.setArguments(bundle); | ||||
|             playbackSpeedBottomSheetFragment.show(getSupportFragmentManager(), playbackSpeedBottomSheetFragment.getTag()); | ||||
|             changePlaybackSpeed(); | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -35,16 +35,9 @@ import javax.inject.Named; | ||||
|  | ||||
| import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
| import eu.toldi.infinityforlemmy.RetrofitHolder; | ||||
| import io.noties.markwon.AbstractMarkwonPlugin; | ||||
| import io.noties.markwon.Markwon; | ||||
| import io.noties.markwon.MarkwonConfiguration; | ||||
| import io.noties.markwon.MarkwonPlugin; | ||||
| import io.noties.markwon.core.MarkwonTheme; | ||||
| import io.noties.markwon.recycler.MarkwonAdapter; | ||||
| import me.saket.bettermovementmethod.BetterLinkMovementMethod; | ||||
| import eu.toldi.infinityforlemmy.Infinity; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RetrofitHolder; | ||||
| import eu.toldi.infinityforlemmy.apis.RedditAPI; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.UrlMenuBottomSheetFragment; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| @@ -57,10 +50,16 @@ import eu.toldi.infinityforlemmy.markdown.MarkdownUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.JSONUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.Utils; | ||||
| import io.noties.markwon.AbstractMarkwonPlugin; | ||||
| import io.noties.markwon.Markwon; | ||||
| import io.noties.markwon.MarkwonConfiguration; | ||||
| import io.noties.markwon.MarkwonPlugin; | ||||
| import io.noties.markwon.core.MarkwonTheme; | ||||
| import io.noties.markwon.recycler.MarkwonAdapter; | ||||
| import me.saket.bettermovementmethod.BetterLinkMovementMethod; | ||||
| import retrofit2.Call; | ||||
| import retrofit2.Callback; | ||||
| import retrofit2.Response; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
| public class WikiActivity extends BaseActivity { | ||||
|  | ||||
| @@ -139,7 +138,7 @@ public class WikiActivity extends BaseActivity { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         mGlide = Glide.with(this); | ||||
|         mGlide = Glide.with(getApplication()); | ||||
|  | ||||
|         swipeRefreshLayout.setEnabled(mSharedPreferences.getBoolean(SharedPreferencesUtils.PULL_TO_REFRESH, true)); | ||||
|         swipeRefreshLayout.setOnRefreshListener(this::loadWiki); | ||||
| @@ -177,7 +176,7 @@ public class WikiActivity extends BaseActivity { | ||||
|             return true; | ||||
|         }; | ||||
|         markwon = MarkdownUtils.createFullRedditMarkwon(this, | ||||
|                 miscPlugin, markdownColor, spoilerBackgroundColor, onLinkLongClickListener); | ||||
|                 miscPlugin, markdownColor, spoilerBackgroundColor, onLinkLongClickListener, mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false)); | ||||
|  | ||||
|         markwonAdapter = MarkdownUtils.createTablesAdapter(); | ||||
|         LinearLayoutManagerBugFixed linearLayoutManager = new SwipeLockLinearLayoutManager(this, new SwipeLockInterface() { | ||||
| @@ -219,7 +218,7 @@ public class WikiActivity extends BaseActivity { | ||||
|  | ||||
|         swipeRefreshLayout.setRefreshing(true); | ||||
|  | ||||
|         Glide.with(this).clear(mFetchWikiInfoImageView); | ||||
|         Glide.with(getApplication()).clear(mFetchWikiInfoImageView); | ||||
|         mFetchWikiInfoLinearLayout.setVisibility(View.GONE); | ||||
|  | ||||
|         retrofit.getRetrofit().create(RedditAPI.class).getWikiPage(getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME), getIntent().getStringExtra(EXTRA_WIKI_PATH)).enqueue(new Callback<String>() { | ||||
|   | ||||
| @@ -0,0 +1,22 @@ | ||||
| package eu.toldi.infinityforlemmy.adapters; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.activities.BaseActivity; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.user.BasicUserRecyclerViewAdapter; | ||||
|  | ||||
| public class AdminRecyclerViewAdapter extends BasicUserRecyclerViewAdapter { | ||||
|  | ||||
|     CustomThemeWrapper mCustomThemeWrapper; | ||||
|  | ||||
|     public AdminRecyclerViewAdapter(BaseActivity activity, CustomThemeWrapper customThemeWrapper) { | ||||
|         super(activity, customThemeWrapper); | ||||
|         mCustomThemeWrapper = customThemeWrapper; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected int getUserNameTextColor() { | ||||
|         return mCustomThemeWrapper.getAdmin(); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,385 @@ | ||||
| package eu.toldi.infinityforlemmy.adapters; | ||||
|  | ||||
| import android.content.Intent; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| import com.bumptech.glide.Glide; | ||||
| import com.bumptech.glide.RequestManager; | ||||
| import com.bumptech.glide.request.RequestOptions; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.concurrent.Executor; | ||||
| import java.util.regex.Pattern; | ||||
|  | ||||
| import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| import eu.toldi.infinityforlemmy.activities.BaseActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.ViewSubredditDetailActivity; | ||||
| import eu.toldi.infinityforlemmy.blockedcommunity.BlockedCommunityData; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import jp.wasabeef.glide.transformations.RoundedCornersTransformation; | ||||
| import me.zhanghai.android.fastscroll.PopupTextProvider; | ||||
| import pl.droidsonroids.gif.GifImageView; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
| public class BlockedCommunitiesRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements PopupTextProvider { | ||||
|     private static final int VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER = 0; | ||||
|     private static final int VIEW_TYPE_FAVORITE_SUBREDDIT = 1; | ||||
|     private static final int VIEW_TYPE_SUBREDDIT_DIVIDER = 2; | ||||
|     private static final int VIEW_TYPE_SUBREDDIT = 3; | ||||
|  | ||||
|     private BaseActivity mActivity; | ||||
|     private Executor mExecutor; | ||||
|     private Retrofit mOauthRetrofit; | ||||
|     private RedditDataRoomDatabase mRedditDataRoomDatabase; | ||||
|     private List<BlockedCommunityData> mBlockedCommunityData; | ||||
|     private List<BlockedCommunityData> mFavoriteBlockedCommunityData; | ||||
|     private RequestManager glide; | ||||
|     private ItemClickListener itemClickListener; | ||||
|  | ||||
|     private String accessToken; | ||||
|     private String username; | ||||
|     private String userIconUrl; | ||||
|     private boolean hasClearSelectionRow; | ||||
|  | ||||
|     private int primaryTextColor; | ||||
|     private int secondaryTextColor; | ||||
|  | ||||
|     public BlockedCommunitiesRecyclerViewAdapter(BaseActivity activity, Executor executor, Retrofit oauthRetrofit, | ||||
|                                                  RedditDataRoomDatabase redditDataRoomDatabase, | ||||
|                                                  CustomThemeWrapper customThemeWrapper, | ||||
|                                                  String accessToken) { | ||||
|         mActivity = activity; | ||||
|         mExecutor = executor; | ||||
|         glide = Glide.with(activity); | ||||
|         mOauthRetrofit = oauthRetrofit; | ||||
|         mRedditDataRoomDatabase = redditDataRoomDatabase; | ||||
|         this.accessToken = accessToken; | ||||
|         primaryTextColor = customThemeWrapper.getPrimaryTextColor(); | ||||
|         secondaryTextColor = customThemeWrapper.getSecondaryTextColor(); | ||||
|     } | ||||
|  | ||||
|     public BlockedCommunitiesRecyclerViewAdapter(BaseActivity activity, Executor executor, Retrofit oauthRetrofit, | ||||
|                                                  RedditDataRoomDatabase redditDataRoomDatabase, | ||||
|                                                  CustomThemeWrapper customThemeWrapper, | ||||
|                                                  String accessToken, boolean hasClearSelectionRow, | ||||
|                                                  ItemClickListener itemClickListener) { | ||||
|         this(activity, executor, oauthRetrofit, redditDataRoomDatabase, customThemeWrapper, accessToken); | ||||
|         this.hasClearSelectionRow = hasClearSelectionRow; | ||||
|         this.itemClickListener = itemClickListener; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int getItemViewType(int position) { | ||||
|         if (mFavoriteBlockedCommunityData != null && mFavoriteBlockedCommunityData.size() > 0) { | ||||
|             if (itemClickListener != null && !hasClearSelectionRow) { | ||||
|                 if (position == 0) { | ||||
|                     return VIEW_TYPE_SUBREDDIT; | ||||
|                 } else if (position == 1) { | ||||
|                     return VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER; | ||||
|                 } else if (position == mFavoriteBlockedCommunityData.size() + 2) { | ||||
|                     return VIEW_TYPE_SUBREDDIT_DIVIDER; | ||||
|                 } else if (position <= mFavoriteBlockedCommunityData.size() + 1) { | ||||
|                     return VIEW_TYPE_FAVORITE_SUBREDDIT; | ||||
|                 } else { | ||||
|                     return VIEW_TYPE_SUBREDDIT; | ||||
|                 } | ||||
|             } else if (hasClearSelectionRow) { | ||||
|                 if (position == 0) { | ||||
|                     return VIEW_TYPE_SUBREDDIT; | ||||
|                 } else if (position == 1) { | ||||
|                     return VIEW_TYPE_SUBREDDIT; | ||||
|                 } else if (position == 2) { | ||||
|                     return VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER; | ||||
|                 } else if (position == mFavoriteBlockedCommunityData.size() + 3) { | ||||
|                     return VIEW_TYPE_SUBREDDIT_DIVIDER; | ||||
|                 } else if (position <= mFavoriteBlockedCommunityData.size() + 2) { | ||||
|                     return VIEW_TYPE_FAVORITE_SUBREDDIT; | ||||
|                 } else { | ||||
|                     return VIEW_TYPE_SUBREDDIT; | ||||
|                 } | ||||
|             } else { | ||||
|                 if (position == 0) { | ||||
|                     return VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER; | ||||
|                 } else if (position == mFavoriteBlockedCommunityData.size() + 1) { | ||||
|                     return VIEW_TYPE_SUBREDDIT_DIVIDER; | ||||
|                 } else if (position <= mFavoriteBlockedCommunityData.size()) { | ||||
|                     return VIEW_TYPE_FAVORITE_SUBREDDIT; | ||||
|                 } else { | ||||
|                     return VIEW_TYPE_SUBREDDIT; | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             return VIEW_TYPE_SUBREDDIT; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { | ||||
|         switch (i) { | ||||
|             case VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER: | ||||
|                 return new FavoriteSubredditsDividerViewHolder(LayoutInflater.from(viewGroup.getContext()) | ||||
|                         .inflate(R.layout.item_favorite_thing_divider, viewGroup, false)); | ||||
|             case VIEW_TYPE_FAVORITE_SUBREDDIT: | ||||
|                 return new FavoriteSubredditViewHolder(LayoutInflater.from(viewGroup.getContext()) | ||||
|                         .inflate(R.layout.item_subscribed_thing, viewGroup, false)); | ||||
|             case VIEW_TYPE_SUBREDDIT_DIVIDER: | ||||
|                 return new AllSubredditsDividerViewHolder(LayoutInflater.from(viewGroup.getContext()) | ||||
|                         .inflate(R.layout.item_favorite_thing_divider, viewGroup, false)); | ||||
|             default: | ||||
|                 return new SubredditViewHolder(LayoutInflater.from(viewGroup.getContext()) | ||||
|                         .inflate(R.layout.item_subscribed_thing, viewGroup, false)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int i) { | ||||
|         if (viewHolder instanceof SubredditViewHolder) { | ||||
|             String name; | ||||
|             String fullname = ""; | ||||
|             String iconUrl; | ||||
|  | ||||
|             if (hasClearSelectionRow && viewHolder.getBindingAdapterPosition() == 0) { | ||||
|                 ((SubredditViewHolder) viewHolder).subredditNameTextView.setText(R.string.all_communities); | ||||
|                 viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(null)); | ||||
|                 return; | ||||
|             } else { | ||||
|                 int offset = hasClearSelectionRow ? 1 : 0; | ||||
|                 BlockedCommunityData communityData = mBlockedCommunityData.get(viewHolder.getBindingAdapterPosition() - offset); | ||||
|                 name = mBlockedCommunityData.get(viewHolder.getBindingAdapterPosition() - offset).getName(); | ||||
|                 fullname = mBlockedCommunityData.get(viewHolder.getBindingAdapterPosition() - offset).getQualified_name(); | ||||
|                 iconUrl = mBlockedCommunityData.get(viewHolder.getBindingAdapterPosition() - offset).getIconUrl(); | ||||
|  | ||||
|                 if (itemClickListener != null) { | ||||
|                     viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(communityData)); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (itemClickListener == null) { | ||||
|                 String finalFullname = fullname; | ||||
|                 viewHolder.itemView.setOnClickListener(view -> { | ||||
|                     Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class); | ||||
|                     intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, name); | ||||
|                     intent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, | ||||
|                             finalFullname); | ||||
|                     mActivity.startActivity(intent); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             if (iconUrl != null && !iconUrl.equals("")) { | ||||
|                 glide.load(iconUrl) | ||||
|                         .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) | ||||
|                         .error(glide.load(R.drawable.subreddit_default_icon) | ||||
|                                 .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) | ||||
|                         .into(((SubredditViewHolder) viewHolder).iconGifImageView); | ||||
|             } else { | ||||
|                 glide.load(R.drawable.subreddit_default_icon) | ||||
|                         .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) | ||||
|                         .into(((SubredditViewHolder) viewHolder).iconGifImageView); | ||||
|             } | ||||
|             ((SubredditViewHolder) viewHolder).subredditNameTextView.setText(name); | ||||
|             if (fullname.contains("@")) { | ||||
|                 ((SubredditViewHolder) viewHolder).communityInstanceTextView.setText("@" + fullname.split(Pattern.quote("@"), 2)[1]); | ||||
|                 ((SubredditViewHolder) viewHolder).communityInstanceTextView.setTextColor(CustomThemeWrapper.darkenColor(primaryTextColor, 0.7f)); | ||||
|             } | ||||
|         } else if (viewHolder instanceof FavoriteSubredditViewHolder) { | ||||
|             int offset; | ||||
|             if (itemClickListener != null) { | ||||
|                 if (hasClearSelectionRow) { | ||||
|                     offset = 3; | ||||
|                 } else { | ||||
|                     offset = 2; | ||||
|                 } | ||||
|             } else { | ||||
|                 offset = 1; | ||||
|             } | ||||
|             BlockedCommunityData communityData = mFavoriteBlockedCommunityData.get(viewHolder.getBindingAdapterPosition() - offset); | ||||
|             String name = mFavoriteBlockedCommunityData.get(viewHolder.getBindingAdapterPosition() - offset).getName(); | ||||
|             String iconUrl = mFavoriteBlockedCommunityData.get(viewHolder.getBindingAdapterPosition() - offset).getIconUrl(); | ||||
|  | ||||
|             if (itemClickListener != null) { | ||||
|                 viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(communityData)); | ||||
|             } else { | ||||
|                 viewHolder.itemView.setOnClickListener(view -> { | ||||
|                     Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class); | ||||
|                     intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, name); | ||||
|                     mActivity.startActivity(intent); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             if (iconUrl != null && !iconUrl.equals("")) { | ||||
|                 glide.load(iconUrl) | ||||
|                         .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) | ||||
|                         .error(glide.load(R.drawable.subreddit_default_icon) | ||||
|                                 .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) | ||||
|                         .into(((FavoriteSubredditViewHolder) viewHolder).iconGifImageView); | ||||
|             } else { | ||||
|                 glide.load(R.drawable.subreddit_default_icon) | ||||
|                         .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) | ||||
|                         .into(((FavoriteSubredditViewHolder) viewHolder).iconGifImageView); | ||||
|             } | ||||
|             ((FavoriteSubredditViewHolder) viewHolder).subredditNameTextView.setText(name); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int getItemCount() { | ||||
|         if (mBlockedCommunityData != null) { | ||||
|  | ||||
|             if (itemClickListener != null) { | ||||
|                 return mBlockedCommunityData.size() > 0 ? mBlockedCommunityData.size() + ((hasClearSelectionRow) ? 1 : 0) : 0; | ||||
|             } | ||||
|  | ||||
|             return mBlockedCommunityData.size(); | ||||
|         } | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { | ||||
|         if (holder instanceof SubredditViewHolder) { | ||||
|             glide.clear(((SubredditViewHolder) holder).iconGifImageView); | ||||
|         } else if (holder instanceof FavoriteSubredditViewHolder) { | ||||
|             glide.clear(((FavoriteSubredditViewHolder) holder).iconGifImageView); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void setSubscribedSubreddits(List<BlockedCommunityData> subscribedSubreddits) { | ||||
|         mBlockedCommunityData = subscribedSubreddits; | ||||
|         notifyDataSetChanged(); | ||||
|     } | ||||
|  | ||||
|     public void setFavoriteSubscribedSubreddits(List<BlockedCommunityData> favoriteBlockedCommunityData) { | ||||
|         mFavoriteBlockedCommunityData = favoriteBlockedCommunityData; | ||||
|         notifyDataSetChanged(); | ||||
|     } | ||||
|  | ||||
|     public void addUser(String username, String userIconUrl) { | ||||
|         this.username = username; | ||||
|         this.userIconUrl = userIconUrl; | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public String getPopupText(int position) { | ||||
|         switch (getItemViewType(position)) { | ||||
|             case VIEW_TYPE_SUBREDDIT: | ||||
|                 if (hasClearSelectionRow && position == 0) { | ||||
|                     return ""; | ||||
|                 } else if (itemClickListener != null && !hasClearSelectionRow && position == 0) { | ||||
|                     return ""; | ||||
|                 } else if (hasClearSelectionRow && position == 1) { | ||||
|                     return ""; | ||||
|                 } else { | ||||
|                     int offset; | ||||
|                     if (itemClickListener != null) { | ||||
|                         if (hasClearSelectionRow) { | ||||
|                             offset = (mFavoriteBlockedCommunityData != null && mFavoriteBlockedCommunityData.size() > 0) ? | ||||
|                                     mFavoriteBlockedCommunityData.size() + 4 : 0; | ||||
|                         } else { | ||||
|                             offset = (mFavoriteBlockedCommunityData != null && mFavoriteBlockedCommunityData.size() > 0) ? | ||||
|                                     mFavoriteBlockedCommunityData.size() + 3 : 0; | ||||
|                         } | ||||
|                     } else { | ||||
|                         offset = (mFavoriteBlockedCommunityData != null && mFavoriteBlockedCommunityData.size() > 0) ? | ||||
|                                 mFavoriteBlockedCommunityData.size() + 2 : 0; | ||||
|                     } | ||||
|  | ||||
|                     return mBlockedCommunityData.get(position - offset).getName().substring(0, 1).toUpperCase(); | ||||
|                 } | ||||
|             case VIEW_TYPE_FAVORITE_SUBREDDIT: | ||||
|                 int offset; | ||||
|                 if (itemClickListener != null) { | ||||
|                     if (hasClearSelectionRow) { | ||||
|                         offset = 3; | ||||
|                     } else { | ||||
|                         offset = 2; | ||||
|                     } | ||||
|                 } else { | ||||
|                     offset = 1; | ||||
|                 } | ||||
|                 return mFavoriteBlockedCommunityData.get(position - offset).getName().substring(0, 1).toUpperCase(); | ||||
|             default: | ||||
|                 return ""; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public interface ItemClickListener { | ||||
|         void onClick(BlockedCommunityData subredditData); | ||||
|     } | ||||
|  | ||||
|     class SubredditViewHolder extends RecyclerView.ViewHolder { | ||||
|         @BindView(R.id.thing_icon_gif_image_view_item_subscribed_thing) | ||||
|         GifImageView iconGifImageView; | ||||
|         @BindView(R.id.thing_name_text_view_item_subscribed_thing) | ||||
|         TextView subredditNameTextView; | ||||
|  | ||||
|         @BindView(R.id.thing_instance_text_view_item_subscribed_thing) | ||||
|         TextView communityInstanceTextView; | ||||
|  | ||||
|         SubredditViewHolder(View itemView) { | ||||
|             super(itemView); | ||||
|             ButterKnife.bind(this, itemView); | ||||
|             if (mActivity.typeface != null) { | ||||
|                 subredditNameTextView.setTypeface(mActivity.typeface); | ||||
|             } | ||||
|             subredditNameTextView.setTextColor(primaryTextColor); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     class FavoriteSubredditViewHolder extends RecyclerView.ViewHolder { | ||||
|         @BindView(R.id.thing_icon_gif_image_view_item_subscribed_thing) | ||||
|         GifImageView iconGifImageView; | ||||
|         @BindView(R.id.thing_name_text_view_item_subscribed_thing) | ||||
|         TextView subredditNameTextView; | ||||
|  | ||||
|         FavoriteSubredditViewHolder(View itemView) { | ||||
|             super(itemView); | ||||
|             ButterKnife.bind(this, itemView); | ||||
|             if (mActivity.typeface != null) { | ||||
|                 subredditNameTextView.setTypeface(mActivity.typeface); | ||||
|             } | ||||
|             subredditNameTextView.setTextColor(primaryTextColor); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     class FavoriteSubredditsDividerViewHolder extends RecyclerView.ViewHolder { | ||||
|         @BindView(R.id.divider_text_view_item_favorite_thing_divider) | ||||
|         TextView dividerTextView; | ||||
|  | ||||
|         FavoriteSubredditsDividerViewHolder(@NonNull View itemView) { | ||||
|             super(itemView); | ||||
|             ButterKnife.bind(this, itemView); | ||||
|             if (mActivity.typeface != null) { | ||||
|                 dividerTextView.setTypeface(mActivity.typeface); | ||||
|             } | ||||
|             dividerTextView.setText(R.string.favorites); | ||||
|             dividerTextView.setTextColor(secondaryTextColor); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     class AllSubredditsDividerViewHolder extends RecyclerView.ViewHolder { | ||||
|         @BindView(R.id.divider_text_view_item_favorite_thing_divider) | ||||
|         TextView dividerTextView; | ||||
|  | ||||
|         AllSubredditsDividerViewHolder(@NonNull View itemView) { | ||||
|             super(itemView); | ||||
|             ButterKnife.bind(this, itemView); | ||||
|             if (mActivity.typeface != null) { | ||||
|                 dividerTextView.setTypeface(mActivity.typeface); | ||||
|             } | ||||
|             dividerTextView.setText(R.string.all); | ||||
|             dividerTextView.setTextColor(secondaryTextColor); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -0,0 +1,216 @@ | ||||
| package eu.toldi.infinityforlemmy.adapters; | ||||
|  | ||||
| import android.content.Intent; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| import com.bumptech.glide.Glide; | ||||
| import com.bumptech.glide.RequestManager; | ||||
| import com.bumptech.glide.request.RequestOptions; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.concurrent.Executor; | ||||
|  | ||||
| import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| import eu.toldi.infinityforlemmy.activities.BaseActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.ViewUserDetailActivity; | ||||
| import eu.toldi.infinityforlemmy.blockeduser.BlockedUserData; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import jp.wasabeef.glide.transformations.RoundedCornersTransformation; | ||||
| import me.zhanghai.android.fastscroll.PopupTextProvider; | ||||
| import pl.droidsonroids.gif.GifImageView; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
| public class BlockedUsersRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements PopupTextProvider { | ||||
|     private static final int VIEW_TYPE_FAVORITE_USER_DIVIDER = 0; | ||||
|     private static final int VIEW_TYPE_FAVORITE_USER = 1; | ||||
|     private static final int VIEW_TYPE_USER_DIVIDER = 2; | ||||
|     private static final int VIEW_TYPE_USER = 3; | ||||
|  | ||||
|     private List<BlockedUserData> mBlockedUserData; | ||||
|     private List<BlockedUserData> mFavoriteBlockedUserData; | ||||
|     private BaseActivity mActivity; | ||||
|     private Executor mExecutor; | ||||
|     private Retrofit mOauthRetrofit; | ||||
|     private RedditDataRoomDatabase mRedditDataRoomDatabase; | ||||
|     private String mAccessToken; | ||||
|     private RequestManager glide; | ||||
|     private int mPrimaryTextColor; | ||||
|     private int mSecondaryTextColor; | ||||
|  | ||||
|     public BlockedUsersRecyclerViewAdapter(BaseActivity activity, Executor executor, Retrofit oauthRetrofit, | ||||
|                                            RedditDataRoomDatabase redditDataRoomDatabase, | ||||
|                                            CustomThemeWrapper customThemeWrapper, | ||||
|                                            String accessToken) { | ||||
|         mActivity = activity; | ||||
|         mExecutor = executor; | ||||
|         mOauthRetrofit = oauthRetrofit; | ||||
|         mRedditDataRoomDatabase = redditDataRoomDatabase; | ||||
|         mAccessToken = accessToken; | ||||
|         glide = Glide.with(activity); | ||||
|         mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); | ||||
|         mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int getItemViewType(int position) { | ||||
|         if (mFavoriteBlockedUserData != null && mFavoriteBlockedUserData.size() > 0) { | ||||
|             if (position == 0) { | ||||
|                 return VIEW_TYPE_FAVORITE_USER_DIVIDER; | ||||
|             } else if (position == mFavoriteBlockedUserData.size() + 1) { | ||||
|                 return VIEW_TYPE_USER_DIVIDER; | ||||
|             } else if (position <= mFavoriteBlockedUserData.size()) { | ||||
|                 return VIEW_TYPE_FAVORITE_USER; | ||||
|             } else { | ||||
|                 return VIEW_TYPE_USER; | ||||
|             } | ||||
|         } else { | ||||
|             return VIEW_TYPE_USER; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { | ||||
|         switch (i) { | ||||
|             case VIEW_TYPE_FAVORITE_USER_DIVIDER: | ||||
|                 return new FavoriteUsersDividerViewHolder(LayoutInflater.from(viewGroup.getContext()) | ||||
|                         .inflate(R.layout.item_favorite_thing_divider, viewGroup, false)); | ||||
|             case VIEW_TYPE_USER_DIVIDER: | ||||
|                 return new AllUsersDividerViewHolder(LayoutInflater.from(viewGroup.getContext()) | ||||
|                         .inflate(R.layout.item_favorite_thing_divider, viewGroup, false)); | ||||
|             default: | ||||
|                 return new UserViewHolder(LayoutInflater.from(viewGroup.getContext()) | ||||
|                         .inflate(R.layout.item_subscribed_thing, viewGroup, false)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int i) { | ||||
|         if (viewHolder instanceof UserViewHolder) { | ||||
|             int offset = 0; | ||||
|  | ||||
|             if (!mBlockedUserData.get(viewHolder.getBindingAdapterPosition() - offset).getAvatar().equals("")) { | ||||
|                 glide.load(mBlockedUserData.get(viewHolder.getBindingAdapterPosition() - offset).getAvatar()) | ||||
|                         .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) | ||||
|                         .error(glide.load(R.drawable.subreddit_default_icon) | ||||
|                                 .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) | ||||
|                         .into(((UserViewHolder) viewHolder).iconGifImageView); | ||||
|             } else { | ||||
|                 glide.load(R.drawable.subreddit_default_icon) | ||||
|                         .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) | ||||
|                         .into(((UserViewHolder) viewHolder).iconGifImageView); | ||||
|             } | ||||
|             ((UserViewHolder) viewHolder).userNameTextView.setText(mBlockedUserData.get(viewHolder.getBindingAdapterPosition() - offset).getName()); | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int getItemCount() { | ||||
|         if (mBlockedUserData != null && mBlockedUserData.size() > 0) { | ||||
|             return mBlockedUserData.size(); | ||||
|         } | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { | ||||
|         if (holder instanceof UserViewHolder) { | ||||
|             glide.clear(((UserViewHolder) holder).iconGifImageView); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void setSubscribedUsers(List<BlockedUserData> subscribedUsers) { | ||||
|         mBlockedUserData = subscribedUsers; | ||||
|         notifyDataSetChanged(); | ||||
|     } | ||||
|  | ||||
|     public void setFavoriteSubscribedUsers(List<BlockedUserData> favoriteSubscribedUsers) { | ||||
|         mFavoriteBlockedUserData = favoriteSubscribedUsers; | ||||
|         notifyDataSetChanged(); | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public String getPopupText(int position) { | ||||
|         switch (getItemViewType(position)) { | ||||
|             case VIEW_TYPE_USER: | ||||
|                 int offset = (mFavoriteBlockedUserData != null && mFavoriteBlockedUserData.size() > 0) ? | ||||
|                         mFavoriteBlockedUserData.size() + 2 : 0; | ||||
|                 return mBlockedUserData.get(position - offset).getName().substring(0, 1).toUpperCase(); | ||||
|             case VIEW_TYPE_FAVORITE_USER: | ||||
|                 return mFavoriteBlockedUserData.get(position - 1).getName().substring(0, 1).toUpperCase(); | ||||
|             default: | ||||
|                 return ""; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     class UserViewHolder extends RecyclerView.ViewHolder { | ||||
|         @BindView(R.id.thing_icon_gif_image_view_item_subscribed_thing) | ||||
|         GifImageView iconGifImageView; | ||||
|         @BindView(R.id.thing_name_text_view_item_subscribed_thing) | ||||
|         TextView userNameTextView; | ||||
|  | ||||
|         UserViewHolder(View itemView) { | ||||
|             super(itemView); | ||||
|             ButterKnife.bind(this, itemView); | ||||
|             if (mActivity.typeface != null) { | ||||
|                 userNameTextView.setTypeface(mActivity.typeface); | ||||
|             } | ||||
|             userNameTextView.setTextColor(mPrimaryTextColor); | ||||
|  | ||||
|             itemView.setOnClickListener(view -> { | ||||
|                 int offset = (mFavoriteBlockedUserData != null && mFavoriteBlockedUserData.size() > 0) ? | ||||
|                         mFavoriteBlockedUserData.size() + 2 : 0; | ||||
|                 int position = getBindingAdapterPosition() - offset; | ||||
|                 if (position >= 0 && mBlockedUserData.size() > position) { | ||||
|                     Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); | ||||
|                     intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mBlockedUserData.get(position).getName()); | ||||
|                     intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, mBlockedUserData.get(position).getQualifiedName()); | ||||
|                     mActivity.startActivity(intent); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     class FavoriteUsersDividerViewHolder extends RecyclerView.ViewHolder { | ||||
|         @BindView(R.id.divider_text_view_item_favorite_thing_divider) | ||||
|         TextView dividerTextView; | ||||
|  | ||||
|         FavoriteUsersDividerViewHolder(@NonNull View itemView) { | ||||
|             super(itemView); | ||||
|             ButterKnife.bind(this, itemView); | ||||
|             if (mActivity.typeface != null) { | ||||
|                 dividerTextView.setTypeface(mActivity.typeface); | ||||
|             } | ||||
|             dividerTextView.setText(R.string.favorites); | ||||
|             dividerTextView.setTextColor(mSecondaryTextColor); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     class AllUsersDividerViewHolder extends RecyclerView.ViewHolder { | ||||
|         @BindView(R.id.divider_text_view_item_favorite_thing_divider) | ||||
|         TextView dividerTextView; | ||||
|  | ||||
|         AllUsersDividerViewHolder(@NonNull View itemView) { | ||||
|             super(itemView); | ||||
|             ButterKnife.bind(this, itemView); | ||||
|             if (mActivity.typeface != null) { | ||||
|                 dividerTextView.setTypeface(mActivity.typeface); | ||||
|             } | ||||
|             dividerTextView.setText(R.string.all); | ||||
|             dividerTextView.setTextColor(mSecondaryTextColor); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,76 @@ | ||||
| package eu.toldi.infinityforlemmy.adapters; | ||||
|  | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.TextView; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.activities.BaseActivity; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsage; | ||||
| import eu.toldi.infinityforlemmy.databinding.ItemCommentFilterUsageEmbeddedBinding; | ||||
|  | ||||
|  | ||||
| public class CommentFilterUsageEmbeddedRecyclerViewAdapter extends RecyclerView.Adapter<CommentFilterUsageEmbeddedRecyclerViewAdapter.EntryViewHolder> { | ||||
|     private BaseActivity baseActivity; | ||||
|     private List<CommentFilterUsage> commentFilterUsageList; | ||||
|  | ||||
|     public CommentFilterUsageEmbeddedRecyclerViewAdapter(BaseActivity baseActivity) { | ||||
|         this.baseActivity = baseActivity; | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public EntryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { | ||||
|         return new EntryViewHolder(ItemCommentFilterUsageEmbeddedBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onBindViewHolder(@NonNull EntryViewHolder holder, int position) { | ||||
|         if (commentFilterUsageList == null || commentFilterUsageList.isEmpty()) { | ||||
|             holder.textView.setText(R.string.comment_filter_applied_to_all_subreddits); | ||||
|         } else if (holder.getBindingAdapterPosition() > 4) { | ||||
|             holder.textView.setText(baseActivity.getString(R.string.comment_filter_usage_embedded_more_count, commentFilterUsageList.size() - 5)); | ||||
|         } else { | ||||
|             CommentFilterUsage commentFilterUsage = commentFilterUsageList.get(holder.getBindingAdapterPosition()); | ||||
|             switch (commentFilterUsage.usage) { | ||||
|                 case CommentFilterUsage.SUBREDDIT_TYPE: | ||||
|                     holder.textView.setText("r/" + commentFilterUsage.nameOfUsage); | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int getItemCount() { | ||||
|         return commentFilterUsageList == null || commentFilterUsageList.isEmpty() ? 1 : (commentFilterUsageList.size() > 5 ? 6 : commentFilterUsageList.size()); | ||||
|     } | ||||
|  | ||||
|     public void setCommentFilterUsageList(List<CommentFilterUsage> commentFilterUsageList) { | ||||
|         this.commentFilterUsageList = commentFilterUsageList; | ||||
|         notifyDataSetChanged(); | ||||
|     } | ||||
|  | ||||
|     class EntryViewHolder extends RecyclerView.ViewHolder { | ||||
|         TextView textView; | ||||
|  | ||||
|         public EntryViewHolder(@NonNull ItemCommentFilterUsageEmbeddedBinding binding) { | ||||
|             super(binding.getRoot()); | ||||
|             textView = binding.getRoot(); | ||||
|             textView.setTextColor(baseActivity.customThemeWrapper.getSecondaryTextColor()); | ||||
|  | ||||
|             if (baseActivity.typeface != null) { | ||||
|                 textView.setTypeface(baseActivity.typeface); | ||||
|             } | ||||
|  | ||||
|             textView.setOnClickListener(view -> { | ||||
|                 Toast.makeText(baseActivity, textView.getText(), Toast.LENGTH_SHORT).show(); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,80 @@ | ||||
| package eu.toldi.infinityforlemmy.adapters; | ||||
|  | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.activities.BaseActivity; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.CommentFilterUsage; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
|  | ||||
|  | ||||
| public class CommentFilterUsageRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { | ||||
|     private List<CommentFilterUsage> commentFilterUsages; | ||||
|     private BaseActivity activity; | ||||
|     private CustomThemeWrapper customThemeWrapper; | ||||
|     private CommentFilterUsageRecyclerViewAdapter.OnItemClickListener onItemClickListener; | ||||
|  | ||||
|     public interface OnItemClickListener { | ||||
|         void onClick(CommentFilterUsage commentFilterUsage); | ||||
|     } | ||||
|  | ||||
|     public CommentFilterUsageRecyclerViewAdapter(BaseActivity activity, CustomThemeWrapper customThemeWrapper, | ||||
|                                                  CommentFilterUsageRecyclerViewAdapter.OnItemClickListener onItemClickListener) { | ||||
|         this.activity = activity; | ||||
|         this.customThemeWrapper = customThemeWrapper; | ||||
|         this.onItemClickListener = onItemClickListener; | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { | ||||
|         return new CommentFilterUsageRecyclerViewAdapter.CommentFilterUsageViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_filter_usage, parent, false)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { | ||||
|         CommentFilterUsage commentFilterUsage = commentFilterUsages.get(position); | ||||
|         switch (commentFilterUsage.usage) { | ||||
|             case CommentFilterUsage.SUBREDDIT_TYPE: | ||||
|                 ((CommentFilterUsageRecyclerViewAdapter.CommentFilterUsageViewHolder) holder).usageTextView.setText(activity.getString(R.string.post_filter_usage_community, commentFilterUsage.nameOfUsage)); | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int getItemCount() { | ||||
|         return commentFilterUsages == null ? 0 : commentFilterUsages.size(); | ||||
|     } | ||||
|  | ||||
|     public void setCommentFilterUsages(List<CommentFilterUsage> commentFilterUsages) { | ||||
|         this.commentFilterUsages = commentFilterUsages; | ||||
|         notifyDataSetChanged(); | ||||
|     } | ||||
|  | ||||
|     private class CommentFilterUsageViewHolder extends RecyclerView.ViewHolder { | ||||
|         TextView usageTextView; | ||||
|  | ||||
|         public CommentFilterUsageViewHolder(@NonNull View itemView) { | ||||
|             super(itemView); | ||||
|             usageTextView = (TextView) itemView; | ||||
|  | ||||
|             usageTextView.setTextColor(customThemeWrapper.getPrimaryTextColor()); | ||||
|  | ||||
|             if (activity.typeface != null) { | ||||
|                 usageTextView.setTypeface(activity.typeface); | ||||
|             } | ||||
|  | ||||
|             usageTextView.setOnClickListener(view -> { | ||||
|                 onItemClickListener.onClick(commentFilterUsages.get(getBindingAdapterPosition())); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,81 @@ | ||||
| package eu.toldi.infinityforlemmy.adapters; | ||||
|  | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.ViewGroup; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.activities.BaseActivity; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.CommentFilter; | ||||
| import eu.toldi.infinityforlemmy.commentfilter.CommentFilterWithUsage; | ||||
| import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; | ||||
| import eu.toldi.infinityforlemmy.databinding.ItemCommentFilterWithUsageBinding; | ||||
|  | ||||
|  | ||||
| public class CommentFilterWithUsageRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { | ||||
|     private BaseActivity activity; | ||||
|     private final OnItemClickListener onItemClickListener; | ||||
|     private List<CommentFilterWithUsage> commentFilterWithUsageList; | ||||
|     private RecyclerView.RecycledViewPool recycledViewPool; | ||||
|  | ||||
|     public interface OnItemClickListener { | ||||
|         void onItemClick(CommentFilter commentFilter); | ||||
|     } | ||||
|  | ||||
|     public CommentFilterWithUsageRecyclerViewAdapter(BaseActivity activity, OnItemClickListener onItemClickListener) { | ||||
|         this.activity = activity; | ||||
|         this.recycledViewPool = new RecyclerView.RecycledViewPool(); | ||||
|         this.onItemClickListener = onItemClickListener; | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { | ||||
|         return new CommentFilterViewHolder(ItemCommentFilterWithUsageBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { | ||||
|         if (holder instanceof CommentFilterViewHolder) { | ||||
|             ((CommentFilterViewHolder) holder).binding.commentFilterNameTextViewItemCommentFilter.setText(commentFilterWithUsageList.get(position).commentFilter.name); | ||||
|             ((CommentFilterViewHolder) holder).adapter.setCommentFilterUsageList(commentFilterWithUsageList.get(position).commentFilterUsageList); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int getItemCount() { | ||||
|         return commentFilterWithUsageList == null ? 0 : commentFilterWithUsageList.size(); | ||||
|     } | ||||
|  | ||||
|     public void setCommentFilterWithUsageList(List<CommentFilterWithUsage> commentFilterWithUsageList) { | ||||
|         this.commentFilterWithUsageList = commentFilterWithUsageList; | ||||
|         notifyDataSetChanged(); | ||||
|     } | ||||
|  | ||||
|     private class CommentFilterViewHolder extends RecyclerView.ViewHolder { | ||||
|         ItemCommentFilterWithUsageBinding binding; | ||||
|         CommentFilterUsageEmbeddedRecyclerViewAdapter adapter; | ||||
|  | ||||
|         public CommentFilterViewHolder(@NonNull ItemCommentFilterWithUsageBinding binding) { | ||||
|             super(binding.getRoot()); | ||||
|             this.binding = binding; | ||||
|             binding.commentFilterNameTextViewItemCommentFilter.setTextColor(activity.customThemeWrapper.getPrimaryTextColor()); | ||||
|  | ||||
|             if (activity.typeface != null) { | ||||
|                 binding.commentFilterNameTextViewItemCommentFilter.setTypeface(activity.typeface); | ||||
|             } | ||||
|  | ||||
|             binding.getRoot().setOnClickListener(view -> { | ||||
|                 onItemClickListener.onItemClick(commentFilterWithUsageList.get(getBindingAdapterPosition()).commentFilter); | ||||
|             }); | ||||
|  | ||||
|             binding.commentFilterUsageRecyclerViewItemCommentFilter.setRecycledViewPool(recycledViewPool); | ||||
|             binding.commentFilterUsageRecyclerViewItemCommentFilter.setLayoutManager(new LinearLayoutManagerBugFixed(activity)); | ||||
|             adapter = new CommentFilterUsageEmbeddedRecyclerViewAdapter(activity); | ||||
|             binding.commentFilterUsageRecyclerViewItemCommentFilter.setAdapter(adapter); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -4,7 +4,6 @@ import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.res.ColorStateList; | ||||
| import android.graphics.Color; | ||||
| import android.graphics.PorterDuff; | ||||
| import android.net.Uri; | ||||
| import android.os.Bundle; | ||||
| import android.text.Spanned; | ||||
| @@ -12,7 +11,6 @@ import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.Button; | ||||
| import android.widget.ImageView; | ||||
| import android.widget.LinearLayout; | ||||
| import android.widget.ProgressBar; | ||||
| import android.widget.TextView; | ||||
| @@ -26,6 +24,8 @@ import androidx.recyclerview.widget.DiffUtil; | ||||
| import androidx.recyclerview.widget.ItemTouchHelper; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| import com.google.android.material.button.MaterialButton; | ||||
|  | ||||
| import java.util.Locale; | ||||
|  | ||||
| import butterknife.BindView; | ||||
| @@ -49,6 +49,7 @@ import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; | ||||
| import eu.toldi.infinityforlemmy.customviews.SpoilerOnClickTextView; | ||||
| import eu.toldi.infinityforlemmy.customviews.SwipeLockInterface; | ||||
| import eu.toldi.infinityforlemmy.customviews.SwipeLockLinearLayoutManager; | ||||
| import eu.toldi.infinityforlemmy.databinding.ItemCommentBinding; | ||||
| import eu.toldi.infinityforlemmy.markdown.MarkdownUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| @@ -169,7 +170,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|             return true; | ||||
|         }; | ||||
|         mMarkwon = MarkdownUtils.createFullRedditMarkwon(mActivity, | ||||
|                 miscPlugin, mCommentColor, commentSpoilerBackgroundColor, onLinkLongClickListener); | ||||
|                 miscPlugin, mCommentColor, commentSpoilerBackgroundColor, onLinkLongClickListener, sharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW, false)); | ||||
|         recycledViewPool = new RecyclerView.RecycledViewPool(); | ||||
|     } | ||||
|  | ||||
| @@ -177,7 +178,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|     @Override | ||||
|     public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { | ||||
|         if (viewType == VIEW_TYPE_DATA) { | ||||
|             return new CommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment, parent, false)); | ||||
|             return new CommentViewHolder(ItemCommentBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); | ||||
|         } else if (viewType == VIEW_TYPE_ERROR) { | ||||
|             return new ErrorViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_error, parent, false)); | ||||
|         } else { | ||||
| @@ -187,24 +188,24 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|  | ||||
|     @Override | ||||
|     public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { | ||||
|         if (holder instanceof CommentViewHolder) { | ||||
|         if (holder instanceof CommentBaseViewHolder) { | ||||
|             Comment comment = getItem(holder.getBindingAdapterPosition()); | ||||
|             if (comment != null) { | ||||
|                 String name = comment.getCommunityQualifiedName(); | ||||
|                 ((CommentViewHolder) holder).authorTextView.setText(name); | ||||
|                 ((CommentViewHolder) holder).authorTextView.setTextColor(mSubredditColor); | ||||
|                 ((CommentBaseViewHolder) holder).authorTextView.setText(name); | ||||
|                 ((CommentBaseViewHolder) holder).authorTextView.setTextColor(mSubredditColor); | ||||
|  | ||||
|  | ||||
|                 if (mShowElapsedTime) { | ||||
|                     ((CommentViewHolder) holder).commentTimeTextView.setText( | ||||
|                     ((CommentBaseViewHolder) holder).commentTimeTextView.setText( | ||||
|                             Utils.getElapsedTime(mActivity, comment.getCommentTimeMillis())); | ||||
|                 } else { | ||||
|                     ((CommentViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); | ||||
|                     ((CommentBaseViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); | ||||
|                 } | ||||
|  | ||||
|                 ((CommentViewHolder) holder).markwonAdapter.setMarkdown(mMarkwon, comment.getCommentMarkdown()); | ||||
|                 // noinspection NotifyDataSetChanged | ||||
|                 ((CommentViewHolder) holder).markwonAdapter.notifyDataSetChanged(); | ||||
|                 ((CommentBaseViewHolder) holder).markwonAdapter.notifyDataSetChanged(); | ||||
|  | ||||
|                 String commentText = Utils.getNVotes(mShowAbsoluteNumberOfVotes, | ||||
|                         comment.getScore() + comment.getVoteType()); | ||||
| @@ -213,21 +214,21 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|  | ||||
|                 switch (comment.getVoteType()) { | ||||
|                     case Comment.VOTE_TYPE_UPVOTE: | ||||
|                         ((CommentViewHolder) holder).upvoteButton | ||||
|                                 .setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN); | ||||
|                         ((CommentViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); | ||||
|                         ((CommentBaseViewHolder) holder).upvoteButton.setIconResource(R.drawable.ic_upvote_filled_24dp); | ||||
|                         ((CommentBaseViewHolder) holder).upvoteButton.setIconTint(ColorStateList.valueOf(mUpvotedColor)); | ||||
|                         ((CommentBaseViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); | ||||
|                         break; | ||||
|                     case Comment.VOTE_TYPE_DOWNVOTE: | ||||
|                         ((CommentViewHolder) holder).downvoteButton | ||||
|                                 .setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN); | ||||
|                         ((CommentViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); | ||||
|                         ((CommentBaseViewHolder) holder).downvoteButton.setIconResource(R.drawable.ic_downvote_filled_24dp); | ||||
|                         ((CommentBaseViewHolder) holder).downvoteButton.setIconTint(ColorStateList.valueOf(mDownvotedColor)); | ||||
|                         ((CommentBaseViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); | ||||
|                         break; | ||||
|                 } | ||||
|  | ||||
|                 if (comment.isSaved()) { | ||||
|                     ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); | ||||
|                     ((CommentBaseViewHolder) holder).saveButton.setIconResource(R.drawable.ic_bookmark_grey_24dp); | ||||
|                 } else { | ||||
|                     ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); | ||||
|                     ((CommentBaseViewHolder) holder).saveButton.setIconResource(R.drawable.ic_bookmark_border_grey_24dp); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -249,14 +250,16 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|  | ||||
|     @Override | ||||
|     public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { | ||||
|         if (holder instanceof CommentViewHolder) { | ||||
|             ((CommentViewHolder) holder).authorFlairTextView.setText(""); | ||||
|             ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.GONE); | ||||
|             ((CommentViewHolder) holder).awardsTextView.setText(""); | ||||
|             ((CommentViewHolder) holder).awardsTextView.setVisibility(View.GONE); | ||||
|             ((CommentViewHolder) holder).upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|             ((CommentViewHolder) holder).downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|             ((CommentViewHolder) holder).scoreTextView.setTextColor(mCommentIconAndInfoColor); | ||||
|         if (holder instanceof CommentBaseViewHolder) { | ||||
|             ((CommentBaseViewHolder) holder).authorFlairTextView.setText(""); | ||||
|             ((CommentBaseViewHolder) holder).authorFlairTextView.setVisibility(View.GONE); | ||||
|             ((CommentBaseViewHolder) holder).awardsTextView.setText(""); | ||||
|             ((CommentBaseViewHolder) holder).awardsTextView.setVisibility(View.GONE); | ||||
|             ((CommentBaseViewHolder) holder).upvoteButton.setIconResource(R.drawable.ic_upvote_24dp); | ||||
|             ((CommentBaseViewHolder) holder).upvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|             ((CommentBaseViewHolder) holder).scoreTextView.setTextColor(mCommentIconAndInfoColor); | ||||
|             ((CommentBaseViewHolder) holder).downvoteButton.setIconResource(R.drawable.ic_downvote_24dp); | ||||
|             ((CommentBaseViewHolder) holder).downvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -289,18 +292,18 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|     } | ||||
|  | ||||
|     public void onItemSwipe(RecyclerView.ViewHolder viewHolder, int direction, int swipeLeftAction, int swipeRightAction) { | ||||
|         if (viewHolder instanceof CommentViewHolder) { | ||||
|         if (viewHolder instanceof CommentBaseViewHolder) { | ||||
|             if (direction == ItemTouchHelper.LEFT || direction == ItemTouchHelper.START) { | ||||
|                 if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { | ||||
|                     ((CommentViewHolder) viewHolder).upvoteButton.performClick(); | ||||
|                     ((CommentBaseViewHolder) viewHolder).upvoteButton.performClick(); | ||||
|                 } else if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { | ||||
|                     ((CommentViewHolder) viewHolder).downvoteButton.performClick(); | ||||
|                     ((CommentBaseViewHolder) viewHolder).downvoteButton.performClick(); | ||||
|                 } | ||||
|             } else { | ||||
|                 if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { | ||||
|                     ((CommentViewHolder) viewHolder).upvoteButton.performClick(); | ||||
|                     ((CommentBaseViewHolder) viewHolder).upvoteButton.performClick(); | ||||
|                 } else if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { | ||||
|                     ((CommentViewHolder) viewHolder).downvoteButton.performClick(); | ||||
|                     ((CommentBaseViewHolder) viewHolder).downvoteButton.performClick(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -318,46 +321,60 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|         void retryLoadingMore(); | ||||
|     } | ||||
|  | ||||
|     public class CommentViewHolder extends RecyclerView.ViewHolder { | ||||
|         @BindView(R.id.vertical_block_indentation_item_comment) | ||||
|         CommentIndentationView commentIndentationView; | ||||
|         @BindView(R.id.linear_layout_item_comment) | ||||
|     public class CommentBaseViewHolder extends RecyclerView.ViewHolder { | ||||
|         LinearLayout linearLayout; | ||||
|         @BindView(R.id.author_text_view_item_post_comment) | ||||
|         TextView authorTextView; | ||||
|         @BindView(R.id.author_flair_text_view_item_post_comment) | ||||
|         TextView authorFlairTextView; | ||||
|         @BindView(R.id.comment_time_text_view_item_post_comment) | ||||
|         TextView commentTimeTextView; | ||||
|         @BindView(R.id.awards_text_view_item_comment) | ||||
|         TextView awardsTextView; | ||||
|         @BindView(R.id.comment_markdown_view_item_post_comment) | ||||
|         RecyclerView commentMarkdownView; | ||||
|         @BindView(R.id.bottom_constraint_layout_item_post_comment) | ||||
|         ConstraintLayout bottomConstraintLayout; | ||||
|         @BindView(R.id.up_vote_button_item_post_comment) | ||||
|         ImageView upvoteButton; | ||||
|         @BindView(R.id.score_text_view_item_post_comment) | ||||
|         MaterialButton upvoteButton; | ||||
|         TextView scoreTextView; | ||||
|         @BindView(R.id.down_vote_button_item_post_comment) | ||||
|         ImageView downvoteButton; | ||||
|         @BindView(R.id.placeholder_item_post_comment) | ||||
|         MaterialButton downvoteButton; | ||||
|         View placeholder; | ||||
|         @BindView(R.id.more_button_item_post_comment) | ||||
|         ImageView moreButton; | ||||
|         @BindView(R.id.save_button_item_post_comment) | ||||
|         ImageView saveButton; | ||||
|         @BindView(R.id.expand_button_item_post_comment) | ||||
|         TextView expandButton; | ||||
|         @BindView(R.id.reply_button_item_post_comment) | ||||
|         ImageView replyButton; | ||||
|         @BindView(R.id.divider_item_comment) | ||||
|         MaterialButton moreButton; | ||||
|         MaterialButton saveButton; | ||||
|         MaterialButton replyButton; | ||||
|         View commentDivider; | ||||
|         CustomMarkwonAdapter markwonAdapter; | ||||
|  | ||||
|         CommentViewHolder(View itemView) { | ||||
|         CommentBaseViewHolder(@NonNull View itemView) { | ||||
|             super(itemView); | ||||
|             ButterKnife.bind(this, itemView); | ||||
|         } | ||||
|  | ||||
|         void setBaseView(LinearLayout linearLayout, | ||||
|                          TextView authorTextView, | ||||
|                          TextView authorFlairTextView, | ||||
|                          TextView commentTimeTextView, | ||||
|                          TextView awardsTextView, | ||||
|                          RecyclerView commentMarkdownView, | ||||
|                          ConstraintLayout bottomConstraintLayout, | ||||
|                          MaterialButton upvoteButton, | ||||
|                          TextView scoreTextView, | ||||
|                          MaterialButton downvoteButton, | ||||
|                          View placeholder, | ||||
|                          MaterialButton moreButton, | ||||
|                          MaterialButton saveButton, | ||||
|                          TextView expandButton, | ||||
|                          MaterialButton replyButton, | ||||
|                          CommentIndentationView commentIndentationView, | ||||
|                          View commentDivider) { | ||||
|             this.linearLayout = linearLayout; | ||||
|             this.authorTextView = authorTextView; | ||||
|             this.authorFlairTextView = authorFlairTextView; | ||||
|             this.commentTimeTextView = commentTimeTextView; | ||||
|             this.awardsTextView = awardsTextView; | ||||
|             this.commentMarkdownView = commentMarkdownView; | ||||
|             this.bottomConstraintLayout = bottomConstraintLayout; | ||||
|             this.upvoteButton = upvoteButton; | ||||
|             this.scoreTextView = scoreTextView; | ||||
|             this.downvoteButton = downvoteButton; | ||||
|             this.placeholder = placeholder; | ||||
|             this.moreButton = moreButton; | ||||
|             this.saveButton = saveButton; | ||||
|             this.replyButton = replyButton; | ||||
|             this.commentDivider = commentDivider; | ||||
|  | ||||
|             replyButton.setVisibility(View.GONE); | ||||
|  | ||||
| @@ -413,19 +430,19 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|                 authorFlairTextView.setTypeface(mActivity.typeface); | ||||
|                 commentTimeTextView.setTypeface(mActivity.typeface); | ||||
|                 awardsTextView.setTypeface(mActivity.typeface); | ||||
|                 scoreTextView.setTypeface(mActivity.typeface); | ||||
|                 upvoteButton.setTypeface(mActivity.typeface); | ||||
|             } | ||||
|             itemView.setBackgroundColor(mCommentBackgroundColor); | ||||
|             authorTextView.setTextColor(mUsernameColor); | ||||
|             authorFlairTextView.setTextColor(mAuthorFlairColor); | ||||
|             commentTimeTextView.setTextColor(mSecondaryTextColor); | ||||
|             awardsTextView.setTextColor(mSecondaryTextColor); | ||||
|             upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|             upvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|             scoreTextView.setTextColor(mCommentIconAndInfoColor); | ||||
|             downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|             moreButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|             saveButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|             replyButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|             downvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|             moreButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|             saveButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|             replyButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|             commentDivider.setBackgroundColor(mDividerColor); | ||||
|  | ||||
|             authorTextView.setOnClickListener(view -> { | ||||
| @@ -450,7 +467,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|                 Comment comment = getItem(getBindingAdapterPosition()); | ||||
|                 if (comment != null) { | ||||
|                     Bundle bundle = new Bundle(); | ||||
|                     if (comment.getAuthor().equals(mAccountName)) { | ||||
|                     if (comment.getAuthorName().equals(mAccountName)) { | ||||
|                         bundle.putBoolean(CommentMoreBottomSheetFragment.EXTRA_EDIT_AND_DELETE_AVAILABLE, true); | ||||
|                     } | ||||
|                     bundle.putString(CommentMoreBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); | ||||
| @@ -472,6 +489,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|                     Intent intent = new Intent(mActivity, ViewPostDetailActivity.class); | ||||
|                     intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, comment.getPostId()); | ||||
|                     intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, comment.getId()); | ||||
|                     intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_PARENT_ID, comment.getParentId()); | ||||
|                     mActivity.startActivity(intent); | ||||
|                 } | ||||
|             }); | ||||
| @@ -516,20 +534,22 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|                     int previousVoteType = comment.getVoteType(); | ||||
|                     int newVoteType; | ||||
|  | ||||
|                     downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|                     downvoteButton.setIconResource(R.drawable.ic_downvote_24dp); | ||||
|                     downvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|  | ||||
|                     if (previousVoteType != Comment.VOTE_TYPE_UPVOTE) { | ||||
|                         //Not upvoted before | ||||
|                         comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); | ||||
|                         newVoteType = Integer.parseInt(APIUtils.DIR_UPVOTE); | ||||
|                         upvoteButton | ||||
|                                 .setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN); | ||||
|                         upvoteButton.setIconResource(R.drawable.ic_upvote_filled_24dp); | ||||
|                         upvoteButton.setIconTint(ColorStateList.valueOf(mUpvotedColor)); | ||||
|                         scoreTextView.setTextColor(mUpvotedColor); | ||||
|                     } else { | ||||
|                         //Upvoted before | ||||
|                         comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); | ||||
|                         newVoteType = Integer.parseInt(APIUtils.DIR_UNVOTE); | ||||
|                         upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|                         upvoteButton.setIconResource(R.drawable.ic_upvote_24dp); | ||||
|                         upvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|                         scoreTextView.setTextColor(mCommentIconAndInfoColor); | ||||
|                     } | ||||
|  | ||||
| @@ -545,23 +565,25 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|                             if (newVoteType == Integer.parseInt(APIUtils.DIR_UPVOTE)) { | ||||
|                                 comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); | ||||
|                                 if (currentPosition == position) { | ||||
|                                     upvoteButton.setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN); | ||||
|                                     upvoteButton.setIconResource(R.drawable.ic_upvote_filled_24dp); | ||||
|                                     upvoteButton.setIconTint(ColorStateList.valueOf(mUpvotedColor)); | ||||
|                                     scoreTextView.setTextColor(mUpvotedColor); | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); | ||||
|                                 if (currentPosition == position) { | ||||
|                                     upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|                                     upvoteButton.setIconResource(R.drawable.ic_upvote_24dp); | ||||
|                                     upvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|                                     scoreTextView.setTextColor(mCommentIconAndInfoColor); | ||||
|                                 } | ||||
|                             } | ||||
|  | ||||
|                             if (currentPosition == position) { | ||||
|                                 downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|                                 downvoteButton.setIconResource(R.drawable.ic_downvote_24dp); | ||||
|                                 downvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|  | ||||
|                                 scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, | ||||
|                                         comment.getScore() + comment.getVoteType())); | ||||
|  | ||||
|                             } | ||||
|                         } | ||||
|  | ||||
| @@ -572,6 +594,10 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             scoreTextView.setOnClickListener(view -> { | ||||
|                 upvoteButton.performClick(); | ||||
|             }); | ||||
|  | ||||
|             downvoteButton.setOnClickListener(view -> { | ||||
|                 if (mAccessToken == null) { | ||||
|                     Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); | ||||
| @@ -587,19 +613,22 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|                     int previousVoteType = comment.getVoteType(); | ||||
|                     int newVoteType; | ||||
|  | ||||
|                     upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|                     upvoteButton.setIconResource(R.drawable.ic_upvote_24dp); | ||||
|                     upvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|  | ||||
|                     if (previousVoteType != Comment.VOTE_TYPE_DOWNVOTE) { | ||||
|                         //Not downvoted before | ||||
|                         comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); | ||||
|                         newVoteType = Integer.parseInt(APIUtils.DIR_DOWNVOTE); | ||||
|                         downvoteButton.setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN); | ||||
|                         downvoteButton.setIconResource(R.drawable.ic_downvote_filled_24dp); | ||||
|                         downvoteButton.setIconTint(ColorStateList.valueOf(mDownvotedColor)); | ||||
|                         scoreTextView.setTextColor(mDownvotedColor); | ||||
|                     } else { | ||||
|                         //Downvoted before | ||||
|                         comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); | ||||
|                         newVoteType = Integer.parseInt(APIUtils.DIR_UNVOTE); | ||||
|                         downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|                         downvoteButton.setIconResource(R.drawable.ic_downvote_24dp); | ||||
|                         downvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|                         scoreTextView.setTextColor(mCommentIconAndInfoColor); | ||||
|                     } | ||||
|  | ||||
| @@ -615,22 +644,24 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|                             if (newVoteType == Integer.parseInt(APIUtils.DIR_DOWNVOTE)) { | ||||
|                                 comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); | ||||
|                                 if (currentPosition == position) { | ||||
|                                     downvoteButton.setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN); | ||||
|                                     downvoteButton.setIconResource(R.drawable.ic_downvote_filled_24dp); | ||||
|                                     downvoteButton.setIconTint(ColorStateList.valueOf(mDownvotedColor)); | ||||
|                                     scoreTextView.setTextColor(mDownvotedColor); | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); | ||||
|                                 if (currentPosition == position) { | ||||
|                                     downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|                                     downvoteButton.setIconResource(R.drawable.ic_downvote_24dp); | ||||
|                                     downvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|                                     scoreTextView.setTextColor(mCommentIconAndInfoColor); | ||||
|                                 } | ||||
|                             } | ||||
|  | ||||
|                             if (currentPosition == position) { | ||||
|                                 upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); | ||||
|                                 upvoteButton.setIconResource(R.drawable.ic_upvote_24dp); | ||||
|                                 upvoteButton.setIconTint(ColorStateList.valueOf(mCommentIconAndInfoColor)); | ||||
|                                 scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, | ||||
|                                         comment.getScore() + comment.getVoteType())); | ||||
|  | ||||
|                             } | ||||
|                         } | ||||
|  | ||||
| @@ -656,7 +687,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|                             public void success() { | ||||
|                                 comment.setSaved(false); | ||||
|                                 if (getBindingAdapterPosition() == position) { | ||||
|                                     saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); | ||||
|                                     saveButton.setIconResource(R.drawable.ic_bookmark_border_grey_24dp); | ||||
|                                 } | ||||
|                                 Toast.makeText(mActivity, R.string.comment_unsaved_success, Toast.LENGTH_SHORT).show(); | ||||
|                             } | ||||
| @@ -665,7 +696,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|                             public void failed() { | ||||
|                                 comment.setSaved(true); | ||||
|                                 if (getBindingAdapterPosition() == position) { | ||||
|                                     saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); | ||||
|                                     saveButton.setIconResource(R.drawable.ic_bookmark_grey_24dp); | ||||
|                                 } | ||||
|                                 Toast.makeText(mActivity, R.string.comment_unsaved_failed, Toast.LENGTH_SHORT).show(); | ||||
|                             } | ||||
| @@ -677,7 +708,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|                             public void success() { | ||||
|                                 comment.setSaved(true); | ||||
|                                 if (getBindingAdapterPosition() == position) { | ||||
|                                     saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); | ||||
|                                     saveButton.setIconResource(R.drawable.ic_bookmark_grey_24dp); | ||||
|                                 } | ||||
|                                 Toast.makeText(mActivity, R.string.comment_saved_success, Toast.LENGTH_SHORT).show(); | ||||
|                             } | ||||
| @@ -686,7 +717,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|                             public void failed() { | ||||
|                                 comment.setSaved(false); | ||||
|                                 if (getBindingAdapterPosition() == position) { | ||||
|                                     saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); | ||||
|                                     saveButton.setIconResource(R.drawable.ic_bookmark_border_grey_24dp); | ||||
|                                 } | ||||
|                                 Toast.makeText(mActivity, R.string.comment_saved_failed, Toast.LENGTH_SHORT).show(); | ||||
|                             } | ||||
| @@ -697,6 +728,32 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     class CommentViewHolder extends CommentBaseViewHolder { | ||||
|         ItemCommentBinding binding; | ||||
|  | ||||
|         CommentViewHolder(ItemCommentBinding binding) { | ||||
|             super(binding.getRoot()); | ||||
|             this.binding = binding; | ||||
|             setBaseView(binding.linearLayoutItemComment, | ||||
|                     binding.authorTextViewItemPostComment, | ||||
|                     binding.authorFlairTextViewItemPostComment, | ||||
|                     binding.commentTimeTextViewItemPostComment, | ||||
|                     binding.awardsTextViewItemComment, | ||||
|                     binding.commentMarkdownViewItemPostComment, | ||||
|                     binding.bottomConstraintLayoutItemPostComment, | ||||
|                     binding.upvoteButtonItemPostComment, | ||||
|                     binding.scoreTextViewItemPostComment, | ||||
|                     binding.downvoteButtonItemPostComment, | ||||
|                     binding.placeholderItemPostComment, | ||||
|                     binding.moreButtonItemPostComment, | ||||
|                     binding.saveButtonItemPostComment, | ||||
|                     binding.expandButtonItemPostComment, | ||||
|                     binding.replyButtonItemPostComment, | ||||
|                     binding.verticalBlockIndentationItemComment, | ||||
|                     binding.dividerItemComment); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     class ErrorViewHolder extends RecyclerView.ViewHolder { | ||||
|         @BindView(R.id.error_text_view_item_footer_error) | ||||
|         TextView errorTextView; | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,41 @@ | ||||
| package eu.toldi.infinityforlemmy.adapters; | ||||
|  | ||||
| import android.content.Context; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.ArrayAdapter; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
|  | ||||
| public class CustomArrayAdapter extends ArrayAdapter<String> { | ||||
|  | ||||
|     CustomThemeWrapper customThemeWrapper; | ||||
|  | ||||
|     public CustomArrayAdapter(@NonNull Context context, int textViewResourceId, @NonNull List<String> objects, CustomThemeWrapper customThemeWrapper) { | ||||
|         super(context, textViewResourceId, objects); | ||||
|         this.customThemeWrapper = customThemeWrapper; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public View getView(int position, View convertView, ViewGroup parent) { | ||||
|         TextView itemView = (TextView) super.getView(position, convertView, parent); | ||||
|         itemView.setTextColor(customThemeWrapper.getPrimaryTextColor()); // Set the text color | ||||
|         itemView.setBackgroundColor(customThemeWrapper.getBackgroundColor()); // Set the background color | ||||
|         // Apply any other styling as needed | ||||
|         return itemView; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public View getDropDownView(int position, View convertView, ViewGroup parent) { | ||||
|         TextView itemView = (TextView) super.getDropDownView(position, convertView, parent); | ||||
|         itemView.setTextColor(customThemeWrapper.getPrimaryTextColor()); // Set the text color | ||||
|         itemView.setBackgroundColor(customThemeWrapper.getBackgroundColor()); // Set the background color | ||||
|         // Apply any other styling as needed | ||||
|         return itemView; | ||||
|     } | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -19,24 +19,13 @@ import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| import org.greenrobot.eventbus.EventBus; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
|  | ||||
| import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
| import io.noties.markwon.AbstractMarkwonPlugin; | ||||
| import io.noties.markwon.Markwon; | ||||
| import io.noties.markwon.MarkwonConfiguration; | ||||
| import io.noties.markwon.core.MarkwonTheme; | ||||
| import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; | ||||
| import io.noties.markwon.inlineparser.BangInlineProcessor; | ||||
| import io.noties.markwon.inlineparser.HtmlInlineProcessor; | ||||
| import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; | ||||
| import io.noties.markwon.linkify.LinkifyPlugin; | ||||
| import io.noties.markwon.movement.MovementMethodPlugin; | ||||
| import eu.toldi.infinityforlemmy.NetworkState; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.activities.BaseActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.LinkResolverActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.ViewPostDetailActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.ViewPrivateMessagesActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.ViewUserDetailActivity; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| @@ -45,28 +34,38 @@ import eu.toldi.infinityforlemmy.markdown.RedditHeadingPlugin; | ||||
| import eu.toldi.infinityforlemmy.markdown.SpoilerAwareMovementMethod; | ||||
| import eu.toldi.infinityforlemmy.markdown.SpoilerParserPlugin; | ||||
| import eu.toldi.infinityforlemmy.markdown.SuperscriptPlugin; | ||||
| import eu.toldi.infinityforlemmy.message.CommentInteraction; | ||||
| import eu.toldi.infinityforlemmy.message.FetchMessage; | ||||
| import eu.toldi.infinityforlemmy.message.Message; | ||||
| import eu.toldi.infinityforlemmy.message.ReadMessage; | ||||
| import io.noties.markwon.AbstractMarkwonPlugin; | ||||
| import io.noties.markwon.Markwon; | ||||
| import io.noties.markwon.MarkwonConfiguration; | ||||
| import io.noties.markwon.core.MarkwonTheme; | ||||
| import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; | ||||
| import io.noties.markwon.image.glide.GlideImagesPlugin; | ||||
| import io.noties.markwon.inlineparser.HtmlInlineProcessor; | ||||
| import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; | ||||
| import io.noties.markwon.linkify.LinkifyPlugin; | ||||
| import io.noties.markwon.movement.MovementMethodPlugin; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
| public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, RecyclerView.ViewHolder> { | ||||
| public class MessageRecyclerViewAdapter extends PagedListAdapter<CommentInteraction, RecyclerView.ViewHolder> { | ||||
|     private static final int VIEW_TYPE_DATA = 0; | ||||
|     private static final int VIEW_TYPE_ERROR = 1; | ||||
|     private static final int VIEW_TYPE_LOADING = 2; | ||||
|     private static final DiffUtil.ItemCallback<Message> DIFF_CALLBACK = new DiffUtil.ItemCallback<>() { | ||||
|     private static final DiffUtil.ItemCallback<CommentInteraction> DIFF_CALLBACK = new DiffUtil.ItemCallback<>() { | ||||
|         @Override | ||||
|         public boolean areItemsTheSame(@NonNull Message message, @NonNull Message t1) { | ||||
|             return message.getId().equals(t1.getId()); | ||||
|         public boolean areItemsTheSame(@NonNull CommentInteraction message, @NonNull CommentInteraction t1) { | ||||
|             return message.getComment().getId() == t1.getComment().getId(); | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public boolean areContentsTheSame(@NonNull Message message, @NonNull Message t1) { | ||||
|             return message.getBody().equals(t1.getBody()); | ||||
|         public boolean areContentsTheSame(@NonNull CommentInteraction message, @NonNull CommentInteraction t1) { | ||||
|             return message.getComment().getCommentMarkdown().equals(t1.getComment().getCommentMarkdown()); | ||||
|         } | ||||
|     }; | ||||
|     private BaseActivity mActivity; | ||||
|     private Retrofit mOauthRetrofit; | ||||
|     private Retrofit retrofit; | ||||
|     private Markwon mMarkwon; | ||||
|     private String mAccessToken; | ||||
|     private int mMessageType; | ||||
| @@ -88,7 +87,7 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl | ||||
|                                       RetryLoadingMoreCallback retryLoadingMoreCallback) { | ||||
|         super(DIFF_CALLBACK); | ||||
|         mActivity = activity; | ||||
|         mOauthRetrofit = oauthRetrofit; | ||||
|         retrofit = oauthRetrofit; | ||||
|         mRetryLoadingMoreCallback = retryLoadingMoreCallback; | ||||
|  | ||||
|         mColorAccent = customThemeWrapper.getColorAccent(); | ||||
| @@ -106,7 +105,6 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl | ||||
|         mMarkwon = Markwon.builder(mActivity) | ||||
|                 .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { | ||||
|                     plugin.excludeInlineProcessor(HtmlInlineProcessor.class); | ||||
|                     plugin.excludeInlineProcessor(BangInlineProcessor.class); | ||||
|                 })) | ||||
|                 .usePlugin(new AbstractMarkwonPlugin() { | ||||
|                     @Override | ||||
| @@ -130,6 +128,7 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl | ||||
|                 .usePlugin(StrikethroughPlugin.create()) | ||||
|                 .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod())) | ||||
|                 .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) | ||||
|                 .usePlugin(GlideImagesPlugin.create(mActivity)) | ||||
|                 .build(); | ||||
|         mAccessToken = accessToken; | ||||
|         if (where.equals(FetchMessage.WHERE_MESSAGES)) { | ||||
| @@ -154,41 +153,38 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl | ||||
|     @Override | ||||
|     public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { | ||||
|         if (holder instanceof DataViewHolder) { | ||||
|             Message message = getItem(holder.getBindingAdapterPosition()); | ||||
|             CommentInteraction message = getItem(holder.getBindingAdapterPosition()); | ||||
|             if (message != null) { | ||||
|                 ArrayList<Message> replies = message.getReplies(); | ||||
|                 Message displayedMessage; | ||||
|                 if (replies != null && !replies.isEmpty() && replies.get(replies.size() - 1) != null) { | ||||
|                     displayedMessage = replies.get(replies.size() - 1); | ||||
|                 } else { | ||||
|                     displayedMessage = message; | ||||
|                 } | ||||
|                 if (message.isNew()) { | ||||
|  | ||||
|                 if (message.isRead()) { | ||||
|                     if (markAllMessagesAsRead) { | ||||
|                         message.setNew(false); | ||||
|                         message.markAsRead(); | ||||
|                     } else { | ||||
|                         holder.itemView.setBackgroundColor( | ||||
|                                 mUnreadMessageBackgroundColor); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if (message.wasComment()) { | ||||
|                     ((DataViewHolder) holder).titleTextView.setText(message.getTitle()); | ||||
|                 } else { | ||||
|                     ((DataViewHolder) holder).titleTextView.setVisibility(View.GONE); | ||||
|                 } | ||||
|  | ||||
|                 ((DataViewHolder) holder).authorTextView.setText(displayedMessage.getAuthor()); | ||||
|                 String subject = displayedMessage.getSubject().substring(0, 1).toUpperCase() + displayedMessage.getSubject().substring(1); | ||||
|                 ((DataViewHolder) holder).titleTextView.setVisibility(View.GONE); | ||||
|  | ||||
|  | ||||
|                 ((DataViewHolder) holder).authorTextView.setText(message.getComment().getAuthorQualifiedName()); | ||||
|                 String subject = message.getComment().getCommunityQualifiedName(); | ||||
|                 ((DataViewHolder) holder).subjectTextView.setText(subject); | ||||
|                 mMarkwon.setMarkdown(((DataViewHolder) holder).contentCustomMarkwonView, displayedMessage.getBody()); | ||||
|                 mMarkwon.setMarkdown(((DataViewHolder) holder).contentCustomMarkwonView, message.getComment().getCommentMarkdown()); | ||||
|  | ||||
|                 holder.itemView.setOnClickListener(view -> { | ||||
|                     if (mMessageType == FetchMessage.MESSAGE_TYPE_INBOX | ||||
|                             && message.getContext() != null && !message.getContext().equals("")) { | ||||
|                         Uri uri = Uri.parse(message.getContext()); | ||||
|                         Intent intent = new Intent(mActivity, LinkResolverActivity.class); | ||||
|                         intent.setData(uri); | ||||
|                             && message.getComment() != null) { | ||||
|  | ||||
|                         Intent intent = new Intent(mActivity, ViewPostDetailActivity.class); | ||||
|  | ||||
|                         intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, message.getComment().getPostId()); | ||||
|                         intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, message.getComment().getId()); | ||||
|                         if(message.getComment().getDepth() > 0) { | ||||
|                             intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_PARENT_ID, message.getComment().getParentId()); | ||||
|                         } | ||||
|                         mActivity.startActivity(intent); | ||||
|                     } else if (mMessageType == FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE) { | ||||
|                         Intent intent = new Intent(mActivity, ViewPrivateMessagesActivity.class); | ||||
| @@ -197,20 +193,21 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl | ||||
|                         mActivity.startActivity(intent); | ||||
|                     } | ||||
|  | ||||
|                     if (displayedMessage.isNew()) { | ||||
|                     if (message.isRead()) { | ||||
|                         holder.itemView.setBackgroundColor(mMessageBackgroundColor); | ||||
|                         message.setNew(false); | ||||
|  | ||||
|                         ReadMessage.readMessage(mOauthRetrofit, mAccessToken, message.getFullname(), | ||||
|  | ||||
|                         ReadMessage.readMessage(retrofit, mAccessToken, message.getId(), | ||||
|                                 new ReadMessage.ReadMessageListener() { | ||||
|                                     @Override | ||||
|                                     public void readSuccess() { | ||||
|                                         message.markAsRead(); | ||||
|                                         EventBus.getDefault().post(new ChangeInboxCountEvent(-1)); | ||||
|                                     } | ||||
|  | ||||
|                                     @Override | ||||
|                                     public void readFailed() { | ||||
|                                         message.setNew(true); | ||||
|                                         message.markAsUnRead(); | ||||
|                                         holder.itemView.setBackgroundColor(mUnreadMessageBackgroundColor); | ||||
|                                     } | ||||
|                                 }); | ||||
| @@ -218,11 +215,10 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl | ||||
|                 }); | ||||
|  | ||||
|                 ((DataViewHolder) holder).authorTextView.setOnClickListener(view -> { | ||||
|                     if (message.isAuthorDeleted()) { | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); | ||||
|                     intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, message.getAuthor()); | ||||
|                     intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, message.getComment().getAuthorName()); | ||||
|                     intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, message.getComment().getAuthorQualifiedName()); | ||||
|                     mActivity.startActivity(intent); | ||||
|                 }); | ||||
|             } | ||||
| @@ -280,9 +276,9 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void updateMessageReply(Message newReply, int position) { | ||||
|     public void updateMessageReply(CommentInteraction newReply, int position) { | ||||
|         if (position >= 0 && position < super.getItemCount()) { | ||||
|             Message message = getItem(position); | ||||
|             CommentInteraction message = getItem(position); | ||||
|             if (message != null) { | ||||
|                 notifyItemChanged(position); | ||||
|             } | ||||
|   | ||||
| @@ -0,0 +1,20 @@ | ||||
| package eu.toldi.infinityforlemmy.adapters; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.activities.BaseActivity; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.user.BasicUserRecyclerViewAdapter; | ||||
|  | ||||
| public class ModeratorRecyclerViewAdapter extends BasicUserRecyclerViewAdapter { | ||||
|  | ||||
|     private final int mModeratorColor; | ||||
|  | ||||
|     public ModeratorRecyclerViewAdapter(BaseActivity activity, CustomThemeWrapper customThemeWrapper) { | ||||
|         super(activity, customThemeWrapper); | ||||
|         mModeratorColor = customThemeWrapper.getModerator(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected int getUserNameTextColor() { | ||||
|         return mModeratorColor; | ||||
|     } | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user