17 Commits

Author SHA1 Message Date
Balazs Toldi
2bb1189e15 Revert "Use minifiedRelease build in pipeline"
This reverts commit c1f8f5a681.
2023-07-30 08:28:37 +02:00
Balazs Toldi
233fc38c23 Revert "Change minifiedRelease name for F-Droid"
This reverts commit 215d31f8ea.
2023-07-30 08:28:09 +02:00
Balazs Toldi
215d31f8ea Change minifiedRelease name for F-Droid 2023-07-29 22:57:53 +02:00
Balazs Toldi
8ae681c753 Better parse image 2023-07-29 22:33:50 +02:00
Balazs Toldi
554eb3c2fe Bump version 2023-07-29 22:07:12 +02:00
Balazs Toldi
c1f8f5a681 Use minifiedRelease build in pipeline 2023-07-29 22:05:08 +02:00
Balazs Toldi
bb5c82aa60 Remove post types incompatible with Lemmy 2023-07-29 22:04:48 +02:00
Balazs Toldi
72ba41c940 Minor fix for sharing users/communities 2023-07-29 22:04:16 +02:00
Balazs Toldi
40b6722e66 Fix community Icon disappearing after post refresh 2023-07-29 21:50:55 +02:00
Balazs Toldi
dd3b72bc1f Basic single comment view
Closes #27
2023-07-29 21:42:36 +02:00
Balazs Toldi
e9ecae117d Fixes community names on CompactLayout and User posts page
Replaced the reddit specific "r/" prefix. Closes #26
2023-07-29 20:32:33 +02:00
Balazs Toldi
5e4793bdaf Merge remote-tracking branch 'codeberg/master' 2023-07-29 20:14:30 +02:00
Balazs Toldi
fe351a8466 Removed reddit specific options from settings
Closes #23
2023-07-29 20:14:23 +02:00
Balazs Toldi
b1b12aba31 Fix comment/post dates on older versions of android
Closes #20
2023-07-29 20:04:22 +02:00
Bazsalanszky
d2b95e1db6 Merge pull request 'Add inputType to instance_url_input to prevent autocorrection on this field' (#21) from anonion/Infinity-For-Lemmy:autocorrect-fix into master
Reviewed-on: https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/pulls/21
2023-07-29 14:04:11 +00:00
Balazs Toldi
20c317b63f LoginActivity password max length 2023-07-29 15:37:44 +02:00
anonion
f2d14a975d add inputType to instance_url_input 2023-07-28 15:14:01 -06:00
19 changed files with 201 additions and 312 deletions

View File

@@ -8,8 +8,8 @@ android {
applicationId "eu.toldi.infinityforlemmy"
minSdk 21
targetSdk 33
versionCode 123
versionName "0.0.3"
versionCode 124
versionName "0.0.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {

View File

@@ -139,9 +139,9 @@ public class LoginActivity extends BaseActivity {
Log.i("LoginActivity", "Login button clicked");
loginButton.setEnabled(false);
progressBar.setVisibility(ProgressBar.VISIBLE);
String username = username_input.getText().toString();
String instance = correctURL(instance_input.getText().toString());
if(!Patterns.WEB_URL.matcher(instance).matches()){
String username = username_input.getText().toString().trim();
String instance = correctURL(instance_input.getText().toString().trim());
if (!Patterns.WEB_URL.matcher(instance).matches()) {
instance_input.setError("Invalid instance URL");
Toast.makeText(LoginActivity.this, "Invalid instance URL", Toast.LENGTH_SHORT).show();
loginButton.setEnabled(true);
@@ -149,7 +149,7 @@ public class LoginActivity extends BaseActivity {
return;
}
Log.i("LoginActivity", "Instance: " + instance);
AccountLoginDTO accountLoginDTO = new AccountLoginDTO(username,password_input.getText().toString(),token_2fa_input.getText().toString());
AccountLoginDTO accountLoginDTO = new AccountLoginDTO(username, password_input.getText().toString(), token_2fa_input.getText().toString());
mRetrofit.setBaseURL(instance);
LemmyAPI api = mRetrofit.getRetrofit().create(LemmyAPI.class);
Call<String> accessTokenCall = api.userLogin(accountLoginDTO);

View File

@@ -869,7 +869,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele
if (postListPosition == position && post != null) {
bundle.putParcelable(ViewPostDetailFragment.EXTRA_POST_DATA, post);
bundle.putInt(ViewPostDetailFragment.EXTRA_POST_LIST_POSITION, position);
bundle.putString(ViewPostDetailFragment.EXTRA_SINGLE_COMMENT_ID, getIntent().getStringExtra(EXTRA_SINGLE_COMMENT_ID));
bundle.putInt(ViewPostDetailFragment.EXTRA_SINGLE_COMMENT_ID, getIntent().getIntExtra(EXTRA_SINGLE_COMMENT_ID, 0));
bundle.putString(ViewPostDetailFragment.EXTRA_CONTEXT_NUMBER, getIntent().getStringExtra(EXTRA_CONTEXT_NUMBER));
bundle.putString(ViewPostDetailFragment.EXTRA_MESSAGE_FULLNAME, getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME));
} else {
@@ -885,12 +885,12 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele
}
} else {
if (post == null) {
bundle.putString(ViewPostDetailFragment.EXTRA_POST_ID, getIntent().getStringExtra(EXTRA_POST_ID));
bundle.putInt(ViewPostDetailFragment.EXTRA_POST_ID, getIntent().getIntExtra(EXTRA_POST_ID, 0));
} else {
bundle.putParcelable(ViewPostDetailFragment.EXTRA_POST_DATA, post);
bundle.putInt(ViewPostDetailFragment.EXTRA_POST_LIST_POSITION, postListPosition);
}
bundle.putString(ViewPostDetailFragment.EXTRA_SINGLE_COMMENT_ID, getIntent().getStringExtra(EXTRA_SINGLE_COMMENT_ID));
bundle.putInt(ViewPostDetailFragment.EXTRA_SINGLE_COMMENT_ID, getIntent().getIntExtra(EXTRA_SINGLE_COMMENT_ID, 0));
bundle.putString(ViewPostDetailFragment.EXTRA_CONTEXT_NUMBER, getIntent().getStringExtra(EXTRA_CONTEXT_NUMBER));
bundle.putString(ViewPostDetailFragment.EXTRA_MESSAGE_FULLNAME, getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME));
}

View File

@@ -1174,7 +1174,8 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
} else if (itemId == R.id.action_share_view_subreddit_detail_activity) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, mRetrofit.getBaseURL() + qualifiedName);
String baseURL = mRetrofit.getBaseURL().endsWith("/") ? mRetrofit.getBaseURL() : mRetrofit.getBaseURL() + "/";
shareIntent.putExtra(Intent.EXTRA_TEXT, baseURL + "/" + qualifiedName);
if (shareIntent.resolveActivity(getPackageManager()) != null) {
startActivity(Intent.createChooser(shareIntent, getString(R.string.share)));
} else {

View File

@@ -1154,7 +1154,8 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele
} else if (itemId == R.id.action_share_view_user_detail_activity) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, mRetrofit.getBaseURL() + qualifiedName);
String baseURL = mRetrofit.getBaseURL().endsWith("/") ? mRetrofit.getBaseURL() : mRetrofit.getBaseURL() + "/";
shareIntent.putExtra(Intent.EXTRA_TEXT, baseURL + qualifiedName);
if (shareIntent.resolveActivity(getPackageManager()) != null) {
startActivity(Intent.createChooser(shareIntent, getString(R.string.share)));
} else {

View File

@@ -190,7 +190,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
if (holder instanceof CommentViewHolder) {
Comment comment = getItem(holder.getBindingAdapterPosition());
if (comment != null) {
String name = "r/" + comment.getCommunityName();
String name = comment.getCommunityQualifiedName();
((CommentViewHolder) holder).authorTextView.setText(name);
((CommentViewHolder) holder).authorTextView.setTextColor(mSubredditColor);
@@ -437,6 +437,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
if (comment != null) {
Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, comment.getCommunityName());
intent.putExtra(ViewSubredditDetailActivity.EXTRA_COMMUNITY_FULL_NAME_KEY, comment.getCommunityQualifiedName());
mActivity.startActivity(intent);
}
});
@@ -469,7 +470,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
Comment comment = getItem(getBindingAdapterPosition());
if (comment != null) {
Intent intent = new Intent(mActivity, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, comment.getLinkId());
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, comment.getPostId());
intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, comment.getId());
mActivity.startActivity(intent);
}

