From 3dd66d9bc78af7bf8dcf4f46a4abd83a99879347 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Tue, 5 Jan 2021 16:39:17 -0500 Subject: [PATCH 1/6] fix #524 --- .../java/awais/instagrabber/adapters/FeedAdapterV2.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/awais/instagrabber/adapters/FeedAdapterV2.java b/app/src/main/java/awais/instagrabber/adapters/FeedAdapterV2.java index 8e3a5a2c..4847fe3c 100644 --- a/app/src/main/java/awais/instagrabber/adapters/FeedAdapterV2.java +++ b/app/src/main/java/awais/instagrabber/adapters/FeedAdapterV2.java @@ -25,6 +25,7 @@ import awais.instagrabber.databinding.ItemFeedVideoBinding; import awais.instagrabber.models.FeedModel; import awais.instagrabber.models.PostsLayoutPreferences; import awais.instagrabber.models.enums.MediaItemType; +import awais.instagrabber.utils.TextUtils; public final class FeedAdapterV2 extends ListAdapter { private static final String TAG = "FeedAdapterV2"; @@ -46,7 +47,13 @@ public final class FeedAdapterV2 extends ListAdapter Date: Tue, 5 Jan 2021 16:44:10 -0500 Subject: [PATCH 2/6] update issue templates (#470 follow up) --- .github/ISSUE_TEMPLATE/ban_report.md | 4 ++-- .github/ISSUE_TEMPLATE/bug_report.md | 12 +++++------- .github/ISSUE_TEMPLATE/questions.md | 6 ++++++ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/ban_report.md b/.github/ISSUE_TEMPLATE/ban_report.md index 99d4d33c..180ca957 100644 --- a/.github/ISSUE_TEMPLATE/ban_report.md +++ b/.github/ISSUE_TEMPLATE/ban_report.md @@ -18,8 +18,8 @@ assignees: 'austinhuang0131' ## Answer honestly. Check accordingly to your situation. - [ ] I had prior rule violations on Instagram, specifically: -- [ ] I have admitted the use of InstaGrabber on Instagram. -- [ ] I have admitted the use of InstaGrabber to a friend who uses Instagram. +- [ ] I have admitted the use of Barinsta on Instagram. +- [ ] I have admitted the use of Barinsta to a friend who uses Instagram. - [ ] I have modified the source code of the app that I use, other than what is present in this repo. Specifically: ## Describe your case, including your usage pattern, but without private information. diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 2c933b53..a3abf780 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -6,10 +6,10 @@ labels: bug assignees: '' --- - + - [ ] My app is on the latest version. I understand that any other version is not supported. -- [ ] I have read [the FAQ](https://instagrabber.austinhuang.me/faq). +- [ ] I have read [the FAQ](https://barinsta.austinhuang.me/en/latest/faq). ## Environment diff --git a/.github/ISSUE_TEMPLATE/questions.md b/.github/ISSUE_TEMPLATE/questions.md index fcaaf0d5..aff97d3e 100644 --- a/.github/ISSUE_TEMPLATE/questions.md +++ b/.github/ISSUE_TEMPLATE/questions.md @@ -7,7 +7,13 @@ assignees: '' --- From b5e110170977cfbea3b971e6534ccf85691889a6 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Tue, 5 Jan 2021 18:42:00 -0500 Subject: [PATCH 3/6] #532 point 2 --- .../fragments/StoryViewerFragment.java | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java index 72d6ed0c..c19d584b 100644 --- a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java @@ -132,7 +132,7 @@ public class StoryViewerFragment extends Fragment { private MenuItem menuDm; private SimpleExoPlayer player; private boolean isHashtag, isLoc; - private String highlight; + private String highlight, actionBarTitle; private boolean fetching = false, sticking = false, shouldRefresh = true; private int currentFeedStoryIndex; private double sliderValue; @@ -239,6 +239,15 @@ public class StoryViewerFragment extends Fragment { releasePlayer(); } + @Override + public void onResume() { + super.onResume(); + final ActionBar actionBar = fragmentActivity.getSupportActionBar(); + if (actionBar != null) { + actionBar.setTitle(actionBarTitle); + } + } + @Override public void onDestroy() { releasePlayer(); @@ -681,6 +690,7 @@ public class StoryViewerFragment extends Fragment { if (isHighlight) { final ActionBar actionBar = fragmentActivity.getSupportActionBar(); if (actionBar != null) { + actionBarTitle = highlight; actionBar.setTitle(highlight); } } @@ -688,6 +698,7 @@ public class StoryViewerFragment extends Fragment { currentStoryUsername = currentStoryUsername.replace("@", ""); final ActionBar actionBar = fragmentActivity.getSupportActionBar(); if (actionBar != null) { + actionBarTitle = currentStoryUsername; actionBar.setTitle(currentStoryUsername); } } @@ -729,21 +740,14 @@ public class StoryViewerFragment extends Fragment { return; } binding.storiesList.setVisibility((storyModels.size() == 1 && currentFeedStoryIndex == -1) ? View.GONE : View.VISIBLE); - binding.btnBackward.setVisibility(currentFeedStoryIndex == -1 ? View.GONE : View.VISIBLE); - binding.btnForward.setVisibility(currentFeedStoryIndex == -1 ? View.GONE : View.VISIBLE); + if (currentFeedStoryIndex == -1) { + binding.btnBackward.setVisibility(View.GONE); + binding.btnForward.setVisibility(View.GONE); + } storiesViewModel.getList().setValue(storyModels); currentStory = storyModels.get(0); refreshStory(); } - binding.storiesList.setVisibility((storyModels.size() == 1 && currentFeedStoryIndex == -1) ? View.GONE : View.VISIBLE); - if (currentFeedStoryIndex == -1) { - binding.btnBackward.setVisibility(View.GONE); - binding.btnForward.setVisibility(View.GONE); - } - storiesViewModel.getList().setValue(storyModels); - currentStory = storyModels.get(0); - refreshStory(); - } @Override public void onFailure(final Throwable t) { @@ -823,6 +827,7 @@ public class StoryViewerFragment extends Fragment { if (isHashtag || isLoc) { final ActionBar actionBar = fragmentActivity.getSupportActionBar(); if (actionBar != null) { + actionBarTitle = currentStory.getUsername(); actionBar.setTitle(currentStory.getUsername()); } } From 853115eb4e2f564de770063ae4683980fe3475e9 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Tue, 5 Jan 2021 22:10:54 -0500 Subject: [PATCH 4/6] live video (untested) #383; also besties story type #460 --- app/build.gradle | 6 +- .../viewholder/FeedStoryViewHolder.java | 4 + .../customviews/CircularImageView.java | 7 +- .../fragments/HashTagFragment.java | 2 +- .../fragments/LocationFragment.java | 2 +- .../fragments/StoryViewerFragment.java | 129 ++++++++++++++---- .../fragments/main/ProfileFragment.java | 2 +- .../instagrabber/models/FeedStoryModel.java | 14 +- .../models/enums/MediaItemType.java | 5 +- .../instagrabber/utils/ResponseBodyUtils.java | 13 ++ .../webservices/StoriesService.java | 24 +++- 11 files changed, 167 insertions(+), 41 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 454e38ad..259b7149 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -60,11 +60,13 @@ dependencies { def appcompat_version = "1.2.0" def nav_version = '2.3.2' + def exoplayer_version = '2.12.0' implementation 'com.google.android.material:material:1.3.0-alpha04' - implementation 'com.google.android.exoplayer:exoplayer-core:2.12.0' - implementation 'com.google.android.exoplayer:exoplayer-ui:2.12.0' + implementation "com.google.android.exoplayer:exoplayer-core:$exoplayer_version" + implementation "com.google.android.exoplayer:exoplayer-dash:$exoplayer_version" + implementation "com.google.android.exoplayer:exoplayer-ui:$exoplayer_version" implementation "androidx.appcompat:appcompat:$appcompat_version" implementation "androidx.appcompat:appcompat-resources:$appcompat_version" diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/FeedStoryViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/FeedStoryViewHolder.java index 76b309e9..7db15277 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/FeedStoryViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/FeedStoryViewHolder.java @@ -33,5 +33,9 @@ public final class FeedStoryViewHolder extends RecyclerView.ViewHolder { binding.title.setAlpha(model.isFullyRead() ? 0.5F : 1.0F); binding.icon.setImageURI(profileModel.getSdProfilePic()); binding.icon.setAlpha(model.isFullyRead() ? 0.5F : 1.0F); + + if (model.isLive()) binding.icon.setStoriesBorder(2); + else if (model.isBestie()) binding.icon.setStoriesBorder(1); + else binding.icon.setStoriesBorder(0); } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/customviews/CircularImageView.java b/app/src/main/java/awais/instagrabber/customviews/CircularImageView.java index 29828709..2f687868 100755 --- a/app/src/main/java/awais/instagrabber/customviews/CircularImageView.java +++ b/app/src/main/java/awais/instagrabber/customviews/CircularImageView.java @@ -49,14 +49,15 @@ public class CircularImageView extends SimpleDraweeView { setBackgroundResource(R.drawable.shape_oval_light); } - public void setStoriesBorder() { + /* types: 0 clear, 1 green (feed bestie / has story), 2 red (live) */ + public void setStoriesBorder(final int type) { // private final int borderSize = 8; - final int color = Color.GREEN; + final int color = type == 2 ? Color.RED : Color.GREEN; RoundingParams roundingParams = getHierarchy().getRoundingParams(); if (roundingParams == null) { roundingParams = RoundingParams.asCircle().setRoundingMethod(RoundingParams.RoundingMethod.BITMAP_ONLY); } - roundingParams.setBorder(color, 5.0f); + roundingParams.setBorder(color, type == 0 ? 0f : 5.0f); getHierarchy().setRoundingParams(roundingParams); } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java index 10fc0482..bdec3b59 100644 --- a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java @@ -580,7 +580,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe @Override public void onSuccess(final List storyModels) { if (storyModels != null && !storyModels.isEmpty()) { - hashtagDetailsBinding.mainHashtagImage.setStoriesBorder(); + hashtagDetailsBinding.mainHashtagImage.setStoriesBorder(1); hasStories = true; } else { hasStories = false; diff --git a/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java b/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java index c48d4939..0d464748 100644 --- a/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java @@ -549,7 +549,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR @Override public void onSuccess(final List storyModels) { if (storyModels != null && !storyModels.isEmpty()) { - locationDetailsBinding.mainLocationImage.setStoriesBorder(); + locationDetailsBinding.mainLocationImage.setStoriesBorder(1); hasStories = true; } storiesFetching = false; diff --git a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java index c19d584b..3fc533f7 100644 --- a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java @@ -50,6 +50,7 @@ import com.facebook.imagepipeline.request.ImageRequestBuilder; import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.SimpleExoPlayer; +import com.google.android.exoplayer2.source.dash.DashMediaSource; import com.google.android.exoplayer2.source.LoadEventInfo; import com.google.android.exoplayer2.source.MediaLoadData; import com.google.android.exoplayer2.source.MediaSource; @@ -643,6 +644,7 @@ public class StoryViewerFragment extends Fragment { private void resetView() { final Context context = getContext(); + StoryModel live = null; slidePos = 0; lastSlidePos = 0; if (menuDownload != null) menuDownload.setVisible(false); @@ -679,6 +681,7 @@ public class StoryViewerFragment extends Fragment { final FeedStoryModel model = models.get(currentFeedStoryIndex); currentStoryMediaId = model.getStoryMediaId(); currentStoryUsername = model.getProfileModel().getUsername(); + if (model.isLive()) live = model.getFirstStoryModel(); } } else if (!TextUtils.isEmpty(fragmentArgs.getProfileId()) && !TextUtils.isEmpty(fragmentArgs.getUsername())) { currentStoryMediaId = fragmentArgs.getProfileId(); @@ -756,7 +759,8 @@ public class StoryViewerFragment extends Fragment { Log.e(TAG, "Error", t); } }; - storiesService.getUserStory(currentStoryMediaId, + if (live != null) storyCallback.onSuccess(Collections.singletonList(live)); + else storiesService.getUserStory(currentStoryMediaId, currentStoryUsername, isLoc, isHashtag, @@ -786,41 +790,43 @@ public class StoryViewerFragment extends Fragment { final MediaItemType itemType = currentStory.getItemType(); if (menuDownload != null) menuDownload.setVisible(false); - url = itemType == MediaItemType.MEDIA_TYPE_VIDEO ? currentStory.getVideoUrl() : currentStory.getStoryUrl(); + url = itemType == MediaItemType.MEDIA_TYPE_IMAGE ? currentStory.getStoryUrl() : currentStory.getVideoUrl(); - final String shortCode = currentStory.getTappableShortCode(); - binding.viewStoryPost.setVisibility(shortCode != null ? View.VISIBLE : View.GONE); - binding.viewStoryPost.setTag(shortCode); + if (itemType != MediaItemType.MEDIA_TYPE_LIVE) { + final String shortCode = currentStory.getTappableShortCode(); + binding.viewStoryPost.setVisibility(shortCode != null ? View.VISIBLE : View.GONE); + binding.viewStoryPost.setTag(shortCode); - final String spotify = currentStory.getSpotify(); - binding.spotify.setVisibility(spotify != null ? View.VISIBLE : View.GONE); - binding.spotify.setTag(spotify); + final String spotify = currentStory.getSpotify(); + binding.spotify.setVisibility(spotify != null ? View.VISIBLE : View.GONE); + binding.spotify.setTag(spotify); - poll = currentStory.getPoll(); - binding.poll.setVisibility(poll != null ? View.VISIBLE : View.GONE); - binding.poll.setTag(poll); + poll = currentStory.getPoll(); + binding.poll.setVisibility(poll != null ? View.VISIBLE : View.GONE); + binding.poll.setTag(poll); - question = currentStory.getQuestion(); - binding.answer.setVisibility((question != null && !TextUtils.isEmpty(cookie)) ? View.VISIBLE : View.GONE); - binding.answer.setTag(question); + question = currentStory.getQuestion(); + binding.answer.setVisibility((question != null && !TextUtils.isEmpty(cookie)) ? View.VISIBLE : View.GONE); + binding.answer.setTag(question); - mentions = currentStory.getMentions(); - binding.mention.setVisibility((mentions != null && mentions.length > 0) ? View.VISIBLE : View.GONE); - binding.mention.setTag(mentions); + mentions = currentStory.getMentions(); + binding.mention.setVisibility((mentions != null && mentions.length > 0) ? View.VISIBLE : View.GONE); + binding.mention.setTag(mentions); - quiz = currentStory.getQuiz(); - binding.quiz.setVisibility(quiz != null ? View.VISIBLE : View.GONE); - binding.quiz.setTag(quiz); + quiz = currentStory.getQuiz(); + binding.quiz.setVisibility(quiz != null ? View.VISIBLE : View.GONE); + binding.quiz.setTag(quiz); - slider = currentStory.getSlider(); - binding.slider.setVisibility(slider != null ? View.VISIBLE : View.GONE); - binding.slider.setTag(slider); + slider = currentStory.getSlider(); + binding.slider.setVisibility(slider != null ? View.VISIBLE : View.GONE); + binding.slider.setTag(slider); - swipeUp = currentStory.getSwipeUp(); - if (swipeUp != null) { - binding.swipeUp.setVisibility(View.VISIBLE); - binding.swipeUp.setText(swipeUp.getText()); - binding.swipeUp.setTag(swipeUp.getUrl()); + swipeUp = currentStory.getSwipeUp(); + if (swipeUp != null) { + binding.swipeUp.setVisibility(View.VISIBLE); + binding.swipeUp.setText(swipeUp.getText()); + binding.swipeUp.setTag(swipeUp.getUrl()); + } else binding.swipeUp.setVisibility(View.GONE); } releasePlayer(); @@ -832,6 +838,7 @@ public class StoryViewerFragment extends Fragment { } } if (itemType == MediaItemType.MEDIA_TYPE_VIDEO) setupVideo(); + else if (itemType == MediaItemType.MEDIA_TYPE_LIVE) setupLive(); else setupImage(); final ActionBar actionBar = fragmentActivity.getSupportActionBar(); @@ -957,6 +964,72 @@ public class StoryViewerFragment extends Fragment { }); } + private void setupLive() { + binding.playerView.setVisibility(View.VISIBLE); + binding.progressView.setVisibility(View.GONE); + binding.imageViewer.setVisibility(View.GONE); + binding.imageViewer.setController(null); + + if (menuDownload != null) menuDownload.setVisible(false); + if (menuDm != null) menuDm.setVisible(false); + + final Context context = getContext(); + if (context == null) return; + player = new SimpleExoPlayer.Builder(context).build(); + binding.playerView.setPlayer(player); + player.setPlayWhenReady(settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS)); + + final Uri uri = Uri.parse(url); + final MediaItem mediaItem = MediaItem.fromUri(uri); + final DashMediaSource mediaSource = new DashMediaSource.Factory(new DefaultDataSourceFactory(context, "instagram")) + .createMediaSource(mediaItem); + mediaSource.addEventListener(new Handler(), new MediaSourceEventListener() { + @Override + public void onLoadCompleted(final int windowIndex, + @Nullable final MediaSource.MediaPeriodId mediaPeriodId, + final LoadEventInfo loadEventInfo, + final MediaLoadData mediaLoadData) { + binding.progressView.setVisibility(View.GONE); + } + + @Override + public void onLoadStarted(final int windowIndex, + @Nullable final MediaSource.MediaPeriodId mediaPeriodId, + final LoadEventInfo loadEventInfo, + final MediaLoadData mediaLoadData) { + binding.progressView.setVisibility(View.VISIBLE); + } + + @Override + public void onLoadCanceled(final int windowIndex, + @Nullable final MediaSource.MediaPeriodId mediaPeriodId, + final LoadEventInfo loadEventInfo, + final MediaLoadData mediaLoadData) { + binding.progressView.setVisibility(View.GONE); + } + + @Override + public void onLoadError(final int windowIndex, + @Nullable final MediaSource.MediaPeriodId mediaPeriodId, + final LoadEventInfo loadEventInfo, + final MediaLoadData mediaLoadData, + final IOException error, + final boolean wasCanceled) { + binding.progressView.setVisibility(View.GONE); + } + }); + player.setMediaSource(mediaSource); + player.prepare(); + + binding.playerView.setOnClickListener(v -> { + if (player != null) { + if (player.getPlaybackState() == Player.STATE_ENDED) player.seekTo(0); + player.setPlayWhenReady(player.getPlaybackState() == Player.STATE_ENDED || !player.isPlaying()); + } + }); + } + + private void openProfile(final String username) { final ActionBar actionBar = fragmentActivity.getSupportActionBar(); if (actionBar != null) { diff --git a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java index d5ab821d..d5a85e34 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java @@ -869,7 +869,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe @Override public void onSuccess(final List storyModels) { if (storyModels != null && !storyModels.isEmpty()) { - profileDetailsBinding.mainProfileImage.setStoriesBorder(); + profileDetailsBinding.mainProfileImage.setStoriesBorder(1); hasStories = true; } } diff --git a/app/src/main/java/awais/instagrabber/models/FeedStoryModel.java b/app/src/main/java/awais/instagrabber/models/FeedStoryModel.java index 01ffac76..74bac68e 100755 --- a/app/src/main/java/awais/instagrabber/models/FeedStoryModel.java +++ b/app/src/main/java/awais/instagrabber/models/FeedStoryModel.java @@ -14,17 +14,21 @@ public final class FeedStoryModel implements Serializable { private final ProfileModel profileModel; private final StoryModel firstStoryModel; private Boolean fullyRead; + private final boolean isLive, isBestie; private final long timestamp; private final int mediaCount; public FeedStoryModel(final String storyMediaId, final ProfileModel profileModel, final boolean fullyRead, - final long timestamp, final StoryModel firstStoryModel, final int mediaCount) { + final long timestamp, final StoryModel firstStoryModel, final int mediaCount, + final boolean isLive, final boolean isBestie) { this.storyMediaId = storyMediaId; this.profileModel = profileModel; this.fullyRead = fullyRead; this.timestamp = timestamp; this.firstStoryModel = firstStoryModel; this.mediaCount = mediaCount; + this.isLive = isLive; + this.isBestie = isBestie; } public String getStoryMediaId() { @@ -63,4 +67,12 @@ public final class FeedStoryModel implements Serializable { public void setFullyRead(final boolean fullyRead) { this.fullyRead = fullyRead; } + + public boolean isLive() { + return isLive; + } + + public boolean isBestie() { + return isBestie; + } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/models/enums/MediaItemType.java b/app/src/main/java/awais/instagrabber/models/enums/MediaItemType.java index 727b0a1b..681926a5 100755 --- a/app/src/main/java/awais/instagrabber/models/enums/MediaItemType.java +++ b/app/src/main/java/awais/instagrabber/models/enums/MediaItemType.java @@ -8,10 +8,11 @@ public enum MediaItemType implements Serializable { MEDIA_TYPE_IMAGE(1), MEDIA_TYPE_VIDEO(2), MEDIA_TYPE_SLIDER(3), - MEDIA_TYPE_VOICE(4); + MEDIA_TYPE_VOICE(4), + MEDIA_TYPE_LIVE(5); private final int id; - private static Map map = new HashMap<>(); + private static final Map map = new HashMap<>(); static { for (MediaItemType type : MediaItemType.values()) { diff --git a/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java b/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java index 9ae87dbf..12505689 100644 --- a/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java +++ b/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java @@ -1009,4 +1009,17 @@ public final class ResponseBodyUtils { return model; } + + public static StoryModel parseBroadcastItem(final JSONObject data) throws JSONException { + final StoryModel model = new StoryModel(data.getString("id"), + data.getString("cover_frame_url"), + data.getString("cover_frame_url"), + MediaItemType.MEDIA_TYPE_LIVE, + data.optLong("published_time", 0), + data.getJSONObject("user").getString("username"), + data.getJSONObject("user").getString("pk"), + false); + model.setVideoUrl(data.getString("dash_playback_url")); + return model; + } } diff --git a/app/src/main/java/awais/instagrabber/webservices/StoriesService.java b/app/src/main/java/awais/instagrabber/webservices/StoriesService.java index cb022372..4c079b04 100644 --- a/app/src/main/java/awais/instagrabber/webservices/StoriesService.java +++ b/app/src/main/java/awais/instagrabber/webservices/StoriesService.java @@ -121,12 +121,32 @@ public class StoriesService extends BaseService { final long timestamp = node.getLong("latest_reel_media"); final int mediaCount = node.getInt("media_count"); final boolean fullyRead = !node.isNull("seen") && node.getLong("seen") == timestamp; - final JSONObject itemJson = node.has("items") ? node.getJSONArray("items").getJSONObject(0) : null; + final JSONObject itemJson = node.has("items") ? node.getJSONArray("items").optJSONObject(0) : null; + final boolean isBestie = node.optBoolean("has_besties_media", false); StoryModel firstStoryModel = null; if (itemJson != null) { firstStoryModel = ResponseBodyUtils.parseStoryItem(itemJson, false, false, null); } - feedStoryModels.add(new FeedStoryModel(id, profileModel, fullyRead, timestamp, firstStoryModel, mediaCount)); + feedStoryModels.add(new FeedStoryModel(id, profileModel, fullyRead, timestamp, firstStoryModel, mediaCount, false, isBestie)); + } + final JSONArray broadcasts = new JSONObject(body).getJSONArray("broadcasts"); + for (int i = 0; i < broadcasts.length(); ++i) { + final JSONObject node = broadcasts.getJSONObject(i); + final JSONObject user = node.getJSONObject("broadcast_owner"); + final ProfileModel profileModel = new ProfileModel(false, false, false, + user.getString("pk"), + user.getString("username"), + null, null, null, + user.getString("profile_pic_url"), + null, 0, 0, 0, false, false, false, false, false); + final String id = node.getString("id"); + final long timestamp = node.getLong("published_time"); + final JSONObject itemJson = node.has("items") ? node.getJSONArray("items").getJSONObject(0) : null; + StoryModel firstStoryModel = null; + if (itemJson != null) { + firstStoryModel = ResponseBodyUtils.parseBroadcastItem(itemJson); + } + feedStoryModels.add(new FeedStoryModel(id, profileModel, false, timestamp, firstStoryModel, 1, true, false)); } callback.onSuccess(sort(feedStoryModels)); } catch (JSONException e) { From 7b07361a2627ba274f5f07e629bbceb6c4c12dee Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Tue, 5 Jan 2021 23:37:06 -0500 Subject: [PATCH 5/6] fix #518 pending testing --- .../fragments/StoryListViewerFragment.java | 1 + .../fragments/main/FeedFragment.java | 30 ++++++++++--------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java index dd851198..2a3cf2fe 100644 --- a/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java @@ -197,6 +197,7 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr @Override public void onSuccess(final List result) { feedStoriesViewModel.getList().postValue(result); + adapter.submitList(result); binding.swipeRefreshLayout.setRefreshing(false); } diff --git a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java index 832977c8..2cbe8d59 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java @@ -79,6 +79,21 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre private RecyclerView storiesRecyclerView; private MenuItem storyListMenu; + private final FeedStoriesAdapter feedStoriesAdapter = new FeedStoriesAdapter( + new FeedStoriesAdapter.OnFeedStoryClickListener() { + @Override + public void onFeedStoryClick(FeedStoryModel model, int position) { + final NavDirections action = FeedFragmentDirections.actionFeedFragmentToStoryViewerFragment(position, null, false, false, null, null, false, false); + NavHostFragment.findNavController(FeedFragment.this).navigate(action); + } + + @Override + public void onFeedStoryLongClick(FeedStoryModel model, int position) { + navigateToProfile("@" + model.getProfileModel().getUsername()); + } + } + ); + private final FeedAdapterV2.FeedItemCallback feedItemCallback = new FeedAdapterV2.FeedItemCallback() { @Override public void onPostClick(final FeedModel feedModel, final View profilePicView, final View mainPostImage) { @@ -353,20 +368,6 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre private void setupFeedStories() { if (storyListMenu != null) storyListMenu.setVisible(false); feedStoriesViewModel = new ViewModelProvider(fragmentActivity).get(FeedStoriesViewModel.class); - final FeedStoriesAdapter feedStoriesAdapter = new FeedStoriesAdapter( - new FeedStoriesAdapter.OnFeedStoryClickListener() { - @Override - public void onFeedStoryClick(FeedStoryModel model, int position) { - final NavDirections action = FeedFragmentDirections.actionFeedFragmentToStoryViewerFragment(position, null, false, false, null, null, false, false); - NavHostFragment.findNavController(FeedFragment.this).navigate(action); - } - - @Override - public void onFeedStoryLongClick(FeedStoryModel model, int position) { - navigateToProfile("@" + model.getProfileModel().getUsername()); - } - } - ); final Context context = getContext(); if (context == null) return; storiesRecyclerView = new RecyclerView(context); @@ -390,6 +391,7 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre @Override public void onSuccess(final List result) { feedStoriesViewModel.getList().postValue(result); + feedStoriesAdapter.submitList(result); storiesFetching = false; if (storyListMenu != null) storyListMenu.setVisible(true); updateSwipeRefreshState(); From c8dda21f9f1ddcbe2a27dfafa9c8587bbfcab488 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Tue, 5 Jan 2021 23:37:16 -0500 Subject: [PATCH 6/6] chore/cleanup --- app/src/main/java/awais/instagrabber/utils/Utils.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/utils/Utils.java b/app/src/main/java/awais/instagrabber/utils/Utils.java index de4acea8..8bd76af5 100644 --- a/app/src/main/java/awais/instagrabber/utils/Utils.java +++ b/app/src/main/java/awais/instagrabber/utils/Utils.java @@ -123,11 +123,6 @@ public final class Utils { return mimeType.startsWith("image"); } - public static void errorFinish(@NonNull final Activity activity) { - Toast.makeText(activity, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); - activity.finish(); - } - public static SimpleCache getSimpleCacheInstance(final Context context) { if (context == null) { return null;