mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-22 22:57:29 +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.
|
## Answer honestly. Check accordingly to your situation.
|
||||||
|
|
||||||
- [ ] I had prior rule violations on Instagram, specifically:
|
- [ ] I had prior rule violations on Instagram, specifically:
|
||||||
- [ ] I have admitted the use of InstaGrabber on Instagram.
|
- [ ] I have admitted the use of Barinsta on Instagram.
|
||||||
- [ ] I have admitted the use of InstaGrabber to a friend who uses 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:
|
- [ ] 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.
|
## 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: ''
|
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.
|
- [ ] 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.
|
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
|
## Steps
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
DETAILED Steps to reproduce the behaviour.
|
1. ...
|
||||||
1. Go to '...'
|
2. ...
|
||||||
2. Click on '....'
|
3. See error...
|
||||||
3. Scroll down to '....'
|
|
||||||
4. See error
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## Environment
|
## 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
|
General questions & feedback should be submitted to
|
||||||
* one of our chatrooms (see README.md), or
|
* one of our chatrooms (see README.md), or
|
||||||
* r/barinsta on reddit.
|
* r/barinsta on reddit.
|
||||||
|
|
||||||
|
STOP!!!
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
@ -60,11 +60,13 @@ dependencies {
|
|||||||
|
|
||||||
def appcompat_version = "1.2.0"
|
def appcompat_version = "1.2.0"
|
||||||
def nav_version = '2.3.2'
|
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.material:material:1.3.0-beta01'
|
||||||
|
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-core:2.12.0'
|
implementation "com.google.android.exoplayer:exoplayer-core:$exoplayer_version"
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-ui:2.12.0'
|
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:$appcompat_version"
|
||||||
implementation "androidx.appcompat:appcompat-resources:$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.FeedModel;
|
||||||
import awais.instagrabber.models.PostsLayoutPreferences;
|
import awais.instagrabber.models.PostsLayoutPreferences;
|
||||||
import awais.instagrabber.models.enums.MediaItemType;
|
import awais.instagrabber.models.enums.MediaItemType;
|
||||||
|
import awais.instagrabber.utils.TextUtils;
|
||||||
|
|
||||||
public final class FeedAdapterV2 extends ListAdapter<FeedModel, RecyclerView.ViewHolder> {
|
public final class FeedAdapterV2 extends ListAdapter<FeedModel, RecyclerView.ViewHolder> {
|
||||||
private static final String TAG = "FeedAdapterV2";
|
private static final String TAG = "FeedAdapterV2";
|
||||||
@ -46,7 +47,13 @@ public final class FeedAdapterV2 extends ListAdapter<FeedModel, RecyclerView.Vie
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean areContentsTheSame(@NonNull final FeedModel oldItem, @NonNull final FeedModel newItem) {
|
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() {
|
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.title.setAlpha(model.isFullyRead() ? 0.5F : 1.0F);
|
||||||
binding.icon.setImageURI(profileModel.getSdProfilePic());
|
binding.icon.setImageURI(profileModel.getSdProfilePic());
|
||||||
binding.icon.setAlpha(model.isFullyRead() ? 0.5F : 1.0F);
|
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);
|
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;
|
// private final int borderSize = 8;
|
||||||
final int color = Color.GREEN;
|
final int color = type == 2 ? Color.RED : Color.GREEN;
|
||||||
RoundingParams roundingParams = getHierarchy().getRoundingParams();
|
RoundingParams roundingParams = getHierarchy().getRoundingParams();
|
||||||
if (roundingParams == null) {
|
if (roundingParams == null) {
|
||||||
roundingParams = RoundingParams.asCircle().setRoundingMethod(RoundingParams.RoundingMethod.BITMAP_ONLY);
|
roundingParams = RoundingParams.asCircle().setRoundingMethod(RoundingParams.RoundingMethod.BITMAP_ONLY);
|
||||||
}
|
}
|
||||||
roundingParams.setBorder(color, 5.0f);
|
roundingParams.setBorder(color, type == 0 ? 0f : 5.0f);
|
||||||
getHierarchy().setRoundingParams(roundingParams);
|
getHierarchy().setRoundingParams(roundingParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -580,7 +580,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(final List<StoryModel> storyModels) {
|
public void onSuccess(final List<StoryModel> storyModels) {
|
||||||
if (storyModels != null && !storyModels.isEmpty()) {
|
if (storyModels != null && !storyModels.isEmpty()) {
|
||||||
hashtagDetailsBinding.mainHashtagImage.setStoriesBorder();
|
hashtagDetailsBinding.mainHashtagImage.setStoriesBorder(1);
|
||||||
hasStories = true;
|
hasStories = true;
|
||||||
} else {
|
} else {
|
||||||
hasStories = false;
|
hasStories = false;
|
||||||
|
@ -563,7 +563,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(final List<StoryModel> storyModels) {
|
public void onSuccess(final List<StoryModel> storyModels) {
|
||||||
if (storyModels != null && !storyModels.isEmpty()) {
|
if (storyModels != null && !storyModels.isEmpty()) {
|
||||||
locationDetailsBinding.mainLocationImage.setStoriesBorder();
|
locationDetailsBinding.mainLocationImage.setStoriesBorder(1);
|
||||||
hasStories = true;
|
hasStories = true;
|
||||||
}
|
}
|
||||||
storiesFetching = false;
|
storiesFetching = false;
|
||||||
|
@ -197,6 +197,7 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(final List<FeedStoryModel> result) {
|
public void onSuccess(final List<FeedStoryModel> result) {
|
||||||
feedStoriesViewModel.getList().postValue(result);
|
feedStoriesViewModel.getList().postValue(result);
|
||||||
|
adapter.submitList(result);
|
||||||
binding.swipeRefreshLayout.setRefreshing(false);
|
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.MediaItem;
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
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.LoadEventInfo;
|
||||||
import com.google.android.exoplayer2.source.MediaLoadData;
|
import com.google.android.exoplayer2.source.MediaLoadData;
|
||||||
import com.google.android.exoplayer2.source.MediaSource;
|
import com.google.android.exoplayer2.source.MediaSource;
|
||||||
@ -134,7 +135,7 @@ public class StoryViewerFragment extends Fragment {
|
|||||||
private MenuItem menuDm;
|
private MenuItem menuDm;
|
||||||
private SimpleExoPlayer player;
|
private SimpleExoPlayer player;
|
||||||
private boolean isHashtag, isLoc;
|
private boolean isHashtag, isLoc;
|
||||||
private String highlight;
|
private String highlight, actionBarTitle;
|
||||||
private boolean fetching = false, sticking = false, shouldRefresh = true;
|
private boolean fetching = false, sticking = false, shouldRefresh = true;
|
||||||
private int currentFeedStoryIndex;
|
private int currentFeedStoryIndex;
|
||||||
private double sliderValue;
|
private double sliderValue;
|
||||||
@ -256,6 +257,15 @@ public class StoryViewerFragment extends Fragment {
|
|||||||
releasePlayer();
|
releasePlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
||||||
|
if (actionBar != null) {
|
||||||
|
actionBar.setTitle(actionBarTitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
releasePlayer();
|
releasePlayer();
|
||||||
@ -646,6 +656,7 @@ public class StoryViewerFragment extends Fragment {
|
|||||||
|
|
||||||
private void resetView() {
|
private void resetView() {
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
|
StoryModel live = null;
|
||||||
slidePos = 0;
|
slidePos = 0;
|
||||||
lastSlidePos = 0;
|
lastSlidePos = 0;
|
||||||
if (menuDownload != null) menuDownload.setVisible(false);
|
if (menuDownload != null) menuDownload.setVisible(false);
|
||||||
@ -681,6 +692,7 @@ public class StoryViewerFragment extends Fragment {
|
|||||||
final FeedStoryModel model = models.get(currentFeedStoryIndex);
|
final FeedStoryModel model = models.get(currentFeedStoryIndex);
|
||||||
currentStoryMediaId = model.getStoryMediaId();
|
currentStoryMediaId = model.getStoryMediaId();
|
||||||
currentStoryUsername = model.getProfileModel().getUsername();
|
currentStoryUsername = model.getProfileModel().getUsername();
|
||||||
|
if (model.isLive()) live = model.getFirstStoryModel();
|
||||||
}
|
}
|
||||||
} else if (!TextUtils.isEmpty(fragmentArgs.getProfileId()) && !TextUtils.isEmpty(fragmentArgs.getUsername())) {
|
} else if (!TextUtils.isEmpty(fragmentArgs.getProfileId()) && !TextUtils.isEmpty(fragmentArgs.getUsername())) {
|
||||||
currentStoryMediaId = fragmentArgs.getProfileId();
|
currentStoryMediaId = fragmentArgs.getProfileId();
|
||||||
@ -692,12 +704,14 @@ public class StoryViewerFragment extends Fragment {
|
|||||||
if (isHighlight) {
|
if (isHighlight) {
|
||||||
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
||||||
if (actionBar != null) {
|
if (actionBar != null) {
|
||||||
|
actionBarTitle = highlight;
|
||||||
actionBar.setTitle(highlight);
|
actionBar.setTitle(highlight);
|
||||||
}
|
}
|
||||||
} else if (hasUsername) {
|
} else if (hasUsername) {
|
||||||
currentStoryUsername = currentStoryUsername.replace("@", "");
|
currentStoryUsername = currentStoryUsername.replace("@", "");
|
||||||
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
||||||
if (actionBar != null) {
|
if (actionBar != null) {
|
||||||
|
actionBarTitle = currentStoryUsername;
|
||||||
actionBar.setTitle(currentStoryUsername);
|
actionBar.setTitle(currentStoryUsername);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -755,13 +769,15 @@ public class StoryViewerFragment extends Fragment {
|
|||||||
Log.e(TAG, "Error", t);
|
Log.e(TAG, "Error", t);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
storiesService.getUserStory(currentStoryMediaId,
|
if (live != null) storyCallback.onSuccess(Collections.singletonList(live));
|
||||||
|
else storiesService.getUserStory(currentStoryMediaId,
|
||||||
currentStoryUsername,
|
currentStoryUsername,
|
||||||
isLoc,
|
isLoc,
|
||||||
isHashtag,
|
isHashtag,
|
||||||
isHighlight,
|
isHighlight,
|
||||||
storyCallback);
|
storyCallback);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void refreshStory() {
|
private void refreshStory() {
|
||||||
if (binding.storiesList.getVisibility() == View.VISIBLE) {
|
if (binding.storiesList.getVisibility() == View.VISIBLE) {
|
||||||
@ -784,8 +800,9 @@ public class StoryViewerFragment extends Fragment {
|
|||||||
final MediaItemType itemType = currentStory.getItemType();
|
final MediaItemType itemType = currentStory.getItemType();
|
||||||
|
|
||||||
if (menuDownload != null) menuDownload.setVisible(false);
|
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();
|
||||||
|
|
||||||
|
if (itemType != MediaItemType.MEDIA_TYPE_LIVE) {
|
||||||
final String shortCode = currentStory.getTappableShortCode();
|
final String shortCode = currentStory.getTappableShortCode();
|
||||||
binding.viewStoryPost.setVisibility(shortCode != null ? View.VISIBLE : View.GONE);
|
binding.viewStoryPost.setVisibility(shortCode != null ? View.VISIBLE : View.GONE);
|
||||||
binding.viewStoryPost.setTag(shortCode);
|
binding.viewStoryPost.setTag(shortCode);
|
||||||
@ -819,16 +836,19 @@ public class StoryViewerFragment extends Fragment {
|
|||||||
binding.swipeUp.setVisibility(View.VISIBLE);
|
binding.swipeUp.setVisibility(View.VISIBLE);
|
||||||
binding.swipeUp.setText(swipeUp.getText());
|
binding.swipeUp.setText(swipeUp.getText());
|
||||||
binding.swipeUp.setTag(swipeUp.getUrl());
|
binding.swipeUp.setTag(swipeUp.getUrl());
|
||||||
|
} else binding.swipeUp.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
releasePlayer();
|
releasePlayer();
|
||||||
if (isHashtag || isLoc) {
|
if (isHashtag || isLoc) {
|
||||||
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
||||||
if (actionBar != null) {
|
if (actionBar != null) {
|
||||||
|
actionBarTitle = currentStory.getUsername();
|
||||||
actionBar.setTitle(currentStory.getUsername());
|
actionBar.setTitle(currentStory.getUsername());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (itemType == MediaItemType.MEDIA_TYPE_VIDEO) setupVideo();
|
if (itemType == MediaItemType.MEDIA_TYPE_VIDEO) setupVideo();
|
||||||
|
else if (itemType == MediaItemType.MEDIA_TYPE_LIVE) setupLive();
|
||||||
else setupImage();
|
else setupImage();
|
||||||
|
|
||||||
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
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) {
|
private void openProfile(final String username) {
|
||||||
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
||||||
if (actionBar != null) {
|
if (actionBar != null) {
|
||||||
|
@ -79,6 +79,21 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
|
|||||||
private RecyclerView storiesRecyclerView;
|
private RecyclerView storiesRecyclerView;
|
||||||
private MenuItem storyListMenu;
|
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() {
|
private final FeedAdapterV2.FeedItemCallback feedItemCallback = new FeedAdapterV2.FeedItemCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onPostClick(final FeedModel feedModel, final View profilePicView, final View mainPostImage) {
|
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() {
|
private void setupFeedStories() {
|
||||||
if (storyListMenu != null) storyListMenu.setVisible(false);
|
if (storyListMenu != null) storyListMenu.setVisible(false);
|
||||||
feedStoriesViewModel = new ViewModelProvider(fragmentActivity).get(FeedStoriesViewModel.class);
|
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();
|
final Context context = getContext();
|
||||||
if (context == null) return;
|
if (context == null) return;
|
||||||
storiesRecyclerView = new RecyclerView(context);
|
storiesRecyclerView = new RecyclerView(context);
|
||||||
@ -390,6 +391,7 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(final List<FeedStoryModel> result) {
|
public void onSuccess(final List<FeedStoryModel> result) {
|
||||||
feedStoriesViewModel.getList().postValue(result);
|
feedStoriesViewModel.getList().postValue(result);
|
||||||
|
feedStoriesAdapter.submitList(result);
|
||||||
storiesFetching = false;
|
storiesFetching = false;
|
||||||
if (storyListMenu != null) storyListMenu.setVisible(true);
|
if (storyListMenu != null) storyListMenu.setVisible(true);
|
||||||
updateSwipeRefreshState();
|
updateSwipeRefreshState();
|
||||||
|
@ -869,7 +869,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(final List<StoryModel> storyModels) {
|
public void onSuccess(final List<StoryModel> storyModels) {
|
||||||
if (storyModels != null && !storyModels.isEmpty()) {
|
if (storyModels != null && !storyModels.isEmpty()) {
|
||||||
profileDetailsBinding.mainProfileImage.setStoriesBorder();
|
profileDetailsBinding.mainProfileImage.setStoriesBorder(1);
|
||||||
hasStories = true;
|
hasStories = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,17 +14,21 @@ public final class FeedStoryModel implements Serializable {
|
|||||||
private final ProfileModel profileModel;
|
private final ProfileModel profileModel;
|
||||||
private final StoryModel firstStoryModel;
|
private final StoryModel firstStoryModel;
|
||||||
private Boolean fullyRead;
|
private Boolean fullyRead;
|
||||||
|
private final boolean isLive, isBestie;
|
||||||
private final long timestamp;
|
private final long timestamp;
|
||||||
private final int mediaCount;
|
private final int mediaCount;
|
||||||
|
|
||||||
public FeedStoryModel(final String storyMediaId, final ProfileModel profileModel, final boolean fullyRead,
|
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.storyMediaId = storyMediaId;
|
||||||
this.profileModel = profileModel;
|
this.profileModel = profileModel;
|
||||||
this.fullyRead = fullyRead;
|
this.fullyRead = fullyRead;
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
this.firstStoryModel = firstStoryModel;
|
this.firstStoryModel = firstStoryModel;
|
||||||
this.mediaCount = mediaCount;
|
this.mediaCount = mediaCount;
|
||||||
|
this.isLive = isLive;
|
||||||
|
this.isBestie = isBestie;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStoryMediaId() {
|
public String getStoryMediaId() {
|
||||||
@ -63,4 +67,12 @@ public final class FeedStoryModel implements Serializable {
|
|||||||
public void setFullyRead(final boolean fullyRead) {
|
public void setFullyRead(final boolean fullyRead) {
|
||||||
this.fullyRead = 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")
|
@SerializedName("8")
|
||||||
MEDIA_TYPE_SLIDER(8),
|
MEDIA_TYPE_SLIDER(8),
|
||||||
@SerializedName("11")
|
@SerializedName("11")
|
||||||
MEDIA_TYPE_VOICE(11);
|
MEDIA_TYPE_VOICE(11),
|
||||||
|
// 5 is arbitrary
|
||||||
|
@SerializedName("5")
|
||||||
|
MEDIA_TYPE_LIVE(5);
|
||||||
|
|
||||||
private final int id;
|
private final int id;
|
||||||
private static final Map<Integer, MediaItemType> map = new HashMap<>();
|
private static final Map<Integer, MediaItemType> map = new HashMap<>();
|
||||||
|
@ -1034,4 +1034,17 @@ public final class ResponseBodyUtils {
|
|||||||
}
|
}
|
||||||
return read;
|
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();
|
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) {
|
public static SimpleCache getSimpleCacheInstance(final Context context) {
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -121,12 +121,32 @@ public class StoriesService extends BaseService {
|
|||||||
final long timestamp = node.getLong("latest_reel_media");
|
final long timestamp = node.getLong("latest_reel_media");
|
||||||
final int mediaCount = node.getInt("media_count");
|
final int mediaCount = node.getInt("media_count");
|
||||||
final boolean fullyRead = !node.isNull("seen") && node.getLong("seen") == timestamp;
|
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;
|
StoryModel firstStoryModel = null;
|
||||||
if (itemJson != null) {
|
if (itemJson != null) {
|
||||||
firstStoryModel = ResponseBodyUtils.parseStoryItem(itemJson, false, false, 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));
|
callback.onSuccess(sort(feedStoryModels));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
Loading…
Reference in New Issue
Block a user