View File

@@ -508,7 +508,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
} else {
if (mPost.getSubredditIconUrl() == null) {
LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(),
mRedditDataRoomDatabase, mPost.getSubredditNamePrefixed().substring(2),
mRedditDataRoomDatabase, mPost.getSubredditNamePrefixed(),
mAccessToken, mOauthRetrofit, mRetrofit, iconImageUrl -> {
if (iconImageUrl == null || iconImageUrl.equals("")) {
mGlide.load(R.drawable.subreddit_default_icon)

View File

@@ -1155,7 +1155,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
if (mHideSubredditAndUserPrefix) {
((PostCompactBaseViewHolder) holder).nameTextView.setText(post.getSubredditName());
} else {
((PostCompactBaseViewHolder) holder).nameTextView.setText("r/" + post.getSubredditName());
((PostCompactBaseViewHolder) holder).nameTextView.setText(post.getSubredditNamePrefixed());
}
} else {
if (post.getAuthorIconUrl() == null) {

View File

@@ -38,12 +38,6 @@ public class PostTypeBottomSheetFragment extends LandscapeExpandedRoundedBottomS
TextView linkTypeTextView;
@BindView(R.id.image_type_linear_layout_post_type_bottom_sheet_fragment)
TextView imageTypeTextView;
@BindView(R.id.video_type_linear_layout_post_type_bottom_sheet_fragment)
TextView videoTypeTextView;
@BindView(R.id.gallery_type_linear_layout_post_type_bottom_sheet_fragment)
TextView galleryTypeTextView;
@BindView(R.id.poll_type_linear_layout_post_type_bottom_sheet_fragment)
TextView pollTypeTextView;
private BaseActivity activity;
public PostTypeBottomSheetFragment() {
@@ -76,20 +70,6 @@ public class PostTypeBottomSheetFragment extends LandscapeExpandedRoundedBottomS
dismiss();
});
videoTypeTextView.setOnClickListener(view -> {
((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_VIDEO);
dismiss();
});
galleryTypeTextView.setOnClickListener(view -> {
((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_GALLERY);
dismiss();
});
pollTypeTextView.setOnClickListener(view -> {
((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_POLL);
dismiss();
});
if (activity.typeface != null) {
Utils.setFontToAllTextViews(rootView, activity.typeface);

View File

@@ -9,13 +9,15 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.Executor;
import java.util.regex.Pattern;
@@ -34,7 +36,6 @@ public class ParseComment {
ArrayList<Comment> expandedNewComments = new ArrayList<>();
ArrayList<Integer> moreChildrenIds = new ArrayList<>();
ArrayList<Comment> newComments = new ArrayList<>();
Map<Integer, Comment> parsedComments = new HashMap<>();
@@ -49,8 +50,13 @@ public class ParseComment {
}
}
Comment parentComment = (commentId != null) ? parsedComments.get(commentId) : null;
if (parentComment != null && parentComment.getDepth() == 0)
parentComment = null;
if (parentComment != null) {
if (parentComment.getDepth() == 0) {
parentComment = null;
} else {
expandedNewComments.add(parentComment);
}
}
for (int i = orderedComments.size() - 1; i >= 0; i--) {
Comment c = orderedComments.get(i);
@@ -64,9 +70,7 @@ public class ParseComment {
}
//Add all comments to newComments
for (int i = 0; i < topLevelComments.size(); i++) {
newComments.add(topLevelComments.get(i));
}
ArrayList<Comment> newComments = new ArrayList<>(topLevelComments);
expandChildren(newComments, expandedNewComments, expandChildren);
@@ -278,15 +282,25 @@ public class ParseComment {
String authorQualifiedName = LemmyUtils.actorID2FullName(creatorObj.getString("actor_id"));
String linkAuthor = creatorObj.getString("actor_id");
long commentTimeMillis = 0;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
commentTimeMillis = ZonedDateTime.parse(commentObj.getString("published"),
DateTimeFormatter.ISO_DATE_TIME.withZone(ZoneId.of("Z"))).toInstant().toEpochMilli();
String dateStr = commentObj.getString("published");
dateStr = dateStr.substring(0, dateStr.lastIndexOf(".") + 4) + 'Z';
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
Date date = sdf.parse(dateStr);
if (date != null) {
commentTimeMillis = date.getTime();
}
} catch (ParseException e) {
e.printStackTrace();
}
String commentMarkdown = commentObj.getString("content");
String commentRawText = commentObj.getString("content");
String linkId = postObj.getString("id");
String communityName = communityObj.getString("name");
String communityQualifiedName = communityObj.getString("actor_id");
String communityQualifiedName = LemmyUtils.actorID2FullName(communityObj.getString("actor_id"));
int score = countsObj.getInt("score");
int voteType = (jsonObject.isNull("my_vote")) ? 0 : jsonObject.getInt("my_vote");

View File

@@ -85,7 +85,6 @@ 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.LemmyAPI;
import eu.toldi.infinityforlemmy.apis.RedditAPI;
import eu.toldi.infinityforlemmy.apis.StreamableAPI;
import eu.toldi.infinityforlemmy.asynctasks.LoadUserData;
@@ -95,7 +94,6 @@ import eu.toldi.infinityforlemmy.comment.Comment;
import eu.toldi.infinityforlemmy.comment.FetchComment;
import eu.toldi.infinityforlemmy.comment.FetchRemovedComment;
import eu.toldi.infinityforlemmy.comment.FetchRemovedCommentReveddit;
import eu.toldi.infinityforlemmy.comment.ParseComment;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.CustomToroContainer;
import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed;
@@ -109,7 +107,6 @@ import eu.toldi.infinityforlemmy.message.ReadMessage;
import eu.toldi.infinityforlemmy.post.FetchPost;
import eu.toldi.infinityforlemmy.post.FetchRemovedPost;
import eu.toldi.infinityforlemmy.post.HidePost;
import eu.toldi.infinityforlemmy.post.ParsePost;
import eu.toldi.infinityforlemmy.post.Post;
import eu.toldi.infinityforlemmy.readpost.InsertReadPost;
import eu.toldi.infinityforlemmy.subreddit.FetchSubredditData;
@@ -546,11 +543,11 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic
}
};
mSingleCommentId = (getArguments().getString(EXTRA_SINGLE_COMMENT_ID) == null) ? null : Integer.valueOf(getArguments().getString(EXTRA_SINGLE_COMMENT_ID));
mSingleCommentId = getArguments().getInt(EXTRA_SINGLE_COMMENT_ID, 0);
mContextNumber = getArguments().getString(EXTRA_CONTEXT_NUMBER, "8");
if (savedInstanceState == null) {
if (mSingleCommentId != null) {
if (mSingleCommentId != 0) {
isSingleCommentThreadMode = true;
}
mMessageFullname = getArguments().getString(EXTRA_MESSAGE_FULLNAME);
@@ -594,7 +591,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic
}
if (mPost == null) {
fetchPostAndCommentsById(getArguments().getString(EXTRA_POST_ID));
fetchPostAndCommentsById(getArguments().getInt(EXTRA_POST_ID));
} else {
setupMenu();
@@ -1240,153 +1237,91 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic
return true;
}
private void fetchPostAndCommentsById(String subredditId) {
private void fetchPostAndCommentsById(int subredditId) {
mFetchPostInfoLinearLayout.setVisibility(View.GONE);
mSwipeRefreshLayout.setRefreshing(true);
mGlide.clear(mFetchPostInfoImageView);
Call<String> postAndComments = mRetrofit.getRetrofit().create(LemmyAPI.class).getComments("All", sortType.value, 5, 1, 25, null, null, Integer.valueOf(subredditId), mSingleCommentId, false, mAccessToken);
postAndComments.enqueue(new Callback<>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (!isAdded()) {
return;
}
mSwipeRefreshLayout.setRefreshing(false);
if (response.isSuccessful()) {
ParsePost.parsePost(mExecutor, new Handler(), response.body(), new ParsePost.ParsePostListener() {
@Override
public void onParsePostSuccess(Post post) {
mPost = post;
tryMarkingPostAsRead();
setupMenu();
mPostAdapter = new PostDetailRecyclerViewAdapter(activity,
ViewPostDetailFragment.this, mExecutor, mCustomThemeWrapper,
mRetrofit.getRetrofit(), mOauthRetrofit, mGfycatRetrofit, mRedgifsRetrofit,
mStreamableApiProvider, mRedditDataRoomDatabase, mGlide, mSeparatePostAndComments,
mAccessToken, mAccountName, mPost, mLocale, mSharedPreferences,
mCurrentAccountSharedPreferences, mNsfwAndSpoilerSharedPreferences,
mPostDetailsSharedPreferences, mExoCreator,
post1 -> EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)));
mCommentsAdapter = new CommentsRecyclerViewAdapter(activity,
ViewPostDetailFragment.this, mCustomThemeWrapper, mExecutor,
mRetrofit.getRetrofit(), mOauthRetrofit, mAccessToken, mAccountName, mPost, mLocale,
mSingleCommentId, isSingleCommentThreadMode, mSharedPreferences,
new CommentsRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() {
@Override
public void retryFetchingComments() {
fetchCommentsRespectRecommendedSort(false);
}
@Override
public void retryFetchingMoreComments() {
isLoadingMoreChildren = false;
loadMoreChildrenSuccess = true;
fetchMoreComments();
}
@Override
public SortType.Type getSortType() {
return sortType;
}
});
if (mCommentsRecyclerView != null) {
mRecyclerView.setAdapter(mPostAdapter);
mCommentsRecyclerView.setAdapter(mCommentsAdapter);
} else {
mConcatAdapter = new ConcatAdapter(mPostAdapter, mCommentsAdapter);
mRecyclerView.setAdapter(mConcatAdapter);
}
if (mRespectSubredditRecommendedSortType) {
fetchCommentsRespectRecommendedSort(false);
} else {
ParseComment.parseComments(mExecutor, new Handler(), response.body(), null,
mExpandChildren, new ParseComment.ParseCommentListener() {
FetchPost.fetchPost(mExecutor, new Handler(), mRetrofit.getRetrofit(), String.valueOf(subredditId), mAccessToken,
new FetchPost.FetchPostListener() {
@Override
public void fetchPostSuccess(Post post) {
if (!isAdded()) {
return;
}
mPost = post;
mPostAdapter = new PostDetailRecyclerViewAdapter(activity,
ViewPostDetailFragment.this, mExecutor, mCustomThemeWrapper,
mRetrofit.getRetrofit(), mOauthRetrofit, mGfycatRetrofit, mRedgifsRetrofit,
mStreamableApiProvider, mRedditDataRoomDatabase, mGlide, mSeparatePostAndComments,
mAccessToken, mAccountName, mPost, mLocale, mSharedPreferences,
mCurrentAccountSharedPreferences, mNsfwAndSpoilerSharedPreferences,
mPostDetailsSharedPreferences, mExoCreator,
post1 -> EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)));
mSwipeRefreshLayout.setRefreshing(false);
FetchComment.fetchComments(mExecutor, new Handler(), mRetrofit.getRetrofit(), mAccessToken, subredditId, mSingleCommentId, sortType, mExpandChildren, 1, new FetchComment.FetchCommentListener() {
@Override
public void onFetchCommentSuccess(ArrayList<Comment> expandedComments, Integer parentId, ArrayList<Integer> children) {
pages_loaded++;
mCommentsAdapter = new CommentsRecyclerViewAdapter(activity,
ViewPostDetailFragment.this, mCustomThemeWrapper, mExecutor,
mRetrofit.getRetrofit(), mOauthRetrofit, mAccessToken, mAccountName, mPost, mLocale,
mSingleCommentId, isSingleCommentThreadMode, mSharedPreferences,
new CommentsRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() {
@Override
public void onParseCommentSuccess(ArrayList<Comment> topLevelComments, ArrayList<Comment> expandedComments, Integer parentId, ArrayList<Integer> moreChildrenIds) {
ViewPostDetailFragment.this.children = moreChildrenIds;
hasMoreChildren = children.size() != 0;
mCommentsAdapter.addComments(expandedComments, hasMoreChildren);
if (children.size() > 0) {
(mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).clearOnScrollListeners();
(mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (!mIsSmoothScrolling && !mLockFab) {
if (!recyclerView.canScrollVertically(1)) {
activity.hideFab();
} else {
if (dy > 0) {
if (mSwipeUpToHideFab) {
activity.showFab();
} else {
activity.hideFab();
}
} else {
if (mSwipeUpToHideFab) {
activity.hideFab();
} else {
activity.showFab();
}
}
}
}
if (!isLoadingMoreChildren && loadMoreChildrenSuccess) {
int visibleItemCount = (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager().getChildCount();
int totalItemCount = (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager().getItemCount();
int firstVisibleItemPosition = ((LinearLayoutManagerBugFixed) (mCommentsRecyclerView == null ? mRecyclerView : mCommentsRecyclerView).getLayoutManager()).findFirstVisibleItemPosition();
if ((visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) {
fetchMoreComments();
}
}
}
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
mIsSmoothScrolling = false;
}
}
});
}
public void retryFetchingComments() {
fetchCommentsRespectRecommendedSort(false);
}
@Override
public void onParseCommentFailed() {
mCommentsAdapter.initiallyLoadCommentsFailed();
public void retryFetchingMoreComments() {
isLoadingMoreChildren = false;
loadMoreChildrenSuccess = true;
fetchMoreComments();
}
@Override
public SortType.Type getSortType() {
return sortType;
}
});
if (mCommentsRecyclerView != null) {
mRecyclerView.setAdapter(mPostAdapter);
mCommentsRecyclerView.setAdapter(mCommentsAdapter);
} else {
mConcatAdapter = new ConcatAdapter(mPostAdapter, mCommentsAdapter);
mRecyclerView.setAdapter(mConcatAdapter);
}
if (mRespectSubredditRecommendedSortType) {
fetchCommentsRespectRecommendedSort(false);
}
ViewPostDetailFragment.this.children = children;
hasMoreChildren = false;
mCommentsAdapter.addComments(expandedComments, hasMoreChildren);
}
}
@Override
public void onParsePostFail() {
showErrorView(subredditId);
}
});
} else {
showErrorView(subredditId);
}
}
@Override
public void onFetchCommentFailed() {
if (isAdded()) {
showErrorView(subredditId);
}
}
});
}
@Override
public void fetchPostFailed() {
if (isAdded()) {
showMessage(R.string.refresh_post_failed);
isRefreshing = false;
}
}
});
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
if (isAdded()) {
showErrorView(subredditId);
}
}
});
}
private void fetchCommentsRespectRecommendedSort(boolean changeRefreshState, SortType.Type sortType) {
@@ -1598,7 +1533,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic
}
}
private void showErrorView(String subredditId) {
private void showErrorView(int subredditId) {
mSwipeRefreshLayout.setRefreshing(false);
mFetchPostInfoLinearLayout.setVisibility(View.VISIBLE);
mFetchPostInfoLinearLayout.setOnClickListener(view -> fetchPostAndCommentsById(subredditId));

View File

@@ -18,13 +18,15 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.Executor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -151,16 +153,27 @@ public class ParsePost {
String author = creator.getString("name");
String authorFull = LemmyUtils.actorID2FullName(creator.getString("actor_id"));
long postTimeMillis = 0;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
postTimeMillis = ZonedDateTime.parse(post.getString("published"),
DateTimeFormatter.ISO_DATE_TIME.withZone(ZoneId.of("Z"))).toInstant().toEpochMilli();
String dateStr = post.getString("published");
dateStr = dateStr.substring(0, dateStr.lastIndexOf(".") + 4) + 'Z';
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
Date date = sdf.parse(dateStr);
if (date != null) {
postTimeMillis = date.getTime();
}
} catch (ParseException e) {
e.printStackTrace();
}
String title = post.getString("name");
String permalink = post.getString("ap_id");
int score = counts.getInt("score");
int voteType = 0;
int nComments = counts.getInt("comments");
int upvoteRatio = 100 * counts.getInt("upvotes") / max(counts.getInt("upvotes") + counts.getInt("downvotes"),1);
int upvoteRatio = 100 * counts.getInt("upvotes") / max(counts.getInt("upvotes") + counts.getInt("downvotes"), 1);
boolean hidden = community.getBoolean("hidden");
boolean nsfw = post.getBoolean("nsfw");
boolean locked = post.getBoolean("locked");
@@ -501,8 +514,23 @@ public class ParsePost {
post.setStreamableShortCode(shortCode);
}
}
} catch (IllegalArgumentException ignore) { }
} else if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) {
} catch (IllegalArgumentException ignore) {
}
} else if (post.getPostType() == Post.TEXT_TYPE) {
List<ImageInfo> images = extractImages(post.getSelfText());
if (images.size() == 1) {
post.setPostType(Post.IMAGE_TYPE);
post.setUrl(images.get(0).imageUrl);
} else if (images.size() > 1) {
post.setPostType(Post.GALLERY_TYPE);
ArrayList<Post.Gallery> gallery = new ArrayList<>();
for (ImageInfo image : images) {
String[] imagePath = image.getImageUrl().split(Pattern.quote("/"));
gallery.add(new Post.Gallery("image/jpg", image.getImageUrl(), "", imagePath[imagePath.length - 1], image.caption, ""));
}
post.setGallery(gallery);
}
if (!data.isNull(JSONUtils.GALLERY_DATA_KEY)) {
JSONArray galleryIdsArray = data.getJSONObject(JSONUtils.GALLERY_DATA_KEY).getJSONArray(JSONUtils.ITEMS_KEY);
JSONObject galleryObject = data.getJSONObject(JSONUtils.MEDIA_METADATA_KEY);
@@ -674,4 +702,40 @@ public class ParsePost {
}
}
}
static class ImageInfo {
private String caption;
private String imageUrl;
public ImageInfo(String caption, String imageUrl) {
this.caption = caption;
this.imageUrl = imageUrl;
}
public String getCaption() {
return caption;
}
public String getImageUrl() {
return imageUrl;
}
}
public static List<ImageInfo> extractImages(String markdown) {
List<ImageInfo> images = new ArrayList<>();
// Regular expression to match markdown image syntax ![alt text](image URL)
Pattern pattern = Pattern.compile("!\\[(.*?)\\]\\((.*?)\\)");
Matcher matcher = pattern.matcher(markdown);
// Find all matches and extract image URLs and captions
while (matcher.find()) {
String caption = matcher.group(1);
String imageUrl = matcher.group(2);
images.add(new ImageInfo(caption, imageUrl));
}
return images;
}
}

View File

@@ -36,26 +36,12 @@ public class AboutPreferenceFragment extends CustomFontPreferenceFragmentCompat
if (openSourcePreference != null) {
openSourcePreference.setOnPreferenceClickListener(preference -> {
Intent intent = new Intent(activity, LinkResolverActivity.class);
intent.setData(Uri.parse("https://github.com/Docile-Alligator/Infinity-For-Reddit"));
intent.setData(Uri.parse("https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy"));
activity.startActivity(intent);
return true;
});
}
if (ratePreference != null) {
ratePreference.setOnPreferenceClickListener(preference -> {
Intent playStoreIntent = new Intent(Intent.ACTION_VIEW);
playStoreIntent.setData(Uri.parse("market://details?id=eu.toldi.infinityforlemmy"));
if (playStoreIntent.resolveActivity(activity.getPackageManager()) != null) {
activity.startActivity(playStoreIntent);
} else {
Intent intent = new Intent(activity, LinkResolverActivity.class);
intent.setData(Uri.parse("https://play.google.com/store/apps/details?id=eu.toldi.infinityforlemmy"));
activity.startActivity(intent);
}
return true;
});
}
if (emailPreference != null) {
emailPreference.setOnPreferenceClickListener(preference -> {
@@ -82,7 +68,7 @@ public class AboutPreferenceFragment extends CustomFontPreferenceFragmentCompat
if (subredditPreference != null) {
subredditPreference.setOnPreferenceClickListener(preference -> {
Intent intent = new Intent(activity, LinkResolverActivity.class);
intent.setData(Uri.parse("https://www.reddit.com/r/Infinity_For_Reddit"));
intent.setData(Uri.parse("https://lemdro.id/c/infinityforlemmy"));
activity.startActivity(intent);
return true;
});

View File

@@ -6,7 +6,6 @@ import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTI
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import androidx.biometric.BiometricManager;
@@ -17,7 +16,6 @@ import javax.inject.Named;
import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.activities.LinkResolverActivity;
import eu.toldi.infinityforlemmy.activities.PostFilterPreferenceActivity;
import eu.toldi.infinityforlemmy.customviews.CustomFontPreferenceFragmentCompat;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
@@ -52,26 +50,5 @@ public class MainPreferenceFragment extends CustomFontPreferenceFragmentCompat {
return true;
});
}
if (privacyPolicyPreference != null) {
privacyPolicyPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent intent = new Intent(activity, LinkResolverActivity.class);
intent.setData(Uri.parse("https://docile-alligator.github.io/"));
activity.startActivity(intent);
return true;
}
});
}
if (redditUserAgreementPreference != null) {
redditUserAgreementPreference.setOnPreferenceClickListener(preference -> {
Intent intent = new Intent(activity, LinkResolverActivity.class);
intent.setData(Uri.parse("https://www.redditinc.com/policies/user-agreement-september-12-2021"));
activity.startActivity(intent);
return true;
});
}
}
}

