parent
b5e1101709
commit
853115eb4e
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -549,7 +549,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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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<Integer, MediaItemType> map = new HashMap<>();
|
||||
private static final Map<Integer, MediaItemType> map = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (MediaItemType type : MediaItemType.values()) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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…
Reference in New Issue
Block a user