mirror of
				https://github.com/KokaKiwi/BarInsta
				synced 2025-10-31 03:25:34 +00:00 
			
		
		
		
	Merge branch 'master' into dm-notifications-enhancements
This commit is contained in:
		
						commit
						b2917e3d63
					
				
							
								
								
									
										4
									
								
								.github/ISSUE_TEMPLATE/ban_report.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/ISSUE_TEMPLATE/ban_report.md
									
									
									
									
										vendored
									
									
								
							| @ -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. | ||||
|  | ||||
							
								
								
									
										12
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							| @ -6,10 +6,10 @@ labels: bug | ||||
| assignees: '' | ||||
| --- | ||||
| 
 | ||||
| <!-- FOLLOW THIS FORMAT --> | ||||
| <!-- If you choose not to follow this format, you should erase the entire body. --> | ||||
| 
 | ||||
| - [ ] 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). | ||||
| 
 | ||||
| <!-- | ||||
| Describe the bug here. Don't stress too much, but do include the key points. | ||||
| @ -18,11 +18,9 @@ Describe the bug here. Don't stress too much, but do include the key points. | ||||
| ## Steps | ||||
| 
 | ||||
| <!-- | ||||
| DETAILED Steps to reproduce the behaviour. | ||||
| 1. Go to '...' | ||||
| 2. Click on '....' | ||||
| 3. Scroll down to '....' | ||||
| 4. See error | ||||
| 1. ... | ||||
| 2. ... | ||||
| 3. See error... | ||||
| --> | ||||
| 
 | ||||
| ## Environment | ||||
|  | ||||
							
								
								
									
										6
									
								
								.github/ISSUE_TEMPLATE/questions.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/ISSUE_TEMPLATE/questions.md
									
									
									
									
										vendored
									
									
								
							| @ -7,7 +7,13 @@ assignees: '' | ||||
| --- | ||||
| 
 | ||||
| <!-- | ||||
| 
 | ||||
| STOP!!! | ||||
| 
 | ||||
| General questions & feedback should be submitted to | ||||
| * one of our chatrooms (see README.md), or | ||||
| * r/barinsta on reddit. | ||||
| 
 | ||||
| STOP!!! | ||||
| 
 | ||||
| --> | ||||
|  | ||||
| @ -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-beta01' | ||||
| 
 | ||||
