From 1e67b34440dbaa3549157c3023baad1b19fbd32a Mon Sep 17 00:00:00 2001 From: Angelo Suzuki <1063155+tinsukE@users.noreply.github.com> Date: Thu, 7 Sep 2023 13:01:28 +0200 Subject: [PATCH] Add previews to RedGIFs posts - Setup Glide with OkHttp in the custom application - Add PostEnricher framework, that allows to add more data to fetched Posts. This was used to fetch the RedGIFs preview from their API. --- app/build.gradle | 1 + .../toldi/infinityforlemmy/AppComponent.java | 2 +- .../eu/toldi/infinityforlemmy/Infinity.java | 26 +++++++-- .../infinityforlemmy/PostEnricherModule.java | 26 +++++++++ .../activities/LinkResolverActivity.java | 6 +- .../activities/ViewPostDetailActivity.java | 7 ++- .../activities/ViewVideoActivity.java | 6 +- .../infinityforlemmy/apis/RedgifsAPI.java | 4 ++ .../fragments/HistoryPostFragment.java | 18 +++--- .../fragments/PostFragment.java | 30 ++++++---- .../fragments/ViewPostDetailFragment.java | 7 ++- .../infinityforlemmy/post/FetchPost.java | 5 +- .../post/HistoryPostPagingSource.java | 7 ++- .../post/HistoryPostViewModel.java | 36 +++++------- .../infinityforlemmy/post/ParsePost.java | 23 +++----- .../post/PostPagingSource.java | 19 +++++-- .../infinityforlemmy/post/PostViewModel.java | 52 +++++++++++------ .../infinityforlemmy/post/SubmitPost.java | 24 ++++---- .../services/SubmitPostService.java | 10 +++- .../infinityforlemmy/utils/JSONUtils.java | 1 + .../post/enrich/CompositePostEnricher.kt | 11 ++++ .../post/enrich/PostEnricher.kt | 7 +++ .../post/enrich/RedGifsPostEnricher.kt | 56 +++++++++++++++++++ 23 files changed, 272 insertions(+), 112 deletions(-) create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/PostEnricherModule.java create mode 100644 app/src/main/kotlin/eu/toldi/infinityforlemmy/post/enrich/CompositePostEnricher.kt create mode 100644 app/src/main/kotlin/eu/toldi/infinityforlemmy/post/enrich/PostEnricher.kt create mode 100644 app/src/main/kotlin/eu/toldi/infinityforlemmy/post/enrich/RedGifsPostEnricher.kt diff --git a/app/build.gradle b/app/build.gradle index 18abf111..c9d7175e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -196,6 +196,7 @@ dependencies { def glideVersion = "4.12.0" implementation "com.github.bumptech.glide:glide:$glideVersion" annotationProcessor "com.github.bumptech.glide:compiler:$glideVersion" + implementation "com.github.bumptech.glide:okhttp-integration:$glideVersion" implementation 'jp.wasabeef:glide-transformations:4.3.0' implementation 'com.github.santalu:aspect-ratio-imageview:1.0.9' implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.23' diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/AppComponent.java b/app/src/main/java/eu/toldi/infinityforlemmy/AppComponent.java index 15e94c51..7997aaf3 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/AppComponent.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/AppComponent.java @@ -113,7 +113,7 @@ import eu.toldi.infinityforlemmy.settings.TranslationFragment; import eu.toldi.infinityforlemmy.settings.VideoPreferenceFragment; @Singleton -@Component(modules = {AppModule.class, NetworkModule.class}) +@Component(modules = {AppModule.class, NetworkModule.class, PostEnricherModule.class}) public interface AppComponent { void inject(MainActivity mainActivity); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/Infinity.java b/app/src/main/java/eu/toldi/infinityforlemmy/Infinity.java index 52566422..3d535b7f 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/Infinity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/Infinity.java @@ -11,6 +11,16 @@ import android.os.Bundle; import android.view.WindowManager; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleObserver; +import androidx.lifecycle.OnLifecycleEvent; +import androidx.lifecycle.ProcessLifecycleOwner; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader; +import com.bumptech.glide.load.model.GlideUrl; import com.evernote.android.state.StateSaver; import com.livefront.bridge.Bridge; import com.livefront.bridge.SavedStateHandler; @@ -18,15 +28,11 @@ import com.livefront.bridge.SavedStateHandler; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; +import java.io.InputStream; + import javax.inject.Inject; import javax.inject.Named; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.lifecycle.Lifecycle; -import androidx.lifecycle.LifecycleObserver; -import androidx.lifecycle.OnLifecycleEvent; -import androidx.lifecycle.ProcessLifecycleOwner; import eu.toldi.infinityforlemmy.activities.LockScreenActivity; import eu.toldi.infinityforlemmy.broadcastreceivers.NetworkWifiStatusReceiver; import eu.toldi.infinityforlemmy.broadcastreceivers.WallpaperChangeReceiver; @@ -38,6 +44,8 @@ import eu.toldi.infinityforlemmy.font.FontFamily; import eu.toldi.infinityforlemmy.font.TitleFontFamily; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; import eu.toldi.infinityforlemmy.utils.Utils; +import okhttp3.Call; +import okhttp3.OkHttpClient; public class Infinity extends Application implements LifecycleObserver { public Typeface typeface; @@ -55,6 +63,9 @@ public class Infinity extends Application implements LifecycleObserver { @Inject @Named("security") SharedPreferences mSecuritySharedPreferences; + @Inject + @Named("glide") + OkHttpClient glideOkHttpClient; @Override public void onCreate() { @@ -159,6 +170,9 @@ public class Infinity extends Application implements LifecycleObserver { registerReceiver(mNetworkWifiStatusReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); registerReceiver(new WallpaperChangeReceiver(mSharedPreferences), new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED)); + + OkHttpUrlLoader.Factory factory = new OkHttpUrlLoader.Factory((Call.Factory) glideOkHttpClient); + Glide.get(this).getRegistry().replace(GlideUrl.class, InputStream.class, factory); } @OnLifecycleEvent(Lifecycle.Event.ON_START) diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/PostEnricherModule.java b/app/src/main/java/eu/toldi/infinityforlemmy/PostEnricherModule.java new file mode 100644 index 00000000..b0668ace --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/PostEnricherModule.java @@ -0,0 +1,26 @@ +package eu.toldi.infinityforlemmy; + +import java.util.Set; + +import dagger.Module; +import dagger.Provides; +import dagger.multibindings.IntoSet; +import eu.toldi.infinityforlemmy.apis.RedgifsAPI; +import eu.toldi.infinityforlemmy.post.enrich.CompositePostEnricher; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; +import eu.toldi.infinityforlemmy.post.enrich.RedGifsPostEnricher; + +@Module +abstract class PostEnricherModule { + + @Provides + @IntoSet + static PostEnricher provideRedGifsPostEnricher(RedgifsAPI redgifsAPI) { + return new RedGifsPostEnricher(redgifsAPI); + } + + @Provides + static PostEnricher providePostEnricher(Set postEnrichers) { + return new CompositePostEnricher(postEnrichers); + } +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/LinkResolverActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/LinkResolverActivity.java index 54ade1b1..46581560 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/LinkResolverActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/LinkResolverActivity.java @@ -36,6 +36,7 @@ import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; import eu.toldi.infinityforlemmy.post.FetchPost; import eu.toldi.infinityforlemmy.post.ObjectResolver; import eu.toldi.infinityforlemmy.post.Post; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; import eu.toldi.infinityforlemmy.utils.LemmyUtils; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; @@ -83,6 +84,9 @@ public class LinkResolverActivity extends AppCompatActivity { @Inject Executor mExecutor; + @Inject + PostEnricher postEnricher; + private String mAccessToken; private Uri getRedditUriByPath(String path) { @@ -214,7 +218,7 @@ public class LinkResolverActivity extends AppCompatActivity { URL baseURL = new URL(mRetrofit.getBaseURL()); if (baseURL.getHost().equalsIgnoreCase(uri.getHost())) { local = true; - FetchPost.fetchPost(mExecutor, new Handler(), mRetrofit.getRetrofit(), segments.get(segments.size() - 1), mAccessToken, new FetchPost.FetchPostListener() { + FetchPost.fetchPost(mExecutor, new Handler(), mRetrofit.getRetrofit(), segments.get(segments.size() - 1), mAccessToken, postEnricher, new FetchPost.FetchPostListener() { @Override public void fetchPostSuccess(Post post) { diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewPostDetailActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewPostDetailActivity.java index f46a5e6a..8453a8b6 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewPostDetailActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewPostDetailActivity.java @@ -81,6 +81,7 @@ import eu.toldi.infinityforlemmy.post.HistoryPostPagingSource; import eu.toldi.infinityforlemmy.post.ParsePost; import eu.toldi.infinityforlemmy.post.Post; import eu.toldi.infinityforlemmy.post.PostPagingSource; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; import eu.toldi.infinityforlemmy.postfilter.PostFilter; import eu.toldi.infinityforlemmy.readpost.ReadPost; import eu.toldi.infinityforlemmy.utils.APIUtils; @@ -151,6 +152,8 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele @Inject @Named("glide") OkHttpClient okHttpClient; + @Inject + PostEnricher postEnricher; @State ArrayList posts; @State @@ -592,7 +595,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele Response response = call.execute(); if (response.isSuccessful()) { String responseString = response.body(); - LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostList); + LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostList, postEnricher); if (newPosts == null) { handler.post(() -> { loadingMorePostsStatus = LoadingMorePostsStatus.NO_MORE_POSTS; @@ -674,7 +677,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele Response response = historyPosts.execute(); if (response.isSuccessful()) { String responseString = response.body(); - LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, null); + LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, null, postEnricher); if (newPosts == null || newPosts.isEmpty()) { handler.post(() -> { loadingMorePostsStatus = LoadingMorePostsStatus.NO_MORE_POSTS; diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewVideoActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewVideoActivity.java index c1662b8d..59192ae5 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewVideoActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewVideoActivity.java @@ -108,6 +108,7 @@ import eu.toldi.infinityforlemmy.font.TitleFontFamily; import eu.toldi.infinityforlemmy.font.TitleFontStyle; import eu.toldi.infinityforlemmy.post.FetchPost; import eu.toldi.infinityforlemmy.post.Post; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; import eu.toldi.infinityforlemmy.services.DownloadMediaService; import eu.toldi.infinityforlemmy.services.DownloadRedditVideoService; import eu.toldi.infinityforlemmy.utils.APIUtils; @@ -231,6 +232,9 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe @Inject SimpleCache mSimpleCache; + @Inject + PostEnricher postEnricher; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -787,7 +791,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe int commentsIndex = segments.lastIndexOf("comments"); String postId = segments.get(commentsIndex + 1); FetchPost.fetchPost(mExecutor, new Handler(), retrofit.getRetrofit(), postId, null, - new FetchPost.FetchPostListener() { + postEnricher, new FetchPost.FetchPostListener() { @Override public void fetchPostSuccess(Post post) { if (post.isGfycat()) { diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/apis/RedgifsAPI.java b/app/src/main/java/eu/toldi/infinityforlemmy/apis/RedgifsAPI.java index f44e7f66..738740ae 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/apis/RedgifsAPI.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/apis/RedgifsAPI.java @@ -8,11 +8,15 @@ import retrofit2.http.FormUrlEncoded; import retrofit2.http.GET; import retrofit2.http.POST; import retrofit2.http.Path; +import retrofit2.http.Query; public interface RedgifsAPI { @GET("/v2/gifs/{id}") Call getRedgifsData(@Path("id") String id); + @GET("/v2/gifs") + Call getRedgifsMultipleData(@Query("ids") String ids); + @FormUrlEncoded @POST("/v2/oauth/client") Call getRedgifsAccessToken(@FieldMap Map params); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/HistoryPostFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/HistoryPostFragment.java index b9f33e1e..2645d6d6 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/HistoryPostFragment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/HistoryPostFragment.java @@ -124,6 +124,7 @@ import eu.toldi.infinityforlemmy.events.ShowThumbnailOnTheRightInCompactLayoutEv import eu.toldi.infinityforlemmy.post.HistoryPostPagingSource; import eu.toldi.infinityforlemmy.post.HistoryPostViewModel; import eu.toldi.infinityforlemmy.post.Post; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; import eu.toldi.infinityforlemmy.postfilter.PostFilter; import eu.toldi.infinityforlemmy.postfilter.PostFilterUsage; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; @@ -195,6 +196,8 @@ public class HistoryPostFragment extends Fragment implements FragmentCommunicato ExoCreator mExoCreator; @Inject Executor mExecutor; + @Inject + PostEnricher postEnricher; private RequestManager mGlide; private BaseActivity activity; private LinearLayoutManagerBugFixed mLinearLayoutManager; @@ -651,15 +654,10 @@ public class HistoryPostFragment extends Fragment implements FragmentCommunicato } private void initializeAndBindPostViewModel(String accessToken) { - if (postType == HistoryPostPagingSource.TYPE_READ_POSTS) { - mHistoryPostViewModel = new ViewModelProvider(HistoryPostFragment.this, new HistoryPostViewModel.Factory(mExecutor, - accessToken == null ? mRetrofit.getRetrofit() : mOauthRetrofit, mRedditDataRoomDatabase, accessToken, - accountName, mSharedPreferences, HistoryPostPagingSource.TYPE_READ_POSTS, postFilter)).get(HistoryPostViewModel.class); - } else { - mHistoryPostViewModel = new ViewModelProvider(HistoryPostFragment.this, new HistoryPostViewModel.Factory(mExecutor, - accessToken == null ? mRetrofit.getRetrofit() : mOauthRetrofit, mRedditDataRoomDatabase, accessToken, - accountName, mSharedPreferences, HistoryPostPagingSource.TYPE_READ_POSTS, postFilter)).get(HistoryPostViewModel.class); - } + mHistoryPostViewModel = new ViewModelProvider(HistoryPostFragment.this, new HistoryPostViewModel.Factory(mExecutor, + accessToken == null ? mRetrofit.getRetrofit() : mOauthRetrofit, mRedditDataRoomDatabase, accessToken, + accountName, mSharedPreferences, HistoryPostPagingSource.TYPE_READ_POSTS, postFilter, postEnricher)) + .get(HistoryPostViewModel.class); bindPostViewModel(); } @@ -1444,4 +1442,4 @@ public class HistoryPostFragment extends Fragment implements FragmentCommunicato public interface LoadIconListener { void loadIconSuccess(String subredditOrUserName, String iconUrl); } -} \ No newline at end of file +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/PostFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/PostFragment.java index 54eaf05e..f0c581a8 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/PostFragment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/PostFragment.java @@ -135,6 +135,7 @@ import eu.toldi.infinityforlemmy.events.ShowThumbnailOnTheRightInCompactLayoutEv import eu.toldi.infinityforlemmy.post.Post; import eu.toldi.infinityforlemmy.post.PostPagingSource; import eu.toldi.infinityforlemmy.post.PostViewModel; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; import eu.toldi.infinityforlemmy.postfilter.PostFilter; import eu.toldi.infinityforlemmy.postfilter.PostFilterUsage; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; @@ -222,6 +223,8 @@ public class PostFragment extends Fragment implements FragmentCommunicator { ExoCreator mExoCreator; @Inject Executor mExecutor; + @Inject + PostEnricher postEnricher; private RequestManager mGlide; private BaseActivity activity; private LinearLayoutManagerBugFixed mLinearLayoutManager; @@ -1221,30 +1224,36 @@ public class PostFragment extends Fragment implements FragmentCommunicator { mRetrofit, accessToken, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, mPostHistorySharedPreferences, subredditName, - query, trendingSource, postType, sortType, postFilter, readPosts)).get(PostViewModel.class); + query, trendingSource, postType, sortType, postFilter, readPosts, postEnricher)) + .get(PostViewModel.class); } else if (postType == PostPagingSource.TYPE_SUBREDDIT) { mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, mRetrofit, accessToken, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, - mPostHistorySharedPreferences, subredditName, postType, sortType, postFilter, readPosts)) + mPostHistorySharedPreferences, subredditName, postType, sortType, postFilter, readPosts, + postEnricher)) .get(PostViewModel.class); } else if (postType == PostPagingSource.TYPE_MULTI_REDDIT) { mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, mRetrofit, accessToken, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, - mPostHistorySharedPreferences, multiRedditPath, postType, sortType, postFilter, readPosts)) + mPostHistorySharedPreferences, multiRedditPath, postType, sortType, postFilter, readPosts, + postEnricher)) .get(PostViewModel.class); } else if (postType == PostPagingSource.TYPE_USER) { mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, mRetrofit, accessToken, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, - mPostHistorySharedPreferences, username, postType, sortType, postFilter, where, readPosts)) + mPostHistorySharedPreferences, username, postType, sortType, postFilter, where, readPosts, + postEnricher)) .get(PostViewModel.class); } else { mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, mRetrofit, accessToken, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, - mPostHistorySharedPreferences, postType, sortType, postFilter, readPosts, subredditName)).get(PostViewModel.class); + mPostHistorySharedPreferences, postType, sortType, postFilter, readPosts, subredditName, + postEnricher)) + .get(PostViewModel.class); } bindPostViewModel(); @@ -1256,26 +1265,27 @@ public class PostFragment extends Fragment implements FragmentCommunicator { mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, mRetrofit, null, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, null, subredditName, query, trendingSource, - postType, sortType, postFilter, readPosts)).get(PostViewModel.class); + postType, sortType, postFilter, readPosts, postEnricher)).get(PostViewModel.class); } else if (postType == PostPagingSource.TYPE_SUBREDDIT) { mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(mExecutor, mRetrofit, null, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, null, subredditName, postType, sortType, - postFilter, readPosts)).get(PostViewModel.class); + postFilter, readPosts, postEnricher)).get(PostViewModel.class); } else if (postType == PostPagingSource.TYPE_MULTI_REDDIT) { mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, mRetrofit, null, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, null, multiRedditPath, - postType, sortType, postFilter, readPosts)).get(PostViewModel.class); + postType, sortType, postFilter, readPosts, postEnricher)).get(PostViewModel.class); } else if (postType == PostPagingSource.TYPE_USER) { mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, mRetrofit, null, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, null, username, postType, sortType, postFilter, - where, readPosts)).get(PostViewModel.class); + where, readPosts, postEnricher)).get(PostViewModel.class); } else { //Anonymous Front Page mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, - mRetrofit, mSharedPreferences, concatenatedSubredditNames, postType, sortType, postFilter, subredditName)) + mRetrofit, mSharedPreferences, concatenatedSubredditNames, postType, sortType, postFilter, subredditName, + postEnricher)) .get(PostViewModel.class); } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewPostDetailFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewPostDetailFragment.java index 063f67c7..acb46d21 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewPostDetailFragment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/ViewPostDetailFragment.java @@ -112,6 +112,7 @@ import eu.toldi.infinityforlemmy.post.HidePost; import eu.toldi.infinityforlemmy.post.LemmyPostAPI; import eu.toldi.infinityforlemmy.post.MarkPostAsRead; import eu.toldi.infinityforlemmy.post.Post; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; import eu.toldi.infinityforlemmy.readpost.InsertReadPost; import eu.toldi.infinityforlemmy.subreddit.FetchSubredditData; import eu.toldi.infinityforlemmy.subreddit.SubredditData; @@ -200,6 +201,8 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic MarkPostAsRead markPostAsRead; @Inject LemmyPostAPI mLemmyPostAPI; + @Inject + PostEnricher postEnricher; @State Post mPost; @State @@ -1329,7 +1332,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic mSwipeRefreshLayout.setRefreshing(true); mGlide.clear(mFetchPostInfoImageView); FetchPost.fetchPost(mExecutor, new Handler(), mRetrofit.getRetrofit(), String.valueOf(subredditId), mAccessToken, - new FetchPost.FetchPostListener() { + postEnricher, new FetchPost.FetchPostListener() { @Override public void fetchPostSuccess(Post post) { if (!isAdded()) { @@ -1588,7 +1591,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic Retrofit retrofit = mRetrofit.getRetrofit(); FetchPost.fetchPost(mExecutor, new Handler(), retrofit, String.valueOf(mPost.getId()), mAccessToken, - new FetchPost.FetchPostListener() { + postEnricher, new FetchPost.FetchPostListener() { @Override public void fetchPostSuccess(Post post) { if (isAdded()) { diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/post/FetchPost.java b/app/src/main/java/eu/toldi/infinityforlemmy/post/FetchPost.java index dd449c07..d4e802d5 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/post/FetchPost.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/post/FetchPost.java @@ -8,6 +8,7 @@ import java.util.concurrent.Executor; import eu.toldi.infinityforlemmy.apis.LemmyAPI; import eu.toldi.infinityforlemmy.apis.RedditAPI; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -15,7 +16,7 @@ import retrofit2.Retrofit; public class FetchPost { public static void fetchPost(Executor executor, Handler handler, Retrofit retrofit, String id, String accessToken, - FetchPostListener fetchPostListener) { + PostEnricher postEnricher, FetchPostListener fetchPostListener) { Call postCall; // Use LemmyAPI.postInfo() instead of RedditAPI.getPost() postCall = retrofit.create(LemmyAPI.class).postInfo(Integer.parseInt(id), null, accessToken); @@ -24,7 +25,7 @@ public class FetchPost { @Override public void onResponse(@NonNull Call call, @NonNull Response response) { if (response.isSuccessful()) { - ParsePost.parsePost(executor, handler, response.body(), new ParsePost.ParsePostListener() { + ParsePost.parsePost(executor, handler, postEnricher, response.body(), new ParsePost.ParsePostListener() { @Override public void onParsePostSuccess(Post post) { fetchPostListener.fetchPostSuccess(post); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/post/HistoryPostPagingSource.java b/app/src/main/java/eu/toldi/infinityforlemmy/post/HistoryPostPagingSource.java index 3f2eb528..f9adca86 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/post/HistoryPostPagingSource.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/post/HistoryPostPagingSource.java @@ -19,6 +19,7 @@ import java.util.concurrent.Executor; import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; import eu.toldi.infinityforlemmy.apis.RedditAPI; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; import eu.toldi.infinityforlemmy.postfilter.PostFilter; import eu.toldi.infinityforlemmy.readpost.ReadPost; import eu.toldi.infinityforlemmy.utils.APIUtils; @@ -39,10 +40,11 @@ public class HistoryPostPagingSource extends ListenableFuturePagingSource response = historyPosts.execute(); if (response.isSuccessful()) { String responseString = response.body(); - LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, null); + LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, null, postEnricher); if (newPosts == null) { return new LoadResult.Error<>(new Exception("Error parsing posts")); } else { diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/post/HistoryPostViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/post/HistoryPostViewModel.java index b0d31faa..96188fb8 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/post/HistoryPostViewModel.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/post/HistoryPostViewModel.java @@ -17,6 +17,7 @@ import androidx.paging.PagingLiveData; import java.util.concurrent.Executor; import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; import eu.toldi.infinityforlemmy.postfilter.PostFilter; import retrofit2.Retrofit; @@ -29,6 +30,7 @@ public class HistoryPostViewModel extends ViewModel { private SharedPreferences sharedPreferences; private int postType; private PostFilter postFilter; + private PostEnricher postEnricher; private LiveData> posts; @@ -36,7 +38,7 @@ public class HistoryPostViewModel extends ViewModel { public HistoryPostViewModel(Executor executor, Retrofit retrofit, RedditDataRoomDatabase redditDataRoomDatabase, String accessToken, String accountName, SharedPreferences sharedPreferences, - int postType, PostFilter postFilter) { + int postType, PostFilter postFilter, PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.redditDataRoomDatabase = redditDataRoomDatabase; @@ -45,11 +47,12 @@ public class HistoryPostViewModel extends ViewModel { this.sharedPreferences = sharedPreferences; this.postType = postType; this.postFilter = postFilter; + this.postEnricher = postEnricher; postFilterLiveData = new MutableLiveData<>(); postFilterLiveData.postValue(postFilter); - Pager pager = new Pager<>(new PagingConfig(25, 25, false), this::returnPagingSoruce); + Pager pager = new Pager<>(new PagingConfig(25, 25, false), this::returnPagingSource); posts = Transformations.switchMap(postFilterLiveData, postFilterValue -> PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager), ViewModelKt.getViewModelScope(this))); } @@ -58,19 +61,9 @@ public class HistoryPostViewModel extends ViewModel { return posts; } - public HistoryPostPagingSource returnPagingSoruce() { - HistoryPostPagingSource paging3PagingSource; - switch (postType) { - case HistoryPostPagingSource.TYPE_READ_POSTS: - paging3PagingSource = new HistoryPostPagingSource(retrofit, executor, redditDataRoomDatabase, accessToken, accountName, - sharedPreferences, accountName, postType, postFilter); - break; - default: - paging3PagingSource = new HistoryPostPagingSource(retrofit, executor, redditDataRoomDatabase, accessToken, accountName, - sharedPreferences, accountName, postType, postFilter); - break; - } - return paging3PagingSource; + public HistoryPostPagingSource returnPagingSource() { + return new HistoryPostPagingSource(retrofit, executor, redditDataRoomDatabase, accessToken, accountName, + sharedPreferences, accountName, postType, postFilter, postEnricher); } public void changePostFilter(PostFilter postFilter) { @@ -86,10 +79,11 @@ public class HistoryPostViewModel extends ViewModel { private SharedPreferences sharedPreferences; private int postType; private PostFilter postFilter; + private PostEnricher postEnricher; public Factory(Executor executor, Retrofit retrofit, RedditDataRoomDatabase redditDataRoomDatabase, String accessToken, String accountName, SharedPreferences sharedPreferences, int postType, - PostFilter postFilter) { + PostFilter postFilter, PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.redditDataRoomDatabase = redditDataRoomDatabase; @@ -98,18 +92,14 @@ public class HistoryPostViewModel extends ViewModel { this.sharedPreferences = sharedPreferences; this.postType = postType; this.postFilter = postFilter; + this.postEnricher = postEnricher; } @NonNull @Override public T create(@NonNull Class modelClass) { - if (postType == HistoryPostPagingSource.TYPE_READ_POSTS) { - return (T) new HistoryPostViewModel(executor, retrofit, redditDataRoomDatabase, accessToken, accountName, sharedPreferences, - postType, postFilter); - } else { - return (T) new HistoryPostViewModel(executor, retrofit, redditDataRoomDatabase, accessToken, accountName, sharedPreferences, - postType, postFilter); - } + return (T) new HistoryPostViewModel(executor, retrofit, redditDataRoomDatabase, accessToken, accountName, sharedPreferences, + postType, postFilter, postEnricher); } } } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/post/ParsePost.java b/app/src/main/java/eu/toldi/infinityforlemmy/post/ParsePost.java index 7c46ec93..e2fa9566 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/post/ParsePost.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/post/ParsePost.java @@ -34,6 +34,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import eu.toldi.infinityforlemmy.community.BasicCommunityInfo; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; import eu.toldi.infinityforlemmy.postfilter.PostFilter; import eu.toldi.infinityforlemmy.user.BasicUserInfo; import eu.toldi.infinityforlemmy.utils.JSONUtils; @@ -45,7 +46,8 @@ import eu.toldi.infinityforlemmy.utils.Utils; */ public class ParsePost { - public static LinkedHashSet parsePostsSync(String response, int nPosts, PostFilter postFilter, List readPostList) { + public static LinkedHashSet parsePostsSync(String response, int nPosts, PostFilter postFilter, + List readPostList, PostEnricher postEnricher) { LinkedHashSet newPosts = new LinkedHashSet<>(); try { JSONObject jsonResponse = new JSONObject(response); @@ -80,6 +82,8 @@ public class ParsePost { } } + postEnricher.enrich(newPosts); + return newPosts; } catch (JSONException e) { e.printStackTrace(); @@ -87,21 +91,9 @@ public class ParsePost { } } - public static String getLastItem(String response) { - try { - JSONObject object = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY); - return object.isNull(JSONUtils.AFTER_KEY) ? null : object.getString(JSONUtils.AFTER_KEY); - } catch (JSONException e) { - e.printStackTrace(); - return null; - } - } - - - public static void parsePost(Executor executor, Handler handler, String response, ParsePostListener parsePostListener) { - PostFilter postFilter = new PostFilter(); - postFilter.allowNSFW = true; + public static void parsePost(Executor executor, Handler handler, PostEnricher postEnricher, + String response, ParsePostListener parsePostListener) { executor.execute(() -> { try { JSONObject allData = new JSONObject(response).getJSONObject("post_view"); @@ -111,6 +103,7 @@ public class ParsePost { } Post post = parseBasicData(allData); + postEnricher.enrich(List.of(post)); handler.post(() -> parsePostListener.onParsePostSuccess(post)); } catch (JSONException e) { e.printStackTrace(); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/post/PostPagingSource.java b/app/src/main/java/eu/toldi/infinityforlemmy/post/PostPagingSource.java index 711dfc96..7d66d585 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/post/PostPagingSource.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/post/PostPagingSource.java @@ -21,6 +21,7 @@ import java.util.concurrent.Executor; import eu.toldi.infinityforlemmy.RetrofitHolder; import eu.toldi.infinityforlemmy.SortType; import eu.toldi.infinityforlemmy.apis.LemmyAPI; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; import eu.toldi.infinityforlemmy.postfilter.PostFilter; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; import retrofit2.HttpException; @@ -57,6 +58,7 @@ public class PostPagingSource extends ListenableFuturePagingSource readPostList; private String userWhere; private String multiRedditPath; + private final PostEnricher postEnricher; private LinkedHashSet postLinkedHashSet; private int page = 1; @@ -64,7 +66,8 @@ public class PostPagingSource extends ListenableFuturePagingSource readPostList, String option) { + SortType sortType, PostFilter postFilter, List readPostList, String option, + PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -76,13 +79,14 @@ public class PostPagingSource extends ListenableFuturePagingSource(); } PostPagingSource(Executor executor, RetrofitHolder retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String path, int postType, SortType sortType, PostFilter postFilter, - List readPostList) { + List readPostList, PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -114,13 +118,14 @@ public class PostPagingSource extends ListenableFuturePagingSource(); } PostPagingSource(Executor executor, RetrofitHolder retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditOrUserName, int postType, SortType sortType, PostFilter postFilter, - String where, List readPostList) { + String where, List readPostList, PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -133,13 +138,14 @@ public class PostPagingSource extends ListenableFuturePagingSource(); } PostPagingSource(Executor executor, RetrofitHolder retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditOrUserName, String query, String trendingSource, int postType, - SortType sortType, PostFilter postFilter, List readPostList) { + SortType sortType, PostFilter postFilter, List readPostList, PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -152,8 +158,9 @@ public class PostPagingSource extends ListenableFuturePagingSource(); this.readPostList = readPostList; + this.postEnricher = postEnricher; + postLinkedHashSet = new LinkedHashSet<>(); } @Nullable @@ -190,7 +197,7 @@ public class PostPagingSource extends ListenableFuturePagingSource transformData(Response response) { if (response.isSuccessful()) { String responseString = response.body(); - LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostList); + LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostList, postEnricher); if (newPosts == null) { return new LoadResult.Error<>(new Exception("Error parsing posts")); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/post/PostViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/post/PostViewModel.java index a29e80c4..cf8106fa 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/post/PostViewModel.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/post/PostViewModel.java @@ -23,6 +23,7 @@ import java.util.concurrent.Executor; import eu.toldi.infinityforlemmy.RetrofitHolder; import eu.toldi.infinityforlemmy.SortType; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; import eu.toldi.infinityforlemmy.postfilter.PostFilter; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; @@ -41,6 +42,7 @@ public class PostViewModel extends ViewModel { private PostFilter postFilter; private String userWhere; private List readPostList; + private PostEnricher postEnricher; private MutableLiveData currentlyReadPostIdsLiveData = new MutableLiveData<>(); private LiveData> posts; @@ -53,7 +55,7 @@ public class PostViewModel extends ViewModel { public PostViewModel(Executor executor, RetrofitHolder retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, @Nullable SharedPreferences postHistorySharedPreferences, int postType, - SortType sortType, PostFilter postFilter, List readPostList, String option) { + SortType sortType, PostFilter postFilter, List readPostList, String option, PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -65,6 +67,7 @@ public class PostViewModel extends ViewModel { this.postFilter = postFilter; this.readPostList = readPostList; this.name = option; + this.postEnricher = postEnricher; sortTypeLiveData = new MutableLiveData<>(); sortTypeLiveData.postValue(sortType); @@ -95,7 +98,7 @@ public class PostViewModel extends ViewModel { public PostViewModel(Executor executor, RetrofitHolder retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, @Nullable SharedPreferences postHistorySharedPreferences, String subredditName, int postType, - SortType sortType, PostFilter postFilter, List readPostList) { + SortType sortType, PostFilter postFilter, List readPostList, PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -107,6 +110,7 @@ public class PostViewModel extends ViewModel { this.postFilter = postFilter; this.readPostList = readPostList; this.name = subredditName; + this.postEnricher = postEnricher; sortTypeLiveData = new MutableLiveData<>(); sortTypeLiveData.postValue(sortType); @@ -139,7 +143,7 @@ public class PostViewModel extends ViewModel { SharedPreferences postFeedScrolledPositionSharedPreferences, @Nullable SharedPreferences postHistorySharedPreferences, String username, int postType, SortType sortType, PostFilter postFilter, String userWhere, - List readPostList) { + List readPostList, PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -152,6 +156,7 @@ public class PostViewModel extends ViewModel { this.readPostList = readPostList; this.name = username; this.userWhere = userWhere; + this.postEnricher = postEnricher; sortTypeLiveData = new MutableLiveData<>(); sortTypeLiveData.postValue(sortType); @@ -183,7 +188,7 @@ public class PostViewModel extends ViewModel { SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, @Nullable SharedPreferences postHistorySharedPreferences, String subredditName, String query, String trendingSource, int postType, SortType sortType, PostFilter postFilter, - List readPostList) { + List readPostList, PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -197,6 +202,7 @@ public class PostViewModel extends ViewModel { this.name = subredditName; this.query = query; this.trendingSource = trendingSource; + this.postEnricher = postEnricher; sortTypeLiveData = new MutableLiveData<>(); sortTypeLiveData.postValue(sortType); @@ -238,25 +244,25 @@ public class PostViewModel extends ViewModel { case PostPagingSource.TYPE_FRONT_PAGE: paging3PagingSource = new PostPagingSource(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, postType, sortType, - postFilter, readPostList,name); + postFilter, readPostList, name, postEnricher); break; case PostPagingSource.TYPE_SUBREDDIT: case PostPagingSource.TYPE_MULTI_REDDIT: case PostPagingSource.TYPE_ANONYMOUS_FRONT_PAGE: paging3PagingSource = new PostPagingSource(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, name, postType, - sortType, postFilter, readPostList); + sortType, postFilter, readPostList, postEnricher); break; case PostPagingSource.TYPE_SEARCH: paging3PagingSource = new PostPagingSource(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, name, query, trendingSource, - postType, sortType, postFilter, readPostList); + postType, sortType, postFilter, readPostList, postEnricher); break; default: //User paging3PagingSource = new PostPagingSource(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, name, postType, - sortType, postFilter, userWhere, readPostList); + sortType, postFilter, userWhere, readPostList, postEnricher); break; } return paging3PagingSource; @@ -291,11 +297,12 @@ public class PostViewModel extends ViewModel { private PostFilter postFilter; private String userWhere; private List readPostList; + private PostEnricher postEnricher; public Factory(Executor executor, RetrofitHolder retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, SharedPreferences postHistorySharedPreferences, int postType, SortType sortType, - PostFilter postFilter, List readPostList, String option) { + PostFilter postFilter, List readPostList, String option, PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -308,12 +315,13 @@ public class PostViewModel extends ViewModel { this.postFilter = postFilter; this.readPostList = readPostList; this.name = option; + this.postEnricher = postEnricher; } public Factory(Executor executor, RetrofitHolder retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, SharedPreferences postHistorySharedPreferences, String name, int postType, SortType sortType, - PostFilter postFilter, List readPostList) { + PostFilter postFilter, List readPostList, PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -326,13 +334,15 @@ public class PostViewModel extends ViewModel { this.sortType = sortType; this.postFilter = postFilter; this.readPostList = readPostList; + this.postEnricher = postEnricher; } //User posts public Factory(Executor executor, RetrofitHolder retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, SharedPreferences postHistorySharedPreferences, String username, int postType, - SortType sortType, PostFilter postFilter, String where, List readPostList) { + SortType sortType, PostFilter postFilter, String where, List readPostList, + PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -346,12 +356,14 @@ public class PostViewModel extends ViewModel { this.postFilter = postFilter; userWhere = where; this.readPostList = readPostList; + this.postEnricher = postEnricher; } public Factory(Executor executor, RetrofitHolder retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, SharedPreferences postHistorySharedPreferences, String name, String query, String trendingSource, - int postType, SortType sortType, PostFilter postFilter, List readPostList) { + int postType, SortType sortType, PostFilter postFilter, List readPostList, + PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -366,19 +378,23 @@ public class PostViewModel extends ViewModel { this.sortType = sortType; this.postFilter = postFilter; this.readPostList = readPostList; + this.postEnricher = postEnricher; } //Anonymous Front Page public Factory(Executor executor, RetrofitHolder retrofit, SharedPreferences sharedPreferences, - String concatenatedSubredditNames, int postType, SortType sortType, PostFilter postFilter, String opt) { + String concatenatedSubredditNames, int postType, SortType sortType, PostFilter postFilter, + String opt, PostEnricher postEnricher) { this.executor = executor; this.retrofit = retrofit; this.sharedPreferences = sharedPreferences; + // TODO is this used? because it is getting overwritten with opt this.name = concatenatedSubredditNames; this.postType = postType; this.sortType = sortType; this.postFilter = postFilter; this.name = opt; + this.postEnricher = postEnricher; } @NonNull @@ -387,23 +403,23 @@ public class PostViewModel extends ViewModel { if (postType == PostPagingSource.TYPE_FRONT_PAGE) { return (T) new PostViewModel(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, postHistorySharedPreferences, postType, - sortType, postFilter, readPostList,name); + sortType, postFilter, readPostList,name, postEnricher); } else if (postType == PostPagingSource.TYPE_SEARCH) { return (T) new PostViewModel(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, postHistorySharedPreferences, name, query, - trendingSource, postType, sortType, postFilter, readPostList); + trendingSource, postType, sortType, postFilter, readPostList, postEnricher); } else if (postType == PostPagingSource.TYPE_SUBREDDIT || postType == PostPagingSource.TYPE_MULTI_REDDIT) { return (T) new PostViewModel(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, postHistorySharedPreferences, name, - postType, sortType, postFilter, readPostList); + postType, sortType, postFilter, readPostList, postEnricher); } else if (postType == PostPagingSource.TYPE_ANONYMOUS_FRONT_PAGE) { return (T) new PostViewModel(executor, retrofit, null, null, sharedPreferences, null, null, name, postType, sortType, - postFilter, null); + postFilter, null, postEnricher); } else { return (T) new PostViewModel(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, postHistorySharedPreferences, name, - postType, sortType, postFilter, userWhere, readPostList); + postType, sortType, postFilter, userWhere, readPostList, postEnricher); } } } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/post/SubmitPost.java b/app/src/main/java/eu/toldi/infinityforlemmy/post/SubmitPost.java index ff11a2f7..cbd1af20 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/post/SubmitPost.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/post/SubmitPost.java @@ -15,6 +15,7 @@ import eu.toldi.infinityforlemmy.Flair; import eu.toldi.infinityforlemmy.RetrofitHolder; import eu.toldi.infinityforlemmy.apis.LemmyAPI; import eu.toldi.infinityforlemmy.dto.SubmitPostDTO; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; import eu.toldi.infinityforlemmy.utils.APIUtils; import eu.toldi.infinityforlemmy.utils.UploadImageUtils; import retrofit2.Call; @@ -25,22 +26,24 @@ public class SubmitPost { public static void submitTextOrLinkPost(Executor executor, Handler handler, Retrofit oauthRetrofit, String accessToken, int communityId, String title, String body, String url, Flair flair, boolean isSpoiler, boolean isNSFW, - boolean receivePostReplyNotifications, String kind, + boolean receivePostReplyNotifications, String kind, PostEnricher postEnricher, SubmitPostListener submitPostListener) { submitPost(executor, handler, oauthRetrofit, accessToken, communityId, title, body, - isNSFW, receivePostReplyNotifications, kind, url, submitPostListener); + isNSFW, receivePostReplyNotifications, kind, url, postEnricher, submitPostListener); } public static void submitImagePost(Executor executor, Handler handler, RetrofitHolder mRetrofit, String accessToken, int communityId, String title, String body, Bitmap image, Flair flair, boolean isSpoiler, boolean isNSFW, - boolean receivePostReplyNotifications, SubmitPostListener submitPostListener) { + boolean receivePostReplyNotifications, PostEnricher postEnricher, + SubmitPostListener submitPostListener) { try { String imageUrlOrError = UploadImageUtils.uploadImage(mRetrofit, accessToken, image); if (imageUrlOrError != null && !imageUrlOrError.startsWith("Error: ")) { submitPost(executor, handler, mRetrofit.getRetrofit(), accessToken, communityId, title, body, isNSFW, - receivePostReplyNotifications, APIUtils.KIND_IMAGE, imageUrlOrError, submitPostListener); + receivePostReplyNotifications, APIUtils.KIND_IMAGE, imageUrlOrError, + postEnricher, submitPostListener); } else { submitPostListener.submitFailed(imageUrlOrError); } @@ -53,17 +56,18 @@ public class SubmitPost { public static void submitCrosspost(Executor executor, Handler handler, Retrofit oauthRetrofit, String accessToken, int communityId, String title, String crosspostFullname, Flair flair, boolean isSpoiler, boolean isNSFW, - boolean receivePostReplyNotifications, String kind, + boolean receivePostReplyNotifications, String kind, PostEnricher postEnricher, SubmitPostListener submitPostListener) { submitPost(executor, handler, oauthRetrofit, accessToken, communityId, title, crosspostFullname, - isNSFW, receivePostReplyNotifications, kind, null, submitPostListener); + isNSFW, receivePostReplyNotifications, kind, null, postEnricher, submitPostListener); } private static void submitPost(Executor executor, Handler handler, Retrofit oauthRetrofit, String accessToken, int communityId, String title, String content, boolean isNSFW, boolean receivePostReplyNotifications, String kind, - @Nullable String posterUrl, SubmitPostListener submitPostListener) { + @Nullable String posterUrl, PostEnricher postEnricher, + SubmitPostListener submitPostListener) { LemmyAPI api = oauthRetrofit.create(LemmyAPI.class); @@ -73,7 +77,7 @@ public class SubmitPost { Response response = submitPostCall.execute(); if (response.isSuccessful()) { getSubmittedPost(executor, handler, response.body(), kind, oauthRetrofit, accessToken, - submitPostListener); + postEnricher, submitPostListener); } else { submitPostListener.submitFailed(response.message()); } @@ -84,10 +88,10 @@ public class SubmitPost { } private static void getSubmittedPost(Executor executor, Handler handler, String response, String kind, - Retrofit oauthRetrofit, String accessToken, + Retrofit oauthRetrofit, String accessToken, PostEnricher postEnricher, SubmitPostListener submitPostListener) throws JSONException, IOException { - ParsePost.parsePost(executor, handler, response, new ParsePost.ParsePostListener() { + ParsePost.parsePost(executor, handler, postEnricher, response, new ParsePost.ParsePostListener() { @Override public void onParsePostSuccess(Post post) { submitPostListener.submitSuccessful(post); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/services/SubmitPostService.java b/app/src/main/java/eu/toldi/infinityforlemmy/services/SubmitPostService.java index 89b94e1b..b3c54cc9 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/services/SubmitPostService.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/services/SubmitPostService.java @@ -54,6 +54,7 @@ import eu.toldi.infinityforlemmy.events.SubmitPollPostEvent; import eu.toldi.infinityforlemmy.events.SubmitTextOrLinkPostEvent; import eu.toldi.infinityforlemmy.post.Post; import eu.toldi.infinityforlemmy.post.SubmitPost; +import eu.toldi.infinityforlemmy.post.enrich.PostEnricher; import eu.toldi.infinityforlemmy.utils.APIUtils; import eu.toldi.infinityforlemmy.utils.JSONUtils; import eu.toldi.infinityforlemmy.utils.NotificationUtils; @@ -102,6 +103,8 @@ public class SubmitPostService extends Service { CustomThemeWrapper mCustomThemeWrapper; @Inject Executor mExecutor; + @Inject + PostEnricher postEnricher; private Handler handler; private ServiceHandler serviceHandler; @@ -221,7 +224,7 @@ public class SubmitPostService extends Service { String kind) { SubmitPost.submitTextOrLinkPost(mExecutor, handler, newAuthenticatorOauthRetrofit, selectedAccount.getAccessToken(), communityId, title, body, url, flair, isSpoiler, - isNSFW, receivePostReplyNotifications, kind, new SubmitPost.SubmitPostListener() { + isNSFW, receivePostReplyNotifications, kind, postEnricher, new SubmitPost.SubmitPostListener() { @Override public void submitSuccessful(Post post) { handler.post(() -> EventBus.getDefault().post(new SubmitTextOrLinkPostEvent(true, post, null))); @@ -243,7 +246,7 @@ public class SubmitPostService extends Service { String title, String content, Flair flair, boolean isSpoiler, boolean isNSFW, boolean receivePostReplyNotifications) { SubmitPost.submitCrosspost(executor, handler, newAuthenticatorOauthRetrofit, selectedAccount.getAccessToken(), communityId, title, - content, flair, isSpoiler, isNSFW, receivePostReplyNotifications, APIUtils.KIND_CROSSPOST, + content, flair, isSpoiler, isNSFW, receivePostReplyNotifications, APIUtils.KIND_CROSSPOST, postEnricher, new SubmitPost.SubmitPostListener() { @Override public void submitSuccessful(Post post) { @@ -266,7 +269,8 @@ public class SubmitPostService extends Service { try { Bitmap resource = Glide.with(this).asBitmap().load(mediaUri).submit().get(); SubmitPost.submitImagePost(mExecutor, handler, newAuthenticatorOauthRetrofit, - selectedAccount.getAccessToken(), communityId, title, body, resource, flair, isSpoiler, isNSFW, receivePostReplyNotifications, + selectedAccount.getAccessToken(), communityId, title, body, resource, flair, isSpoiler, + isNSFW, receivePostReplyNotifications, postEnricher, new SubmitPost.SubmitPostListener() { @Override public void submitSuccessful(Post post) { diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/utils/JSONUtils.java b/app/src/main/java/eu/toldi/infinityforlemmy/utils/JSONUtils.java index cc8f921c..5bedadb8 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/utils/JSONUtils.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/utils/JSONUtils.java @@ -126,6 +126,7 @@ public class JSONUtils { public static final String Y_KEY = "y"; public static final String DEST_KEY = "dest"; public static final String GIF_KEY = "gif"; + public static final String GIFS_KEY = "gifs"; public static final String MAX_EMOJIS_KEY = "max_emojis"; public static final String RICHTEXT_KEY = "richtext"; public static final String SUGGESTED_COMMENT_SORT_KEY = "suggested_comment_sort"; diff --git a/app/src/main/kotlin/eu/toldi/infinityforlemmy/post/enrich/CompositePostEnricher.kt b/app/src/main/kotlin/eu/toldi/infinityforlemmy/post/enrich/CompositePostEnricher.kt new file mode 100644 index 00000000..dea27b16 --- /dev/null +++ b/app/src/main/kotlin/eu/toldi/infinityforlemmy/post/enrich/CompositePostEnricher.kt @@ -0,0 +1,11 @@ +package eu.toldi.infinityforlemmy.post.enrich + +import eu.toldi.infinityforlemmy.post.Post + +class CompositePostEnricher(private val enrichers: Set) : PostEnricher { + override fun enrich(posts: Collection) { + for (enricher in enrichers) { + enricher.enrich(posts) + } + } +} diff --git a/app/src/main/kotlin/eu/toldi/infinityforlemmy/post/enrich/PostEnricher.kt b/app/src/main/kotlin/eu/toldi/infinityforlemmy/post/enrich/PostEnricher.kt new file mode 100644 index 00000000..d36fff9d --- /dev/null +++ b/app/src/main/kotlin/eu/toldi/infinityforlemmy/post/enrich/PostEnricher.kt @@ -0,0 +1,7 @@ +package eu.toldi.infinityforlemmy.post.enrich + +import eu.toldi.infinityforlemmy.post.Post + +interface PostEnricher { + fun enrich(posts: Collection) +} diff --git a/app/src/main/kotlin/eu/toldi/infinityforlemmy/post/enrich/RedGifsPostEnricher.kt b/app/src/main/kotlin/eu/toldi/infinityforlemmy/post/enrich/RedGifsPostEnricher.kt new file mode 100644 index 00000000..3f199560 --- /dev/null +++ b/app/src/main/kotlin/eu/toldi/infinityforlemmy/post/enrich/RedGifsPostEnricher.kt @@ -0,0 +1,56 @@ +package eu.toldi.infinityforlemmy.post.enrich + +import android.util.Log +import eu.toldi.infinityforlemmy.apis.RedgifsAPI +import eu.toldi.infinityforlemmy.post.Post +import eu.toldi.infinityforlemmy.post.Post.Preview +import eu.toldi.infinityforlemmy.utils.JSONUtils +import org.json.JSONException +import org.json.JSONObject +import java.io.IOException + +class RedGifsPostEnricher(private val redgifsAPI: RedgifsAPI) : PostEnricher { + override fun enrich(posts: Collection) { + val redGifsPosts = posts.filter { it.isRedgifs && it.previews.isEmpty() } + .groupBy { it.gfycatId } + + if (redGifsPosts.isEmpty()) { + return + } + + try { + val response = redgifsAPI.getRedgifsMultipleData(redGifsPosts.keys.joinToString(",")).execute() + val body = response.body() + if (response.isSuccessful && body != null) { + try { + val gifsJson = JSONObject(body).getJSONArray(JSONUtils.GIFS_KEY) + for (i in 0 until gifsJson.length()) { + val gifJson = gifsJson.getJSONObject(i) + val id = gifJson.getString(JSONUtils.ID_KEY) + val width = gifJson.getInt(JSONUtils.WIDTH_KEY) + val height = gifJson.getInt(JSONUtils.HEIGHT_KEY) + val thumbnail = gifJson.getJSONObject(JSONUtils.URLS_KEY) + .getString(JSONUtils.THUMBNAIL_KEY) + + val previews = ArrayList(listOf(Preview(thumbnail, width, height, null, null))) + + redGifsPosts[id]?.forEach { + it.previews = previews + } + } + + } catch (e: JSONException) { + Log.w(TAG, "Failed to parse JSON", e) + } + } else { + Log.w(TAG, "Failed fetch data. Status code ${response.code()}") + } + } catch (e: IOException) { + Log.w(TAG, "Failed fetch data", e) + } + } + + companion object { + private const val TAG = "RedGifsPostEnricher" + } +}