View File

@@ -55,6 +55,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/instance_url"
android:inputType="textUri"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
@@ -90,6 +91,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/user_password"
android:maxLength="60"
android:maxLines="1"
android:password="true" />

View File

@@ -48,25 +48,6 @@
android:focusable="true"
android:background="?attr/selectableItemBackground" />
<TextView
android:id="@+id/video_type_linear_layout_post_type_bottom_sheet_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingStart="32dp"
android:paddingEnd="32dp"
android:text="@string/bottom_sheet_post_video"
android:textColor="?attr/primaryTextColor"
android:textSize="?attr/font_default"
android:fontFamily="?attr/font_family"
android:drawableStart="@drawable/ic_outline_video_24dp"
android:drawablePadding="48dp"
android:clickable="true"
android:focusable="true"
android:background="?attr/selectableItemBackground" />
<TextView
android:id="@+id/image_type_linear_layout_post_type_bottom_sheet_fragment"
android:layout_width="match_parent"
@@ -86,44 +67,6 @@
android:focusable="true"
android:background="?attr/selectableItemBackground" />
<TextView
android:id="@+id/gallery_type_linear_layout_post_type_bottom_sheet_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingStart="32dp"
android:paddingEnd="32dp"
android:text="@string/bottom_sheet_post_gallery"
android:textColor="?attr/primaryTextColor"
android:textSize="?attr/font_default"
android:fontFamily="?attr/font_family"
android:drawableStart="@drawable/ic_gallery_24dp"
android:drawablePadding="48dp"
android:clickable="true"
android:focusable="true"
android:background="?attr/selectableItemBackground" />
<TextView
android:id="@+id/poll_type_linear_layout_post_type_bottom_sheet_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingStart="32dp"
android:paddingEnd="32dp"
android:text="@string/bottom_sheet_post_poll"
android:textColor="?attr/primaryTextColor"
android:textSize="?attr/font_default"
android:fontFamily="?attr/font_family"
android:drawableStart="@drawable/ic_poll_24dp"
android:drawablePadding="48dp"
android:clickable="true"
android:focusable="true"
android:background="?attr/selectableItemBackground" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View File

