Resolve posts from links

This commit is contained in:
Balazs Toldi 2023-07-31 13:46:34 +02:00
parent 7e433954c5
commit a2e22bc525
No known key found for this signature in database
GPG Key ID: 6C7D440036F99D58
7 changed files with 159 additions and 16 deletions

View File

@ -82,6 +82,7 @@ import eu.toldi.infinityforlemmy.fragments.ViewImgurVideoFragment;
import eu.toldi.infinityforlemmy.fragments.ViewPostDetailFragment; import eu.toldi.infinityforlemmy.fragments.ViewPostDetailFragment;
import eu.toldi.infinityforlemmy.fragments.ViewRedditGalleryImageOrGifFragment; import eu.toldi.infinityforlemmy.fragments.ViewRedditGalleryImageOrGifFragment;
import eu.toldi.infinityforlemmy.fragments.ViewRedditGalleryVideoFragment; import eu.toldi.infinityforlemmy.fragments.ViewRedditGalleryVideoFragment;
import eu.toldi.infinityforlemmy.post.ObjectResolver;
import eu.toldi.infinityforlemmy.services.DownloadMediaService; import eu.toldi.infinityforlemmy.services.DownloadMediaService;
import eu.toldi.infinityforlemmy.services.DownloadRedditVideoService; import eu.toldi.infinityforlemmy.services.DownloadRedditVideoService;
import eu.toldi.infinityforlemmy.services.EditProfileService; import eu.toldi.infinityforlemmy.services.EditProfileService;
@ -307,6 +308,9 @@ public interface AppComponent {
void inject(MorePostsInfoFragment morePostsInfoFragment); void inject(MorePostsInfoFragment morePostsInfoFragment);
void inject(ObjectResolver mObjectResolver);
@Component.Factory @Component.Factory
interface Factory { interface Factory {
AppComponent create(@BindsInstance Application application); AppComponent create(@BindsInstance Application application);

View File

@ -22,6 +22,7 @@ import dagger.Module;
import dagger.Provides; import dagger.Provides;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.LoopAvailableExoCreator; import eu.toldi.infinityforlemmy.customviews.LoopAvailableExoCreator;
import eu.toldi.infinityforlemmy.post.ObjectResolver;
import eu.toldi.infinityforlemmy.utils.CustomThemeSharedPreferencesUtils; import eu.toldi.infinityforlemmy.utils.CustomThemeSharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.videoautoplay.Config; import eu.toldi.infinityforlemmy.videoautoplay.Config;
@ -202,4 +203,10 @@ abstract class AppModule {
static Executor provideExecutor() { static Executor provideExecutor() {
return Executors.newFixedThreadPool(4); return Executors.newFixedThreadPool(4);
} }
@Provides
@Singleton
static ObjectResolver provideObjectResolver() {
return new ObjectResolver();
}
} }

View File

@ -25,7 +25,10 @@ import javax.inject.Named;
import eu.toldi.infinityforlemmy.Infinity; import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R; import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.post.ObjectResolver;
import eu.toldi.infinityforlemmy.post.Post;
import eu.toldi.infinityforlemmy.utils.LemmyUtils; import eu.toldi.infinityforlemmy.utils.LemmyUtils;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
@ -35,8 +38,7 @@ public class LinkResolverActivity extends AppCompatActivity {
public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN";
public static final String EXTRA_IS_NSFW = "EIN"; public static final String EXTRA_IS_NSFW = "EIN";
private static final String POST_PATTERN = "/r/[\\w-]+/comments/\\w+/?\\w+/?"; private static final String POST_PATTERN = "https?:\\/\\/\\S+\\/post\\/\\d+";
private static final String POST_PATTERN_2 = "/(u|U|user)/[\\w-]+/comments/\\w+/?\\w+/?";
private static final String POST_PATTERN_3 = "/[\\w-]+$"; private static final String POST_PATTERN_3 = "/[\\w-]+$";
private static final String COMMENT_PATTERN = "/(r|u|U|user)/[\\w-]+/comments/\\w+/?[\\w-]+/\\w+/?"; private static final String COMMENT_PATTERN = "/(r|u|U|user)/[\\w-]+/comments/\\w+/?[\\w-]+/\\w+/?";
private static final String SUBREDDIT_PATTERN = "(?:https?://[\\w.-]+)?/c/[\\w-]+(@[\\w.-]+)?"; private static final String SUBREDDIT_PATTERN = "(?:https?://[\\w.-]+)?/c/[\\w-]+(@[\\w.-]+)?";
@ -60,6 +62,19 @@ public class LinkResolverActivity extends AppCompatActivity {
@Inject @Inject
CustomThemeWrapper mCustomThemeWrapper; CustomThemeWrapper mCustomThemeWrapper;
@Inject
ObjectResolver mObjectResolver;
@Inject
@Named("current_account")
SharedPreferences mCurrentAccountSharedPreferences;
@Inject
@Named("no_oauth")
RetrofitHolder mRetrofit;
private String mAccessToken;
private Uri getRedditUriByPath(String path) { private Uri getRedditUriByPath(String path) {
if (path.charAt(0) != '/') { if (path.charAt(0) != '/') {
return Uri.parse("https://www.reddit.com/" + path); return Uri.parse("https://www.reddit.com/" + path);
@ -73,6 +88,7 @@ public class LinkResolverActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
((Infinity) getApplication()).getAppComponent().inject(this); ((Infinity) getApplication()).getAppComponent().inject(this);
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
Uri uri = getIntent().getData(); Uri uri = getIntent().getData();
if (uri == null) { if (uri == null) {
@ -169,6 +185,35 @@ public class LinkResolverActivity extends AppCompatActivity {
intent.putExtra(ViewUserDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); intent.putExtra(ViewUserDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewUserDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); intent.putExtra(ViewUserDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
startActivity(intent); startActivity(intent);
} else if (uri.toString().matches(POST_PATTERN)) {
if (mAccessToken == null) {
// switch retrofit to use the current instance for anonymous requests
mRetrofit.setBaseURL(uri.getScheme() + "://" + uri.getHost() + "/");
Intent intent = new Intent(LinkResolverActivity.this, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, Integer.parseInt(segments.get(segments.size() - 1)));
intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
startActivity(intent);
} else {
((Infinity) getApplication()).getAppComponent().inject(mObjectResolver);
mObjectResolver.resolvePost(uri.toString(), mAccessToken, new ObjectResolver.ObjectResolverListener() {
@Override
public void onResolveObjectSuccess(Object p) {
Post post = (Post) p;
Intent intent = new Intent(LinkResolverActivity.this, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, post.getId());
intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
startActivity(intent);
}
@Override
public void onResolveObjectFailed() {
Toast.makeText(LinkResolverActivity.this, R.string.could_not_resolve_link, Toast.LENGTH_SHORT).show();
finish();
}
});
}
} else if (authority.equals("v.redd.it")) { } else if (authority.equals("v.redd.it")) {
Intent intent = new Intent(this, ViewVideoActivity.class); Intent intent = new Intent(this, ViewVideoActivity.class);
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_V_REDD_IT); intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_V_REDD_IT);
@ -187,17 +232,6 @@ public class LinkResolverActivity extends AppCompatActivity {
startActivity(intent); startActivity(intent);
} else if (path.equals("/report")) { } else if (path.equals("/report")) {
openInWebView(uri); openInWebView(uri);
} else if (path.matches(POST_PATTERN) || path.matches(POST_PATTERN_2)) {
int commentsIndex = segments.lastIndexOf("comments");
if (commentsIndex >= 0 && commentsIndex < segments.size() - 1) {
Intent intent = new Intent(this, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, segments.get(commentsIndex + 1));
intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
startActivity(intent);
} else {
deepLinkError(uri);
}
} else if (path.matches(POST_PATTERN_3)) { } else if (path.matches(POST_PATTERN_3)) {
Intent intent = new Intent(this, ViewPostDetailActivity.class); Intent intent = new Intent(this, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, path.substring(1)); intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, path.substring(1));

View File

@ -159,4 +159,10 @@ public interface LemmyAPI {
@Header("Cookie") String token, @Header("Cookie") String token,
@Part MultipartBody.Part filePart @Part MultipartBody.Part filePart
); );
@GET("api/v3/resolve_object")
Call<String> resolveObject(
@Query("q") String query,
@Query("auth") String auth
);
} }

View File

@ -1258,7 +1258,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic
mPostDetailsSharedPreferences, mExoCreator, mPostDetailsSharedPreferences, mExoCreator,
post1 -> EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition))); post1 -> EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)));
mSwipeRefreshLayout.setRefreshing(false); mSwipeRefreshLayout.setRefreshing(false);
FetchComment.fetchComments(mExecutor, new Handler(), mRetrofit.getRetrofit(), mAccessToken, subredditId, mSingleCommentId, sortType, mExpandChildren, 1, new FetchComment.FetchCommentListener() { FetchComment.fetchComments(mExecutor, new Handler(), mRetrofit.getRetrofit(), mAccessToken, post.getId(), mSingleCommentId == 0 ? null : mSingleCommentId, sortType, mExpandChildren, 1, new FetchComment.FetchCommentListener() {
@Override @Override
public void onFetchCommentSuccess(ArrayList<Comment> expandedComments, Integer parentId, ArrayList<Integer> children) { public void onFetchCommentSuccess(ArrayList<Comment> expandedComments, Integer parentId, ArrayList<Integer> children) {
pages_loaded++; pages_loaded++;

View File

@ -0,0 +1,91 @@
package eu.toldi.infinityforlemmy.post;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Objects;
import javax.inject.Inject;
import javax.inject.Named;
import eu.toldi.infinityforlemmy.RetrofitHolder;
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;
public class ObjectResolver {
@Inject
@Named("no_oauth")
RetrofitHolder retrofitHolder;
public void resolvePost(String query, String auth, ObjectResolverListener objectResolverListener) {
LemmyAPI lemmyAPI = retrofitHolder.getRetrofit().create(LemmyAPI.class);
Call<String> response = lemmyAPI.resolveObject(query, auth);
response.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if (response.isSuccessful()
&& response.body() != null) {
try {
JSONObject jsonObject = new JSONObject(Objects.requireNonNull(response.body())).getJSONObject("post");
Post p = ParsePost.parseBasicData(jsonObject);
objectResolverListener.onResolveObjectSuccess(p);
} catch (JSONException e) {
objectResolverListener.onResolveObjectFailed();
}
} else {
objectResolverListener.onResolveObjectFailed();
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
objectResolverListener.onResolveObjectFailed();
}
});
}
public void resolveComment(String query, String auth, ObjectResolverListener objectResolverListener) {
LemmyAPI lemmyAPI = retrofitHolder.getRetrofit().create(LemmyAPI.class);
Call<String> response = lemmyAPI.resolveObject(query, auth);
response.enqueue(
new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if (response.isSuccessful()
&& response.body() != null) {
try {
JSONObject jsonObject = new JSONObject(Objects.requireNonNull(response.body())).getJSONObject("comment");
Comment c = ParseComment.parseSingleComment(jsonObject);
objectResolverListener.onResolveObjectSuccess(c);
} catch (JSONException e) {
objectResolverListener.onResolveObjectFailed();
}
} else {
objectResolverListener.onResolveObjectFailed();
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
objectResolverListener.onResolveObjectFailed();
}
}
);
}
public interface ObjectResolverListener {
void onResolveObjectSuccess(Object resolvedObject);
void onResolveObjectFailed();
}
}

View File

@ -1341,4 +1341,5 @@
<string name="sort_time_9months">9 Months</string> <string name="sort_time_9months">9 Months</string>
<string name="anonymous_account_instance">Anonymous Account Instance</string> <string name="anonymous_account_instance">Anonymous Account Instance</string>
<string name="url_cannot_be_null_or_empty">URL cannot be null or empty</string> <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>
</resources> </resources>