mirror of
				https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy.git
				synced 2025-10-31 17:08:11 +01:00 
			
		
		
		
	Compare commits
	
		
			13 Commits
		
	
	
		
			v0.0.6
			...
			images_in_
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 079269efea | ||
|  | 6d114f84fa | ||
|  | 394cff9ebe | ||
|  | 465abd4498 | ||
|  | 0178569f14 | ||
|  | f7185445e1 | ||
|  | d4b107bc79 | ||
|  | fd14753a1d | ||
|  | 7cc4e93ad4 | ||
|  | 4c95404fe1 | ||
|  | 1c2212f0fe | ||
|  | 065fcedd34 | ||
|  | 3a66a79f49 | 
							
								
								
									
										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 | ||||
| @@ -8,8 +8,8 @@ android { | ||||
|         applicationId "eu.toldi.infinityforlemmy" | ||||
|         minSdk 21 | ||||
|         targetSdk 33 | ||||
|         versionCode 126 | ||||
|         versionName "0.0.6" | ||||
|         versionCode 128 | ||||
|         versionName "0.0.8" | ||||
|         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||||
|         javaCompileOptions { | ||||
|             annotationProcessorOptions { | ||||
| @@ -169,6 +169,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' | ||||
|  | ||||
|   | ||||
| @@ -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(); | ||||
|  | ||||
|   | ||||
| @@ -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()) { | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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,16 +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.ImageView; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| @@ -22,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; | ||||
| @@ -47,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; | ||||
| @@ -63,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) | ||||
| @@ -87,6 +100,15 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled | ||||
|     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; | ||||
| @@ -103,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); | ||||
| @@ -137,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); | ||||
|         titleEditText.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(this); | ||||
|  | ||||
|         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); | ||||
| @@ -192,7 +255,10 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled | ||||
|         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) { | ||||
|             titleEditText.setTypeface(titleTypeface); | ||||
|         } | ||||
| @@ -201,6 +267,12 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void loadImage() { | ||||
|         uploadImageButton.setVisibility(View.GONE); | ||||
|         imageView.setVisibility(View.VISIBLE); | ||||
|         mGlide.load(mPost.getUrl()).into(imageView); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onPause() { | ||||
|         super.onPause(); | ||||
| @@ -236,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(), 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 | ||||
| @@ -274,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(this).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); | ||||
| @@ -281,6 +384,7 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled | ||||
|                 editPost(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -304,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); | ||||
| @@ -352,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()); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -265,7 +265,7 @@ 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) { | ||||
|   | ||||
| @@ -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,11 @@ 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.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 { | ||||
|  | ||||
| @@ -229,7 +225,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 +264,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 +301,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(); | ||||
| @@ -438,7 +427,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 +441,29 @@ 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; | ||||
|             InboxFragment 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); | ||||
|                     fragment.setArguments(bundle); | ||||
|                     break; | ||||
|                 case 2: | ||||
|                     bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_MESSAGES); | ||||
|                     fragment.setArguments(bundle); | ||||
|                     break; | ||||
|             } | ||||
|             fragment.setArguments(bundle); | ||||
|             return fragment; | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public int getItemCount() { | ||||
|             return 2; | ||||
|             return 3; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -107,6 +107,7 @@ 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; | ||||
| @@ -230,9 +231,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; | ||||
| @@ -259,6 +262,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), | ||||
| @@ -344,11 +348,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); | ||||
|         } | ||||
|  | ||||
| @@ -385,7 +389,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() { | ||||
| @@ -1025,11 +1029,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 | ||||
| @@ -1072,20 +1076,29 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb | ||||
|  | ||||
|     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; | ||||
|                 } | ||||
|             }); | ||||
| @@ -1177,7 +1190,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); | ||||
|     } | ||||
| @@ -1336,6 +1349,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) { | ||||
|   | ||||
| @@ -33,6 +33,7 @@ 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.utils.SharedPreferencesUtils; | ||||
|  | ||||
| public class PostFilterPreferenceActivity extends BaseActivity { | ||||
|  | ||||
| @@ -205,7 +206,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 { | ||||
| @@ -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()); | ||||
|     } | ||||
| } | ||||
| @@ -475,8 +475,9 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF | ||||
|         nsfwTextView.setTextColor(primaryTextColor); | ||||
|         titleEditText.setTextColor(primaryTextColor); | ||||
|         titleEditText.setHintTextColor(secondaryTextColor); | ||||
|         applyFABTheme(captureFab); | ||||
|         applyFABTheme(selectFromLibraryFab); | ||||
|         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); | ||||
| @@ -791,7 +792,7 @@ public class PostImageActivity extends BaseActivity implements FlairBottomSheetF | ||||
|         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()); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -722,7 +722,7 @@ public class PostLinkActivity 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()); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -238,7 +238,7 @@ 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) { | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -221,7 +221,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()); | ||||
|     } | ||||
|   | ||||
| @@ -853,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 | ||||
|   | ||||
| @@ -335,7 +335,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); | ||||
| @@ -425,11 +425,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); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -229,13 +229,15 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit | ||||
|                         } | ||||
|                         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 +334,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 +353,7 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit | ||||
|             } | ||||
|  | ||||
|             bindView(); | ||||
|         } | ||||
|         }*/ | ||||
|     } | ||||
|  | ||||
|     public interface ProvideUserAvatarCallback { | ||||
|   | ||||
| @@ -221,7 +221,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; | ||||
| @@ -352,12 +352,12 @@ 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) { | ||||
| @@ -420,7 +420,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp | ||||
|         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); | ||||
| @@ -872,11 +872,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 | ||||
| @@ -1234,7 +1234,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); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -233,7 +233,7 @@ 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; | ||||
| @@ -282,11 +282,11 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|  | ||||
|  | ||||
|         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); | ||||
|         } | ||||
|  | ||||
| @@ -631,7 +631,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele | ||||
|         karmaTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); | ||||
|         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); | ||||
| @@ -706,11 +706,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 | ||||
| @@ -1098,12 +1098,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(); | ||||
| @@ -1268,7 +1268,7 @@ 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); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -161,7 +161,7 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi | ||||
|  | ||||
|     public CommentsRecyclerViewAdapter(BaseActivity activity, ViewPostDetailFragment fragment, | ||||
|                                        CustomThemeWrapper customThemeWrapper, | ||||
|                                        Executor executor, Retrofit retrofit, Retrofit oauthRetrofit, | ||||
|                                        Executor executor, Retrofit retrofit, | ||||
|                                        String accessToken, String accountName, | ||||
|                                        Post post, Locale locale, Integer singleCommentId, | ||||
|                                        boolean isSingleCommentThreadMode, | ||||
| @@ -171,7 +171,6 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi | ||||
|         mFragment = fragment; | ||||
|         mExecutor = executor; | ||||
|         mRetrofit = retrofit; | ||||
|         mOauthRetrofit = oauthRetrofit; | ||||
|         mGlide = Glide.with(activity); | ||||
|         mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); | ||||
|         mCommentTextColor = customThemeWrapper.getCommentColor(); | ||||
|   | ||||
| @@ -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,35 @@ 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()); | ||||
|                         mActivity.startActivity(intent); | ||||
|                     } else if (mMessageType == FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE) { | ||||
|                         Intent intent = new Intent(mActivity, ViewPrivateMessagesActivity.class); | ||||
| @@ -197,20 +190,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 +212,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().getAuthor()); | ||||
|                     intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, message.getComment().getCommunityQualifiedName()); | ||||
|                     mActivity.startActivity(intent); | ||||
|                 }); | ||||
|             } | ||||
| @@ -280,9 +273,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); | ||||
|             } | ||||
|   | ||||
| @@ -42,7 +42,9 @@ import com.bumptech.glide.load.DataSource; | ||||
| import com.bumptech.glide.load.engine.GlideException; | ||||
| import com.bumptech.glide.request.RequestListener; | ||||
| import com.bumptech.glide.request.RequestOptions; | ||||
| import com.bumptech.glide.request.target.CustomTarget; | ||||
| import com.bumptech.glide.request.target.Target; | ||||
| import com.bumptech.glide.request.transition.Transition; | ||||
| import com.google.android.exoplayer2.Tracks; | ||||
| import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; | ||||
| import com.google.android.exoplayer2.ui.DefaultTimeBar; | ||||
| @@ -214,7 +216,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler | ||||
|  | ||||
|     public PostDetailRecyclerViewAdapter(BaseActivity activity, ViewPostDetailFragment fragment, | ||||
|                                          Executor executor, CustomThemeWrapper customThemeWrapper, | ||||
|                                          Retrofit retrofit, Retrofit oauthRetrofit, Retrofit gfycatRetrofit, | ||||
|                                          Retrofit retrofit, Retrofit gfycatRetrofit, | ||||
|                                          Retrofit redgifsRetrofit, Provider<StreamableAPI> streamableApiProvider, | ||||
|                                          RedditDataRoomDatabase redditDataRoomDatabase, RequestManager glide, | ||||
|                                          boolean separatePostAndComments, String accessToken, | ||||
| @@ -229,7 +231,6 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler | ||||
|         mFragment = fragment; | ||||
|         mExecutor = executor; | ||||
|         mRetrofit = retrofit; | ||||
|         mOauthRetrofit = oauthRetrofit; | ||||
|         mGfycatRetrofit = gfycatRetrofit; | ||||
|         mRedgifsRetrofit = redgifsRetrofit; | ||||
|         mStreamableApiProvider = streamableApiProvider; | ||||
| @@ -635,8 +636,20 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler | ||||
|                 ((PostDetailVideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.VISIBLE); | ||||
|                 Post.Preview preview = getSuitablePreview(mPost.getPreviews()); | ||||
|                 if (preview != null) { | ||||
|                     ((PostDetailVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewWidth() / preview.getPreviewHeight()); | ||||
|                     mGlide.load(preview.getPreviewUrl()).centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostDetailVideoAutoplayViewHolder) holder).previewImageView); | ||||
|                     mGlide.load(preview.getPreviewUrl()).centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(new CustomTarget<Drawable>() { | ||||
|                         @Override | ||||
|                         public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                             int width = resource.getIntrinsicWidth(); | ||||
|                             int height = resource.getIntrinsicHeight(); | ||||
|                             ((PostDetailVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) width / height); | ||||
|                             ((PostDetailVideoAutoplayViewHolder) holder).previewImageView.setImageDrawable(resource); | ||||
|                         } | ||||
|  | ||||
|                         @Override | ||||
|                         public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|  | ||||
|                         } | ||||
|                     }); | ||||
|                 } else { | ||||
|                     ((PostDetailVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio(1); | ||||
|                 } | ||||
| @@ -844,9 +857,45 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler | ||||
|                     }); | ||||
|  | ||||
|             if (blurImage) { | ||||
|                 imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))).into(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView); | ||||
|                 imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))).into(new CustomTarget<Drawable>() { | ||||
|                     @Override | ||||
|                     public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                         int width = resource.getIntrinsicWidth(); | ||||
|                         int height = resource.getIntrinsicHeight(); | ||||
|                         if (preview.getPreviewHeight() == 0 || preview.getPreviewWidth() == 0) { | ||||
|                             ((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView.setRatio((float) height / width); | ||||
|                             ((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView.getLayoutParams().height = height; | ||||
|                             preview.setPreviewHeight(height); | ||||
|                             preview.setPreviewWidth(width); | ||||
|                         } | ||||
|                         ((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView.setImageDrawable(resource); | ||||
|                     } | ||||
|  | ||||
|                     @Override | ||||
|                     public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|                         ((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView.setImageDrawable(null); | ||||
|                     } | ||||
|                 }); | ||||
|             } else { | ||||
|                 imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView); | ||||
|                 imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(new CustomTarget<Drawable>() { | ||||
|                     @Override | ||||
|                     public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                         int width = resource.getIntrinsicWidth(); | ||||
|                         int height = resource.getIntrinsicHeight(); | ||||
|                         if (preview.getPreviewHeight() == 0 || preview.getPreviewWidth() == 0) { | ||||
|                             ((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView.setRatio((float) height / width); | ||||
|                             ((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView.getLayoutParams().height = height; | ||||
|                             preview.setPreviewHeight(height); | ||||
|                             preview.setPreviewWidth(width); | ||||
|                         } | ||||
|                         ((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView.setImageDrawable(resource); | ||||
|                     } | ||||
|  | ||||
|                     @Override | ||||
|                     public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|                         ((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView.setImageDrawable(null); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } else if (holder instanceof PostDetailVideoAndGifPreviewHolder) { | ||||
|             RequestBuilder<Drawable> imageRequestBuilder = mGlide.load(preview.getPreviewUrl()) | ||||
| @@ -872,9 +921,45 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler | ||||
|  | ||||
|             if ((mPost.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()))) { | ||||
|                 imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) | ||||
|                         .into(((PostDetailVideoAndGifPreviewHolder) holder).mImageView); | ||||
|                         .into(new CustomTarget<Drawable>() { | ||||
|                             @Override | ||||
|                             public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                                 int width = resource.getIntrinsicWidth(); | ||||
|                                 int height = resource.getIntrinsicHeight(); | ||||
|                                 if (preview.getPreviewHeight() == 0 || preview.getPreviewWidth() == 0) { | ||||
|                                     ((PostDetailVideoAndGifPreviewHolder) holder).mImageView.setRatio((float) height / width); | ||||
|                                     ((PostDetailVideoAndGifPreviewHolder) holder).mImageView.getLayoutParams().height = height; | ||||
|                                     preview.setPreviewHeight(height); | ||||
|                                     preview.setPreviewWidth(width); | ||||
|                                 } | ||||
|                                 ((PostDetailVideoAndGifPreviewHolder) holder).mImageView.setImageDrawable(resource); | ||||
|                             } | ||||
|  | ||||
|                             @Override | ||||
|                             public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|                                 ((PostDetailVideoAndGifPreviewHolder) holder).mImageView.setImageDrawable(null); | ||||
|                             } | ||||
|                         }); | ||||
|             } else { | ||||
|                 imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostDetailVideoAndGifPreviewHolder) holder).mImageView); | ||||
|                 imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(new CustomTarget<Drawable>() { | ||||
|                     @Override | ||||
|                     public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                         int width = resource.getIntrinsicWidth(); | ||||
|                         int height = resource.getIntrinsicHeight(); | ||||
|                         if (preview.getPreviewHeight() == 0 || preview.getPreviewWidth() == 0) { | ||||
|                             ((PostDetailVideoAndGifPreviewHolder) holder).mImageView.setRatio((float) height / width); | ||||
|                             ((PostDetailVideoAndGifPreviewHolder) holder).mImageView.getLayoutParams().height = height; | ||||
|                             preview.setPreviewHeight(height); | ||||
|                             preview.setPreviewWidth(width); | ||||
|                         } | ||||
|                         ((PostDetailVideoAndGifPreviewHolder) holder).mImageView.setImageDrawable(resource); | ||||
|                     } | ||||
|  | ||||
|                     @Override | ||||
|                     public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|                         ((PostDetailVideoAndGifPreviewHolder) holder).mImageView.setImageDrawable(null); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } else if (holder instanceof PostDetailLinkViewHolder) { | ||||
|             RequestBuilder<Drawable> imageRequestBuilder = mGlide.load(preview.getPreviewUrl()) | ||||
| @@ -900,9 +985,51 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler | ||||
|  | ||||
|             if ((mPost.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()))) { | ||||
|                 imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) | ||||
|                         .into(((PostDetailLinkViewHolder) holder).mImageView); | ||||
|                         .into(new CustomTarget<Drawable>() { | ||||
|                             @Override | ||||
|                             public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                                 int width = resource.getIntrinsicWidth(); | ||||
|                                 int height = resource.getIntrinsicHeight(); | ||||
|                                 if (preview.getPreviewHeight() == 0 || preview.getPreviewWidth() == 0) { | ||||
|                                     ((PostDetailLinkViewHolder) holder).mImageView.setRatio((float) height / width); | ||||
|                                     ((PostDetailLinkViewHolder) holder).mImageView.getLayoutParams().height = height; | ||||
|                                     preview.setPreviewHeight(height); | ||||
|                                     preview.setPreviewWidth(width); | ||||
|                                 } else { | ||||
|                                     ((PostDetailLinkViewHolder) holder).mImageView.setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); | ||||
|                                     ((PostDetailLinkViewHolder) holder).mImageView.getLayoutParams().height = height; | ||||
|                                 } | ||||
|                                 ((PostDetailLinkViewHolder) holder).mImageView.setImageDrawable(resource); | ||||
|                             } | ||||
|  | ||||
|                             @Override | ||||
|                             public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|                                 ((PostDetailLinkViewHolder) holder).mImageView.setImageDrawable(null); | ||||
|                             } | ||||
|                         }); | ||||
|             } else { | ||||
|                 imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostDetailLinkViewHolder) holder).mImageView); | ||||
|                 imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(new CustomTarget<Drawable>() { | ||||
|                     @Override | ||||
|                     public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                         int width = resource.getIntrinsicWidth(); | ||||
|                         int height = resource.getIntrinsicHeight(); | ||||
|                         ((PostDetailLinkViewHolder) holder).mImageView.setImageDrawable(resource); | ||||
|                         if (preview.getPreviewHeight() == 0 || preview.getPreviewWidth() == 0) { | ||||
|                             ((PostDetailLinkViewHolder) holder).mImageView.setRatio((float) height / width); | ||||
|                             ((PostDetailLinkViewHolder) holder).mImageView.getLayoutParams().height = height; | ||||
|                             preview.setPreviewHeight(height); | ||||
|                             preview.setPreviewWidth(width); | ||||
|                         } else { | ||||
|                             ((PostDetailLinkViewHolder) holder).mImageView.setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); | ||||
|                         } | ||||
|  | ||||
|                     } | ||||
|  | ||||
|                     @Override | ||||
|                     public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|                         ((PostDetailLinkViewHolder) holder).mImageView.setImageDrawable(null); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -44,7 +44,9 @@ import com.bumptech.glide.load.DataSource; | ||||
| import com.bumptech.glide.load.engine.GlideException; | ||||
| import com.bumptech.glide.request.RequestListener; | ||||
| import com.bumptech.glide.request.RequestOptions; | ||||
| import com.bumptech.glide.request.target.CustomTarget; | ||||
| import com.bumptech.glide.request.target.Target; | ||||
| import com.bumptech.glide.request.transition.Transition; | ||||
| import com.google.android.exoplayer2.Tracks; | ||||
| import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; | ||||
| import com.google.android.exoplayer2.ui.DefaultTimeBar; | ||||
| @@ -439,7 +441,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                 switch (post.getPostType()) { | ||||
|                     case Post.VIDEO_TYPE: | ||||
|                         if (mAutoplay) { | ||||
|                             if ((!mAutoplayNsfwVideos && post.isNSFW()) ) { | ||||
|                             if ((!mAutoplayNsfwVideos && post.isNSFW())) { | ||||
|                                 return VIEW_TYPE_POST_CARD_2_WITH_PREVIEW_TYPE; | ||||
|                             } | ||||
|                             return VIEW_TYPE_POST_CARD_2_VIDEO_AUTOPLAY_TYPE; | ||||
| @@ -524,7 +526,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|  | ||||
|                     ((PostBaseViewHolder) holder).titleTextView.setTextColor(mReadPostTitleColor); | ||||
|                 } | ||||
|                 String authorPrefixed =  post.getAuthorNamePrefixed(); | ||||
|                 String authorPrefixed = post.getAuthorNamePrefixed(); | ||||
|  | ||||
|                 if (mHideSubredditAndUserPrefix) { | ||||
|                     ((PostBaseViewHolder) holder).subredditTextView.setText(post.getSubredditName()); | ||||
| @@ -714,8 +716,28 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                     ((PostVideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.VISIBLE); | ||||
|                     Post.Preview preview = getSuitablePreview(post.getPreviews()); | ||||
|                     if (!mFixedHeightPreviewInCard && preview != null) { | ||||
|                         ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewWidth() / preview.getPreviewHeight()); | ||||
|                         mGlide.load(preview.getPreviewUrl()).centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostVideoAutoplayViewHolder) holder).previewImageView); | ||||
|                         mGlide.load(preview.getPreviewUrl()).centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(new CustomTarget<Drawable>() { | ||||
|                             @Override | ||||
|                             public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                                 int width = resource.getIntrinsicWidth(); | ||||
|                                 int height = resource.getIntrinsicHeight(); | ||||
|                                 ((PostVideoAutoplayViewHolder) holder).previewImageView.setImageDrawable(resource); | ||||
|                                 if (preview.getPreviewHeight() <= 0 || preview.getPreviewWidth() <= 0) { | ||||
|                                     ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) height / width); | ||||
|                                     ((PostVideoAutoplayViewHolder) holder).previewImageView.getLayoutParams().height = height; | ||||
|                                     preview.setPreviewHeight(height); | ||||
|                                     preview.setPreviewWidth(width); | ||||
|                                 } else { | ||||
|                                     ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); | ||||
|                                     ((PostVideoAutoplayViewHolder) holder).previewImageView.getLayoutParams().height = preview.getPreviewHeight(); | ||||
|                                 } | ||||
|                             } | ||||
|  | ||||
|                             @Override | ||||
|                             public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|  | ||||
|                             } | ||||
|                         }); | ||||
|                     } else { | ||||
|                         ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio(1); | ||||
|                     } | ||||
| @@ -752,7 +774,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                                         } | ||||
|                                     } | ||||
|                                 }); | ||||
|                     } else if(post.isStreamable() && !post.isLoadGfycatOrStreamableVideoSuccess()) { | ||||
|                     } else if (post.isStreamable() && !post.isLoadGfycatOrStreamableVideoSuccess()) { | ||||
|                         ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall = | ||||
|                                 mStreamableApiProvider.get().getStreamableData(post.getStreamableShortCode()); | ||||
|                         FetchStreamableVideo.fetchStreamableVideoInRecyclerViewAdapter(mExecutor, new Handler(), | ||||
| @@ -833,21 +855,12 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                             if (preview != null) { | ||||
|                                 ((PostWithPreviewTypeViewHolder) holder).imageView.setVisibility(View.VISIBLE); | ||||
|                                 ((PostWithPreviewTypeViewHolder) holder).imageWrapperRelativeLayout.setVisibility(View.VISIBLE); | ||||
|                                 if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { | ||||
|                                 if (mFixedHeightPreviewInCard) { | ||||
|                                     int height = (int) (400 * mScale); | ||||
|                                     ((PostWithPreviewTypeViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); | ||||
|                                     ((PostWithPreviewTypeViewHolder) holder).imageView.getLayoutParams().height = height; | ||||
|                                 } else { | ||||
|                                     ((PostWithPreviewTypeViewHolder) holder).imageView | ||||
|                                             .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); | ||||
|                                 } | ||||
|                                 ((PostWithPreviewTypeViewHolder) holder).imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { | ||||
|                                     @Override | ||||
|                                     public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { | ||||
|                                         ((PostWithPreviewTypeViewHolder) holder).imageView.removeOnLayoutChangeListener(this); | ||||
|                                         loadImage(holder); | ||||
|                                     } | ||||
|                                 }); | ||||
|                                 loadImage(holder); | ||||
|                             } else { | ||||
|                                 ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); | ||||
|                                 if (post.getPostType() == Post.VIDEO_TYPE) { | ||||
| @@ -873,10 +886,8 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                         ((PostBaseGalleryTypeViewHolder) holder).imageIndexTextView.setText(mActivity.getString(R.string.image_index_in_gallery, 1, post.getGallery().size())); | ||||
|                         Post.Preview preview = getSuitablePreview(post.getPreviews()); | ||||
|                         if (preview != null) { | ||||
|                             if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { | ||||
|                             if (mFixedHeightPreviewInCard) { | ||||
|                                 ((PostBaseGalleryTypeViewHolder) holder).adapter.setRatio(-1); | ||||
|                             } else { | ||||
|                                 ((PostBaseGalleryTypeViewHolder) holder).adapter.setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); | ||||
|                             } | ||||
|                         } else { | ||||
|                             ((PostBaseGalleryTypeViewHolder) holder).adapter.setRatio(-1); | ||||
| @@ -886,7 +897,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                                 (post.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()))); | ||||
|                     } | ||||
|                 } else if (holder instanceof PostTextTypeViewHolder) { | ||||
|                     if (!mHideTextPostContent  && post.getSelfTextPlainTrimmed() != null && !post.getSelfTextPlainTrimmed().equals("")) { | ||||
|                     if (!mHideTextPostContent && post.getSelfTextPlainTrimmed() != null && !post.getSelfTextPlainTrimmed().equals("")) { | ||||
|                         ((PostTextTypeViewHolder) holder).contentTextView.setVisibility(View.VISIBLE); | ||||
|                         if (post.isRead()) { | ||||
|                             ((PostTextTypeViewHolder) holder).contentTextView.setTextColor(mReadPostContentColor); | ||||
| @@ -897,8 +908,28 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                     ((PostCard2VideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.VISIBLE); | ||||
|                     Post.Preview preview = getSuitablePreview(post.getPreviews()); | ||||
|                     if (!mFixedHeightPreviewInCard && preview != null) { | ||||
|                         ((PostCard2VideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewWidth() / preview.getPreviewHeight()); | ||||
|                         mGlide.load(preview.getPreviewUrl()).centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostCard2VideoAutoplayViewHolder) holder).previewImageView); | ||||
|                         mGlide.load(preview.getPreviewUrl()).centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(new CustomTarget<Drawable>() { | ||||
|                             @Override | ||||
|                             public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                                 int width = resource.getIntrinsicWidth(); | ||||
|                                 int height = resource.getIntrinsicHeight(); | ||||
|                                 ((PostVideoAutoplayViewHolder) holder).previewImageView.setImageDrawable(resource); | ||||
|                                 if (preview.getPreviewHeight() <= 0 || preview.getPreviewWidth() <= 0) { | ||||
|                                     ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) height / width); | ||||
|                                     ((PostVideoAutoplayViewHolder) holder).previewImageView.getLayoutParams().height = height; | ||||
|                                     preview.setPreviewHeight(height); | ||||
|                                     preview.setPreviewWidth(width); | ||||
|                                 } else { | ||||
|                                     ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); | ||||
|                                     ((PostVideoAutoplayViewHolder) holder).previewImageView.getLayoutParams().height = height; | ||||
|                                 } | ||||
|                             } | ||||
|  | ||||
|                             @Override | ||||
|                             public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|  | ||||
|                             } | ||||
|                         }); | ||||
|                     } else { | ||||
|                         ((PostCard2VideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio(1); | ||||
|                     } | ||||
| @@ -935,7 +966,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                                         } | ||||
|                                     } | ||||
|                                 }); | ||||
|                     } else if(post.isStreamable() && !post.isLoadGfycatOrStreamableVideoSuccess()) { | ||||
|                     } else if (post.isStreamable() && !post.isLoadGfycatOrStreamableVideoSuccess()) { | ||||
|                         ((PostCard2VideoAutoplayViewHolder) holder).fetchGfycatOrStreamableVideoCall = | ||||
|                                 mStreamableApiProvider.get().getStreamableData(post.getStreamableShortCode()); | ||||
|                         FetchStreamableVideo.fetchStreamableVideoInRecyclerViewAdapter(mExecutor, new Handler(), | ||||
| @@ -1023,21 +1054,12 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                             ((PostCard2WithPreviewViewHolder) holder).preview = preview; | ||||
|                             if (preview != null) { | ||||
|                                 ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.VISIBLE); | ||||
|                                 if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { | ||||
|                                 if (mFixedHeightPreviewInCard) { | ||||
|                                     int height = (int) (400 * mScale); | ||||
|                                     ((PostCard2WithPreviewViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); | ||||
|                                     ((PostCard2WithPreviewViewHolder) holder).imageView.getLayoutParams().height = height; | ||||
|                                 } else { | ||||
|                                     ((PostCard2WithPreviewViewHolder) holder).imageView | ||||
|                                             .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); | ||||
|                                 } | ||||
|                                 ((PostCard2WithPreviewViewHolder) holder).imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { | ||||
|                                     @Override | ||||
|                                     public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { | ||||
|                                         ((PostCard2WithPreviewViewHolder) holder).imageView.removeOnLayoutChangeListener(this); | ||||
|                                         loadImage(holder); | ||||
|                                     } | ||||
|                                 }); | ||||
|                                 loadImage(holder); | ||||
|                             } else { | ||||
|                                 ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.GONE); | ||||
|                                 ((PostCard2WithPreviewViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); | ||||
| @@ -1078,7 +1100,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                 } | ||||
|                 final String subredditNamePrefixed = post.getSubredditNamePrefixed(); | ||||
|                 String subredditName = subredditNamePrefixed.substring(2); | ||||
|                 String authorPrefixed =  post.getAuthorNamePrefixed(); | ||||
|                 String authorPrefixed = post.getAuthorNamePrefixed(); | ||||
|                 final String title = post.getTitle(); | ||||
|                 int voteType = post.getVoteType(); | ||||
|                 boolean nsfw = post.isNSFW(); | ||||
| @@ -1401,21 +1423,12 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                                 ((PostGalleryViewHolder) holder).imageView.setVisibility(View.VISIBLE); | ||||
|                                 ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.VISIBLE); | ||||
|  | ||||
|                                 if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { | ||||
|                                 if (mFixedHeightPreviewInCard) { | ||||
|                                     int height = (int) (400 * mScale); | ||||
|                                     ((PostGalleryViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); | ||||
|                                     ((PostGalleryViewHolder) holder).imageView.getLayoutParams().height = height; | ||||
|                                 } else { | ||||
|                                     ((PostGalleryViewHolder) holder).imageView | ||||
|                                             .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); | ||||
|                                 } | ||||
|                                 ((PostGalleryViewHolder) holder).imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { | ||||
|                                     @Override | ||||
|                                     public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { | ||||
|                                         ((PostGalleryViewHolder) holder).imageView.removeOnLayoutChangeListener(this); | ||||
|                                         loadImage(holder); | ||||
|                                     } | ||||
|                                 }); | ||||
|                                 loadImage(holder); | ||||
|                             } else { | ||||
|                                 ((PostGalleryViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); | ||||
|                                 ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_image_24dp); | ||||
| @@ -1423,7 +1436,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                             break; | ||||
|                         } | ||||
|                         case Post.GIF_TYPE: { | ||||
|                             if (post.getPostType() == Post.GIF_TYPE && ((post.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()) && !(mAutoplay && mAutoplayNsfwVideos)) )) { | ||||
|                             if (post.getPostType() == Post.GIF_TYPE && ((post.isNSFW() && mNeedBlurNsfw && !(mDoNotBlurNsfwInNsfwSubreddits && mFragment != null && mFragment.getIsNsfwSubreddit()) && !(mAutoplay && mAutoplayNsfwVideos)))) { | ||||
|                                 ((PostGalleryViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); | ||||
|                                 ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_image_24dp); | ||||
|                             } else { | ||||
| @@ -1435,21 +1448,12 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                                     ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); | ||||
|                                     ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); | ||||
|  | ||||
|                                     if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { | ||||
|                                     if (mFixedHeightPreviewInCard) { | ||||
|                                         int height = (int) (400 * mScale); | ||||
|                                         ((PostGalleryViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); | ||||
|                                         ((PostGalleryViewHolder) holder).imageView.getLayoutParams().height = height; | ||||
|                                     } else { | ||||
|                                         ((PostGalleryViewHolder) holder).imageView | ||||
|                                                 .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); | ||||
|                                     } | ||||
|                                     ((PostGalleryViewHolder) holder).imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { | ||||
|                                         @Override | ||||
|                                         public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { | ||||
|                                             ((PostGalleryViewHolder) holder).imageView.removeOnLayoutChangeListener(this); | ||||
|                                             loadImage(holder); | ||||
|                                         } | ||||
|                                     }); | ||||
|                                     loadImage(holder); | ||||
|                                 } else { | ||||
|                                     ((PostGalleryViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); | ||||
|                                     ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_image_24dp); | ||||
| @@ -1466,21 +1470,12 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                                 ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); | ||||
|                                 ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_play_circle_36dp)); | ||||
|  | ||||
|                                 if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { | ||||
|                                 if (mFixedHeightPreviewInCard) { | ||||
|                                     int height = (int) (400 * mScale); | ||||
|                                     ((PostGalleryViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); | ||||
|                                     ((PostGalleryViewHolder) holder).imageView.getLayoutParams().height = height; | ||||
|                                 } else { | ||||
|                                     ((PostGalleryViewHolder) holder).imageView | ||||
|                                             .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); | ||||
|                                 } | ||||
|                                 ((PostGalleryViewHolder) holder).imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { | ||||
|                                     @Override | ||||
|                                     public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { | ||||
|                                         ((PostGalleryViewHolder) holder).imageView.removeOnLayoutChangeListener(this); | ||||
|                                         loadImage(holder); | ||||
|                                     } | ||||
|                                 }); | ||||
|                                 loadImage(holder); | ||||
|                             } else { | ||||
|                                 ((PostGalleryViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); | ||||
|                                 ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_outline_video_24dp); | ||||
| @@ -1496,21 +1491,12 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                                 ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); | ||||
|                                 ((PostGalleryViewHolder) holder).videoOrGifIndicatorImageView.setImageDrawable(ContextCompat.getDrawable(mActivity, R.drawable.ic_link_post_type_indicator)); | ||||
|  | ||||
|                                 if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { | ||||
|                                 if (mFixedHeightPreviewInCard) { | ||||
|                                     int height = (int) (400 * mScale); | ||||
|                                     ((PostGalleryViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); | ||||
|                                     ((PostGalleryViewHolder) holder).imageView.getLayoutParams().height = height; | ||||
|                                 } else { | ||||
|                                     ((PostGalleryViewHolder) holder).imageView | ||||
|                                             .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); | ||||
|                                 } | ||||
|                                 ((PostGalleryViewHolder) holder).imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { | ||||
|                                     @Override | ||||
|                                     public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { | ||||
|                                         ((PostGalleryViewHolder) holder).imageView.removeOnLayoutChangeListener(this); | ||||
|                                         loadImage(holder); | ||||
|                                     } | ||||
|                                 }); | ||||
|                                 loadImage(holder); | ||||
|                             } else { | ||||
|                                 ((PostGalleryViewHolder) holder).noPreviewImageView.setVisibility(View.VISIBLE); | ||||
|                                 ((PostGalleryViewHolder) holder).noPreviewImageView.setImageResource(R.drawable.ic_link); | ||||
| @@ -1549,10 +1535,8 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                     ((PostGalleryBaseGalleryTypeViewHolder) holder).frameLayout.setVisibility(View.VISIBLE); | ||||
|                     ((PostGalleryBaseGalleryTypeViewHolder) holder).imageIndexTextView.setText(mActivity.getString(R.string.image_index_in_gallery, 1, post.getGallery().size())); | ||||
|                     if (preview != null) { | ||||
|                         if (mFixedHeightPreviewInCard || (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0)) { | ||||
|                         if (mFixedHeightPreviewInCard) { | ||||
|                             ((PostGalleryBaseGalleryTypeViewHolder) holder).adapter.setRatio(-1); | ||||
|                         } else { | ||||
|                             ((PostGalleryBaseGalleryTypeViewHolder) holder).adapter.setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); | ||||
|                         } | ||||
|                     } else { | ||||
|                         ((PostGalleryBaseGalleryTypeViewHolder) holder).adapter.setRatio(-1); | ||||
| @@ -1605,9 +1589,71 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                 RequestBuilder<Drawable> imageRequestBuilder = mGlide.load(url).listener(((PostWithPreviewTypeViewHolder) holder).glideRequestListener); | ||||
|                 if (blurImage) { | ||||
|                     imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) | ||||
|                             .into(((PostWithPreviewTypeViewHolder) holder).imageView); | ||||
|                             .into(new CustomTarget<Drawable>() { | ||||
|                                 @Override | ||||
|                                 public void onLoadStarted(@Nullable Drawable placeholder) { | ||||
|                                     ((PostWithPreviewTypeViewHolder) holder).imageView.setVisibility(View.GONE); | ||||
|                                     ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.VISIBLE); | ||||
|                                 } | ||||
|  | ||||
|                                 @Override | ||||
|                                 public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                                     ((PostWithPreviewTypeViewHolder) holder).imageView.setImageDrawable(resource); | ||||
|                                     int height = resource.getIntrinsicHeight(); | ||||
|                                     if (!mFixedHeightPreviewInCard) { | ||||
|                                         float imageRatio = (float) resource.getIntrinsicHeight() / resource.getIntrinsicWidth(); | ||||
|                                         ((PostWithPreviewTypeViewHolder) holder).imageView.setRatio(imageRatio); | ||||
|                                         ((PostWithPreviewTypeViewHolder) holder).imageView.setImageDrawable(resource); | ||||
|                                     } else { | ||||
|                                         ((PostWithPreviewTypeViewHolder) holder).imageView.setRatio(-1); | ||||
|                                         ((PostWithPreviewTypeViewHolder) holder).imageView.getLayoutParams().height = height; | ||||
|                                     } | ||||
|                                     ((PostWithPreviewTypeViewHolder) holder).imageView.setVisibility(View.VISIBLE); | ||||
|                                     ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.GONE); | ||||
|                                 } | ||||
|  | ||||
|                                 @Override | ||||
|                                 public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|                                     // Reset to default aspect ratio | ||||
|                                     ((PostWithPreviewTypeViewHolder) holder).imageView.setRatio(1); | ||||
|                                     ((PostWithPreviewTypeViewHolder) holder).imageView.setImageDrawable(placeholder); | ||||
|                                     ((PostWithPreviewTypeViewHolder) holder).imageView.setVisibility(View.GONE); | ||||
|                                     ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.VISIBLE); | ||||
|                                 } | ||||
|                             }); | ||||
|                 } else { | ||||
|                     imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostWithPreviewTypeViewHolder) holder).imageView); | ||||
|                     imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(new CustomTarget<Drawable>() { | ||||
|                         @Override | ||||
|                         public void onLoadStarted(@Nullable Drawable placeholder) { | ||||
|                             ((PostWithPreviewTypeViewHolder) holder).imageView.setVisibility(View.GONE); | ||||
|                             ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.VISIBLE); | ||||
|                         } | ||||
|  | ||||
|                         @Override | ||||
|                         public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                             ((PostWithPreviewTypeViewHolder) holder).imageView.setImageDrawable(resource); | ||||
|                             int height = resource.getIntrinsicHeight(); | ||||
|                             if (!mFixedHeightPreviewInCard) { | ||||
|                                 float imageRatio = (float) resource.getIntrinsicHeight() / resource.getIntrinsicWidth(); | ||||
|                                 ((PostWithPreviewTypeViewHolder) holder).imageView.setRatio(imageRatio); | ||||
|                                 ((PostWithPreviewTypeViewHolder) holder).imageView.setImageDrawable(resource); | ||||
|                             } else { | ||||
|                                 ((PostWithPreviewTypeViewHolder) holder).imageView.setRatio(-1); | ||||
|                                 ((PostWithPreviewTypeViewHolder) holder).imageView.getLayoutParams().height = height; | ||||
|                             } | ||||
|                             ((PostWithPreviewTypeViewHolder) holder).imageView.setVisibility(View.VISIBLE); | ||||
|                             ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.GONE); | ||||
|                         } | ||||
|  | ||||
|                         @Override | ||||
|                         public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|                             // Reset to default aspect ratio | ||||
|                             ((PostWithPreviewTypeViewHolder) holder).imageView.setRatio(1); | ||||
|                             ((PostWithPreviewTypeViewHolder) holder).imageView.setImageDrawable(placeholder); | ||||
|                             ((PostWithPreviewTypeViewHolder) holder).imageView.setVisibility(View.GONE); | ||||
|                             ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.VISIBLE); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         } else if (holder instanceof PostCompactBaseViewHolder) { | ||||
| @@ -1645,9 +1691,71 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|  | ||||
|                 if (blurImage) { | ||||
|                     imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) | ||||
|                             .into(((PostGalleryViewHolder) holder).imageView); | ||||
|                             .into(new CustomTarget<Drawable>() { | ||||
|                                 @Override | ||||
|                                 public void onLoadStarted(@Nullable Drawable placeholder) { | ||||
|                                     ((PostGalleryViewHolder) holder).imageView.setVisibility(View.GONE); | ||||
|                                     ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.VISIBLE); | ||||
|                                 } | ||||
|  | ||||
|                                 @Override | ||||
|                                 public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                                     ((PostGalleryViewHolder) holder).imageView.setImageDrawable(resource); | ||||
|                                     int height = resource.getIntrinsicHeight(); | ||||
|                                     if (!mFixedHeightPreviewInCard) { | ||||
|                                         float imageRatio = (float) resource.getIntrinsicHeight() / resource.getIntrinsicWidth(); | ||||
|                                         ((PostGalleryViewHolder) holder).imageView.setRatio(imageRatio); | ||||
|                                         ((PostGalleryViewHolder) holder).imageView.setImageDrawable(resource); | ||||
|                                     } else { | ||||
|                                         ((PostGalleryViewHolder) holder).imageView.setRatio(-1); | ||||
|                                         ((PostGalleryViewHolder) holder).imageView.getLayoutParams().height = height; | ||||
|                                     } | ||||
|                                     ((PostGalleryViewHolder) holder).imageView.setVisibility(View.VISIBLE); | ||||
|                                     ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.GONE); | ||||
|                                 } | ||||
|  | ||||
|                                 @Override | ||||
|                                 public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|                                     // Reset to default aspect ratio | ||||
|                                     ((PostGalleryViewHolder) holder).imageView.setRatio(1); | ||||
|                                     ((PostGalleryViewHolder) holder).imageView.setImageDrawable(placeholder); | ||||
|                                     ((PostGalleryViewHolder) holder).imageView.setVisibility(View.GONE); | ||||
|                                     ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.VISIBLE); | ||||
|                                 } | ||||
|                             }); | ||||
|                 } else { | ||||
|                     imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostGalleryViewHolder) holder).imageView); | ||||
|                     imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(new CustomTarget<Drawable>() { | ||||
|                         @Override | ||||
|                         public void onLoadStarted(@Nullable Drawable placeholder) { | ||||
|                             ((PostGalleryViewHolder) holder).imageView.setVisibility(View.GONE); | ||||
|                             ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.VISIBLE); | ||||
|                         } | ||||
|  | ||||
|                         @Override | ||||
|                         public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                             ((PostGalleryViewHolder) holder).imageView.setImageDrawable(resource); | ||||
|                             int height = resource.getIntrinsicHeight(); | ||||
|                             if (!mFixedHeightPreviewInCard) { | ||||
|                                 float imageRatio = (float) resource.getIntrinsicHeight() / resource.getIntrinsicWidth(); | ||||
|                                 ((PostGalleryViewHolder) holder).imageView.setRatio(imageRatio); | ||||
|                                 ((PostGalleryViewHolder) holder).imageView.setImageDrawable(resource); | ||||
|                             } else { | ||||
|                                 ((PostGalleryViewHolder) holder).imageView.setRatio(-1); | ||||
|                                 ((PostGalleryViewHolder) holder).imageView.getLayoutParams().height = height; | ||||
|                             } | ||||
|                             ((PostGalleryViewHolder) holder).imageView.setVisibility(View.VISIBLE); | ||||
|                             ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.GONE); | ||||
|                         } | ||||
|  | ||||
|                         @Override | ||||
|                         public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|                             // Reset to default aspect ratio | ||||
|                             ((PostGalleryViewHolder) holder).imageView.setRatio(1); | ||||
|                             ((PostGalleryViewHolder) holder).imageView.setImageDrawable(placeholder); | ||||
|                             ((PostGalleryViewHolder) holder).imageView.setVisibility(View.GONE); | ||||
|                             ((PostGalleryViewHolder) holder).progressBar.setVisibility(View.VISIBLE); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         } else if (holder instanceof PostCard2WithPreviewViewHolder) { | ||||
| @@ -1665,9 +1773,71 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|  | ||||
|                 if (blurImage) { | ||||
|                     imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) | ||||
|                             .into(((PostCard2WithPreviewViewHolder) holder).imageView); | ||||
|                             .into(new CustomTarget<Drawable>() { | ||||
|                                 @Override | ||||
|                                 public void onLoadStarted(@Nullable Drawable placeholder) { | ||||
|                                     ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.GONE); | ||||
|                                     ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.VISIBLE); | ||||
|                                 } | ||||
|  | ||||
|                                 @Override | ||||
|                                 public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                                     ((PostCard2WithPreviewViewHolder) holder).imageView.setImageDrawable(resource); | ||||
|                                     int height = resource.getIntrinsicHeight(); | ||||
|                                     if (!mFixedHeightPreviewInCard) { | ||||
|                                         float imageRatio = (float) resource.getIntrinsicHeight() / resource.getIntrinsicWidth(); | ||||
|                                         ((PostCard2WithPreviewViewHolder) holder).imageView.setRatio(imageRatio); | ||||
|                                         ((PostCard2WithPreviewViewHolder) holder).imageView.setImageDrawable(resource); | ||||
|                                     } else { | ||||
|                                         ((PostCard2WithPreviewViewHolder) holder).imageView.setRatio(-1); | ||||
|                                         ((PostCard2WithPreviewViewHolder) holder).imageView.getLayoutParams().height = height; | ||||
|                                     } | ||||
|                                     ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.VISIBLE); | ||||
|                                     ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.GONE); | ||||
|                                 } | ||||
|  | ||||
|                                 @Override | ||||
|                                 public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|                                     // Reset to default aspect ratio | ||||
|                                     ((PostCard2WithPreviewViewHolder) holder).imageView.setRatio(1); | ||||
|                                     ((PostCard2WithPreviewViewHolder) holder).imageView.setImageDrawable(placeholder); | ||||
|                                     ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.GONE); | ||||
|                                     ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.VISIBLE); | ||||
|                                 } | ||||
|                             }); | ||||
|                 } else { | ||||
|                     imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(((PostCard2WithPreviewViewHolder) holder).imageView); | ||||
|                     imageRequestBuilder.centerInside().downsample(mSaveMemoryCenterInsideDownsampleStrategy).into(new CustomTarget<Drawable>() { | ||||
|                         @Override | ||||
|                         public void onLoadStarted(@Nullable Drawable placeholder) { | ||||
|                             ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.GONE); | ||||
|                             ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.VISIBLE); | ||||
|                         } | ||||
|  | ||||
|                         @Override | ||||
|                         public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { | ||||
|                             ((PostCard2WithPreviewViewHolder) holder).imageView.setImageDrawable(resource); | ||||
|                             int height = resource.getIntrinsicHeight(); | ||||
|                             if (!mFixedHeightPreviewInCard) { | ||||
|                                 float imageRatio = (float) resource.getIntrinsicHeight() / resource.getIntrinsicWidth(); | ||||
|                                 ((PostCard2WithPreviewViewHolder) holder).imageView.setRatio(imageRatio); | ||||
|                                 ((PostCard2WithPreviewViewHolder) holder).imageView.setImageDrawable(resource); | ||||
|                             } else { | ||||
|                                 ((PostCard2WithPreviewViewHolder) holder).imageView.setRatio(-1); | ||||
|                                 ((PostCard2WithPreviewViewHolder) holder).imageView.getLayoutParams().height = height; | ||||
|                             } | ||||
|                             ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.VISIBLE); | ||||
|                             ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.GONE); | ||||
|                         } | ||||
|  | ||||
|                         @Override | ||||
|                         public void onLoadCleared(@Nullable Drawable placeholder) { | ||||
|                             // Reset to default aspect ratio | ||||
|                             ((PostCard2WithPreviewViewHolder) holder).imageView.setRatio(1); | ||||
|                             ((PostCard2WithPreviewViewHolder) holder).imageView.setImageDrawable(placeholder); | ||||
|                             ((PostCard2WithPreviewViewHolder) holder).imageView.setVisibility(View.GONE); | ||||
|                             ((PostCard2WithPreviewViewHolder) holder).progressBar.setVisibility(View.VISIBLE); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -3307,7 +3477,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                             downY = e.getRawY(); | ||||
|                             break; | ||||
|                         case MotionEvent.ACTION_MOVE: | ||||
|                             if(Math.abs(e.getRawX() - downX) > minTouchSlop || Math.abs(e.getRawY() - downY) > minTouchSlop) { | ||||
|                             if (Math.abs(e.getRawX() - downX) > minTouchSlop || Math.abs(e.getRawY() - downY) > minTouchSlop) { | ||||
|                                 dragged = true; | ||||
|                             } | ||||
|                             break; | ||||
| @@ -3510,21 +3680,21 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|         } | ||||
|  | ||||
|         void setBaseView(AspectRatioGifImageView iconGifImageView, | ||||
|                                          TextView nameTextView, ImageView stickiedPostImageView, | ||||
|                                          TextView postTimeTextView, ConstraintLayout titleAndImageConstraintLayout, | ||||
|                                          TextView titleTextView, CustomTextView typeTextView, | ||||
|                                          ImageView archivedImageView, ImageView lockedImageView, | ||||
|                                          ImageView crosspostImageView, CustomTextView nsfwTextView, | ||||
|                                          CustomTextView spoilerTextView, CustomTextView flairTextView, | ||||
|                                          CustomTextView awardsTextView, TextView linkTextView, | ||||
|                                          RelativeLayout relativeLayout, ProgressBar progressBar, | ||||
|                                          ImageView imageView, ImageView playButtonImageView, | ||||
|                                          FrameLayout noPreviewLinkImageFrameLayout, | ||||
|                                          ImageView noPreviewLinkImageView, Barrier imageBarrier, | ||||
|                                          ConstraintLayout bottomConstraintLayout, ImageView upvoteButton, | ||||
|                                          TextView scoreTextView, ImageView downvoteButton, | ||||
|                                          TextView commentsCountTextView, ImageView saveButton, | ||||
|                                          ImageView shareButton, View divider) { | ||||
|                          TextView nameTextView, ImageView stickiedPostImageView, | ||||
|                          TextView postTimeTextView, ConstraintLayout titleAndImageConstraintLayout, | ||||
|                          TextView titleTextView, CustomTextView typeTextView, | ||||
|                          ImageView archivedImageView, ImageView lockedImageView, | ||||
|                          ImageView crosspostImageView, CustomTextView nsfwTextView, | ||||
|                          CustomTextView spoilerTextView, CustomTextView flairTextView, | ||||
|                          CustomTextView awardsTextView, TextView linkTextView, | ||||
|                          RelativeLayout relativeLayout, ProgressBar progressBar, | ||||
|                          ImageView imageView, ImageView playButtonImageView, | ||||
|                          FrameLayout noPreviewLinkImageFrameLayout, | ||||
|                          ImageView noPreviewLinkImageView, Barrier imageBarrier, | ||||
|                          ConstraintLayout bottomConstraintLayout, ImageView upvoteButton, | ||||
|                          TextView scoreTextView, ImageView downvoteButton, | ||||
|                          TextView commentsCountTextView, ImageView saveButton, | ||||
|                          ImageView shareButton, View divider) { | ||||
|             this.iconGifImageView = iconGifImageView; | ||||
|             this.nameTextView = nameTextView; | ||||
|             this.stickiedPostImageView = stickiedPostImageView; | ||||
| @@ -4419,7 +4589,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie | ||||
|                             downTime = System.currentTimeMillis(); | ||||
|                             break; | ||||
|                         case MotionEvent.ACTION_MOVE: | ||||
|                             if(Math.abs(e.getRawX() - downX) > minTouchSlop || Math.abs(e.getRawY() - downY) > minTouchSlop) { | ||||
|                             if (Math.abs(e.getRawX() - downX) > minTouchSlop || Math.abs(e.getRawY() - downY) > minTouchSlop) { | ||||
|                                 dragged = true; | ||||
|                             } | ||||
|                             if (!dragged) { | ||||
|   | ||||
| @@ -1,18 +1,26 @@ | ||||
| package eu.toldi.infinityforlemmy.apis; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
|  | ||||
| import com.google.common.util.concurrent.ListenableFuture; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.dto.AccountLoginDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.AuthDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.CommentDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.CommentVoteDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.DeleteCommentDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.DeletePostDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.EditCommentDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.EditPostDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.FollowCommunityDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.PostVoteDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.ReadCommentDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.ReadMessageDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.ReadPostDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.SaveCommentDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.SavePostDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.SubmitPostDTO; | ||||
| import eu.toldi.infinityforlemmy.message.MessageCount; | ||||
| import okhttp3.MultipartBody; | ||||
| import retrofit2.Call; | ||||
| import retrofit2.Response; | ||||
| @@ -34,6 +42,30 @@ public interface LemmyAPI { | ||||
|     @GET("api/v3/user") | ||||
|     Call<String> userInfo(@Query("username") String username, @Query("auth") String access_token); | ||||
|  | ||||
|     @GET("api/v3/user/mention") | ||||
|     Call<String> userMentions(@Query("sort") String sort, @Query("page") Integer page, @Query("limit") Integer limit, @Query("unread_only") boolean unread_only, @Query("auth") String access_token); | ||||
|  | ||||
|     @GET("api/v3/user/replies") | ||||
|     Call<String> userReplies(@Query("sort") String sort, @Query("page") Integer page, @Query("limit") Integer limit, @Query("unread_only") boolean unread_only, @Query("auth") String access_token); | ||||
|  | ||||
|     @GET("api/v3/private_message/list") | ||||
|     Call<String> privateMessageList(@Query("page") Integer page, @Query("limit") Integer limit, @Query("unread_only") boolean unread_only, @Query("auth") String access_token); | ||||
|  | ||||
|     @GET("api/v3/user/unread_count") | ||||
|     Call<MessageCount> userUnreadCount(@NonNull @Query("auth") String access_token); | ||||
|  | ||||
|     @Headers("Content-Type: application/json") | ||||
|     @POST("api/v3/user/mention/mark_as_read") | ||||
|     Call<String> userMentionMarkAsRead(@Body ReadMessageDTO params); | ||||
|  | ||||
|     @Headers("Content-Type: application/json") | ||||
|     @POST("api/v3/comment/mark_as_read") | ||||
|     Call<String> commentMarkAsRead(@Body ReadCommentDTO params); | ||||
|  | ||||
|     @Headers("Content-Type: application/json") | ||||
|     @POST("api/v3/user/mark_all_as_read") | ||||
|     Call<String> userMarkAllAsRead(@Body AuthDTO params); | ||||
|  | ||||
|     @GET("api/v3/community") | ||||
|     Call<String> communityInfo(@Query("name") String name, @Query("auth") String access_token); | ||||
|  | ||||
| @@ -48,6 +80,10 @@ public interface LemmyAPI { | ||||
|     @PUT("api/v3/post") | ||||
|     Call<String> postUpdate(@Body EditPostDTO params); | ||||
|  | ||||
|     @Headers("Content-Type: application/json") | ||||
|     @POST("api/v3/post/delete") | ||||
|     Call<String> postDelete(@Body DeletePostDTO params); | ||||
|  | ||||
|     @GET("api/v3/user") | ||||
|     ListenableFuture<Response<String>> getUserPosts( | ||||
|             @Query("username") String username, | ||||
| @@ -159,6 +195,10 @@ public interface LemmyAPI { | ||||
|     @POST("api/v3/comment") | ||||
|     Call<String> postComment(@Body CommentDTO params); | ||||
|  | ||||
|     @Headers("Content-Type: application/json") | ||||
|     @POST("api/v3/comment/delete") | ||||
|     Call<String> commentDelete(@Body DeleteCommentDTO params); | ||||
|  | ||||
|     @Headers("Content-Type: application/json") | ||||
|     @PUT("api/v3/comment") | ||||
|     Call<String> commentEdit(@Body EditCommentDTO params); | ||||
|   | ||||
| @@ -127,9 +127,9 @@ public class CommentMoreBottomSheetFragment extends LandscapeExpandedRoundedBott | ||||
|                 deleteTextView.setOnClickListener(view -> { | ||||
|                     dismiss(); | ||||
|                     if (activity instanceof ViewPostDetailActivity) { | ||||
|                         ((ViewPostDetailActivity) activity).deleteComment(comment.getFullName(), bundle.getInt(EXTRA_POSITION)); | ||||
|                         ((ViewPostDetailActivity) activity).deleteComment(comment.getId(), bundle.getInt(EXTRA_POSITION)); | ||||
|                     } else if (activity instanceof ViewUserDetailActivity) { | ||||
|                         ((ViewUserDetailActivity) activity).deleteComment(comment.getFullName()); | ||||
|                         ((ViewUserDetailActivity) activity).deleteComment(comment.getId()); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|   | ||||
| @@ -49,6 +49,8 @@ public class Comment implements Parcelable { | ||||
|     private int depth; | ||||
|     private int childCount; | ||||
|     private boolean collapsed; | ||||
|  | ||||
|     private boolean isDeleted; | ||||
|     private boolean hasReply; | ||||
|     private boolean saved; | ||||
|     private boolean isExpanded; | ||||
| @@ -67,7 +69,7 @@ public class Comment implements Parcelable { | ||||
|                    long commentTimeMillis, String commentMarkdown, String commentRawText, | ||||
|                    String linkId, String communityName, String communityQualifiedName, Integer parentId, int score, | ||||
|                    int voteType, boolean isSubmitter, String distinguished, String permalink, | ||||
|                    int depth, boolean collapsed, boolean hasReply, boolean saved, long edited, String[] path) { | ||||
|                    int depth, boolean collapsed, boolean hasReply, boolean saved, boolean deleted, long edited, String[] path) { | ||||
|         this.id = id; | ||||
|         this.postId = postId; | ||||
|         this.fullName = fullName; | ||||
| @@ -90,6 +92,7 @@ public class Comment implements Parcelable { | ||||
|         this.collapsed = collapsed; | ||||
|         this.hasReply = hasReply; | ||||
|         this.saved = saved; | ||||
|         this.isDeleted = deleted; | ||||
|         this.isExpanded = false; | ||||
|         this.hasExpandedBefore = false; | ||||
|         this.editedTimeMillis = edited; | ||||
|   | ||||
| @@ -24,7 +24,6 @@ import java.util.TimeZone; | ||||
| import java.util.concurrent.Executor; | ||||
| import java.util.regex.Pattern; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.markdown.MarkdownUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.JSONUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.LemmyUtils; | ||||
|  | ||||
| @@ -304,7 +303,7 @@ public class ParseComment { | ||||
|                 e.printStackTrace(); | ||||
|             } | ||||
|         } | ||||
|         String content = MarkdownUtils.processImageCaptions(commentObj.getString("content"), "Image"); | ||||
|         String content = commentObj.getString("content"); | ||||
|         String commentMarkdown = content; | ||||
|         String commentRawText = content; | ||||
|         String linkId = postObj.getString("id"); | ||||
| @@ -327,11 +326,12 @@ public class ParseComment { | ||||
|         boolean collapsed = false; | ||||
|         boolean hasReply = countsObj.getInt("child_count") > 0; | ||||
|         boolean saved = jsonObject.getBoolean("saved"); | ||||
|         boolean deleted = commentObj.getBoolean("deleted"); | ||||
|         long edited = 0; | ||||
|  | ||||
|         Comment comment = new Comment(id,postID, fullName, author, authorQualifiedName, linkAuthor, commentTimeMillis, | ||||
|         Comment comment = new Comment(id, postID, fullName, author, authorQualifiedName, linkAuthor, commentTimeMillis, | ||||
|                 commentMarkdown, commentRawText, linkId, communityName, communityQualifiedName, parentId, | ||||
|                 score, voteType, isSubmitter, distinguished, permalink, depth, collapsed, hasReply, saved, edited, path); | ||||
|                 score, voteType, isSubmitter, distinguished, permalink, depth, collapsed, hasReply, saved, deleted, edited, path); | ||||
|         int child_count = countsObj.getInt("child_count"); | ||||
|         comment.setChildCount(child_count); | ||||
|         return comment; | ||||
|   | ||||
							
								
								
									
										14
									
								
								app/src/main/java/eu/toldi/infinityforlemmy/dto/AuthDTO.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								app/src/main/java/eu/toldi/infinityforlemmy/dto/AuthDTO.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| package eu.toldi.infinityforlemmy.dto; | ||||
|  | ||||
| public class AuthDTO { | ||||
|  | ||||
|     private String auth; | ||||
|  | ||||
|     public AuthDTO(String auth) { | ||||
|         this.auth = auth; | ||||
|     } | ||||
|  | ||||
|     public String getAuth() { | ||||
|         return auth; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,26 @@ | ||||
| package eu.toldi.infinityforlemmy.dto; | ||||
|  | ||||
| public class DeleteCommentDTO { | ||||
|  | ||||
|     private int comment_id; | ||||
|     boolean deleted; | ||||
|     String auth; | ||||
|  | ||||
|     public DeleteCommentDTO(int comment_id, boolean deleted, String auth) { | ||||
|         this.comment_id = comment_id; | ||||
|         this.deleted = deleted; | ||||
|         this.auth = auth; | ||||
|     } | ||||
|  | ||||
|     public int getComment_id() { | ||||
|         return comment_id; | ||||
|     } | ||||
|  | ||||
|     public boolean isDeleted() { | ||||
|         return deleted; | ||||
|     } | ||||
|  | ||||
|     public String getAuth() { | ||||
|         return auth; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,26 @@ | ||||
| package eu.toldi.infinityforlemmy.dto; | ||||
|  | ||||
| public class DeletePostDTO { | ||||
|  | ||||
|     int post_id; | ||||
|     boolean deleted; | ||||
|     String auth; | ||||
|  | ||||
|     public DeletePostDTO(int post_id, boolean deleted, String auth) { | ||||
|         this.post_id = post_id; | ||||
|         this.deleted = deleted; | ||||
|         this.auth = auth; | ||||
|     } | ||||
|  | ||||
|     public int getPost_id() { | ||||
|         return post_id; | ||||
|     } | ||||
|  | ||||
|     public boolean isDeleted() { | ||||
|         return deleted; | ||||
|     } | ||||
|  | ||||
|     public String getAuth() { | ||||
|         return auth; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,26 @@ | ||||
| package eu.toldi.infinityforlemmy.dto; | ||||
|  | ||||
| public class ReadCommentDTO { | ||||
|  | ||||
|     private int comment_reply_id; | ||||
|     private boolean read; | ||||
|     private String auth; | ||||
|  | ||||
|     public ReadCommentDTO(int comment_reply_id, boolean read, String auth) { | ||||
|         this.comment_reply_id = comment_reply_id; | ||||
|         this.read = read; | ||||
|         this.auth = auth; | ||||
|     } | ||||
|  | ||||
|     public int getComment_reply_id() { | ||||
|         return comment_reply_id; | ||||
|     } | ||||
|  | ||||
|     public boolean isRead() { | ||||
|         return read; | ||||
|     } | ||||
|  | ||||
|     public String getAuth() { | ||||
|         return auth; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,26 @@ | ||||
| package eu.toldi.infinityforlemmy.dto; | ||||
|  | ||||
| public class ReadMessageDTO { | ||||
|  | ||||
|     private int person_mention_id; | ||||
|     private boolean read; | ||||
|     private String auth; | ||||
|  | ||||
|     public ReadMessageDTO(int person_mention_id, boolean read, String auth) { | ||||
|         this.person_mention_id = person_mention_id; | ||||
|         this.read = read; | ||||
|         this.auth = auth; | ||||
|     } | ||||
|  | ||||
|     public int getPerson_mention_id() { | ||||
|         return person_mention_id; | ||||
|     } | ||||
|  | ||||
|     public boolean isRead() { | ||||
|         return read; | ||||
|     } | ||||
|  | ||||
|     public String getAuth() { | ||||
|         return auth; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,14 @@ | ||||
| package eu.toldi.infinityforlemmy.events; | ||||
|  | ||||
| public class ChangeUseCircularFabEvent { | ||||
|  | ||||
|     private boolean useCircularFab; | ||||
|  | ||||
|     public ChangeUseCircularFabEvent(boolean useCircularFab) { | ||||
|         this.useCircularFab = useCircularFab; | ||||
|     } | ||||
|  | ||||
|     public boolean isUseCircularFab() { | ||||
|         return useCircularFab; | ||||
|     } | ||||
| } | ||||
| @@ -1,11 +1,11 @@ | ||||
| package eu.toldi.infinityforlemmy.events; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.message.Message; | ||||
| import eu.toldi.infinityforlemmy.message.CommentInteraction; | ||||
|  | ||||
| public class PassPrivateMessageEvent { | ||||
|     public Message message; | ||||
|     public CommentInteraction message; | ||||
|  | ||||
|     public PassPrivateMessageEvent(Message message) { | ||||
|     public PassPrivateMessageEvent(CommentInteraction message) { | ||||
|         this.message = message; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -35,15 +35,15 @@ import eu.toldi.infinityforlemmy.NetworkState; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.RecyclerViewContentScrollingInterface; | ||||
| import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| import eu.toldi.infinityforlemmy.RetrofitHolder; | ||||
| import eu.toldi.infinityforlemmy.activities.BaseActivity; | ||||
| import eu.toldi.infinityforlemmy.adapters.MessageRecyclerViewAdapter; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; | ||||
| import eu.toldi.infinityforlemmy.events.RepliedToPrivateMessageEvent; | ||||
| import eu.toldi.infinityforlemmy.message.CommentInteraction; | ||||
| import eu.toldi.infinityforlemmy.message.FetchMessage; | ||||
| import eu.toldi.infinityforlemmy.message.Message; | ||||
| import eu.toldi.infinityforlemmy.message.MessageViewModel; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
| public class InboxFragment extends Fragment implements FragmentCommunicator { | ||||
|  | ||||
| @@ -61,8 +61,8 @@ public class InboxFragment extends Fragment implements FragmentCommunicator { | ||||
|     TextView mFetchMessageInfoTextView; | ||||
|     MessageViewModel mMessageViewModel; | ||||
|     @Inject | ||||
|     @Named("oauth") | ||||
|     Retrofit mOauthRetrofit; | ||||
|     @Named("no_oauth") | ||||
|     RetrofitHolder mRetrofit; | ||||
|     @Inject | ||||
|     RedditDataRoomDatabase mRedditDataRoomDatabase; | ||||
|     @Inject | ||||
| @@ -106,7 +106,7 @@ public class InboxFragment extends Fragment implements FragmentCommunicator { | ||||
|         } | ||||
|  | ||||
|         mWhere = arguments.getString(EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_INBOX); | ||||
|         mAdapter = new MessageRecyclerViewAdapter(mActivity, mOauthRetrofit, mCustomThemeWrapper, | ||||
|         mAdapter = new MessageRecyclerViewAdapter(mActivity, mRetrofit.getRetrofit(), mCustomThemeWrapper, | ||||
|                 mAccessToken, mWhere, () -> mMessageViewModel.retryLoadingMore()); | ||||
|         mLinearLayoutManager = new LinearLayoutManagerBugFixed(mActivity); | ||||
|         mRecyclerView.setLayoutManager(mLinearLayoutManager); | ||||
| @@ -127,7 +127,7 @@ public class InboxFragment extends Fragment implements FragmentCommunicator { | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         MessageViewModel.Factory factory = new MessageViewModel.Factory(mOauthRetrofit, | ||||
|         MessageViewModel.Factory factory = new MessageViewModel.Factory(mRetrofit.getRetrofit(), | ||||
|                 getResources().getConfiguration().locale, mAccessToken, mWhere); | ||||
|         mMessageViewModel = new ViewModelProvider(this, factory).get(MessageViewModel.class); | ||||
|         mMessageViewModel.getMessages().observe(getViewLifecycleOwner(), messages -> mAdapter.submitList(messages)); | ||||
| @@ -216,11 +216,11 @@ public class InboxFragment extends Fragment implements FragmentCommunicator { | ||||
|         mAdapter.setNetworkState(null); | ||||
|     } | ||||
|  | ||||
|     public Message getMessageByIndex(int index) { | ||||
|     public CommentInteraction getMessageByIndex(int index) { | ||||
|         if (mMessageViewModel == null || index < 0) { | ||||
|             return null; | ||||
|         } | ||||
|         PagedList<Message> messages = mMessageViewModel.getMessages().getValue(); | ||||
|         PagedList<CommentInteraction> messages = mMessageViewModel.getMessages().getValue(); | ||||
|         if (messages == null) { | ||||
|             return null; | ||||
|         } | ||||
| @@ -245,8 +245,8 @@ public class InboxFragment extends Fragment implements FragmentCommunicator { | ||||
|  | ||||
|     @Subscribe | ||||
|     public void onRepliedToPrivateMessageEvent(RepliedToPrivateMessageEvent repliedToPrivateMessageEvent) { | ||||
|         if (mAdapter != null && mWhere.equals(FetchMessage.WHERE_MESSAGES)) { | ||||
|        /* if (mAdapter != null && mWhere.equals(FetchMessage.WHERE_MESSAGES)) { | ||||
|             mAdapter.updateMessageReply(repliedToPrivateMessageEvent.newReply, repliedToPrivateMessageEvent.messagePosition); | ||||
|         } | ||||
|         }*/ | ||||
|     } | ||||
| } | ||||
| @@ -85,7 +85,7 @@ import eu.toldi.infinityforlemmy.activities.SubmitCrosspostActivity; | ||||
| import eu.toldi.infinityforlemmy.activities.ViewPostDetailActivity; | ||||
| import eu.toldi.infinityforlemmy.adapters.CommentsRecyclerViewAdapter; | ||||
| import eu.toldi.infinityforlemmy.adapters.PostDetailRecyclerViewAdapter; | ||||
| import eu.toldi.infinityforlemmy.apis.RedditAPI; | ||||
| import eu.toldi.infinityforlemmy.apis.LemmyAPI; | ||||
| import eu.toldi.infinityforlemmy.apis.StreamableAPI; | ||||
| import eu.toldi.infinityforlemmy.asynctasks.LoadUserData; | ||||
| import eu.toldi.infinityforlemmy.bottomsheetfragments.FlairBottomSheetFragment; | ||||
| @@ -97,6 +97,7 @@ import eu.toldi.infinityforlemmy.comment.FetchRemovedCommentReveddit; | ||||
| import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; | ||||
| import eu.toldi.infinityforlemmy.customviews.CustomToroContainer; | ||||
| import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; | ||||
| import eu.toldi.infinityforlemmy.dto.EditPostDTO; | ||||
| import eu.toldi.infinityforlemmy.events.ChangeNSFWBlurEvent; | ||||
| import eu.toldi.infinityforlemmy.events.ChangeNetworkStatusEvent; | ||||
| import eu.toldi.infinityforlemmy.events.ChangeSpoilerBlurEvent; | ||||
| @@ -155,9 +156,6 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|     @Named("reveddit") | ||||
|     Retrofit revedditRetrofit; | ||||
|     @Inject | ||||
|     @Named("oauth") | ||||
|     Retrofit mOauthRetrofit; | ||||
|     @Inject | ||||
|     @Named("gfycat") | ||||
|     Retrofit mGfycatRetrofit; | ||||
|     @Inject | ||||
| @@ -215,7 +213,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|     @State | ||||
|     boolean isFetchingComments = false; | ||||
|     @State | ||||
|     String mMessageFullname; | ||||
|     int mMessageFullname; | ||||
|     @State | ||||
|     SortType.Type sortType; | ||||
|     @State | ||||
| @@ -555,7 +553,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|             if (mSingleCommentId != 0) { | ||||
|                 isSingleCommentThreadMode = true; | ||||
|             } | ||||
|             mMessageFullname = getArguments().getString(EXTRA_MESSAGE_FULLNAME); | ||||
|             mMessageFullname = getArguments().getInt(EXTRA_MESSAGE_FULLNAME); | ||||
|  | ||||
|             if (!mRespectSubredditRecommendedSortType || isSingleCommentThreadMode) { | ||||
|                 sortType = loadSortType(); | ||||
| @@ -577,11 +575,11 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|     } | ||||
|  | ||||
|     private void bindView() { | ||||
|         if (mAccessToken != null && mMessageFullname != null) { | ||||
|             ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() { | ||||
|         if (mAccessToken != null && mMessageFullname != 0) { | ||||
|             ReadMessage.readMessage(mRetrofit.getRetrofit(), mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() { | ||||
|                 @Override | ||||
|                 public void readSuccess() { | ||||
|                     mMessageFullname = null; | ||||
|                     mMessageFullname = 0; | ||||
|                 } | ||||
|  | ||||
|                 @Override | ||||
| @@ -601,13 +599,13 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|             setupMenu(); | ||||
|  | ||||
|             mPostAdapter = new PostDetailRecyclerViewAdapter(activity, | ||||
|                     this, mExecutor, mCustomThemeWrapper, mRetrofit.getRetrofit(), mOauthRetrofit, mGfycatRetrofit, | ||||
|                     this, mExecutor, mCustomThemeWrapper, mRetrofit.getRetrofit(), mGfycatRetrofit, | ||||
|                     mRedgifsRetrofit, mStreamableApiProvider, mRedditDataRoomDatabase, mGlide, | ||||
|                     mSeparatePostAndComments, mAccessToken, mAccountName, mPost, mLocale, | ||||
|                     mSharedPreferences, mCurrentAccountSharedPreferences, mNsfwAndSpoilerSharedPreferences, mPostDetailsSharedPreferences, | ||||
|                     mExoCreator, post -> EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition))); | ||||
|             mCommentsAdapter = new CommentsRecyclerViewAdapter(activity, | ||||
|                     this, mCustomThemeWrapper, mExecutor, mRetrofit.getRetrofit(), mOauthRetrofit, | ||||
|                     this, mCustomThemeWrapper, mExecutor, mRetrofit.getRetrofit(), | ||||
|                     mAccessToken, mAccountName, mPost, mLocale, mSingleCommentId, | ||||
|                     isSingleCommentThreadMode, mSharedPreferences, | ||||
|                     new CommentsRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { | ||||
| @@ -691,10 +689,8 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|                 hideItem.setVisible(false); | ||||
|             } | ||||
|  | ||||
|             if (mPost.getAuthor().equals(mAccountName)) { | ||||
|                 if (mPost.getPostType() == Post.TEXT_TYPE) { | ||||
|                     mMenu.findItem(R.id.action_edit_view_post_detail_fragment).setVisible(true); | ||||
|                 } | ||||
|             if (mPost.getAuthorNamePrefixed().equals(mAccountQualifiedName)) { | ||||
|                 mMenu.findItem(R.id.action_edit_view_post_detail_fragment).setVisible(true); | ||||
|                 mMenu.findItem(R.id.action_delete_view_post_detail_fragment).setVisible(true); | ||||
|  | ||||
|                 MenuItem nsfwItem = mMenu.findItem(R.id.action_nsfw_view_post_detail_fragment); | ||||
| @@ -778,29 +774,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|     } | ||||
|  | ||||
|     public void changeFlair(Flair flair) { | ||||
|         Map<String, String> params = new HashMap<>(); | ||||
|         params.put(APIUtils.API_TYPE_KEY, APIUtils.API_TYPE_JSON); | ||||
|         params.put(APIUtils.FLAIR_TEMPLATE_ID_KEY, flair.getId()); | ||||
|         params.put(APIUtils.LINK_KEY, mPost.getFullName()); | ||||
|         params.put(APIUtils.TEXT_KEY, flair.getText()); | ||||
|  | ||||
|         mOauthRetrofit.create(RedditAPI.class).selectFlair(mPost.getSubredditNamePrefixed(), | ||||
|                 APIUtils.getOAuthHeader(mAccessToken), params).enqueue(new Callback<String>() { | ||||
|             @Override | ||||
|             public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { | ||||
|                 if (response.isSuccessful()) { | ||||
|                     refresh(true, false); | ||||
|                     showMessage(R.string.update_flair_success); | ||||
|                 } else { | ||||
|                     showMessage(R.string.update_flair_failed); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { | ||||
|                 showMessage(R.string.update_flair_failed); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public void changeSortType(SortType sortType) { | ||||
| @@ -954,7 +928,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|                 SavePost savePost = new SavePost(); | ||||
|                 if (mPost.isSaved()) { | ||||
|                     item.setIcon(mUnsavedIcon); | ||||
|                     savePost.unsaveThing(mOauthRetrofit, mAccessToken, mPost.getId(), | ||||
|                     savePost.unsaveThing(mRetrofit.getRetrofit(), mAccessToken, mPost.getId(), | ||||
|                             new SaveThing.SaveThingListener() { | ||||
|                                 @Override | ||||
|                                 public void success() { | ||||
| @@ -978,7 +952,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|                             }); | ||||
|                 } else { | ||||
|                     item.setIcon(mSavedIcon); | ||||
|                     savePost.saveThing(mOauthRetrofit, mAccessToken, mPost.getId(), | ||||
|                     savePost.saveThing(mRetrofit.getRetrofit(), mAccessToken, mPost.getId(), | ||||
|                             new SaveThing.SaveThingListener() { | ||||
|                                 @Override | ||||
|                                 public void success() { | ||||
| @@ -1019,7 +993,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|                 if (mPost.isHidden()) { | ||||
|                     Utils.setTitleWithCustomFontToMenuItem(activity.typeface, item, getString(R.string.action_hide_post)); | ||||
|  | ||||
|                     HidePost.unhidePost(mOauthRetrofit, mAccessToken, mPost.getFullName(), new HidePost.HidePostListener() { | ||||
|                     HidePost.unhidePost(mRetrofit.getRetrofit(), mAccessToken, mPost.getFullName(), new HidePost.HidePostListener() { | ||||
|                         @Override | ||||
|                         public void success() { | ||||
|                             mPost.setHidden(false); | ||||
| @@ -1039,7 +1013,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|                 } else { | ||||
|                     Utils.setTitleWithCustomFontToMenuItem(activity.typeface, item, getString(R.string.action_unhide_post)); | ||||
|  | ||||
|                     HidePost.hidePost(mOauthRetrofit, mAccessToken, mPost.getFullName(), new HidePost.HidePostListener() { | ||||
|                     HidePost.hidePost(mRetrofit.getRetrofit(), mAccessToken, mPost.getFullName(), new HidePost.HidePostListener() { | ||||
|                         @Override | ||||
|                         public void success() { | ||||
|                             mPost.setHidden(true); | ||||
| @@ -1061,9 +1035,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|             return true; | ||||
|         } else if (itemId == R.id.action_edit_view_post_detail_fragment) { | ||||
|             Intent editPostIntent = new Intent(activity, EditPostActivity.class); | ||||
|             editPostIntent.putExtra(EditPostActivity.EXTRA_FULLNAME, mPost.getFullName()); | ||||
|             editPostIntent.putExtra(EditPostActivity.EXTRA_TITLE, mPost.getTitle()); | ||||
|             editPostIntent.putExtra(EditPostActivity.EXTRA_CONTENT, mPost.getSelfText()); | ||||
|             editPostIntent.putExtra(EditPostActivity.EXTRA_DATA, mPost); | ||||
|             startActivityForResult(editPostIntent, EDIT_POST_REQUEST_CODE); | ||||
|             return true; | ||||
|         } else if (itemId == R.id.action_delete_view_post_detail_fragment) { | ||||
| @@ -1071,7 +1043,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|                     .setTitle(R.string.delete_this_post) | ||||
|                     .setMessage(R.string.are_you_sure) | ||||
|                     .setPositiveButton(R.string.delete, (dialogInterface, i) | ||||
|                             -> DeleteThing.delete(mOauthRetrofit, mPost.getFullName(), mAccessToken, new DeleteThing.DeleteThingListener() { | ||||
|                             -> DeleteThing.deletePost(mRetrofit.getRetrofit(), mPost.getId(), mAccessToken, new DeleteThing.DeleteThingListener() { | ||||
|                         @Override | ||||
|                         public void deleteSuccess() { | ||||
|                             Toast.makeText(activity, R.string.delete_post_success, Toast.LENGTH_SHORT).show(); | ||||
| @@ -1266,7 +1238,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|                         mPost = post; | ||||
|                         mPostAdapter = new PostDetailRecyclerViewAdapter(activity, | ||||
|                                 ViewPostDetailFragment.this, mExecutor, mCustomThemeWrapper, | ||||
|                                 mRetrofit.getRetrofit(), mOauthRetrofit, mGfycatRetrofit, mRedgifsRetrofit, | ||||
|                                 mRetrofit.getRetrofit(), mGfycatRetrofit, mRedgifsRetrofit, | ||||
|                                 mStreamableApiProvider, mRedditDataRoomDatabase, mGlide, mSeparatePostAndComments, | ||||
|                                 mAccessToken, mAccountName, mPost, mLocale, mSharedPreferences, | ||||
|                                 mCurrentAccountSharedPreferences, mNsfwAndSpoilerSharedPreferences, | ||||
| @@ -1279,7 +1251,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|                                 pages_loaded++; | ||||
|                                 mCommentsAdapter = new CommentsRecyclerViewAdapter(activity, | ||||
|                                         ViewPostDetailFragment.this, mCustomThemeWrapper, mExecutor, | ||||
|                                         mRetrofit.getRetrofit(), mOauthRetrofit, mAccessToken, mAccountName, mPost, mLocale, | ||||
|                                         mRetrofit.getRetrofit(), mAccessToken, mAccountName, mPost, mLocale, | ||||
|                                         mSingleCommentId, isSingleCommentThreadMode, mSharedPreferences, | ||||
|                                         new CommentsRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { | ||||
|                                             @Override | ||||
| @@ -1571,7 +1543,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|  | ||||
|         Map<String, String> params = new HashMap<>(); | ||||
|         params.put(APIUtils.ID_KEY, mPost.getFullName()); | ||||
|         mOauthRetrofit.create(RedditAPI.class).markNSFW(APIUtils.getOAuthHeader(mAccessToken), params) | ||||
|         mRetrofit.getRetrofit().create(LemmyAPI.class).postUpdate(new EditPostDTO(mPost.getId(), mPost.getTitle(), mPost.getUrl(), mPost.getSelfText(), true, null, mAccessToken)) | ||||
|                 .enqueue(new Callback<String>() { | ||||
|                     @Override | ||||
|                     public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { | ||||
| @@ -1609,7 +1581,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|  | ||||
|         Map<String, String> params = new HashMap<>(); | ||||
|         params.put(APIUtils.ID_KEY, mPost.getFullName()); | ||||
|         mOauthRetrofit.create(RedditAPI.class).unmarkNSFW(APIUtils.getOAuthHeader(mAccessToken), params) | ||||
|         mRetrofit.getRetrofit().create(LemmyAPI.class).postUpdate(new EditPostDTO(mPost.getId(), mPost.getTitle(), mPost.getUrl(), mPost.getSelfText(), false, null, mAccessToken)) | ||||
|                 .enqueue(new Callback<String>() { | ||||
|                     @Override | ||||
|                     public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { | ||||
| @@ -1640,88 +1612,12 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic | ||||
|                 }); | ||||
|     } | ||||
|  | ||||
|     private void markSpoiler() { | ||||
|         if (mMenu != null) { | ||||
|             mMenu.findItem(R.id.action_spoiler_view_post_detail_fragment).setTitle(R.string.action_unmark_spoiler); | ||||
|         } | ||||
|  | ||||
|         Map<String, String> params = new HashMap<>(); | ||||
|         params.put(APIUtils.ID_KEY, mPost.getFullName()); | ||||
|         mOauthRetrofit.create(RedditAPI.class).markSpoiler(APIUtils.getOAuthHeader(mAccessToken), params) | ||||
|                 .enqueue(new Callback<String>() { | ||||
|                     @Override | ||||
|                     public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { | ||||
|                         if (response.isSuccessful()) { | ||||
|                             if (mMenu != null) { | ||||
|                                 mMenu.findItem(R.id.action_spoiler_view_post_detail_fragment).setTitle(R.string.action_unmark_spoiler); | ||||
|                             } | ||||
|  | ||||
|                             refresh(true, false); | ||||
|                             showMessage(R.string.mark_spoiler_success); | ||||
|                         } else { | ||||
|                             if (mMenu != null) { | ||||
|                                 mMenu.findItem(R.id.action_spoiler_view_post_detail_fragment).setTitle(R.string.action_mark_spoiler); | ||||
|                             } | ||||
|  | ||||
|                             showMessage(R.string.mark_spoiler_failed); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     @Override | ||||
|                     public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { | ||||
|                         if (mMenu != null) { | ||||
|                             mMenu.findItem(R.id.action_spoiler_view_post_detail_fragment).setTitle(R.string.action_mark_spoiler); | ||||
|                         } | ||||
|  | ||||
|                         showMessage(R.string.mark_spoiler_failed); | ||||
|                     } | ||||
|                 }); | ||||
|     } | ||||
|  | ||||
|     private void unmarkSpoiler() { | ||||
|         if (mMenu != null) { | ||||
|             mMenu.findItem(R.id.action_spoiler_view_post_detail_fragment).setTitle(R.string.action_mark_spoiler); | ||||
|         } | ||||
|  | ||||
|         Map<String, String> params = new HashMap<>(); | ||||
|         params.put(APIUtils.ID_KEY, mPost.getFullName()); | ||||
|         mOauthRetrofit.create(RedditAPI.class).unmarkSpoiler(APIUtils.getOAuthHeader(mAccessToken), params) | ||||
|                 .enqueue(new Callback<String>() { | ||||
|                     @Override | ||||
|                     public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { | ||||
|                         if (response.isSuccessful()) { | ||||
|                             if (mMenu != null) { | ||||
|                                 mMenu.findItem(R.id.action_spoiler_view_post_detail_fragment).setTitle(R.string.action_mark_spoiler); | ||||
|                             } | ||||
|  | ||||
|                             refresh(true, false); | ||||
|                             showMessage(R.string.unmark_spoiler_success); | ||||
|                         } else { | ||||
|                             if (mMenu != null) { | ||||
|                                 mMenu.findItem(R.id.action_spoiler_view_post_detail_fragment).setTitle(R.string.action_unmark_spoiler); | ||||
|                             } | ||||
|  | ||||
|                             showMessage(R.string.unmark_spoiler_failed); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     @Override | ||||
|                     public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { | ||||
|                         if (mMenu != null) { | ||||
|                             mMenu.findItem(R.id.action_spoiler_view_post_detail_fragment).setTitle(R.string.action_unmark_spoiler); | ||||
|                         } | ||||
|  | ||||
|                         showMessage(R.string.unmark_spoiler_failed); | ||||
|                     } | ||||
|                 }); | ||||
|     } | ||||
|  | ||||
|     public void deleteComment(String fullName, int position) { | ||||
|     public void deleteComment(int commentId, int position) { | ||||
|         new MaterialAlertDialogBuilder(activity, 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(activity, R.string.delete_post_success, Toast.LENGTH_SHORT).show(); | ||||
|   | ||||
| @@ -8,7 +8,6 @@ import androidx.annotation.Nullable; | ||||
|  | ||||
| import org.commonmark.ext.gfm.tables.TableBlock; | ||||
|  | ||||
| import java.util.regex.Matcher; | ||||
| import java.util.regex.Pattern; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| @@ -16,6 +15,7 @@ import eu.toldi.infinityforlemmy.customviews.CustomMarkwonAdapter; | ||||
| import io.noties.markwon.Markwon; | ||||
| import io.noties.markwon.MarkwonPlugin; | ||||
| import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; | ||||
| import io.noties.markwon.image.glide.GlideImagesPlugin; | ||||
| import io.noties.markwon.inlineparser.BangInlineProcessor; | ||||
| import io.noties.markwon.inlineparser.HtmlInlineProcessor; | ||||
| import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; | ||||
| @@ -38,9 +38,9 @@ public class MarkdownUtils { | ||||
|                                                   int spoilerBackgroundColor, | ||||
|                                                   @Nullable BetterLinkMovementMethod.OnLinkLongClickListener onLinkLongClickListener) { | ||||
|         return Markwon.builder(context) | ||||
|                 .usePlugin(GlideImagesPlugin.create(context)) | ||||
|                 .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { | ||||
|                     plugin.excludeInlineProcessor(HtmlInlineProcessor.class); | ||||
|                     plugin.excludeInlineProcessor(BangInlineProcessor.class); | ||||
|                 })) | ||||
|                 .usePlugin(miscPlugin) | ||||
|                 .usePlugin(SuperscriptPlugin.create()) | ||||
| @@ -60,7 +60,6 @@ public class MarkdownUtils { | ||||
|         return Markwon.builder(context) | ||||
|                 .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { | ||||
|                     plugin.excludeInlineProcessor(HtmlInlineProcessor.class); | ||||
|                     plugin.excludeInlineProcessor(BangInlineProcessor.class); | ||||
|                 })) | ||||
|                 .usePlugin(miscPlugin) | ||||
|                 .usePlugin(SuperscriptPlugin.create()) | ||||
| @@ -70,6 +69,7 @@ public class MarkdownUtils { | ||||
|                         .setOnLinkLongClickListener(onLinkLongClickListener))) | ||||
|                 .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) | ||||
|                 .usePlugin(TableEntryPlugin.create(context)) | ||||
|                 .usePlugin(GlideImagesPlugin.create(context)) | ||||
|                 .build(); | ||||
|     } | ||||
|  | ||||
| @@ -104,6 +104,15 @@ public class MarkdownUtils { | ||||
|                 .build(); | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     public static MarkwonAdapter createTablesAndImagesAdapter(@NonNull Context context) { | ||||
|         return MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) | ||||
|                 .include(TableBlock.class, TableEntry.create(builder -> builder | ||||
|                         .tableLayout(R.layout.adapter_table_block, R.id.table_layout) | ||||
|                         .textLayoutIsRoot(R.layout.view_table_entry_cell))) | ||||
|                 .build(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Creates a CustomMarkwonAdapter configured with support for tables. | ||||
|      */ | ||||
| @@ -119,35 +128,4 @@ public class MarkdownUtils { | ||||
|     private static final Pattern emptyPattern = Pattern.compile("!\\[\\]\\((.*?)\\)"); | ||||
|     private static final Pattern nonEmptyPattern = Pattern.compile("!\\[(.*?)\\]\\((.*?)\\)"); | ||||
|  | ||||
|     public static String processImageCaptions(String markdown, String replacementCaption) { | ||||
|         // Pattern for Markdown images with empty captions | ||||
|  | ||||
|         // Pattern for Markdown images with non-empty captions | ||||
|  | ||||
|  | ||||
|         Matcher emptyMatcher = emptyPattern.matcher(markdown); | ||||
|         StringBuffer sb = new StringBuffer(); | ||||
|  | ||||
|         while (emptyMatcher.find()) { | ||||
|             // Replace the matched pattern with the same URL, but with a caption | ||||
|             emptyMatcher.appendReplacement(sb, "[" + replacementCaption + "](" + emptyMatcher.group(1) + ")"); | ||||
|         } | ||||
|  | ||||
|         // Append the rest of the content | ||||
|         emptyMatcher.appendTail(sb); | ||||
|  | ||||
|         // Now process non-empty captions | ||||
|         Matcher nonEmptyMatcher = nonEmptyPattern.matcher(sb.toString()); | ||||
|         StringBuffer finalSb = new StringBuffer(); | ||||
|  | ||||
|         while (nonEmptyMatcher.find()) { | ||||
|             // Replace the matched pattern with the same URL and caption, but without the "!" | ||||
|             nonEmptyMatcher.appendReplacement(finalSb, "[" + nonEmptyMatcher.group(1) + "](" + nonEmptyMatcher.group(2) + ")"); | ||||
|         } | ||||
|  | ||||
|         // Append the rest of the content | ||||
|         nonEmptyMatcher.appendTail(finalSb); | ||||
|  | ||||
|         return finalSb.toString(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,36 @@ | ||||
| package eu.toldi.infinityforlemmy.message; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.comment.Comment; | ||||
|  | ||||
| public class CommentInteraction { | ||||
|     int id; | ||||
|     private Comment comment; | ||||
|     private boolean isRead; | ||||
|  | ||||
|     public CommentInteraction(int id, Comment comment, boolean isRead) { | ||||
|         this.id = id; | ||||
|         this.comment = comment; | ||||
|         this.isRead = isRead; | ||||
|     } | ||||
|  | ||||
|     public Comment getComment() { | ||||
|         return this.comment; | ||||
|     } | ||||
|  | ||||
|     public boolean isRead() { | ||||
|         return this.isRead; | ||||
|     } | ||||
|  | ||||
|     public void markAsUnRead() { | ||||
|         this.isRead = false; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public void markAsRead() { | ||||
|         this.isRead = true; | ||||
|     } | ||||
|  | ||||
|     public int getId() { | ||||
|         return id; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,100 @@ | ||||
| package eu.toldi.infinityforlemmy.message; | ||||
|  | ||||
| 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.comment.Comment; | ||||
| import eu.toldi.infinityforlemmy.comment.ParseComment; | ||||
| import retrofit2.Call; | ||||
| import retrofit2.Callback; | ||||
| import retrofit2.Response; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
| public class FetchCommentInteractions { | ||||
|     public static void fetchReplies(Retrofit retrofit, Integer page, boolean unreadOnly, String auth, FetchCommentInteractionsListener fetchMessagesListener) { | ||||
|         LemmyAPI api = retrofit.create(LemmyAPI.class); | ||||
|  | ||||
|         api.userReplies("New", page, 25, unreadOnly, auth).enqueue( | ||||
|                 new Callback<String>() { | ||||
|                     @Override | ||||
|                     public void onResponse(Call<String> call, Response<String> response) { | ||||
|                         if (response.isSuccessful()) { | ||||
|                             try { | ||||
|                                 JSONObject jsonObject = new JSONObject(response.body()); | ||||
|                                 JSONArray jsonArray = jsonObject.getJSONArray("replies"); | ||||
|                                 List<CommentInteraction> commentInteractions = new ArrayList<>(); | ||||
|                                 for (int i = 0; i < jsonArray.length(); i++) { | ||||
|                                     JSONObject commentInteractionObject = jsonArray.getJSONObject(i); | ||||
|                                     Comment comment = ParseComment.parseSingleComment(commentInteractionObject); | ||||
|                                     boolean isRead = !commentInteractionObject.getJSONObject("comment_reply").getBoolean("read"); | ||||
|                                     int id = commentInteractionObject.getJSONObject("comment_reply").getInt("id"); | ||||
|                                     commentInteractions.add(new CommentInteraction(id, comment, isRead)); | ||||
|                                 } | ||||
|                                 fetchMessagesListener.fetchSuccess(commentInteractions); | ||||
|  | ||||
|                             } catch (JSONException e) { | ||||
|                                 e.printStackTrace(); | ||||
|                                 fetchMessagesListener.fetchFailed(); | ||||
|                             } | ||||
|                         } else { | ||||
|                             fetchMessagesListener.fetchFailed(); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     @Override | ||||
|                     public void onFailure(Call<String> call, Throwable t) { | ||||
|                         fetchMessagesListener.fetchFailed(); | ||||
|                     } | ||||
|                 } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     static void fetchMentions(Retrofit retrofit, Integer page, boolean unreadOnly, String auth, FetchCommentInteractionsListener fetchMessagesListener) { | ||||
|         LemmyAPI api = retrofit.create(LemmyAPI.class); | ||||
|  | ||||
|         api.userMentions("New", page, 25, unreadOnly, auth).enqueue( | ||||
|                 new Callback<String>() { | ||||
|                     @Override | ||||
|                     public void onResponse(Call<String> call, Response<String> response) { | ||||
|                         if (response.isSuccessful()) { | ||||
|                             try { | ||||
|                                 JSONObject jsonObject = new JSONObject(response.body()); | ||||
|                                 JSONArray jsonArray = jsonObject.getJSONArray("mentions"); | ||||
|                                 List<CommentInteraction> commentInteractions = new ArrayList<>(); | ||||
|                                 for (int i = 0; i < jsonArray.length(); i++) { | ||||
|                                     JSONObject commentInteractionObject = jsonArray.getJSONObject(i); | ||||
|                                     Comment comment = ParseComment.parseSingleComment(commentInteractionObject); | ||||
|                                     boolean isRead = commentInteractionObject.getJSONObject("person_mention").getBoolean("read"); | ||||
|                                     int id = commentInteractionObject.getJSONObject("person_mention").getInt("id"); | ||||
|                                     commentInteractions.add(new CommentInteraction(id, comment, isRead)); | ||||
|                                 } | ||||
|                                 fetchMessagesListener.fetchSuccess(commentInteractions); | ||||
|  | ||||
|                             } catch (JSONException e) { | ||||
|                                 e.printStackTrace(); | ||||
|                                 fetchMessagesListener.fetchFailed(); | ||||
|                             } | ||||
|                         } else { | ||||
|                             fetchMessagesListener.fetchFailed(); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     @Override | ||||
|                     public void onFailure(Call<String> call, Throwable t) { | ||||
|                         fetchMessagesListener.fetchFailed(); | ||||
|                     } | ||||
|                 } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     public interface FetchCommentInteractionsListener { | ||||
|         void fetchSuccess(List<CommentInteraction> commentInteractions); | ||||
|  | ||||
|         void fetchFailed(); | ||||
|     } | ||||
| } | ||||
| @@ -15,6 +15,8 @@ import retrofit2.Retrofit; | ||||
|  | ||||
| public class FetchMessage { | ||||
|  | ||||
|     public static final String WHERE_REPLIES = "replies"; | ||||
|     public static final String WHERE_MENTIONS = "mentions"; | ||||
|     public static final String WHERE_INBOX = "inbox"; | ||||
|     public static final String WHERE_UNREAD = "unread"; | ||||
|     public static final String WHERE_SENT = "sent"; | ||||
| @@ -24,6 +26,9 @@ public class FetchMessage { | ||||
|     public static final int MESSAGE_TYPE_INBOX = 0; | ||||
|     public static final int MESSAGE_TYPE_PRIVATE_MESSAGE = 1; | ||||
|     public static final int MESSAGE_TYPE_NOTIFICATION = 2; | ||||
|     public static final int MESSAGE_TYPE_REPLIES = 3; | ||||
|     public static final int MESSAGE_TYPE_MENTIONS = 4; | ||||
|  | ||||
|  | ||||
|     static void fetchInbox(Retrofit oauthRetrofit, Locale locale, String accessToken, String where, | ||||
|                            String after, int messageType, FetchMessagesListener fetchMessagesListener) { | ||||
|   | ||||
| @@ -0,0 +1,38 @@ | ||||
| package eu.toldi.infinityforlemmy.message; | ||||
|  | ||||
| public class MessageCount { | ||||
|  | ||||
|     /* | ||||
|     Example: | ||||
|     { | ||||
|   "replies": 1, | ||||
|   "mentions": 0, | ||||
|   "private_messages": 0 | ||||
| } | ||||
|      */ | ||||
|     public int replies; | ||||
|     public int mentions; | ||||
|     public int private_messages; | ||||
|  | ||||
|     public MessageCount(int replies, int mentions, int private_messages) { | ||||
|         this.replies = replies; | ||||
|         this.mentions = mentions; | ||||
|         this.private_messages = private_messages; | ||||
|     } | ||||
|  | ||||
|     public int getReplies() { | ||||
|         return replies; | ||||
|     } | ||||
|  | ||||
|     public int getMentions() { | ||||
|         return mentions; | ||||
|     } | ||||
|  | ||||
|     public int getPrivate_messages() { | ||||
|         return private_messages; | ||||
|     } | ||||
|  | ||||
|     public int getSum() { | ||||
|         return replies + mentions + private_messages; | ||||
|     } | ||||
| } | ||||
| @@ -1,18 +1,18 @@ | ||||
| package eu.toldi.infinityforlemmy.message; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.lifecycle.MutableLiveData; | ||||
| import androidx.paging.PageKeyedDataSource; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Locale; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.NetworkState; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
| class MessageDataSource extends PageKeyedDataSource<String, Message> { | ||||
|     private Retrofit oauthRetrofit; | ||||
| class MessageDataSource extends PageKeyedDataSource<Integer, CommentInteraction> { | ||||
|     private Retrofit retrofit; | ||||
|     private Locale locale; | ||||
|     private String accessToken; | ||||
|     private String where; | ||||
| @@ -22,18 +22,22 @@ class MessageDataSource extends PageKeyedDataSource<String, Message> { | ||||
|     private MutableLiveData<NetworkState> initialLoadStateLiveData; | ||||
|     private MutableLiveData<Boolean> hasPostLiveData; | ||||
|  | ||||
|     private LoadParams<String> params; | ||||
|     private LoadCallback<String, Message> callback; | ||||
|     private LoadParams<Integer> params; | ||||
|     private LoadCallback<Integer, CommentInteraction> callback; | ||||
|  | ||||
|     private int page = 0; | ||||
|  | ||||
|     MessageDataSource(Retrofit oauthRetrofit, Locale locale, String accessToken, String where) { | ||||
|         this.oauthRetrofit = oauthRetrofit; | ||||
|         this.retrofit = oauthRetrofit; | ||||
|         this.locale = locale; | ||||
|         this.accessToken = accessToken; | ||||
|         this.where = where; | ||||
|         if (where.equals(FetchMessage.WHERE_MESSAGES)) { | ||||
|             messageType = FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE; | ||||
|         } else if (where.equals(FetchMessage.WHERE_REPLIES)) { | ||||
|             messageType = FetchMessage.MESSAGE_TYPE_REPLIES; | ||||
|         } else { | ||||
|             messageType = FetchMessage.MESSAGE_TYPE_INBOX; | ||||
|             messageType = FetchMessage.MESSAGE_TYPE_MENTIONS; | ||||
|         } | ||||
|         paginationNetworkStateLiveData = new MutableLiveData<>(); | ||||
|         initialLoadStateLiveData = new MutableLiveData<>(); | ||||
| @@ -57,63 +61,97 @@ class MessageDataSource extends PageKeyedDataSource<String, Message> { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void loadInitial(@NonNull LoadInitialParams<String> params, @NonNull LoadInitialCallback<String, Message> callback) { | ||||
|     public void loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull LoadInitialCallback<Integer, CommentInteraction> callback) { | ||||
|         initialLoadStateLiveData.postValue(NetworkState.LOADING); | ||||
|  | ||||
|         FetchMessage.fetchInbox(oauthRetrofit, locale, accessToken, where, null, messageType, | ||||
|                 new FetchMessage.FetchMessagesListener() { | ||||
|             @Override | ||||
|             public void fetchSuccess(ArrayList<Message> messages, @Nullable String after) { | ||||
|                 if (messages.size() == 0) { | ||||
|                     hasPostLiveData.postValue(false); | ||||
|                 } else { | ||||
|         if (messageType == FetchMessage.MESSAGE_TYPE_REPLIES) { | ||||
|             FetchCommentInteractions.fetchReplies(retrofit, 1, false, accessToken, new FetchCommentInteractions.FetchCommentInteractionsListener() { | ||||
|                 @Override | ||||
|                 public void fetchSuccess(List<CommentInteraction> commentInteractions) { | ||||
|                     hasPostLiveData.postValue(true); | ||||
|                     if (commentInteractions.size() == 0) { | ||||
|                         callback.onResult(commentInteractions, null, null); | ||||
|                     } else { | ||||
|                         callback.onResult(commentInteractions, null, 2); | ||||
|                     } | ||||
|  | ||||
|                     initialLoadStateLiveData.postValue(NetworkState.LOADED); | ||||
|                 } | ||||
|  | ||||
|                 if (after == null || after.equals("") || after.equals("null")) { | ||||
|                     callback.onResult(messages, null, null); | ||||
|                 } else { | ||||
|                     callback.onResult(messages, null, after); | ||||
|                 @Override | ||||
|                 public void fetchFailed() { | ||||
|                     initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetch messages")); | ||||
|                 } | ||||
|                 initialLoadStateLiveData.postValue(NetworkState.LOADED); | ||||
|             } | ||||
|             }); | ||||
|         } else if (messageType == FetchMessage.MESSAGE_TYPE_MENTIONS) { | ||||
|             FetchCommentInteractions.fetchMentions(retrofit, 1, false, accessToken, new FetchCommentInteractions.FetchCommentInteractionsListener() { | ||||
|                 @Override | ||||
|                 public void fetchSuccess(List<CommentInteraction> commentInteractions) { | ||||
|                     hasPostLiveData.postValue(true); | ||||
|                     if (commentInteractions.size() == 0) { | ||||
|                         callback.onResult(commentInteractions, null, null); | ||||
|                     } else { | ||||
|                         callback.onResult(commentInteractions, null, 2); | ||||
|                     } | ||||
|  | ||||
|             @Override | ||||
|             public void fetchFailed() { | ||||
|                 initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetch messages")); | ||||
|             } | ||||
|         }); | ||||
|                     initialLoadStateLiveData.postValue(NetworkState.LOADED); | ||||
|                 } | ||||
|  | ||||
|                 @Override | ||||
|                 public void fetchFailed() { | ||||
|                     initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetch messages")); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void loadBefore(@NonNull LoadParams<String> params, @NonNull LoadCallback<String, Message> callback) { | ||||
|     public void loadBefore(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, CommentInteraction> callback) { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void loadAfter(@NonNull LoadParams<String> params, @NonNull LoadCallback<String, Message> callback) { | ||||
|     public void loadAfter(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, CommentInteraction> callback) { | ||||
|         this.params = params; | ||||
|         this.callback = callback; | ||||
|  | ||||
|         paginationNetworkStateLiveData.postValue(NetworkState.LOADING); | ||||
|         if (messageType == FetchMessage.MESSAGE_TYPE_REPLIES) { | ||||
|             FetchCommentInteractions.fetchReplies(retrofit, params.key, false, accessToken, new FetchCommentInteractions.FetchCommentInteractionsListener() { | ||||
|                 @Override | ||||
|                 public void fetchSuccess(List<CommentInteraction> commentInteractions) { | ||||
|                     hasPostLiveData.postValue(true); | ||||
|                     if (commentInteractions.size() == 0) { | ||||
|                         callback.onResult(new ArrayList<>(), null); | ||||
|                     } else { | ||||
|                         callback.onResult(commentInteractions, params.key + 1); | ||||
|                     } | ||||
|  | ||||
|         FetchMessage.fetchInbox(oauthRetrofit, locale, accessToken, where, params.key, messageType, | ||||
|                 new FetchMessage.FetchMessagesListener() { | ||||
|             @Override | ||||
|             public void fetchSuccess(ArrayList<Message> messages, @Nullable String after) { | ||||
|                 if (after == null || after.equals("") || after.equals("null")) { | ||||
|                     callback.onResult(messages, null); | ||||
|                 } else { | ||||
|                     callback.onResult(messages, after); | ||||
|                     paginationNetworkStateLiveData.postValue(NetworkState.LOADED); | ||||
|                 } | ||||
|  | ||||
|                 paginationNetworkStateLiveData.postValue(NetworkState.LOADED); | ||||
|             } | ||||
|                 @Override | ||||
|                 public void fetchFailed() { | ||||
|                     paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetch messages")); | ||||
|                 } | ||||
|             }); | ||||
|         } else if (messageType == FetchMessage.MESSAGE_TYPE_MENTIONS) { | ||||
|             FetchCommentInteractions.fetchMentions(retrofit, params.key, false, accessToken, new FetchCommentInteractions.FetchCommentInteractionsListener() { | ||||
|                 @Override | ||||
|                 public void fetchSuccess(List<CommentInteraction> commentInteractions) { | ||||
|                     hasPostLiveData.postValue(true); | ||||
|                     if (commentInteractions.size() == 0) { | ||||
|                         callback.onResult(new ArrayList<>(), null); | ||||
|                     } else { | ||||
|                         callback.onResult(commentInteractions, params.key + 1); | ||||
|                     } | ||||
|                     paginationNetworkStateLiveData.postValue(NetworkState.LOADED); | ||||
|                 } | ||||
|  | ||||
|             @Override | ||||
|             public void fetchFailed() { | ||||
|                 paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetching data")); | ||||
|             } | ||||
|         }); | ||||
|                 @Override | ||||
|                 public void fetchFailed() { | ||||
|                     paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetch messages")); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -19,7 +19,7 @@ public class MessageViewModel extends ViewModel { | ||||
|     private LiveData<NetworkState> paginationNetworkState; | ||||
|     private LiveData<NetworkState> initialLoadingState; | ||||
|     private LiveData<Boolean> hasMessageLiveData; | ||||
|     private LiveData<PagedList<Message>> messages; | ||||
|     private LiveData<PagedList<CommentInteraction>> messages; | ||||
|     private MutableLiveData<String> whereLiveData; | ||||
|  | ||||
|     public MessageViewModel(Retrofit retrofit, Locale locale, String accessToken, String where) { | ||||
| @@ -47,7 +47,7 @@ public class MessageViewModel extends ViewModel { | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public LiveData<PagedList<Message>> getMessages() { | ||||
|     public LiveData<PagedList<CommentInteraction>> getMessages() { | ||||
|         return messages; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -2,22 +2,38 @@ package eu.toldi.infinityforlemmy.message; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
|  | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.apis.RedditAPI; | ||||
| import eu.toldi.infinityforlemmy.utils.APIUtils; | ||||
| import eu.toldi.infinityforlemmy.apis.LemmyAPI; | ||||
| import eu.toldi.infinityforlemmy.dto.AuthDTO; | ||||
| import eu.toldi.infinityforlemmy.dto.ReadCommentDTO; | ||||
| import retrofit2.Call; | ||||
| import retrofit2.Callback; | ||||
| import retrofit2.Response; | ||||
| import retrofit2.Retrofit; | ||||
|  | ||||
| public class ReadMessage { | ||||
|     public static void readMessage(Retrofit oauthRetrofit, String accessToken, String commaSeparatedFullnames, | ||||
|     public static void readMessage(Retrofit oauthRetrofit, String accessToken, int messageId, | ||||
|                                    ReadMessageListener readMessageListener) { | ||||
|         Map<String, String> params = new HashMap<>(); | ||||
|         params.put(APIUtils.ID_KEY, commaSeparatedFullnames); | ||||
|         oauthRetrofit.create(RedditAPI.class).readMessage(APIUtils.getOAuthHeader(accessToken), params) | ||||
|         oauthRetrofit.create(LemmyAPI.class).commentMarkAsRead(new ReadCommentDTO(messageId, true, accessToken)) | ||||
|                 .enqueue(new Callback<String>() { | ||||
|                     @Override | ||||
|                     public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { | ||||
|                         if (response.isSuccessful()) { | ||||
|                             readMessageListener.readSuccess(); | ||||
|                         } else { | ||||
|                             readMessageListener.readFailed(); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     @Override | ||||
|                     public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { | ||||
|                         readMessageListener.readFailed(); | ||||
|                     } | ||||
|                 }); | ||||
|     } | ||||
|  | ||||
|     public static void readAllMessages(Retrofit retrofit, String accessToken, | ||||
|                                        ReadMessageListener readMessageListener) { | ||||
|         retrofit.create(LemmyAPI.class).userMarkAllAsRead(new AuthDTO(accessToken)) | ||||
|                 .enqueue(new Callback<String>() { | ||||
|                     @Override | ||||
|                     public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { | ||||
|   | ||||
| @@ -5,7 +5,6 @@ import static java.lang.Integer.max; | ||||
| import android.graphics.BitmapFactory; | ||||
| import android.net.Uri; | ||||
| import android.os.Handler; | ||||
| import android.os.StrictMode; | ||||
| import android.text.Html; | ||||
| import android.text.TextUtils; | ||||
| import android.util.Log; | ||||
| @@ -34,7 +33,6 @@ import java.util.concurrent.Executor; | ||||
| import java.util.regex.Matcher; | ||||
| import java.util.regex.Pattern; | ||||
|  | ||||
| import eu.toldi.infinityforlemmy.markdown.MarkdownUtils; | ||||
| import eu.toldi.infinityforlemmy.postfilter.PostFilter; | ||||
| import eu.toldi.infinityforlemmy.utils.JSONUtils; | ||||
| import eu.toldi.infinityforlemmy.utils.LemmyUtils; | ||||
| @@ -191,8 +189,8 @@ public class ParsePost { | ||||
|         ArrayList <Post.Preview> previews = new ArrayList<>(); | ||||
|         if(!post.isNull("thumbnail_url")) { | ||||
|             String thumbnail = post.getString("thumbnail_url"); | ||||
|             int[] wh_array = getImageDimension(thumbnail); | ||||
|             previews.add(new Post.Preview(thumbnail, wh_array[0], wh_array[1], "", "")); | ||||
|             //int[] wh_array = getImageDimension(thumbnail); | ||||
|             previews.add(new Post.Preview(thumbnail, 0, 0, "", "")); | ||||
|         } | ||||
|  | ||||
|  | ||||
| @@ -655,14 +653,6 @@ public class ParsePost { | ||||
|             post.setVoteType(data.getInt("my_vote")); | ||||
|             post.setScore(post.getScore() - 1); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         if (!data.getJSONObject("post").isNull("body")) { | ||||
|             String body = MarkdownUtils.processImageCaptions(data.getJSONObject("post").getString("body"), "Image"); | ||||
|             post.setSelfText(body); | ||||
|             post.setSelfTextPlain(body); | ||||
|             post.setSelfTextPlainTrimmed(body.trim()); | ||||
|         } | ||||
|         return post; | ||||
|     } | ||||
|  | ||||
| @@ -684,8 +674,7 @@ public class ParsePost { | ||||
|     } | ||||
|  | ||||
|     public static int[] getImageDimension(String imageUrl) { | ||||
|         StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); | ||||
|         StrictMode.setThreadPolicy(policy); //Permit all for simplicity. You may want to revise this for your actual app. | ||||
|  | ||||
|  | ||||
|         HttpURLConnection urlConnection = null; | ||||
|         try { | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| package eu.toldi.infinityforlemmy.post; | ||||
|  | ||||
| import android.graphics.Bitmap; | ||||
| import android.os.Parcel; | ||||
| import android.os.Parcelable; | ||||
|  | ||||
| @@ -624,6 +625,8 @@ public class Post implements Parcelable { | ||||
|         private String previewCaption; | ||||
|         private String previewCaptionUrl; | ||||
|  | ||||
|         private Bitmap previewBitmap; | ||||
|  | ||||
|         public Preview(String previewUrl, int previewWidth, int previewHeight, String previewCaption, String previewCaptionUrl) { | ||||
|             this.previewUrl = previewUrl; | ||||
|             this.previewWidth = previewWidth; | ||||
| @@ -638,6 +641,7 @@ public class Post implements Parcelable { | ||||
|             previewHeight = in.readInt(); | ||||
|             previewCaption = in.readString(); | ||||
|             previewCaptionUrl = in.readString(); | ||||
|             previewBitmap = in.readParcelable(Bitmap.class.getClassLoader()); | ||||
|         } | ||||
|  | ||||
|         public static final Creator<Preview> CREATOR = new Creator<Preview>() { | ||||
| @@ -686,13 +690,23 @@ public class Post implements Parcelable { | ||||
|             return previewCaptionUrl; | ||||
|         } | ||||
|  | ||||
|         public void setPreviewCaptionUrl(String previewCaptionUrl) { this.previewCaptionUrl = previewCaptionUrl; } | ||||
|         public void setPreviewCaptionUrl(String previewCaptionUrl) { | ||||
|             this.previewCaptionUrl = previewCaptionUrl; | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public int describeContents() { | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|         public Bitmap getPreviewBitmap() { | ||||
|             return previewBitmap; | ||||
|         } | ||||
|  | ||||
|         public void setPreviewBitmap(Bitmap previewBitmap) { | ||||
|             this.previewBitmap = previewBitmap; | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public void writeToParcel(Parcel parcel, int i) { | ||||
|             parcel.writeString(previewUrl); | ||||
| @@ -700,6 +714,7 @@ public class Post implements Parcelable { | ||||
|             parcel.writeInt(previewHeight); | ||||
|             parcel.writeString(previewCaption); | ||||
|             parcel.writeString(previewCaptionUrl); | ||||
|             parcel.writeParcelable(previewBitmap, i); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -12,6 +12,7 @@ import org.greenrobot.eventbus.EventBus; | ||||
| import eu.toldi.infinityforlemmy.R; | ||||
| import eu.toldi.infinityforlemmy.customviews.CustomFontPreferenceFragmentCompat; | ||||
| import eu.toldi.infinityforlemmy.events.ChangeHideFabInPostFeedEvent; | ||||
| import eu.toldi.infinityforlemmy.events.ChangeUseCircularFabEvent; | ||||
| import eu.toldi.infinityforlemmy.events.ChangeVoteButtonsPositionEvent; | ||||
| import eu.toldi.infinityforlemmy.events.RecreateActivityEvent; | ||||
| import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; | ||||
| @@ -23,6 +24,7 @@ public class InterfacePreferenceFragment extends CustomFontPreferenceFragmentCom | ||||
|  | ||||
|         Preference immersiveInterfaceEntryPreference = findPreference(SharedPreferencesUtils.IMMERSIVE_INTERFACE_ENTRY_KEY); | ||||
|         SwitchPreference hideFabInPostFeedSwitchPreference = findPreference(SharedPreferencesUtils.HIDE_FAB_IN_POST_FEED); | ||||
|         SwitchPreference useCircularFAbSwitchPreference = findPreference(SharedPreferencesUtils.USE_CIRCULAR_FAB); | ||||
|         SwitchPreference bottomAppBarSwitch = findPreference(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY); | ||||
|         SwitchPreference voteButtonsOnTheRightSwitch = findPreference(SharedPreferencesUtils.VOTE_BUTTONS_ON_THE_RIGHT_KEY); | ||||
|  | ||||
| @@ -37,6 +39,13 @@ public class InterfacePreferenceFragment extends CustomFontPreferenceFragmentCom | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         if (useCircularFAbSwitchPreference != null) { | ||||
|             useCircularFAbSwitchPreference.setOnPreferenceChangeListener((preference, newValue) -> { | ||||
|                 EventBus.getDefault().post(new ChangeUseCircularFabEvent((Boolean) newValue)); | ||||
|                 return true; | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         if (bottomAppBarSwitch != null) { | ||||
|             bottomAppBarSwitch.setOnPreferenceChangeListener((preference, newValue) -> { | ||||
|                 EventBus.getDefault().post(new RecreateActivityEvent()); | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import java.util.ArrayList; | ||||
| import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; | ||||
| import eu.toldi.infinityforlemmy.SortType; | ||||
| import eu.toldi.infinityforlemmy.apis.LemmyAPI; | ||||
| import eu.toldi.infinityforlemmy.message.MessageCount; | ||||
| import retrofit2.Call; | ||||
| import retrofit2.Callback; | ||||
| import retrofit2.Retrofit; | ||||
| @@ -85,6 +86,33 @@ public class FetchUserData { | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public static void fetchUnreadCount(Retrofit retrofit, String accessToken, FetchUserUnreadCountListener fetchUserUnreadCountListener) { | ||||
|         LemmyAPI api = retrofit.create(LemmyAPI.class); | ||||
|  | ||||
|         Call<MessageCount> userUnreadCount = api.userUnreadCount(accessToken); | ||||
|         userUnreadCount.enqueue(new Callback<>() { | ||||
|             @Override | ||||
|             public void onResponse(@NonNull Call<MessageCount> call, @NonNull retrofit2.Response<MessageCount> response) { | ||||
|                 if (response.isSuccessful() && response.body() != null) { | ||||
|                     fetchUserUnreadCountListener.onFetchUserUnreadCountSuccess(response.body().getSum()); | ||||
|                 } else { | ||||
|                     fetchUserUnreadCountListener.onFetchUserUnreadCountFailed(); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onFailure(@NonNull Call<MessageCount> call, @NonNull Throwable t) { | ||||
|                 fetchUserUnreadCountListener.onFetchUserUnreadCountFailed(); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public interface FetchUserUnreadCountListener { | ||||
|         void onFetchUserUnreadCountSuccess(int unreadCount); | ||||
|  | ||||
|         void onFetchUserUnreadCountFailed(); | ||||
|     } | ||||
|  | ||||
|     public interface FetchUserDataListener { | ||||
|         void onFetchUserDataSuccess(UserData userData, int inboxCount); | ||||
|  | ||||
|   | ||||
| @@ -46,6 +46,8 @@ public class SharedPreferencesUtils { | ||||
|     public static final String REDDIT_USER_AGREEMENT_KEY = "reddit_user_agreement"; | ||||
|     public static final String HIDE_FAB_IN_POST_FEED = "hide_fab_in_post_feed"; | ||||
|  | ||||
|     public static final String USE_CIRCULAR_FAB = "use_circular_fab"; | ||||
|  | ||||
|     public static final String SORT_TYPE_SHARED_PREFERENCES_FILE = "eu.toldi.infinityforlemmy.sort_type"; | ||||
|     public static final String SORT_TYPE_BEST_POST = "sort_type_best_post"; | ||||
|     public static final String SORT_TIME_BEST_POST = "sort_time_best_post"; | ||||
|   | ||||
| @@ -382,8 +382,8 @@ public final class Utils { | ||||
|                         int start = Math.max(editText.getSelectionStart(), 0); | ||||
|                         int end = Math.max(editText.getSelectionEnd(), 0); | ||||
|                         editText.getText().replace(Math.min(start, end), Math.max(start, end), | ||||
|                                 "[" + fileName + "](" + imageUrlOrError + ")", | ||||
|                                 0, "[]()".length() + fileName.length() + imageUrlOrError.length()); | ||||
|                                 "", | ||||
|                                 0, "![]()".length() + fileName.length() + imageUrlOrError.length()); | ||||
|                         Snackbar.make(coordinatorLayout, R.string.upload_image_success, Snackbar.LENGTH_LONG).show(); | ||||
|                     } else { | ||||
|                         Toast.makeText(context, R.string.upload_image_failed, Toast.LENGTH_LONG).show(); | ||||
|   | ||||
| @@ -49,10 +49,53 @@ | ||||
|                     android:textColor="?attr/primaryTextColor" | ||||
|                     android:fontFamily="?attr/title_font_family" /> | ||||
|  | ||||
|                 <View | ||||
|                     android:id="@+id/divider_edit_post_activity" | ||||
|                 <LinearLayout | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:orientation="vertical"> | ||||
|  | ||||
|                     <View | ||||
|                         android:id="@+id/divider_edit_post_activity" | ||||
|                         android:layout_width="match_parent" | ||||
|                         android:layout_height="1dp" /> | ||||
|  | ||||
|                     <EditText | ||||
|                         android:id="@+id/post_link_edit_text_post_edit_activity" | ||||
|                         android:layout_width="match_parent" | ||||
|                         android:layout_height="match_parent" | ||||
|                         android:background="#00000000" | ||||
|                         android:fontFamily="?attr/content_font_family" | ||||
|                         android:gravity="top" | ||||
|                         android:hint="@string/post_link_hint" | ||||
|                         android:inputType="textMultiLine" | ||||
|                         android:padding="16dp" | ||||
|                         android:textColor="?attr/primaryTextColor" | ||||
|                         android:textSize="?attr/content_font_18" /> | ||||
|                 </LinearLayout> | ||||
|  | ||||
|                 <com.google.android.material.button.MaterialButton | ||||
|                     android:id="@+id/upload_image_button_post_edit_activity" | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:layout_gravity="center_vertical" | ||||
|                     android:layout_marginStart="16dp" | ||||
|                     android:layout_marginEnd="16dp" | ||||
|                     android:fontFamily="?attr/font_family" | ||||
|                     android:text="@string/upload_image" | ||||
|                     android:textSize="?attr/font_default" /> | ||||
|  | ||||
|                 <ImageView | ||||
|                     android:id="@+id/image_view_post_edit_activity" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="1dp" /> | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:adjustViewBounds="true" | ||||
|                     android:scaleType="fitStart" | ||||
|                     android:visibility="gone" /> | ||||
|  | ||||
|                 <View | ||||
|                     android:id="@+id/divider2_edit_post_activity" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content" /> | ||||
|  | ||||
|                 <EditText | ||||
|                     android:id="@+id/post_text_content_edit_text_edit_post_activity" | ||||
|   | ||||
| @@ -1343,4 +1343,8 @@ | ||||
|     <string name="url_cannot_be_null_or_empty">URL cannot be null or empty</string> | ||||
|     <string name="could_not_resolve_link">Could not resolve URL :(</string> | ||||
|     <string name="mark_post_as_read_failed">Failed to mark post as read</string> | ||||
|     <string name="upload_image">Upload an image</string> | ||||
|     <string name="mentions">Mentions</string> | ||||
|     <string name="replies">Replies</string> | ||||
|     <string name="use_circular_fab">Use Circular FAB</string> | ||||
| </resources> | ||||
|   | ||||
| @@ -29,6 +29,11 @@ | ||||
|         app:key="hide_fab_in_post_feed" | ||||
|         app:title="@string/settings_hide_fab_in_post_feed" /> | ||||
|  | ||||
|     <eu.toldi.infinityforlemmy.customviews.CustomFontSwitchPreference | ||||
|         app:defaultValue="false" | ||||
|         app:key="use_circular_fab" | ||||
|         app:title="@string/use_circular_fab" /> | ||||
|  | ||||
|     <eu.toldi.infinityforlemmy.customviews.CustomFontSwitchPreference | ||||
|         app:defaultValue="false" | ||||
|         app:key="bottom_app_bar" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user