diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 613d579d..9b389438 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -177,6 +177,15 @@ android:value=".activities.Main" /> + + + + + { @@ -779,8 +788,9 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener { final String myId = Utils.getUserIdFromCookie(Utils.settingsHelper.getString(Constants.COOKIE)); if (!profileId.equals(myId)) { + main.mainBinding.btnTagged.setVisibility(View.GONE); + main.mainBinding.btnSaved.setVisibility(View.GONE); main.mainBinding.btnFollow.setVisibility(View.VISIBLE); - main.mainBinding.btnFollow.setOnClickListener(profileActionListener); if (profileModel.getFollowing() == true) { main.mainBinding.btnFollow.setText(R.string.unfollow); main.mainBinding.btnFollow.setBackgroundTintList(ColorStateList.valueOf(resources.getColor( @@ -797,30 +807,51 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener { R.color.btn_pink_background, null))); } main.mainBinding.btnRestrict.setVisibility(View.VISIBLE); - main.mainBinding.btnRestrict.setOnClickListener(profileActionListener); if (profileModel.getRestricted() == true) { main.mainBinding.btnRestrict.setText(R.string.unrestrict); main.mainBinding.btnRestrict.setBackgroundTintList(ColorStateList.valueOf(resources.getColor( - R.color.btn_blue_background, null))); + R.color.btn_green_background, null))); } else { main.mainBinding.btnRestrict.setText(R.string.restrict); main.mainBinding.btnRestrict.setBackgroundTintList(ColorStateList.valueOf(resources.getColor( R.color.btn_orange_background, null))); } - main.mainBinding.btnBlock.setVisibility(View.VISIBLE); - main.mainBinding.btnBlock.setOnClickListener(profileActionListener); - if (profileModel.getBlocked() == true) { - main.mainBinding.btnBlock.setText(R.string.unblock); - main.mainBinding.btnBlock.setBackgroundTintList(ColorStateList.valueOf(resources.getColor( - R.color.btn_green_background, null))); - } - else { - main.mainBinding.btnBlock.setText(R.string.block); - main.mainBinding.btnBlock.setBackgroundTintList(ColorStateList.valueOf(resources.getColor( - R.color.btn_red_background, null))); + if (profileModel.isReallyPrivate()) { + main.mainBinding.btnBlock.setVisibility(View.VISIBLE); + main.mainBinding.btnSaved.setVisibility(View.GONE); + main.mainBinding.btnTagged.setVisibility(View.GONE); + if (profileModel.getBlocked() == true) { + main.mainBinding.btnBlock.setText(R.string.unblock); + main.mainBinding.btnBlock.setBackgroundTintList(ColorStateList.valueOf(resources.getColor( + R.color.btn_green_background, null))); + } else { + main.mainBinding.btnBlock.setText(R.string.block); + main.mainBinding.btnBlock.setBackgroundTintList(ColorStateList.valueOf(resources.getColor( + R.color.btn_red_background, null))); + } + } else { + main.mainBinding.btnBlock.setVisibility(View.GONE); + main.mainBinding.btnSaved.setVisibility(View.VISIBLE); + main.mainBinding.btnTagged.setVisibility(View.VISIBLE); + if (profileModel.getBlocked() == true) { + main.mainBinding.btnSaved.setText(R.string.unblock); + main.mainBinding.btnSaved.setBackgroundTintList(ColorStateList.valueOf(resources.getColor( + R.color.btn_green_background, null))); + } else { + main.mainBinding.btnSaved.setText(R.string.block); + main.mainBinding.btnSaved.setBackgroundTintList(ColorStateList.valueOf(resources.getColor( + R.color.btn_red_background, null))); + } } } + else { + main.mainBinding.btnTagged.setVisibility(View.VISIBLE); + main.mainBinding.btnSaved.setVisibility(View.VISIBLE); + main.mainBinding.btnSaved.setText(R.string.saved); + main.mainBinding.btnSaved.setBackgroundTintList(ColorStateList.valueOf(resources.getColor( + R.color.btn_orange_background, null))); + } } else { if (Utils.dataBox.getFavorite(main.userQuery) != null) { main.mainBinding.btnFollow.setText(R.string.unfavorite); @@ -832,7 +863,6 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener { main.mainBinding.btnFollow.setBackgroundTintList(ColorStateList.valueOf(resources.getColor( R.color.btn_pink_background, null))); } - main.mainBinding.btnFollow.setOnClickListener(profileActionListener); main.mainBinding.btnFollow.setVisibility(View.VISIBLE); } @@ -864,7 +894,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener { span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0); main.mainBinding.mainFollowing.setText(span); - main.mainBinding.mainFullName.setText(profileModel.getName()); + main.mainBinding.mainFullName.setText(Utils.isEmpty(profileModel.getName()) ? profileModel.getUsername() : profileModel.getName()); CharSequence biography = profileModel.getBiography(); main.mainBinding.mainBiography.setCaptionIsExpandable(true); @@ -1163,6 +1193,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener { private final View.OnClickListener profileActionListener = new View.OnClickListener() { @Override public void onClick(final View v) { + final boolean iamme = Utils.getUserIdFromCookie(Utils.settingsHelper.getString(Constants.COOKIE)).equals(main.profileModel.getId()); if (!isLoggedIn && Utils.dataBox.getFavorite(main.userQuery) != null) { Utils.dataBox.delFavorite(new DataBox.FavoriteModel(main.userQuery, Long.parseLong(Utils.dataBox.getFavorite(main.userQuery).split("/")[1]), @@ -1176,10 +1207,20 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener { new ProfileAction().execute("follow"); } else if (v == main.mainBinding.btnRestrict) { new ProfileAction().execute("restrict"); - } else if (v == main.mainBinding.btnBlock) { + } else if (v == main.mainBinding.btnSaved && !iamme) { new ProfileAction().execute("block"); } else if (v == main.mainBinding.btnFollowTag) { new ProfileAction().execute("followtag"); + } else if (v == main.mainBinding.btnTagged) { + main.startActivity(new Intent(main, SavedViewer.class) + .putExtra(Constants.EXTRAS_INDEX, "%"+main.profileModel.getId()) + .putExtra(Constants.EXTRAS_USER, "@"+main.profileModel.getUsername()) + ); + } else if (v == main.mainBinding.btnSaved) { + main.startActivity(new Intent(main, SavedViewer.class) + .putExtra(Constants.EXTRAS_INDEX, "$"+main.profileModel.getId()) + .putExtra(Constants.EXTRAS_USER, "@"+main.profileModel.getUsername()) + ); } } }; diff --git a/app/src/main/java/awais/instagrabber/activities/CommentsViewer.java b/app/src/main/java/awais/instagrabber/activities/CommentsViewer.java index 5f031251..bb458a34 100755 --- a/app/src/main/java/awais/instagrabber/activities/CommentsViewer.java +++ b/app/src/main/java/awais/instagrabber/activities/CommentsViewer.java @@ -87,8 +87,6 @@ public final class CommentsViewer extends BaseLanguageActivity implements SwipeR new CommentsFetcher(shortCode, new FetchListener() { @Override public void onResult(final CommentModel[] commentModels) { - commentsBinding.toolbar.progressCircular.setVisibility(View.GONE); - commentsAdapter = new CommentsAdapter(commentModels, true, clickListener, mentionClickListener); commentsBinding.rvComments.setAdapter(commentsAdapter); @@ -105,8 +103,6 @@ public final class CommentsViewer extends BaseLanguageActivity implements SwipeR public void onResult(final CommentModel[] commentModels) { commentsBinding.swipeRefreshLayout.setRefreshing(false); - commentsBinding.toolbar.progressCircular.setVisibility(View.GONE); - commentsAdapter = new CommentsAdapter(commentModels, true, clickListener, mentionClickListener); commentsBinding.rvComments.setAdapter(commentsAdapter); diff --git a/app/src/main/java/awais/instagrabber/activities/Main.java b/app/src/main/java/awais/instagrabber/activities/Main.java index 6a6079c6..10eaa5c5 100755 --- a/app/src/main/java/awais/instagrabber/activities/Main.java +++ b/app/src/main/java/awais/instagrabber/activities/Main.java @@ -458,6 +458,9 @@ public final class Main extends BaseLanguageActivity { return; } } + else { + finish(); + } } @Override diff --git a/app/src/main/java/awais/instagrabber/activities/PostViewer.java b/app/src/main/java/awais/instagrabber/activities/PostViewer.java index d197a118..6dc0c4ba 100755 --- a/app/src/main/java/awais/instagrabber/activities/PostViewer.java +++ b/app/src/main/java/awais/instagrabber/activities/PostViewer.java @@ -268,7 +268,11 @@ public final class PostViewer extends BaseLanguageActivity { final List itemGetterItems; final boolean isMainSwipe; - if (itemGetType != null && Main.itemGetter != null) { + if (itemGetType == ItemGetType.SAVED_ITEMS && SavedViewer.itemGetter != null) { + itemGetterItems = SavedViewer.itemGetter.get(itemGetType); + isMainSwipe = !(itemGetterItems.size() < 1 || itemGetType == ItemGetType.SAVED_ITEMS && isFromShare); + } + else if (itemGetType != null && Main.itemGetter != null) { itemGetterItems = Main.itemGetter.get(itemGetType); isMainSwipe = !(itemGetterItems.size() < 1 || itemGetType == ItemGetType.MAIN_ITEMS && isFromShare); } else { diff --git a/app/src/main/java/awais/instagrabber/activities/SavedViewer.java b/app/src/main/java/awais/instagrabber/activities/SavedViewer.java new file mode 100755 index 00000000..191d5f06 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/activities/SavedViewer.java @@ -0,0 +1,234 @@ +package awais.instagrabber.activities; + +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.os.AsyncTask; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import java.util.ArrayList; +import java.util.Arrays; + +import awais.instagrabber.BuildConfig; +import awais.instagrabber.R; +import awais.instagrabber.adapters.PostsAdapter; +import awais.instagrabber.asyncs.PostsFetcher; +import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager; +import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; +import awais.instagrabber.customviews.helpers.RecyclerLazyLoader; +import awais.instagrabber.databinding.ActivitySavedBinding; +import awais.instagrabber.interfaces.FetchListener; +import awais.instagrabber.interfaces.ItemGetter; +import awais.instagrabber.models.BasePostModel; +import awais.instagrabber.models.PostModel; +import awais.instagrabber.models.enums.DownloadMethod; +import awais.instagrabber.models.enums.ItemGetType; +import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.Utils; +import awaisomereport.LogCollector; + +import static awais.instagrabber.utils.Constants.AUTOLOAD_POSTS; +import static awais.instagrabber.utils.Utils.logCollector; + +public final class SavedViewer extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener { + private static AsyncTask currentlyExecuting; + public static ItemGetter itemGetter; + private PostsAdapter postsAdapter; + private boolean hasNextPage, autoloadPosts; + //private CommentModel commentModel; + private ActivitySavedBinding savedBinding; + private String action, username, endCursor; + private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE); + private RecyclerLazyLoader lazyLoader; + private Resources resources; + private ArrayList selectedItems = new ArrayList<>(); + private final ArrayList allItems = new ArrayList<>(); + private MenuItem downloadAction; + + private final FetchListener postsFetchListener = new FetchListener() { + @Override + public void onResult(final PostModel[] result) { + if (result != null) { + final int oldSize = allItems.size(); + allItems.addAll(Arrays.asList(result)); + + postsAdapter.notifyItemRangeInserted(oldSize, result.length); + + savedBinding.mainPosts.post(() -> { + savedBinding.mainPosts.setNestedScrollingEnabled(true); + savedBinding.mainPosts.setVisibility(View.VISIBLE); + }); + + final PostModel model = result[result.length - 1]; + if (model != null) { + endCursor = model.getEndCursor(); + + hasNextPage = model.hasNextPage(); + if (autoloadPosts && hasNextPage) + currentlyExecuting = new PostsFetcher(action, endCursor, this) + .setUsername(username).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + else { + savedBinding.swipeRefreshLayout.setRefreshing(false); + } + model.setPageCursor(false, null); + } + } + else { + savedBinding.swipeRefreshLayout.setRefreshing(false); + Toast.makeText(getApplicationContext(), R.string.empty_list, Toast.LENGTH_SHORT).show(); + finish(); + } + } + }; + + @Override + protected void onCreate(@Nullable final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + savedBinding = ActivitySavedBinding.inflate(getLayoutInflater()); + setContentView(savedBinding.getRoot()); + savedBinding.swipeRefreshLayout.setOnRefreshListener(this); + autoloadPosts = Utils.settingsHelper.getBoolean(AUTOLOAD_POSTS); + savedBinding.mainPosts.setNestedScrollingEnabled(false); + final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(this, Utils.convertDpToPx(110)); + savedBinding.mainPosts.setLayoutManager(layoutManager); + savedBinding.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4))); + + final Intent intent = getIntent(); + if (intent == null || !intent.hasExtra(Constants.EXTRAS_INDEX) + || Utils.isEmpty((action = intent.getStringExtra(Constants.EXTRAS_INDEX))) + || !intent.hasExtra(Constants.EXTRAS_USER) + || Utils.isEmpty((username = intent.getStringExtra(Constants.EXTRAS_USER)))) { + Utils.errorFinish(this); + return; + } + + savedBinding.mainPosts.setAdapter(postsAdapter = new PostsAdapter(allItems, v -> { + final Object tag = v.getTag(); + if (tag instanceof PostModel) { + final PostModel postModel = (PostModel) tag; + + if (postsAdapter.isSelecting) toggleSelection(postModel); + else startActivity(new Intent(this, PostViewer.class) + .putExtra(Constants.EXTRAS_INDEX, postModel.getPosition()) + .putExtra(Constants.EXTRAS_POST, postModel) + .putExtra(Constants.EXTRAS_USER, username) + .putExtra(Constants.EXTRAS_TYPE, ItemGetType.SAVED_ITEMS)); + } + }, v -> { + final Object tag = v.getTag(); + if (tag instanceof PostModel) { + postsAdapter.isSelecting = true; + toggleSelection((PostModel) tag); + } + return true; + })); + savedBinding.swipeRefreshLayout.setRefreshing(true); + setSupportActionBar(savedBinding.toolbar.toolbar); + savedBinding.toolbar.toolbar.setTitle((action.charAt(0) == '$' ? R.string.saved : + (action.charAt(0) == '%' ? R.string.tagged : R.string.liked))); + savedBinding.toolbar.toolbar.setSubtitle(username); + + lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> { + if (!autoloadPosts && hasNextPage) { + savedBinding.swipeRefreshLayout.setRefreshing(true); + stopCurrentExecutor(); + currentlyExecuting = new PostsFetcher(action, endCursor, postsFetchListener) + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + endCursor = null; + } + }); + savedBinding.mainPosts.addOnScrollListener(lazyLoader); + + itemGetter = itemGetType -> { + if (itemGetType == ItemGetType.SAVED_ITEMS) return allItems; + return null; + }; + + new PostsFetcher(action, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + @Override + public boolean onCreateOptionsMenu(final Menu menu) { + getMenuInflater().inflate(R.menu.saved, menu); + + downloadAction = menu.findItem(R.id.downloadAction); + downloadAction.setVisible(false); + + downloadAction.setOnMenuItemClickListener(item -> { + if (selectedItems.size() > 0) { + Utils.batchDownload(this, null, DownloadMethod.DOWNLOAD_SAVED, selectedItems); + } + return true; + }); + return true; + } + + public void deselectSelection(final BasePostModel postModel) { + if (postModel instanceof PostModel) { + selectedItems.remove(postModel); + postModel.setSelected(false); + if (postsAdapter != null) notifyAdapter((PostModel) postModel); + } + } + + @Override + public void onRefresh() { + if (lazyLoader != null) lazyLoader.resetState(); + stopCurrentExecutor(); + allItems.clear(); + selectedItems.clear(); + if (postsAdapter != null) { + postsAdapter.isSelecting = false; + postsAdapter.notifyDataSetChanged(); + } + savedBinding.swipeRefreshLayout.setRefreshing(true); + new PostsFetcher(action, postsFetchListener).setUsername(username).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + @Override + public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (requestCode == 8020 && grantResults[0] == PackageManager.PERMISSION_GRANTED && selectedItems.size() > 0) + Utils.batchDownload(this, null, DownloadMethod.DOWNLOAD_SAVED, selectedItems); + } + + public static void stopCurrentExecutor() { + if (currentlyExecuting != null) { + try { + currentlyExecuting.cancel(true); + } catch (final Exception e) { + if (logCollector != null) + logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor"); + if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); + } + } + } + + private void toggleSelection(final PostModel postModel) { + if (postModel != null && postsAdapter != null) { + if (postModel.isSelected()) selectedItems.remove(postModel); + else selectedItems.add(postModel); + postModel.setSelected(!postModel.isSelected()); + notifyAdapter(postModel); + } + } + + private void notifyAdapter(final PostModel postModel) { + if (selectedItems.size() < 1) postsAdapter.isSelecting = false; + if (postModel.getPosition() < 0) postsAdapter.notifyDataSetChanged(); + else postsAdapter.notifyItemChanged(postModel.getPosition(), postModel); + + if (downloadAction != null) { + downloadAction.setVisible(postsAdapter.isSelecting); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/activities/StoryViewer.java b/app/src/main/java/awais/instagrabber/activities/StoryViewer.java index d0adf0df..78c73cc2 100755 --- a/app/src/main/java/awais/instagrabber/activities/StoryViewer.java +++ b/app/src/main/java/awais/instagrabber/activities/StoryViewer.java @@ -194,6 +194,15 @@ public final class StoryViewer extends BaseLanguageActivity { return false; }); + storyViewerBinding.spotify.setOnClickListener(v -> { + final Object tag = v.getTag(); + if (tag instanceof CharSequence) { + final Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(tag.toString())); + startActivity(intent); + } + }); + storyViewerBinding.viewStoryPost.setOnClickListener(v -> { final Object tag = v.getTag(); if (tag instanceof CharSequence) startActivity(new Intent(this, PostViewer.class) @@ -397,6 +406,10 @@ public final class StoryViewer extends BaseLanguageActivity { storyViewerBinding.viewStoryPost.setVisibility(shortCode != null ? View.VISIBLE : View.GONE); storyViewerBinding.viewStoryPost.setTag(shortCode); + final String spotify = currentStory.getSpotify(); + storyViewerBinding.spotify.setVisibility(spotify != null ? View.VISIBLE : View.GONE); + storyViewerBinding.spotify.setTag(spotify); + final PollModel poll = currentStory.getPoll(); storyViewerBinding.interactStory.setVisibility(poll != null ? View.VISIBLE : View.GONE); storyViewerBinding.interactStory.setText(R.string.vote_story_poll); diff --git a/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java index 8a41325a..5a144d11 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java @@ -49,6 +49,9 @@ public final class PostsFetcher extends AsyncTask { @Override protected PostModel[] doInBackground(final Void... voids) { final boolean isHashTag = id.charAt(0) == '#'; + final boolean isSaved = id.charAt(0) == '$'; + final boolean isTagged = id.charAt(0) == '%'; + //final boolean isLiked = id.charAt(0) == '^'; final boolean isLocation = id.contains("/"); final String url; @@ -58,6 +61,12 @@ public final class PostsFetcher extends AsyncTask { else if (isLocation) url = "https://www.instagram.com/graphql/query/?query_hash=36bd0f2bf5911908de389b8ceaa3be6d&variables=" + "{\"id\":\""+ id.split("/")[0] +"\",\"first\":150,\"after\":\"" + endCursor + "\"}"; + else if (isSaved) + url = "https://www.instagram.com/graphql/query/?query_hash=8c86fed24fa03a8a2eea2a70a80c7b6b&variables=" + + "{\"id\":\""+ id.substring(1) +"\",\"first\":150,\"after\":\"" + endCursor + "\"}"; + else if (isTagged) + url = "https://www.instagram.com/graphql/query/?query_hash=ff260833edf142911047af6024eb634a&variables=" + + "{\"id\":\""+ id.substring(1) +"\",\"first\":150,\"after\":\"" + endCursor + "\"}"; else url = "https://www.instagram.com/graphql/query/?query_id=17880160963012870&id=" + id + "&first=50&after=" + endCursor; @@ -80,7 +89,9 @@ public final class PostsFetcher extends AsyncTask { .getJSONObject(isHashTag ? Constants.EXTRAS_HASHTAG : (isLocation ? Constants.EXTRAS_LOCATION : Constants.EXTRAS_USER)) .getJSONObject(isHashTag ? "edge_hashtag_to_media" : - (isLocation ? "edge_location_to_media" : "edge_owner_to_timeline_media")); + (isLocation ? "edge_location_to_media" : + (isSaved ? "edge_saved_media" : + (isTagged ? "edge_user_to_photos_of_you" : "edge_owner_to_timeline_media")))); final String endCursor; final boolean hasNextPage; @@ -116,6 +127,7 @@ public final class PostsFetcher extends AsyncTask { mediaNode.optBoolean("viewer_has_saved"), mediaNode.getJSONObject("edge_liked_by").getLong("count")); Utils.checkExistence(downloadDir, customDir, username, isSlider, models[i]); + Utils.checkExistence(downloadDir, customDir, "@"+username, isSlider, models[i]); } if (models[models.length - 1] != null) diff --git a/app/src/main/java/awais/instagrabber/asyncs/StoryStatusFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/StoryStatusFetcher.java index 4c84fca1..2929c67a 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/StoryStatusFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/StoryStatusFetcher.java @@ -74,6 +74,9 @@ public final class StoryStatusFetcher extends AsyncTask= 0; i--) { final BasePostModel selectedItem = itemsToDownload.get(i); - if (main == null) { + if (main == null && saved == null) { new DownloadAsync(context, selectedItem.getDisplayUrl(), getDownloadSaveFile(finalDir, selectedItem, ""), null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } else if (saved != null) { + new PostFetcher(selectedItem.getShortCode(), result -> { + if (result != null) { + final int resultsSize = result.length; + final boolean multiResult = resultsSize > 1; + + for (int j = 0; j < resultsSize; j++) { + final BasePostModel model = result[j]; + final File saveFile = getDownloadSaveFile(finalDir, model, multiResult ? "_slide_" + (j + 1) : ""); + + new DownloadAsync(context, + model.getDisplayUrl(), + saveFile, + file -> { + model.setDownloaded(true); + saved.deselectSelection(selectedItem); + }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + } else { + saved.deselectSelection(selectedItem); + } + }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } else { new PostFetcher(selectedItem.getShortCode(), result -> { if (result != null) { @@ -986,16 +1010,7 @@ public final class Utils { final String fileWithoutPrefix = fileName + '0' + extension; exists = new File(downloadDir, fileWithoutPrefix).exists(); if (!exists) { - if (customDir != null) exists = new File(customDir, fileWithoutPrefix).exists(); - if (!exists && !Utils.isEmpty(username)) { - exists = new File(new File(downloadDir, username), fileWithoutPrefix).exists(); - } - if (!exists && customDir != null) - exists = new File(new File(customDir, username), fileWithoutPrefix).exists(); - } - - if (!exists && isSlider) { - final String fileWithPrefix = fileName + "[\\d]+_slide_[\\d]+" + extension; + final String fileWithPrefix = fileName + "[\\d]+(|_slide_[\\d]+)(\\.mp4|\\" + extension + ")"; final FilenameFilter filenameFilter = (dir, name) -> Pattern.matches(fileWithPrefix, name); File[] files = downloadDir.listFiles(filenameFilter); @@ -1163,6 +1178,9 @@ public final class Utils { if (isVideo && data.has("video_resources")) storyModels[j].setVideoUrl(Utils.getHighQualityPost(data.getJSONArray("video_resources"), true)); + if (!data.isNull("story_app_attribution")) + storyModels[j].setSpotify(data.getJSONObject("story_app_attribution").optString("content_url").split("\\?")[0]); + if (hasTappableObjecs) { for (int k = 0; k < tappableLength; ++k) { JSONObject jsonObject = tappableObjects.getJSONObject(k); diff --git a/app/src/main/java/awaisomereport/LogCollector.java b/app/src/main/java/awaisomereport/LogCollector.java index fb1ce720..b0144c87 100755 --- a/app/src/main/java/awaisomereport/LogCollector.java +++ b/app/src/main/java/awaisomereport/LogCollector.java @@ -110,6 +110,7 @@ public final class LogCollector { ASYNC_LOCATION_FETCHER("async-location-fetcher.txt"), ASYNC_PROFILE_FETCHER("async-profile-fetcher.txt"), ASYNC_PROFILE_PICTURE_FETCHER("async-pfp-fetcher.txt"), + ASYNC_SAVED_FETCHER("async-saved-fetcher.txt"), ASYNC_STORY_STATUS_FETCHER("async-story-status-fetcher.txt"), ASYNC_DISCOVER_FETCHER("async-discover-fetcher.txt"), ASYNC_COMMENTS_FETCHER("async-comments-fetcher.txt"), diff --git a/app/src/main/res/drawable-anydpi/ic_bookmark.xml b/app/src/main/res/drawable-anydpi/ic_bookmark.xml new file mode 100644 index 00000000..69bc5089 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_bookmark.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable-anydpi/ic_like.xml b/app/src/main/res/drawable-anydpi/ic_like.xml new file mode 100644 index 00000000..f68e110e --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_like.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable-hdpi/ic_bookmark.png b/app/src/main/res/drawable-hdpi/ic_bookmark.png new file mode 100644 index 00000000..8dbfafa9 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_bookmark.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_like.png b/app/src/main/res/drawable-hdpi/ic_like.png new file mode 100644 index 00000000..3984ecbb Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_like.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_bookmark.png b/app/src/main/res/drawable-mdpi/ic_bookmark.png new file mode 100644 index 00000000..d37d3cd9 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_bookmark.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_like.png b/app/src/main/res/drawable-mdpi/ic_like.png new file mode 100644 index 00000000..ebc88607 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_like.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_bookmark.png b/app/src/main/res/drawable-xhdpi/ic_bookmark.png new file mode 100644 index 00000000..6dae7417 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_bookmark.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_like.png b/app/src/main/res/drawable-xhdpi/ic_like.png new file mode 100644 index 00000000..eadf8e7b Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_like.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_bookmark.png b/app/src/main/res/drawable-xxhdpi/ic_bookmark.png new file mode 100644 index 00000000..620babe1 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_bookmark.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_like.png b/app/src/main/res/drawable-xxhdpi/ic_like.png new file mode 100644 index 00000000..ac66ff42 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_like.png differ diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 94abacf5..aeabab5b 100755 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -112,26 +112,25 @@ android:id="@+id/profileActions" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_below="@id/mainUrl" - android:weightSum="3"> + android:layout_below="@id/mainUrl"> + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_story_viewer.xml b/app/src/main/res/layout/activity_story_viewer.xml index f332cb0b..d6a6a7f4 100755 --- a/app/src/main/res/layout/activity_story_viewer.xml +++ b/app/src/main/res/layout/activity_story_viewer.xml @@ -44,7 +44,7 @@ android:layout_height="wrap_content" android:layout_weight="0.3" android:background="#0000" - android:weightSum="2" + android:weightSum="3" android:layout_gravity="bottom"> + diff --git a/app/src/main/res/layout/layout_include_toolbar.xml b/app/src/main/res/layout/layout_include_toolbar.xml index 600dced8..8beaabe3 100755 --- a/app/src/main/res/layout/layout_include_toolbar.xml +++ b/app/src/main/res/layout/layout_include_toolbar.xml @@ -6,14 +6,4 @@ android:layout_height="?actionBarSize" android:background="@null" app:title="@string/app_name"> - - \ No newline at end of file diff --git a/app/src/main/res/menu/saved.xml b/app/src/main/res/menu/saved.xml new file mode 100755 index 00000000..1af65823 --- /dev/null +++ b/app/src/main/res/menu/saved.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7140ceef..7dfa1719 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -60,11 +60,13 @@ Show stories No more stories! View Story Post + Spotify Vote Vote successful! You have already voted! This Account is Private This Account has No Posts + No Such Posts! Current version: v%s read moreā€¦ Login @@ -75,6 +77,10 @@ Join Telegram Group Join Matrix Room + Liked + Saved + Tagged + Like (%s) Unlike (%s) Bookmark