@@ -468,7 +468,7 @@
<string name="settings_credits_best_rocket_icon_summary">Icon made by Freepik from www.flaticon.com</string>
<string name="settings_credits_material_icons_title">Material Icons</string>
<string name="settings_open_source_title">Open Source</string>
<string name="settings_open_source_summary">Star it on Github if you like this app</string>
<string name="settings_open_source_summary">Star it on Codeberg if you like this app</string>
<string name="settings_rate_title">Rate on Google Play</string>
<string name="settings_rate_summary">Give me a 5-star rating and I will be really happy</string>
<string name="settings_email_title">Mastodon</string>
@@ -476,7 +476,7 @@
<string name="settings_reddit_account_title">Lemmy Account</string>
<string name="settings_reddit_account_summary">\@bazsalanszky@lemmy.toldi.eu</string>
<string name="settings_community_title">Community</string>
<string name="settings_community_summary">r/Infinity_For_Reddit</string>
<string name="settings_community_summary">!infinityforlemmy@lemdro.id</string>
<string name="settings_share_title">Share</string>
<string name="settings_share_summary">Share this app to other people if you enjoy it</string>
<string name="settings_privacy_policy_title">Privacy Policy</string>

View File

@@ -21,11 +21,6 @@
app:title="@string/settings_open_source_title"
app:summary="@string/settings_open_source_summary" />
<eu.toldi.infinityforlemmy.customviews.CustomFontPreference
android:key="rate"
app:title="@string/settings_rate_title"
app:summary="@string/settings_rate_summary" />
<eu.toldi.infinityforlemmy.customviews.CustomFontPreference
android:key="email"
app:title="@string/settings_email_title"

View File

@@ -87,14 +87,4 @@
app:title="@string/settings_about_master_title"
app:fragment="eu.toldi.infinityforlemmy.settings.AboutPreferenceFragment" />
<eu.toldi.infinityforlemmy.customviews.CustomFontPreference
android:key="privacy_policy"
app:icon="@drawable/ic_outline_privacy_policy_24dp"
app:title="@string/settings_privacy_policy_title" />
<eu.toldi.infinityforlemmy.customviews.CustomFontPreference
android:key="reddit_user_agreement"
app:icon="@drawable/ic_outline_user_agreement_24dp"
app:title="@string/settings_reddit_user_agreement_title" />
</androidx.preference.PreferenceScreen>