|     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" | ||||
|  | ||||
| @ -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<FeedModel, RecyclerView.ViewHolder> { | ||||
|     private static final String TAG = "FeedAdapterV2"; | ||||
| @ -46,7 +47,13 @@ public final class FeedAdapterV2 extends ListAdapter<FeedModel, RecyclerView.Vie | ||||
| 
 | ||||
|         @Override | ||||
|         public boolean areContentsTheSame(@NonNull final FeedModel oldItem, @NonNull final FeedModel newItem) { | ||||
|             return oldItem.getPostId().equals(newItem.getPostId()) && oldItem.getPostCaption().equals(newItem.getPostCaption()); | ||||
|             boolean result = oldItem.getPostId().equals(newItem.getPostId()); | ||||
|             if (TextUtils.isEmpty(oldItem.getPostCaption())) { | ||||
|                 return result ? TextUtils.isEmpty(newItem.getPostCaption()) : false; | ||||
|             } | ||||
|             else { | ||||
|                 return result ? oldItem.getPostCaption().equals(newItem.getPostCaption()) : false; | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|     private final AdapterSelectionCallback adapterSelectionCallback = new AdapterSelectionCallback() { | ||||
|  | ||||
| @ -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); | ||||
|     } | ||||
| } | ||||
| @ -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); | ||||
|     } | ||||
| } | ||||
| @ -580,7 +580,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe | ||||
|                     @Override | ||||
|                     public void onSuccess(final List<StoryModel> storyModels) { | ||||
|                         if (storyModels != null && !storyModels.isEmpty()) { | ||||
|                             hashtagDetailsBinding.mainHashtagImage.setStoriesBorder(); | ||||
|                             hashtagDetailsBinding.mainHashtagImage.setStoriesBorder(1); | ||||
|                             hasStories = true; | ||||
|                         } else { | ||||
|                             hasStories = false; | ||||
|  | ||||
| @ -563,7 +563,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR | ||||
|                                             @Override | ||||
|                                             public void onSuccess(final List<StoryModel> storyModels) { | ||||
|                                                 if (storyModels != null && !storyModels.isEmpty()) { | ||||
|                                                     locationDetailsBinding.mainLocationImage.setStoriesBorder(); | ||||
|                                                     locationDetailsBinding.mainLocationImage.setStoriesBorder(1); | ||||
|                                                     hasStories = true; | ||||
|                                                 } | ||||
|                                                 storiesFetching = false; | ||||
|  | ||||
| @ -197,6 +197,7 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr | ||||
|                 @Override | ||||
|                 public void onSuccess(final List<FeedStoryModel> result) { | ||||
|                     feedStoriesViewModel.getList().postValue(result); | ||||
|                     adapter.submitList(result); | ||||
|                     binding.swipeRefreshLayout.setRefreshing(false); | ||||
|                 } | ||||
| 
 | ||||
|  | ||||
| @ -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; | ||||
| @ -134,7 +135,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; | ||||
| @ -256,6 +257,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(); | ||||
| @ -646,6 +656,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); | ||||
| @ -681,6 +692,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(); | ||||
| @ -692,12 +704,14 @@ public class StoryViewerFragment extends Fragment { | ||||
|         if (isHighlight) { | ||||
|             final ActionBar actionBar = fragmentActivity.getSupportActionBar(); | ||||
|             if (actionBar != null) { | ||||
|                 actionBarTitle = highlight; | ||||
|                 actionBar.setTitle(highlight); | ||||
|             } | ||||
|         } else if (hasUsername) { | ||||
|             currentStoryUsername = currentStoryUsername.replace("@", ""); | ||||
|             final ActionBar actionBar = fragmentActivity.getSupportActionBar(); | ||||
|             if (actionBar != null) { | ||||
|                 actionBarTitle = currentStoryUsername; | ||||
|                 actionBar.setTitle(currentStoryUsername); | ||||
|             } | ||||
|         } | ||||
| @ -755,12 +769,14 @@ public class StoryViewerFragment extends Fragment { | ||||
|                 Log.e(TAG, "Error", t); | ||||
|             } | ||||
|         }; | ||||
|         storiesService.getUserStory(currentStoryMediaId, | ||||
|                                     currentStoryUsername, | ||||
|                                     isLoc, | ||||
|                                     isHashtag, | ||||
|                                     isHighlight, | ||||
|                                     storyCallback); | ||||
|           if (live != null) storyCallback.onSuccess(Collections.singletonList(live)); | ||||
|           else storiesService.getUserStory(currentStoryMediaId, | ||||
|                   currentStoryUsername, | ||||
|                   isLoc, | ||||
|                   isHashtag, | ||||
|                   isHighlight, | ||||
|                   storyCallback); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     private void refreshStory() { | ||||
| @ -784,51 +800,55 @@ 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); | ||||
| 
 | ||||
|         final SwipeUpModel swipeUp = currentStory.getSwipeUp(); | ||||
|         if (swipeUp != null) { | ||||
|             binding.swipeUp.setVisibility(View.VISIBLE); | ||||
|             binding.swipeUp.setText(swipeUp.getText()); | ||||
|             binding.swipeUp.setTag(swipeUp.getUrl()); | ||||
|             final SwipeUpModel 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(); | ||||
|         if (isHashtag || isLoc) { | ||||
|             final ActionBar actionBar = fragmentActivity.getSupportActionBar(); | ||||
|             if (actionBar != null) { | ||||
|                 actionBarTitle = currentStory.getUsername(); | ||||
|                 actionBar.setTitle(currentStory.getUsername()); | ||||
|             } | ||||
|         } | ||||
|         if (itemType == MediaItemType.MEDIA_TYPE_VIDEO) setupVideo(); | ||||
|         else if (itemType == MediaItemType.MEDIA_TYPE_LIVE) setupLive(); | ||||
|         else setupImage(); | ||||
| 
 | ||||
|         final ActionBar actionBar = fragmentActivity.getSupportActionBar(); | ||||
| @ -954,6 +974,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) { | ||||
|  | ||||
| @ -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<FeedStoryModel> result) { | ||||
|                 feedStoriesViewModel.getList().postValue(result); | ||||
|                 feedStoriesAdapter.submitList(result); | ||||
|                 storiesFetching = false; | ||||
|                 if (storyListMenu != null) storyListMenu.setVisible(true); | ||||
|                 updateSwipeRefreshState(); | ||||
|  | ||||
| @ -869,7 +869,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe | ||||
|                                         @Override | ||||
|                                         public void onSuccess(final List<StoryModel> storyModels) { | ||||
|                                             if (storyModels != null && !storyModels.isEmpty()) { | ||||
|                                                 profileDetailsBinding.mainProfileImage.setStoriesBorder(); | ||||
|                                                 profileDetailsBinding.mainProfileImage.setStoriesBorder(1); | ||||
|                                                 hasStories = true; | ||||
|                                             } | ||||
|                                         } | ||||
|  | ||||
| @ -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; | ||||
|     } | ||||
| } | ||||
| @ -14,7 +14,10 @@ public enum MediaItemType implements Serializable { | ||||
|     @SerializedName("8") | ||||
|     MEDIA_TYPE_SLIDER(8), | ||||
|     @SerializedName("11") | ||||
|     MEDIA_TYPE_VOICE(11); | ||||
|     MEDIA_TYPE_VOICE(11), | ||||
|     // 5 is arbitrary | ||||
|     @SerializedName("5") | ||||
|     MEDIA_TYPE_LIVE(5); | ||||
| 
 | ||||
|     private final int id; | ||||
|     private static final Map<Integer, MediaItemType> map = new HashMap<>(); | ||||
|  | ||||
| @ -1034,4 +1034,17 @@ public final class ResponseBodyUtils { | ||||
|         } | ||||
|         return read; | ||||
|     } | ||||
|    | ||||
|     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; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -140,11 +140,6 @@ public final class Utils { | ||||
|         return mimeType.toLowerCase(); | ||||
|     } | ||||
| 
 | ||||
|     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; | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user