Browse Source
Merge remote-tracking branch 'origin/new-posts-grid' into new-posts-grid
renovate/org.robolectric-robolectric-4.x
Merge remote-tracking branch 'origin/new-posts-grid' into new-posts-grid
renovate/org.robolectric-robolectric-4.x
Ammar Githam
4 years ago
30 changed files with 137 additions and 444 deletions
-
7.github/CONTRIBUTING.md
-
4app/build.gradle
-
10app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java
-
3app/src/main/java/awais/instagrabber/adapters/viewholder/comments/ChildCommentViewHolder.java
-
3app/src/main/java/awais/instagrabber/adapters/viewholder/comments/ParentCommentViewHolder.java
-
2app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java
-
340app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java
-
1app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java
-
1app/src/main/java/awais/instagrabber/utils/LocaleUtils.java
-
5app/src/main/java/awais/instagrabber/webservices/AddCookiesInterceptor.java
-
2app/src/main/java/awais/instagrabber/webservices/ProfileService.java
-
19app/src/main/res/layout/dialog_post_view.xml
-
16app/src/main/res/layout/item_comment.xml
-
14app/src/main/res/layout/item_comment_small.xml
-
2app/src/main/res/values-de/strings.xml
-
2app/src/main/res/values-es/strings.xml
-
4app/src/main/res/values-fa/arrays.xml
-
2app/src/main/res/values-fa/strings.xml
-
2app/src/main/res/values-fr/strings.xml
-
44app/src/main/res/values-hi/strings.xml
-
2app/src/main/res/values-in/strings.xml
-
2app/src/main/res/values-it/strings.xml
-
2app/src/main/res/values-mk/strings.xml
-
2app/src/main/res/values-pl/strings.xml
-
66app/src/main/res/values-pt/strings.xml
-
2app/src/main/res/values-tr/strings.xml
-
2app/src/main/res/values-vi/strings.xml
-
2app/src/main/res/values-zh/strings.xml
-
10app/src/main/res/values/strings.xml
-
8gradle/wrapper/gradle-wrapper.properties
@ -1,7 +1,8 @@ |
|||
## WARNING |
|||
|
|||
* All forks must respect [GPLv3](https://www.gnu.org/licenses/gpl-3.0.html). Please report violations in Issues or [confidentially](https://austinhuang.me/#hey-you-look-cool). |
|||
* Although publishing a fork is allowed by license, it is strongly discouraged to do so as it divides the effort and creates confusion. It is, therefore, recommended to send a pull request back to us, so that the larger community can enjoy your improvement. (This does not apply if you're adapting this app for a different platform other than Instagram.) |
|||
* Some people have asked me about publishing a "commercial" fork that serves ads. However, if you do properly comply with GPLv3, users would realize that the original non-commercial version exists and, in turn, abandon your fork. And if you don't comply, you get copystriked. |
|||
* Although publishing a fork is allowed by license, it is strongly discouraged to do so as it divides the effort and creates confusion (as well as for the reason above). It is, therefore, recommended to send a pull request back to us, so that the larger community can enjoy your improvement. (This does not apply if you're adapting this app for a different platform other than Instagram.) |
|||
|
|||
## Contributing |
|||
|
|||
@ -35,11 +36,11 @@ If you have questions, don't be afraid to ask for help from any current maintain |
|||
|
|||
## I found a bug! |
|||
|
|||
**Please read [FAQ](https://instagrabber.austinhuang.me/faq) first.** |
|||
**Please read [FAQ](https://barinsta.austinhuang.me/en/latest/faq/) first.** |
|||
|
|||
Bugs are inevitable during active development, as nobody can cover all the possible test cases. |
|||
|
|||
You can either email your crash dump to `instagrabber@austinhuang.me` (The crash reporter will fill in this address for you) or create a GitHub issue. If you're on GitHub, please follow the template. If you're reporting by email, your email address will be published in the GitHub issue. You can contact me [privately](https://austinhuang.me/#hey-you-look-cool) or [through support channels](https://instagrabber.austinhuang.me/#what-can-i-do) to remove it. |
|||
You can either email your crash dump to `bar[email protected]` (The crash reporter will fill in this address for you) or create a GitHub issue. If you're on GitHub, please follow the template. If you're reporting by email, your email address will be published in the GitHub issue. You can contact me [privately](https://austinhuang.me/#hey-you-look-cool) or [through support channels](https://barinsta.austinhuang.me/en/latest/#contact-us) to remove it. |
|||
|
|||
Generally, reporting bugs directly in support channels is not recommended, as they can be difficult to find. |
|||
|
|||
|
@ -1,340 +0,0 @@ |
|||
// package awais.instagrabber.fragments; |
|||
// |
|||
// import android.content.Context; |
|||
// import android.content.DialogInterface; |
|||
// import android.content.pm.PackageManager; |
|||
// import android.os.AsyncTask; |
|||
// import android.os.Bundle; |
|||
// import android.util.Log; |
|||
// import android.view.LayoutInflater; |
|||
// import android.view.View; |
|||
// import android.view.ViewGroup; |
|||
// |
|||
// import androidx.annotation.NonNull; |
|||
// import androidx.annotation.Nullable; |
|||
// import androidx.appcompat.app.AlertDialog; |
|||
// import androidx.fragment.app.Fragment; |
|||
// import androidx.fragment.app.FragmentActivity; |
|||
// import androidx.lifecycle.ViewModelProvider; |
|||
// import androidx.navigation.NavDirections; |
|||
// import androidx.navigation.fragment.NavHostFragment; |
|||
// import androidx.viewpager2.widget.ViewPager2; |
|||
// |
|||
// import java.util.ArrayList; |
|||
// import java.util.Arrays; |
|||
// import java.util.Collections; |
|||
// import java.util.List; |
|||
// |
|||
// import awais.instagrabber.R; |
|||
// import awais.instagrabber.adapters.PostViewAdapter; |
|||
// import awais.instagrabber.adapters.PostViewAdapter.OnPostViewChildViewClickListener; |
|||
// import awais.instagrabber.asyncs.PostFetcher; |
|||
// import awais.instagrabber.asyncs.i.iPostFetcher; |
|||
// import awais.instagrabber.databinding.FragmentPostViewBinding; |
|||
// import awais.instagrabber.interfaces.FetchListener; |
|||
// import awais.instagrabber.interfaces.MentionClickListener; |
|||
// import awais.instagrabber.models.FeedModel; |
|||
// import awais.instagrabber.models.ViewerPostModel; |
|||
// import awais.instagrabber.models.ViewerPostModelWrapper; |
|||
// import awais.instagrabber.models.enums.DownloadMethod; |
|||
// import awais.instagrabber.utils.Constants; |
|||
// import awais.instagrabber.utils.CookieUtils; |
|||
// import awais.instagrabber.utils.DownloadUtils; |
|||
// import awais.instagrabber.utils.Utils; |
|||
// import awais.instagrabber.viewmodels.ViewerPostViewModel; |
|||
// import awais.instagrabber.webservices.MediaService; |
|||
// import awais.instagrabber.webservices.ServiceCallback; |
|||
// |
|||
// import static androidx.core.content.ContextCompat.checkSelfPermission; |
|||
// import static awais.instagrabber.utils.Utils.settingsHelper; |
|||
// |
|||
// public class PostViewFragment extends Fragment { |
|||
// private static final String TAG = "PostViewFragment"; |
|||
// private static final String COOKIE = settingsHelper.getString(Constants.COOKIE); |
|||
// |
|||
// private FragmentActivity fragmentActivity; |
|||
// private FragmentPostViewBinding binding; |
|||
// private ViewPager2 root; |
|||
// private boolean shouldRefresh = true; |
|||
// private ViewerPostViewModel viewerPostViewModel; |
|||
// private boolean isId; |
|||
// private int currentPostIndex; |
|||
// private List<String> idOrCodeList; |
|||
// private boolean hasInitialResult = false; |
|||
// private PostViewAdapter adapter; |
|||
// private boolean session; |
|||
// private MediaService mediaService; |
|||
// |
|||
// private FetchListener<FeedModel> pfl = result -> { |
|||
// if (result == null) return; |
|||
// final List<ViewerPostModelWrapper> viewerPostModels = viewerPostViewModel.getList().getValue(); |
|||
// final List<ViewerPostModelWrapper> temp = viewerPostModels == null ? new ArrayList<>(idOrCodeList.size()) |
|||
// : new ArrayList<>(viewerPostModels); |
|||
// String idOrCode = isId ? result.getPostId() : result.getShortCode(); |
|||
// if (idOrCode == null) return; |
|||
// if (isId) { |
|||
// // the post id is appended with `_` in the result |
|||
// idOrCode = idOrCode.substring(0, idOrCode.indexOf('_')); |
|||
// } |
|||
// final int index = idOrCodeList.indexOf(idOrCode); |
|||
// if (index < 0) return; |
|||
// final ViewerPostModelWrapper viewerPostModelWrapper = temp.get(index); |
|||
// viewerPostModelWrapper.setViewerPostModels(result.getSliderItems() == null ? Collections.emptyList() : result.getSliderItems()); |
|||
// temp.set(index, viewerPostModelWrapper); |
|||
// viewerPostViewModel.getList().setValue(temp); |
|||
// adapter.notifyItemChanged(index); |
|||
// if (!hasInitialResult) { |
|||
// Log.d(TAG, "setting delayed position to: " + currentPostIndex); |
|||
// binding.getRoot() |
|||
// .postDelayed(() -> binding.getRoot().setCurrentItem(currentPostIndex), 200); |
|||
// } |
|||
// hasInitialResult = true; |
|||
// }; |
|||
// private MentionClickListener mentionListener = (view, text, isHashtag, isLocation) -> { |
|||
// if (isHashtag) { |
|||
// final NavDirections action = PostViewFragmentDirections |
|||
// .actionGlobalHashTagFragment(text); |
|||
// NavHostFragment.findNavController(this).navigate(action); |
|||
// return; |
|||
// } |
|||
// if (isLocation) { |
|||
// final NavDirections action = PostViewFragmentDirections |
|||
// .actionGlobalLocationFragment(text); |
|||
// NavHostFragment.findNavController(this).navigate(action); |
|||
// return; |
|||
// } |
|||
// final NavDirections action = PostViewFragmentDirections |
|||
// .actionGlobalProfileFragment("@" + text); |
|||
// NavHostFragment.findNavController(this).navigate(action); |
|||
// }; |
|||
// private OnPostViewChildViewClickListener clickListener = (v, wrapper, postPosition, childPosition) -> { |
|||
// final ViewerPostModel postModel = wrapper.getViewerPostModels().get(0); |
|||
// final String username = postModel.getProfileModel().getUsername(); |
|||
// final int id = v.getId(); |
|||
// switch (id) { |
|||
// case R.id.viewerCaption: |
|||
// break; |
|||
// case R.id.btnComments: |
|||
// String postId = postModel.getPostId(); |
|||
// if (postId.contains("_")) postId = postId.substring(0, postId.indexOf("_")); |
|||
// final NavDirections commentsAction = PostViewFragmentDirections.actionGlobalCommentsViewerFragment( |
|||
// postModel.getShortCode(), |
|||
// postId, |
|||
// postModel.getProfileModel().getId() |
|||
// ); |
|||
// NavHostFragment.findNavController(this).navigate(commentsAction); |
|||
// break; |
|||
// case R.id.btnDownload: |
|||
// final Context context = getContext(); |
|||
// if (context == null) return; |
|||
// if (checkSelfPermission(context, |
|||
// DownloadUtils.PERMS[0]) == PackageManager.PERMISSION_GRANTED) { |
|||
// showDownloadDialog(wrapper.getViewerPostModels(), |
|||
// childPosition, |
|||
// username); |
|||
// return; |
|||
// } |
|||
// requestPermissions(DownloadUtils.PERMS, 8020); |
|||
// break; |
|||
// case R.id.ivProfilePic: |
|||
// case R.id.title: |
|||
// mentionListener.onClick(null, username, false, false); |
|||
// break; |
|||
// case R.id.btnLike: |
|||
// if (mediaService != null) { |
|||
// final String userId = CookieUtils.getUserIdFromCookie(COOKIE); |
|||
// final String csrfToken = CookieUtils.getCsrfTokenFromCookie(COOKIE); |
|||
// v.setEnabled(false); |
|||
// final ServiceCallback<Boolean> likeCallback = new ServiceCallback<Boolean>() { |
|||
// @Override |
|||
// public void onSuccess(final Boolean result) { |
|||
// v.setEnabled(true); |
|||
// if (result) { |
|||
// postModel.setManualLike(!postModel.getLike()); |
|||
// adapter.notifyItemChanged(postPosition); |
|||
// return; |
|||
// } |
|||
// Log.e(TAG, "like/unlike unsuccessful!"); |
|||
// } |
|||
// |
|||
// @Override |
|||
// public void onFailure(final Throwable t) { |
|||
// v.setEnabled(true); |
|||
// Log.e(TAG, "Error during like/unlike", t); |
|||
// } |
|||
// }; |
|||
// if (!postModel.getLike()) { |
|||
// mediaService.like(postModel.getPostId(), userId, csrfToken, likeCallback); |
|||
// } else { |
|||
// mediaService.unlike(postModel.getPostId(), userId, csrfToken, likeCallback); |
|||
// } |
|||
// } |
|||
// break; |
|||
// case R.id.btnBookmark: |
|||
// if (mediaService != null) { |
|||
// final String userId = CookieUtils.getUserIdFromCookie(COOKIE); |
|||
// final String csrfToken = CookieUtils.getCsrfTokenFromCookie(COOKIE); |
|||
// v.setEnabled(false); |
|||
// final ServiceCallback<Boolean> saveCallback = new ServiceCallback<Boolean>() { |
|||
// @Override |
|||
// public void onSuccess(final Boolean result) { |
|||
// v.setEnabled(true); |
|||
// if (result) { |
|||
// // postModel.setBookmarked(!postModel.isSaved()); |
|||
// adapter.notifyItemChanged(postPosition); |
|||
// return; |
|||
// } |
|||
// Log.e(TAG, "save/unsave unsuccessful!"); |
|||
// } |
|||
// |
|||
// @Override |
|||
// public void onFailure(final Throwable t) { |
|||
// v.setEnabled(true); |
|||
// Log.e(TAG, "Error during save/unsave", t); |
|||
// } |
|||
// }; |
|||
// if (!postModel.isSaved()) { |
|||
// mediaService.save(postModel.getPostId(), userId, csrfToken, saveCallback); |
|||
// } else { |
|||
// mediaService.unsave(postModel.getPostId(), userId, csrfToken, saveCallback); |
|||
// } |
|||
// } |
|||
// break; |
|||
// } |
|||
// }; |
|||
// private PostViewAdapter.OnPostCaptionLongClickListener captionLongClickListener = text -> { |
|||
// final Context context = getContext(); |
|||
// if (context == null) return; |
|||
// Utils.copyText(context, text); |
|||
// }; |
|||
// |
|||
// @Override |
|||
// public void onCreate(@Nullable final Bundle savedInstanceState) { |
|||
// super.onCreate(savedInstanceState); |
|||
// fragmentActivity = getActivity(); |
|||
// mediaService = MediaService.getInstance(); |
|||
// } |
|||
// |
|||
// @Nullable |
|||
// @Override |
|||
// public View onCreateView(@NonNull final LayoutInflater inflater, |
|||
// @Nullable final ViewGroup container, |
|||
// @Nullable final Bundle savedInstanceState) { |
|||
// if (root != null) { |
|||
// shouldRefresh = false; |
|||
// return root; |
|||
// } |
|||
// binding = FragmentPostViewBinding.inflate(inflater, container, false); |
|||
// root = binding.getRoot(); |
|||
// setupViewPager(); |
|||
// return root; |
|||
// } |
|||
// |
|||
// @Override |
|||
// public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { |
|||
// if (!shouldRefresh) return; |
|||
// init(); |
|||
// shouldRefresh = false; |
|||
// } |
|||
// |
|||
// private void setupViewPager() { |
|||
// viewerPostViewModel = new ViewModelProvider(fragmentActivity) |
|||
// .get(ViewerPostViewModel.class); |
|||
// adapter = new PostViewAdapter(clickListener, captionLongClickListener, mentionListener); |
|||
// root.setAdapter(adapter); |
|||
// root.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { |
|||
// |
|||
// @Override |
|||
// public void onPageSelected(final int position) { |
|||
// // Log.d(TAG, "onPageSelected: " + position + ", hasInitialResult: " + hasInitialResult); |
|||
// if (!hasInitialResult) { |
|||
// return; |
|||
// } |
|||
// currentPostIndex = position; |
|||
// fetchPost(); |
|||
// } |
|||
// }); |
|||
// viewerPostViewModel.getList().observe(fragmentActivity, list -> adapter.submitList(list)); |
|||
// } |
|||
// |
|||
// private void init() { |
|||
// if (getArguments() == null) return; |
|||
// final PostViewFragmentArgs fragmentArgs = PostViewFragmentArgs.fromBundle(getArguments()); |
|||
// final String[] idOrCodeArray = fragmentArgs.getIdOrCodeArray(); |
|||
// if (idOrCodeArray.length == 0) return; |
|||
// currentPostIndex = fragmentArgs.getIndex(); |
|||
// if (currentPostIndex < 0) return; |
|||
// if (currentPostIndex >= idOrCodeArray.length) return; |
|||
// idOrCodeList = Arrays.asList(idOrCodeArray); |
|||
// viewerPostViewModel.getList().setValue(createPlaceholderModels(idOrCodeArray.length)); |
|||
// isId = fragmentArgs.getIsId(); |
|||
// fetchPost(); |
|||
// } |
|||
// |
|||
// private List<ViewerPostModelWrapper> createPlaceholderModels(final int size) { |
|||
// final List<ViewerPostModelWrapper> viewerPostModels = new ArrayList<>(size); |
|||
// for (int i = 0; i < size; i++) { |
|||
// // viewerPostModels.add(new ViewerPostModel[]{ViewerPostModel.getDefaultModel(-i, "")}); |
|||
// viewerPostModels.add(new ViewerPostModelWrapper(i, null)); |
|||
// } |
|||
// return viewerPostModels; |
|||
// } |
|||
// |
|||
// private void fetchPost() { |
|||
// // Log.d(TAG, "fetchPost, currentPostIndex: " + currentPostIndex); |
|||
// final List<ViewerPostModelWrapper> list = viewerPostViewModel.getList().getValue(); |
|||
// if (list != null) { |
|||
// final ViewerPostModelWrapper viewerPostModels = list.get(currentPostIndex); |
|||
// if (viewerPostModels != null && viewerPostModels |
|||
// .getViewerPostModels() != null && viewerPostModels |
|||
// .getViewerPostModels().size() > 0) { |
|||
// Log.d(TAG, "returning without fetching"); |
|||
// return; |
|||
// } |
|||
// } |
|||
// if (currentPostIndex >= idOrCodeList.size() || currentPostIndex < 0) return; |
|||
// final String idOrShortCode = idOrCodeList.get(currentPostIndex); |
|||
// if (isId) { |
|||
// new iPostFetcher(idOrShortCode, pfl).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
|||
// return; |
|||
// } |
|||
// new PostFetcher(idOrShortCode, pfl).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
|||
// } |
|||
// |
|||
// private void showDownloadDialog(final List<ViewerPostModel> postModels, |
|||
// final int childPosition, |
|||
// final String username) { |
|||
// final List<ViewerPostModel> postModelsToDownload = new ArrayList<>(); |
|||
// final Context context = getContext(); |
|||
// if (context == null) return; |
|||
// if (!session && postModels.size() > 1) { |
|||
// final DialogInterface.OnClickListener clickListener = (dialog, which) -> { |
|||
// if (which == DialogInterface.BUTTON_NEGATIVE) { |
|||
// postModelsToDownload.addAll(postModels); |
|||
// } else if (which == DialogInterface.BUTTON_POSITIVE) { |
|||
// postModelsToDownload.add(postModels.get(childPosition)); |
|||
// } else { |
|||
// session = true; |
|||
// postModelsToDownload.add(postModels.get(childPosition)); |
|||
// } |
|||
// if (postModelsToDownload.size() > 0) { |
|||
// DownloadUtils.batchDownload(context, |
|||
// username, |
|||
// DownloadMethod.DOWNLOAD_POST_VIEWER, |
|||
// postModelsToDownload); |
|||
// } |
|||
// }; |
|||
// new AlertDialog.Builder(context) |
|||
// .setTitle(R.string.post_viewer_download_dialog_title) |
|||
// .setMessage(R.string.post_viewer_download_message) |
|||
// .setNeutralButton(R.string.post_viewer_download_session, clickListener) |
|||
// .setPositiveButton(R.string.post_viewer_download_current, clickListener) |
|||
// .setNegativeButton(R.string.post_viewer_download_album, clickListener).show(); |
|||
// } else { |
|||
// DownloadUtils.batchDownload(context, |
|||
// username, |
|||
// DownloadMethod.DOWNLOAD_POST_VIEWER, |
|||
// Collections.singletonList(postModels.get(childPosition))); |
|||
// } |
|||
// } |
|||
// } |
@ -1,6 +1,8 @@ |
|||
distributionBase=GRADLE_USER_HOME |
|||
distributionPath=wrapper/dists |
|||
distributionSha256Sum=5252d2f1a984e5518e604678b3964bb0227c4573fcc880b92548bc687c851704 |
|||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-rc-5-all.zip |
|||
distributionSha256Sum=0080de8491f0918e4f529a6db6820fa0b9e818ee2386117f4394f95feb1d5583 |
|||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip |
|||
# https://gradle.org/releases/ |
|||
# https://gradle.org/release-checksums/ |
|||
zipStoreBase=GRADLE_USER_HOME |
|||
zipStorePath=wrapper/dists |
|||
zipStorePath=wrapper/dists |
Write
Preview
Loading…
Cancel
Save
Reference in new issue