mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-22 06:37:30 +00:00
parent
53b0301385
commit
4d9494cbcf
@ -10,20 +10,21 @@ import androidx.recyclerview.widget.ListAdapter;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import awais.instagrabber.databinding.ItemStoryBinding;
|
||||
import awais.instagrabber.models.StoryModel;
|
||||
import awais.instagrabber.repositories.responses.stories.StoryMedia;
|
||||
import awais.instagrabber.utils.ResponseBodyUtils;
|
||||
|
||||
public final class StoriesAdapter extends ListAdapter<StoryModel, StoriesAdapter.StoryViewHolder> {
|
||||
public final class StoriesAdapter extends ListAdapter<StoryMedia, StoriesAdapter.StoryViewHolder> {
|
||||
private final OnItemClickListener onItemClickListener;
|
||||
|
||||
private static final DiffUtil.ItemCallback<StoryModel> diffCallback = new DiffUtil.ItemCallback<StoryModel>() {
|
||||
private static final DiffUtil.ItemCallback<StoryMedia> diffCallback = new DiffUtil.ItemCallback<StoryMedia>() {
|
||||
@Override
|
||||
public boolean areItemsTheSame(@NonNull final StoryModel oldItem, @NonNull final StoryModel newItem) {
|
||||
return oldItem.getStoryMediaId().equals(newItem.getStoryMediaId());
|
||||
public boolean areItemsTheSame(@NonNull final StoryMedia oldItem, @NonNull final StoryMedia newItem) {
|
||||
return oldItem.getId().equals(newItem.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(@NonNull final StoryModel oldItem, @NonNull final StoryModel newItem) {
|
||||
return oldItem.getStoryMediaId().equals(newItem.getStoryMediaId());
|
||||
public boolean areContentsTheSame(@NonNull final StoryMedia oldItem, @NonNull final StoryMedia newItem) {
|
||||
return oldItem.getId().equals(newItem.getId());
|
||||
}
|
||||
};
|
||||
|
||||
@ -42,8 +43,8 @@ public final class StoriesAdapter extends ListAdapter<StoryModel, StoriesAdapter
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final StoryViewHolder holder, final int position) {
|
||||
final StoryModel storyModel = getItem(position);
|
||||
holder.bind(storyModel, position, onItemClickListener);
|
||||
final StoryMedia storyMedia = getItem(position);
|
||||
holder.bind(storyMedia, position, onItemClickListener);
|
||||
}
|
||||
|
||||
public final static class StoryViewHolder extends RecyclerView.ViewHolder {
|
||||
@ -54,7 +55,7 @@ public final class StoriesAdapter extends ListAdapter<StoryModel, StoriesAdapter
|
||||
this.binding = binding;
|
||||
}
|
||||
|
||||
public void bind(final StoryModel model,
|
||||
public void bind(final StoryMedia model,
|
||||
final int position,
|
||||
final OnItemClickListener clickListener) {
|
||||
if (model == null) return;
|
||||
@ -67,14 +68,11 @@ public final class StoriesAdapter extends ListAdapter<StoryModel, StoriesAdapter
|
||||
});
|
||||
|
||||
binding.selectedView.setVisibility(model.isCurrentSlide() ? View.VISIBLE : View.GONE);
|
||||
binding.icon.setImageURI(model.getStoryUrl());
|
||||
// Glide.with(itemView).load(model.getStoryUrl())
|
||||
// .apply(new RequestOptions().override(width, height))
|
||||
// .into(holder.icon);
|
||||
binding.icon.setImageURI(ResponseBodyUtils.getThumbUrl(model));
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onItemClick(StoryModel storyModel, int position);
|
||||
void onItemClick(StoryMedia storyModel, int position);
|
||||
}
|
||||
}
|
@ -548,7 +548,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
// private void fetchStories() {
|
||||
// if (!isLoggedIn) return;
|
||||
// storiesFetching = true;
|
||||
// storiesRepository.getUserStory(
|
||||
// storiesRepository.getStories(
|
||||
// StoryViewerOptions.forHashtag(hashtagModel.getName()),
|
||||
// CoroutineUtilsKt.getContinuation((storyModels, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
// if (throwable != null) {
|
||||
|
@ -552,7 +552,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
||||
// private void fetchStories() {
|
||||
// if (isLoggedIn) {
|
||||
// storiesFetching = true;
|
||||
// storiesRepository.getUserStory(
|
||||
// storiesRepository.getStories(
|
||||
// StoryViewerOptions.forLocation(locationId, locationModel.getName()),
|
||||
// CoroutineUtilsKt.getContinuation((storyModels, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
// if (throwable != null) {
|
||||
|
@ -58,8 +58,10 @@ import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@ -72,23 +74,17 @@ import awais.instagrabber.databinding.FragmentStoryViewerBinding;
|
||||
import awais.instagrabber.fragments.main.ProfileFragmentDirections;
|
||||
import awais.instagrabber.fragments.settings.PreferenceKeys;
|
||||
import awais.instagrabber.interfaces.SwipeEvent;
|
||||
import awais.instagrabber.models.StoryModel;
|
||||
import awais.instagrabber.models.enums.MediaItemType;
|
||||
import awais.instagrabber.models.stickers.PollModel;
|
||||
import awais.instagrabber.models.stickers.QuestionModel;
|
||||
import awais.instagrabber.models.stickers.QuizModel;
|
||||
import awais.instagrabber.models.stickers.SliderModel;
|
||||
import awais.instagrabber.models.stickers.SwipeUpModel;
|
||||
import awais.instagrabber.repositories.requests.StoryViewerOptions;
|
||||
import awais.instagrabber.repositories.requests.StoryViewerOptions.Type;
|
||||
import awais.instagrabber.repositories.requests.directmessages.ThreadIdsOrUserIds;
|
||||
import awais.instagrabber.repositories.responses.stories.Broadcast;
|
||||
import awais.instagrabber.repositories.responses.stories.Story;
|
||||
import awais.instagrabber.repositories.responses.stories.*;
|
||||
import awais.instagrabber.utils.AppExecutors;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.utils.CoroutineUtilsKt;
|
||||
import awais.instagrabber.utils.DownloadUtils;
|
||||
import awais.instagrabber.utils.ResponseBodyUtils;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
import awais.instagrabber.viewmodels.ArchivesViewModel;
|
||||
@ -121,16 +117,16 @@ public class StoryViewerFragment extends Fragment {
|
||||
private GestureDetectorCompat gestureDetector;
|
||||
private StoriesRepository storiesRepository;
|
||||
private MediaRepository mediaRepository;
|
||||
private StoryModel currentStory;
|
||||
private StoryMedia currentStory;
|
||||
private Broadcast live;
|
||||
private int slidePos;
|
||||
private int lastSlidePos;
|
||||
private String url;
|
||||
private PollModel poll;
|
||||
private QuestionModel question;
|
||||
private String[] mentions;
|
||||
private QuizModel quiz;
|
||||
private SliderModel slider;
|
||||
private PollSticker poll;
|
||||
private QuestionSticker question;
|
||||
private List<String> mentions = new ArrayList<String>();
|
||||
private QuizSticker quiz;
|
||||
private SliderSticker slider;
|
||||
private MenuItem menuDownload, menuDm, menuProfile;
|
||||
private SimpleExoPlayer player;
|
||||
// private boolean isHashtag;
|
||||
@ -220,10 +216,10 @@ public class StoryViewerFragment extends Fragment {
|
||||
csrfToken,
|
||||
userId,
|
||||
deviceId,
|
||||
ThreadIdsOrUserIds.Companion.ofOneUser(String.valueOf(currentStory.getUserId())),
|
||||
ThreadIdsOrUserIds.Companion.ofOneUser(String.valueOf(currentStory.getUser().getPk())),
|
||||
input.getText().toString(),
|
||||
currentStory.getStoryMediaId(),
|
||||
String.valueOf(currentStory.getUserId()),
|
||||
currentStory.getId(),
|
||||
String.valueOf(currentStory.getUser().getPk()),
|
||||
CoroutineUtilsKt.getContinuation(
|
||||
(directThreadBroadcastResponse, throwable1) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
if (throwable1 != null) {
|
||||
@ -253,7 +249,7 @@ public class StoryViewerFragment extends Fragment {
|
||||
return true;
|
||||
}
|
||||
if (itemId == R.id.action_profile) {
|
||||
openProfile("@" + currentStory.getUsername());
|
||||
openProfile("@" + currentStory.getUser().getPk());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -357,7 +353,7 @@ public class StoryViewerFragment extends Fragment {
|
||||
final Context context = getContext();
|
||||
if (context == null) return;
|
||||
swipeEvent = isRightSwipe -> {
|
||||
final List<StoryModel> storyModels = storiesViewModel.getList().getValue();
|
||||
final List<StoryMedia> storyModels = storiesViewModel.getList().getValue();
|
||||
final int storiesLen = storyModels == null ? 0 : storyModels.size();
|
||||
if (sticking) {
|
||||
Toast.makeText(context, R.string.follower_wait_to_load, Toast.LENGTH_SHORT).show();
|
||||
@ -373,12 +369,14 @@ public class StoryViewerFragment extends Fragment {
|
||||
Toast.makeText(context, R.string.no_more_stories, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
removeStickers();
|
||||
final Object feedStoryModel = isRightSwipe
|
||||
? finalModels.get(index - 1)
|
||||
: finalModels.size() == index + 1 ? null : finalModels.get(index + 1);
|
||||
paginateStories(feedStoryModel, finalModels.get(index), context, isRightSwipe, currentFeedStoryIndex == finalModels.size() - 2);
|
||||
return;
|
||||
}
|
||||
removeStickers();
|
||||
if (isRightSwipe) {
|
||||
if (--slidePos <= 0) {
|
||||
slidePos = 0;
|
||||
@ -471,35 +469,31 @@ public class StoryViewerFragment extends Fragment {
|
||||
});
|
||||
final View.OnClickListener storyActionListener = v -> {
|
||||
final Object tag = v.getTag();
|
||||
if (tag instanceof PollModel) {
|
||||
poll = (PollModel) tag;
|
||||
if (poll.getMyChoice() > -1) {
|
||||
if (tag instanceof PollSticker) {
|
||||
poll = (PollSticker) tag;
|
||||
final List<Tally> tallies = poll.getTallies();
|
||||
final String[] choices = tallies.stream()
|
||||
.map(t -> (poll.getViewerVote() == tallies.indexOf(t) ? "√ " : "")
|
||||
+ t.getText() + " (" + t.getCount() + ")" )
|
||||
.toArray(String[]::new);
|
||||
final ArrayAdapter adapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, choices);
|
||||
if (poll.getViewerVote() > -1) {
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(R.string.voted_story_poll)
|
||||
.setAdapter(new ArrayAdapter<>(
|
||||
context,
|
||||
android.R.layout.simple_list_item_1,
|
||||
new String[]{
|
||||
(poll.getMyChoice() == 0 ? "√ " : "") + poll.getLeftChoice() + " (" + poll.getLeftCount() + ")",
|
||||
(poll.getMyChoice() == 1 ? "√ " : "") + poll.getRightChoice() + " (" + poll.getRightCount() + ")"
|
||||
}),
|
||||
null)
|
||||
.setAdapter(adapter, null)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show();
|
||||
} else {
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(poll.getQuestion())
|
||||
.setAdapter(new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, new String[]{
|
||||
poll.getLeftChoice() + " (" + poll.getLeftCount() + ")",
|
||||
poll.getRightChoice() + " (" + poll.getRightCount() + ")"
|
||||
}), (d, w) -> {
|
||||
.setAdapter(adapter, (d, w) -> {
|
||||
sticking = true;
|
||||
storiesRepository.respondToPoll(
|
||||
csrfToken,
|
||||
userId,
|
||||
deviceId,
|
||||
currentStory.getStoryMediaId().split("_")[0],
|
||||
poll.getId(),
|
||||
currentStory.getId().split("_")[0],
|
||||
poll.getPollId(),
|
||||
w,
|
||||
CoroutineUtilsKt.getContinuation(
|
||||
(storyStickerResponse, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
@ -513,7 +507,7 @@ public class StoryViewerFragment extends Fragment {
|
||||
}
|
||||
sticking = false;
|
||||
try {
|
||||
poll.setMyChoice(w);
|
||||
poll.setViewerVote(w);
|
||||
Toast.makeText(context, R.string.votef_story_poll, Toast.LENGTH_SHORT).show();
|
||||
} catch (Exception ignored) {}
|
||||
}),
|
||||
@ -524,8 +518,8 @@ public class StoryViewerFragment extends Fragment {
|
||||
.setPositiveButton(R.string.cancel, null)
|
||||
.show();
|
||||
}
|
||||
} else if (tag instanceof QuestionModel) {
|
||||
question = (QuestionModel) tag;
|
||||
} else if (tag instanceof QuestionSticker) {
|
||||
question = (QuestionSticker) tag;
|
||||
final EditText input = new EditText(context);
|
||||
input.setHint(R.string.answer_hint);
|
||||
final AlertDialog ad = new AlertDialog.Builder(context)
|
||||
@ -537,8 +531,8 @@ public class StoryViewerFragment extends Fragment {
|
||||
csrfToken,
|
||||
userId,
|
||||
deviceId,
|
||||
currentStory.getStoryMediaId().split("_")[0],
|
||||
question.getId(),
|
||||
currentStory.getId().split("_")[0],
|
||||
question.getQuestionId(),
|
||||
input.getText().toString(),
|
||||
CoroutineUtilsKt.getContinuation(
|
||||
(storyStickerResponse, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
@ -575,28 +569,31 @@ public class StoryViewerFragment extends Fragment {
|
||||
public void afterTextChanged(final Editable s) {}
|
||||
});
|
||||
} else if (tag instanceof String[]) {
|
||||
mentions = (String[]) tag;
|
||||
final String[] rawMentions = (String[]) tag;
|
||||
mentions = new ArrayList<String>(Arrays.asList(rawMentions));
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(R.string.story_mentions)
|
||||
.setAdapter(new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, mentions), (d, w) -> openProfile(mentions[w]))
|
||||
.setAdapter(new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, rawMentions), (d, w) -> openProfile(mentions.get(w)))
|
||||
.setPositiveButton(R.string.cancel, null)
|
||||
.show();
|
||||
} else if (tag instanceof QuizModel) {
|
||||
String[] choices = new String[quiz.getChoices().length];
|
||||
for (int q = 0; q < choices.length; ++q) {
|
||||
choices[q] = (quiz.getMyChoice() == q ? "√ " : "") + quiz.getChoices()[q] + " (" + quiz.getCounts()[q] + ")";
|
||||
}
|
||||
} else if (tag instanceof QuizSticker) {
|
||||
final List<Tally> tallies = quiz.getTallies();
|
||||
final String[] choices = tallies.stream().map(
|
||||
t -> (quiz.getViewerAnswer() == tallies.indexOf(t) ? "√ " : "") +
|
||||
(quiz.getCorrectAnswer() == tallies.indexOf(t) ? "*** " : "") +
|
||||
t.getText() + " (" + t.getCount() + ")"
|
||||
).toArray(String[]::new);
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(quiz.getMyChoice() > -1 ? getString(R.string.story_quizzed) : quiz.getQuestion())
|
||||
.setTitle(quiz.getViewerAnswer() > -1 ? getString(R.string.story_quizzed) : quiz.getQuestion())
|
||||
.setAdapter(new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, choices), (d, w) -> {
|
||||
if (quiz.getMyChoice() == -1) {
|
||||
if (quiz.getViewerAnswer() == -1) {
|
||||
sticking = true;
|
||||
storiesRepository.respondToQuiz(
|
||||
csrfToken,
|
||||
userId,
|
||||
deviceId,
|
||||
currentStory.getStoryMediaId().split("_")[0],
|
||||
quiz.getId(),
|
||||
currentStory.getId().split("_")[0],
|
||||
quiz.getQuizId(),
|
||||
w,
|
||||
CoroutineUtilsKt.getContinuation(
|
||||
(storyStickerResponse, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
@ -610,7 +607,7 @@ public class StoryViewerFragment extends Fragment {
|
||||
}
|
||||
sticking = false;
|
||||
try {
|
||||
quiz.setMyChoice(w);
|
||||
quiz.setViewerAnswer(w);
|
||||
Toast.makeText(context, R.string.answered_story, Toast.LENGTH_SHORT).show();
|
||||
} catch (Exception ignored) {}
|
||||
}),
|
||||
@ -621,8 +618,8 @@ public class StoryViewerFragment extends Fragment {
|
||||
})
|
||||
.setPositiveButton(R.string.cancel, null)
|
||||
.show();
|
||||
} else if (tag instanceof SliderModel) {
|
||||
slider = (SliderModel) tag;
|
||||
} else if (tag instanceof SliderSticker) {
|
||||
slider = (SliderSticker) tag;
|
||||
NumberFormat percentage = NumberFormat.getPercentInstance();
|
||||
percentage.setMaximumFractionDigits(2);
|
||||
LinearLayout sliderView = new LinearLayout(context);
|
||||
@ -633,11 +630,11 @@ public class StoryViewerFragment extends Fragment {
|
||||
TextView tv = new TextView(context);
|
||||
tv.setGravity(Gravity.CENTER_HORIZONTAL);
|
||||
final SeekBar input = new SeekBar(context);
|
||||
double avg = slider.getAverage() * 100;
|
||||
double avg = slider.getSliderVoteAverage() * 100;
|
||||
input.setProgress((int) avg);
|
||||
sliderView.addView(input);
|
||||
sliderView.addView(tv);
|
||||
if (slider.getMyChoice().isNaN() && slider.canVote()) {
|
||||
if (slider.getViewerVote().isNaN() && slider.getViewerCanVote()) {
|
||||
input.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
@ -656,9 +653,9 @@ public class StoryViewerFragment extends Fragment {
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(TextUtils.isEmpty(slider.getQuestion()) ? slider.getEmoji() : slider.getQuestion())
|
||||
.setMessage(getResources().getQuantityString(R.plurals.slider_info,
|
||||
slider.getVoteCount(),
|
||||
slider.getVoteCount(),
|
||||
percentage.format(slider.getAverage())))
|
||||
slider.getSliderVoteCount(),
|
||||
slider.getSliderVoteCount(),
|
||||
percentage.format(slider.getSliderVoteAverage())))
|
||||
.setView(sliderView)
|
||||
.setPositiveButton(R.string.confirm, (d, w) -> {
|
||||
sticking = true;
|
||||
@ -666,8 +663,8 @@ public class StoryViewerFragment extends Fragment {
|
||||
csrfToken,
|
||||
userId,
|
||||
deviceId,
|
||||
currentStory.getStoryMediaId().split("_")[0],
|
||||
slider.getId(),
|
||||
currentStory.getId().split("_")[0],
|
||||
slider.getSliderId(),
|
||||
sliderValue,
|
||||
CoroutineUtilsKt.getContinuation(
|
||||
(storyStickerResponse, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
@ -681,7 +678,7 @@ public class StoryViewerFragment extends Fragment {
|
||||
}
|
||||
sticking = false;
|
||||
try {
|
||||
slider.setMyChoice(sliderValue);
|
||||
slider.setViewerVote(sliderValue);
|
||||
Toast.makeText(context, R.string.answered_story, Toast.LENGTH_SHORT).show();
|
||||
} catch (Exception ignored) {}
|
||||
}), Dispatchers.getIO()
|
||||
@ -692,13 +689,13 @@ public class StoryViewerFragment extends Fragment {
|
||||
.show();
|
||||
} else {
|
||||
input.setEnabled(false);
|
||||
tv.setText(getString(R.string.slider_answer, percentage.format(slider.getMyChoice())));
|
||||
tv.setText(getString(R.string.slider_answer, percentage.format(slider.getViewerVote())));
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(TextUtils.isEmpty(slider.getQuestion()) ? slider.getEmoji() : slider.getQuestion())
|
||||
.setMessage(getResources().getQuantityString(R.plurals.slider_info,
|
||||
slider.getVoteCount(),
|
||||
slider.getVoteCount(),
|
||||
percentage.format(slider.getAverage())))
|
||||
slider.getSliderVoteCount(),
|
||||
slider.getSliderVoteCount(),
|
||||
percentage.format(slider.getSliderVoteAverage())))
|
||||
.setView(sliderView)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show();
|
||||
@ -746,11 +743,12 @@ public class StoryViewerFragment extends Fragment {
|
||||
case FEED_STORY_POSITION: {
|
||||
final FeedStoriesViewModel feedStoriesViewModel = (FeedStoriesViewModel) viewModel;
|
||||
final List<Story> models = feedStoriesViewModel.getList().getValue();
|
||||
if (models == null || currentFeedStoryIndex >= models.size() || currentFeedStoryIndex < 0) return;
|
||||
if (models == null || currentFeedStoryIndex >= models.size() || currentFeedStoryIndex < 0)
|
||||
return;
|
||||
final Story model = models.get(currentFeedStoryIndex);
|
||||
currentStoryMediaId = model.getId();
|
||||
currentStoryMediaId = String.valueOf(model.getUser().getPk());
|
||||
currentStoryUsername = model.getUser().getUsername();
|
||||
fetchOptions = StoryViewerOptions.forUser(Long.parseLong(currentStoryMediaId), currentStoryUsername);
|
||||
fetchOptions = StoryViewerOptions.forUser(model.getUser().getPk(), currentStoryUsername);
|
||||
live = model.getBroadcast();
|
||||
break;
|
||||
}
|
||||
@ -767,11 +765,12 @@ public class StoryViewerFragment extends Fragment {
|
||||
fetchOptions = StoryViewerOptions.forStoryArchive(model.getId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (type == Type.USER) {
|
||||
case USER: {
|
||||
currentStoryMediaId = String.valueOf(options.getId());
|
||||
currentStoryUsername = options.getName();
|
||||
fetchOptions = StoryViewerOptions.forUser(options.getId(), currentStoryUsername);
|
||||
break;
|
||||
}
|
||||
}
|
||||
setTitle(type);
|
||||
storiesViewModel.getList().setValue(Collections.emptyList());
|
||||
@ -804,9 +803,9 @@ public class StoryViewerFragment extends Fragment {
|
||||
refreshLive();
|
||||
return;
|
||||
}
|
||||
final ServiceCallback<List<StoryModel>> storyCallback = new ServiceCallback<List<StoryModel>>() {
|
||||
final ServiceCallback<List<StoryMedia>> storyCallback = new ServiceCallback<List<StoryMedia>>() {
|
||||
@Override
|
||||
public void onSuccess(final List<StoryModel> storyModels) {
|
||||
public void onSuccess(final List<StoryMedia> storyModels) {
|
||||
fetching = false;
|
||||
if (storyModels == null || storyModels.isEmpty()) {
|
||||
storiesViewModel.getList().setValue(Collections.emptyList());
|
||||
@ -826,11 +825,10 @@ public class StoryViewerFragment extends Fragment {
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
Log.e(TAG, "Error", t);
|
||||
}
|
||||
};
|
||||
storiesRepository.getUserStory(
|
||||
storiesRepository.getStories(
|
||||
fetchOptions,
|
||||
CoroutineUtilsKt.getContinuation((storyModels, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
if (throwable != null) {
|
||||
@ -838,7 +836,7 @@ public class StoryViewerFragment extends Fragment {
|
||||
return;
|
||||
}
|
||||
//noinspection unchecked
|
||||
storyCallback.onSuccess((List<StoryModel>) storyModels);
|
||||
storyCallback.onSuccess((List<StoryMedia>) storyModels);
|
||||
}), Dispatchers.getIO())
|
||||
);
|
||||
}
|
||||
@ -887,9 +885,9 @@ public class StoryViewerFragment extends Fragment {
|
||||
|
||||
private synchronized void refreshStory() {
|
||||
if (binding.storiesList.getVisibility() == View.VISIBLE) {
|
||||
final List<StoryModel> storyModels = storiesViewModel.getList().getValue();
|
||||
final List<StoryMedia> storyModels = storiesViewModel.getList().getValue();
|
||||
if (storyModels != null && storyModels.size() > 0) {
|
||||
StoryModel item = storyModels.get(lastSlidePos);
|
||||
StoryMedia item = storyModels.get(lastSlidePos);
|
||||
if (item != null) {
|
||||
item.setCurrentSlide(false);
|
||||
storiesAdapter.notifyItemChanged(lastSlidePos, item);
|
||||
@ -903,59 +901,96 @@ public class StoryViewerFragment extends Fragment {
|
||||
}
|
||||
lastSlidePos = slidePos;
|
||||
|
||||
final MediaItemType itemType = currentStory.getItemType();
|
||||
final MediaItemType itemType = currentStory.getMediaType();
|
||||
|
||||
url = itemType == MediaItemType.MEDIA_TYPE_IMAGE ? currentStory.getStoryUrl() : currentStory.getVideoUrl();
|
||||
url = itemType == MediaItemType.MEDIA_TYPE_IMAGE
|
||||
? ResponseBodyUtils.getImageUrl(currentStory)
|
||||
: ResponseBodyUtils.getVideoUrl(currentStory);
|
||||
|
||||
final String shortCode = currentStory.getTappableShortCode();
|
||||
binding.viewStoryPost.setVisibility(shortCode != null ? View.VISIBLE : View.GONE);
|
||||
if (currentStory.getStoryFeedMedia() != null) {
|
||||
final String shortCode = currentStory.getStoryFeedMedia().get(0).getMediaId();
|
||||
binding.viewStoryPost.setVisibility(View.VISIBLE);
|
||||
binding.viewStoryPost.setTag(shortCode);
|
||||
}
|
||||
|
||||
final String spotify = currentStory.getSpotify();
|
||||
binding.spotify.setVisibility(spotify != null ? View.VISIBLE : View.GONE);
|
||||
binding.spotify.setTag(spotify);
|
||||
final StoryAppAttribution spotify = currentStory.getStoryAppAttribution();
|
||||
if (spotify != null) {
|
||||
binding.spotify.setVisibility(View.VISIBLE);
|
||||
binding.spotify.setText(spotify.getName());
|
||||
binding.spotify.setTag(spotify.getContentUrl().split("?")[0]);
|
||||
}
|
||||
|
||||
poll = currentStory.getPoll();
|
||||
binding.poll.setVisibility(poll != null ? View.VISIBLE : View.GONE);
|
||||
if (currentStory.getStoryPolls() != null) {
|
||||
poll = currentStory.getStoryPolls().get(0).getPollSticker();
|
||||
binding.poll.setVisibility(View.VISIBLE);
|
||||
binding.poll.setTag(poll);
|
||||
}
|
||||
|
||||
question = currentStory.getQuestion();
|
||||
binding.answer.setVisibility((question != null) ? View.VISIBLE : View.GONE);
|
||||
if (currentStory.getStoryQuestions() != null) {
|
||||
question = currentStory.getStoryQuestions().get(0).getQuestionSticker();
|
||||
binding.answer.setVisibility(View.VISIBLE);
|
||||
binding.answer.setTag(question);
|
||||
}
|
||||
|
||||
mentions = currentStory.getMentions();
|
||||
binding.mention.setVisibility((mentions != null && mentions.length > 0) ? View.VISIBLE : View.GONE);
|
||||
binding.mention.setTag(mentions);
|
||||
mentions.clear();
|
||||
if (currentStory.getReelMentions() != null) {
|
||||
mentions.addAll(currentStory.getReelMentions().stream().map(
|
||||
s -> s.getUser().getUsername()
|
||||
).distinct().collect(Collectors.toList()));
|
||||
}
|
||||
if (currentStory.getStoryHashtags() != null) {
|
||||
mentions.addAll(currentStory.getStoryHashtags().stream().map(
|
||||
s -> s.getHashtag().getName()
|
||||
).distinct().collect(Collectors.toList()));
|
||||
}
|
||||
if (currentStory.getStoryLocations() != null) {
|
||||
mentions.addAll(currentStory.getStoryLocations().stream().map(
|
||||
s -> s.getLocation().getShortName() + " (" + s.getLocation().getPk() + ")"
|
||||
).distinct().collect(Collectors.toList()));
|
||||
}
|
||||
if (mentions.size() > 0) {
|
||||
binding.mention.setVisibility(View.VISIBLE);
|
||||
binding.mention.setTag(mentions.stream().toArray(String[]::new));
|
||||
}
|
||||
|
||||
quiz = currentStory.getQuiz();
|
||||
binding.quiz.setVisibility(quiz != null ? View.VISIBLE : View.GONE);
|
||||
if (currentStory.getStoryQuizs() != null) {
|
||||
quiz = currentStory.getStoryQuizs().get(0).getQuizSticker();
|
||||
binding.quiz.setVisibility(View.VISIBLE);
|
||||
binding.quiz.setTag(quiz);
|
||||
}
|
||||
|
||||
slider = currentStory.getSlider();
|
||||
binding.slider.setVisibility(slider != null ? View.VISIBLE : View.GONE);
|
||||
if (currentStory.getStorySliders() != null) {
|
||||
slider = currentStory.getStorySliders().get(0).getSliderSticker();
|
||||
binding.slider.setVisibility(View.VISIBLE);
|
||||
binding.slider.setTag(slider);
|
||||
}
|
||||
|
||||
final SwipeUpModel swipeUp = currentStory.getSwipeUp();
|
||||
if (swipeUp != null) {
|
||||
if (currentStory.getStoryCta() != null) {
|
||||
final StoryCta swipeUp = currentStory.getStoryCta().get(0).getLinks();
|
||||
binding.swipeUp.setVisibility(View.VISIBLE);
|
||||
binding.swipeUp.setText(swipeUp.getText());
|
||||
binding.swipeUp.setTag(swipeUp.getUrl());
|
||||
} else binding.swipeUp.setVisibility(View.GONE);
|
||||
binding.swipeUp.setText(currentStory.getLinkText());
|
||||
final String swipeUpUrl = swipeUp.getWebUri();
|
||||
final String actualLink = swipeUpUrl.startsWith("https://l.instagram.com/")
|
||||
? Uri.parse(swipeUpUrl).getQueryParameter("u")
|
||||
: null;
|
||||
binding.swipeUp.setTag(actualLink == null && actualLink.startsWith("http")
|
||||
? swipeUpUrl : actualLink);
|
||||
}
|
||||
|
||||
releasePlayer();
|
||||
final Type type = options.getType();
|
||||
if (type == Type.HASHTAG || type == Type.LOCATION) {
|
||||
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBarTitle = currentStory.getUsername();
|
||||
actionBar.setTitle(currentStory.getUsername());
|
||||
actionBarTitle = currentStory.getUser().getUsername();
|
||||
actionBar.setTitle(currentStory.getUser().getUsername());
|
||||
}
|
||||
}
|
||||
if (itemType == MediaItemType.MEDIA_TYPE_VIDEO) setupVideo();
|
||||
else setupImage();
|
||||
|
||||
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
||||
actionBarSubtitle = TextUtils.epochSecondToString(currentStory.getTimestamp());
|
||||
actionBarSubtitle = TextUtils.epochSecondToString(currentStory.getTakenAt());
|
||||
if (actionBar != null) {
|
||||
try {
|
||||
actionBar.setSubtitle(actionBarSubtitle);
|
||||
@ -969,13 +1004,23 @@ public class StoryViewerFragment extends Fragment {
|
||||
csrfToken,
|
||||
userId,
|
||||
deviceId,
|
||||
currentStory.getStoryMediaId(),
|
||||
currentStory.getTimestamp(),
|
||||
currentStory.getId(),
|
||||
currentStory.getTakenAt(),
|
||||
System.currentTimeMillis() / 1000,
|
||||
CoroutineUtilsKt.getContinuation((s, throwable) -> {}, Dispatchers.getIO())
|
||||
);
|
||||
}
|
||||
|
||||
private void removeStickers() {
|
||||
binding.swipeUp.setVisibility(View.GONE);
|
||||
binding.quiz.setVisibility(View.GONE);
|
||||
binding.spotify.setVisibility(View.GONE);
|
||||
binding.mention.setVisibility(View.GONE);
|
||||
binding.viewStoryPost.setVisibility(View.GONE);
|
||||
binding.answer.setVisibility(View.GONE);
|
||||
binding.slider.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void downloadStory() {
|
||||
final Context context = getContext();
|
||||
if (context == null) return;
|
||||
@ -1016,7 +1061,7 @@ public class StoryViewerFragment extends Fragment {
|
||||
dmVisible = true;
|
||||
menuDm.setVisible(true);
|
||||
}
|
||||
if (!TextUtils.isEmpty(currentStory.getUsername())) {
|
||||
if (!TextUtils.isEmpty(currentStory.getUser().getUsername())) {
|
||||
profileVisible = true;
|
||||
menuProfile.setVisible(true);
|
||||
}
|
||||
@ -1057,7 +1102,7 @@ public class StoryViewerFragment extends Fragment {
|
||||
dmVisible = true;
|
||||
menuDm.setVisible(true);
|
||||
}
|
||||
if (!TextUtils.isEmpty(currentStory.getUsername()) && menuProfile != null) {
|
||||
if (!TextUtils.isEmpty(currentStory.getUser().getUsername()) && menuProfile != null) {
|
||||
profileVisible = true;
|
||||
menuProfile.setVisible(true);
|
||||
}
|
||||
@ -1077,7 +1122,7 @@ public class StoryViewerFragment extends Fragment {
|
||||
dmVisible = true;
|
||||
menuDm.setVisible(true);
|
||||
}
|
||||
if (!TextUtils.isEmpty(currentStory.getUsername()) && menuProfile != null) {
|
||||
if (!TextUtils.isEmpty(currentStory.getUser().getUsername()) && menuProfile != null) {
|
||||
profileVisible = true;
|
||||
menuProfile.setVisible(true);
|
||||
}
|
||||
|
@ -1,29 +0,0 @@
|
||||
package awais.instagrabber.models
|
||||
|
||||
import awais.instagrabber.models.enums.MediaItemType
|
||||
import awais.instagrabber.models.stickers.*
|
||||
import java.io.Serializable
|
||||
|
||||
data class StoryModel(
|
||||
val storyMediaId: String? = null,
|
||||
val storyUrl: String? = null,
|
||||
var thumbnail: String? = null,
|
||||
val itemType: MediaItemType? = null,
|
||||
val timestamp: Long = 0,
|
||||
val username: String? = null,
|
||||
val userId: Long = 0,
|
||||
val canReply: Boolean = false,
|
||||
) : Serializable {
|
||||
var videoUrl: String? = null
|
||||
var tappableShortCode: String? = null
|
||||
val tappableId: String? = null
|
||||
var spotify: String? = null
|
||||
var poll: PollModel? = null
|
||||
var question: QuestionModel? = null
|
||||
var slider: SliderModel? = null
|
||||
var quiz: QuizModel? = null
|
||||
var swipeUp: SwipeUpModel? = null
|
||||
var mentions: Array<String>? = null
|
||||
var position = 0
|
||||
var isCurrentSlide = false
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package awais.instagrabber.models.stickers;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public final class PollModel implements Serializable {
|
||||
private int leftcount, rightcount, mychoice;
|
||||
private final String id, question, leftchoice, rightchoice;
|
||||
|
||||
public PollModel(final String id, final String question, final String leftchoice, final int leftcount,
|
||||
final String rightchoice, final int rightcount, final int mychoice) {
|
||||
this.id = id; // only the poll id
|
||||
this.question = question;
|
||||
this.leftchoice = leftchoice;
|
||||
this.leftcount = leftcount;
|
||||
this.rightchoice = rightchoice;
|
||||
this.rightcount = rightcount;
|
||||
this.mychoice = mychoice;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getQuestion() {
|
||||
return question;
|
||||
}
|
||||
|
||||
public String getLeftChoice() {
|
||||
return leftchoice;
|
||||
}
|
||||
|
||||
public int getLeftCount() {
|
||||
return leftcount;
|
||||
}
|
||||
|
||||
public String getRightChoice() {
|
||||
return rightchoice;
|
||||
}
|
||||
|
||||
public int getRightCount() {
|
||||
return rightcount;
|
||||
}
|
||||
|
||||
public int getMyChoice() { return mychoice; }
|
||||
|
||||
public int setMyChoice(final int choice) {
|
||||
this.mychoice = choice;
|
||||
if (choice == 0) this.leftcount += 1;
|
||||
else if (choice == 1) this.rightcount += 1;
|
||||
return choice;
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package awais.instagrabber.models.stickers;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public final class QuestionModel implements Serializable {
|
||||
private final String id, question;
|
||||
|
||||
public QuestionModel(final String id, final String question) {
|
||||
this.id = id; // only the poll id
|
||||
this.question = question;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getQuestion() {
|
||||
return question;
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package awais.instagrabber.models.stickers;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public final class QuizModel implements Serializable {
|
||||
private final String id, question;
|
||||
private final String[] choices;
|
||||
private Long[] counts;
|
||||
private int mychoice;
|
||||
|
||||
public QuizModel(final String id, final String question, final String[] choices, final Long[] counts, final int mychoice) {
|
||||
this.id = id; // only the poll id
|
||||
this.question = question;
|
||||
this.choices = choices;
|
||||
this.counts = counts;
|
||||
this.mychoice = mychoice;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getQuestion() {
|
||||
return question;
|
||||
}
|
||||
|
||||
public String[] getChoices() { return choices;}
|
||||
|
||||
public Long[] getCounts() { return counts;}
|
||||
|
||||
public int getMyChoice() { return mychoice; }
|
||||
|
||||
public void setMyChoice(final int choice) {
|
||||
this.mychoice = choice;
|
||||
counts[choice] += 1L;
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package awais.instagrabber.models.stickers;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public final class SliderModel implements Serializable {
|
||||
private final int voteCount;
|
||||
private final Double average;
|
||||
private Double myChoice;
|
||||
private final boolean canVote;
|
||||
private final String id, question, emoji;
|
||||
|
||||
public SliderModel(final String id, final String question, final String emoji, final boolean canVote,
|
||||
final Double average, final int voteCount, final Double myChoice) {
|
||||
this.id = id;
|
||||
this.question = question;
|
||||
this.emoji = emoji;
|
||||
this.canVote = canVote;
|
||||
this.average = average;
|
||||
this.voteCount = voteCount;
|
||||
this.myChoice = myChoice;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getQuestion() {
|
||||
return question;
|
||||
}
|
||||
|
||||
public String getEmoji() {
|
||||
return emoji;
|
||||
}
|
||||
|
||||
public boolean canVote() {
|
||||
return canVote;
|
||||
}
|
||||
|
||||
public int getVoteCount() {
|
||||
return voteCount;
|
||||
}
|
||||
|
||||
public Double getAverage() {
|
||||
return average;
|
||||
}
|
||||
|
||||
public Double getMyChoice() { return myChoice; }
|
||||
|
||||
public Double setMyChoice(final Double choice) {
|
||||
this.myChoice = choice;
|
||||
return choice;
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package awais.instagrabber.models.stickers;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public final class SwipeUpModel implements Serializable {
|
||||
private final String url, text;
|
||||
|
||||
public SwipeUpModel(final String url, final String text) {
|
||||
this.url = url;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
}
|
@ -1,14 +1,17 @@
|
||||
package awais.instagrabber.repositories
|
||||
|
||||
import awais.instagrabber.repositories.responses.stories.ArchiveResponse
|
||||
import awais.instagrabber.repositories.responses.stories.ReelsMediaResponse
|
||||
import awais.instagrabber.repositories.responses.stories.ReelsResponse
|
||||
import awais.instagrabber.repositories.responses.stories.ReelsTrayResponse
|
||||
import awais.instagrabber.repositories.responses.stories.StoryMediaResponse
|
||||
import awais.instagrabber.repositories.responses.stories.StoryStickerResponse
|
||||
import retrofit2.http.*
|
||||
|
||||
interface StoriesService {
|
||||
// this one is the same as MediaRepository.fetch BUT you need to make sure it's a story
|
||||
@GET("/api/v1/media/{mediaId}/info/")
|
||||
suspend fun fetch(@Path("mediaId") mediaId: Long): String
|
||||
suspend fun fetch(@Path("mediaId") mediaId: Long): StoryMediaResponse
|
||||
|
||||
@GET("/api/v1/feed/reels_tray/")
|
||||
suspend fun getFeedStories(): ReelsTrayResponse?
|
||||
@ -19,14 +22,20 @@ interface StoriesService {
|
||||
@GET("/api/v1/archive/reel/day_shells/")
|
||||
suspend fun fetchArchive(@QueryMap queryParams: Map<String, String>): ArchiveResponse?
|
||||
|
||||
@GET
|
||||
suspend fun getUserStory(@Url url: String): String
|
||||
@GET("/api/v1/feed/reels_media/")
|
||||
suspend fun getReelsMedia(@Query("user_ids") id: String): ReelsMediaResponse
|
||||
|
||||
@GET("/api/v1/{type}/{id}/story/")
|
||||
suspend fun getStories(@Path("type") type: String, @Path("id") id: String): ReelsResponse
|
||||
|
||||
@GET("/api/v1/feed/user/{id}/story/")
|
||||
suspend fun getUserStories(@Path("id") id: String): ReelsResponse
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/api/v1/media/{storyId}/{stickerId}/{action}/")
|
||||
suspend fun respondToSticker(
|
||||
@Path("storyId") storyId: String,
|
||||
@Path("stickerId") stickerId: String,
|
||||
@Path("stickerId") stickerId: Long,
|
||||
@Path("action") action: String, // story_poll_vote, story_question_response, story_slider_vote, story_quiz_answer
|
||||
@FieldMap form: Map<String, String>,
|
||||
): StoryStickerResponse
|
||||
|
@ -42,7 +42,7 @@ public class StoryViewerOptions implements Serializable {
|
||||
}
|
||||
|
||||
public static StoryViewerOptions forUser(final long id, final String name) {
|
||||
return new StoryViewerOptions(id, name,Type.USER);
|
||||
return new StoryViewerOptions(id, name, Type.USER);
|
||||
}
|
||||
|
||||
public static StoryViewerOptions forHighlight(final String highlight) {
|
||||
|
@ -9,5 +9,5 @@ data class PollSticker(
|
||||
val pollId: Long?,
|
||||
val question: String?,
|
||||
val tallies: List<Tally>?,
|
||||
val viewerVote: Int?
|
||||
var viewerVote: Int = -1
|
||||
) : Serializable
|
@ -9,6 +9,6 @@ data class QuizSticker(
|
||||
val quizId: Long?,
|
||||
val question: String?,
|
||||
val tallies: List<Tally>?,
|
||||
val viewerAnswer: Int?,
|
||||
var viewerAnswer: Int? = -1,
|
||||
val correctAnswer: Int?
|
||||
) : Serializable
|
@ -0,0 +1,8 @@
|
||||
package awais.instagrabber.repositories.responses.stories
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
data class ReelsMediaResponse(
|
||||
val status: String?,
|
||||
val reels: Map<String, Story?>?
|
||||
) : Serializable
|
@ -4,6 +4,7 @@ import java.io.Serializable
|
||||
|
||||
data class ReelsResponse(
|
||||
val status: String?,
|
||||
val reel: Story?,
|
||||
val reel: Story?, // users
|
||||
val story: Story?, // hashtag and locations (unused)
|
||||
val broadcast: Broadcast?
|
||||
) : Serializable
|
@ -10,7 +10,7 @@ data class SliderSticker(
|
||||
val question: String?,
|
||||
val emoji: String?,
|
||||
val viewerCanVote: Boolean?,
|
||||
val viewerVote: Double?,
|
||||
var viewerVote: Double?,
|
||||
val sliderVoteAverage: Double?,
|
||||
val sliderVoteCount: Int?,
|
||||
) : Serializable
|
@ -41,6 +41,8 @@ data class StoryMedia(
|
||||
val storyAppAttribution: StoryAppAttribution? = null
|
||||
) : Serializable {
|
||||
private var dateString: String? = null
|
||||
var position = 0
|
||||
var isCurrentSlide = false
|
||||
|
||||
// TODO use extension once all usages are converted to kotlin
|
||||
// val date: String by lazy {
|
||||
|
@ -0,0 +1,14 @@
|
||||
package awais.instagrabber.repositories.responses.stories
|
||||
|
||||
import awais.instagrabber.models.enums.MediaItemType
|
||||
import awais.instagrabber.repositories.responses.ImageVersions2
|
||||
import awais.instagrabber.repositories.responses.MediaCandidate
|
||||
import awais.instagrabber.repositories.responses.User
|
||||
import awais.instagrabber.utils.TextUtils
|
||||
import java.io.Serializable
|
||||
|
||||
data class StoryMediaResponse(
|
||||
val items: List<StoryMedia?>?, // length 1
|
||||
val status: String?
|
||||
// ignoring pagination properties
|
||||
) : Serializable
|
@ -13,9 +13,9 @@ import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.work.*
|
||||
import awais.instagrabber.R
|
||||
import awais.instagrabber.fragments.settings.PreferenceKeys
|
||||
import awais.instagrabber.models.StoryModel
|
||||
import awais.instagrabber.models.enums.MediaItemType
|
||||
import awais.instagrabber.repositories.responses.Media
|
||||
import awais.instagrabber.repositories.responses.stories.StoryMedia
|
||||
import awais.instagrabber.utils.TextUtils.isEmpty
|
||||
import awais.instagrabber.workers.DownloadWorker
|
||||
import com.google.gson.Gson
|
||||
@ -392,18 +392,19 @@ object DownloadUtils {
|
||||
@JvmStatic
|
||||
fun download(
|
||||
context: Context,
|
||||
storyModel: StoryModel
|
||||
storyModel: StoryMedia
|
||||
) {
|
||||
val downloadDir = getDownloadDir(context, storyModel.username) ?: return
|
||||
val downloadDir = getDownloadDir(context, storyModel.user?.username) ?: return
|
||||
val url =
|
||||
if (storyModel.itemType == MediaItemType.MEDIA_TYPE_VIDEO) storyModel.videoUrl else storyModel.storyUrl
|
||||
if (storyModel.mediaType == MediaItemType.MEDIA_TYPE_VIDEO) ResponseBodyUtils.getVideoUrl(storyModel)
|
||||
else ResponseBodyUtils.getImageUrl(storyModel)
|
||||
val extension = getFileExtensionFromUrl(url)
|
||||
val baseFileName = (storyModel.storyMediaId + "_"
|
||||
+ storyModel.timestamp + extension)
|
||||
val baseFileName = (storyModel.id + "_"
|
||||
+ storyModel.takenAt + extension)
|
||||
val usernamePrepend =
|
||||
if (Utils.settingsHelper.getBoolean(PreferenceKeys.DOWNLOAD_PREPEND_USER_NAME)
|
||||
&& storyModel.username != null
|
||||
) storyModel.username + "_" else ""
|
||||
&& storyModel.user?.username != null
|
||||
) storyModel.user.username + "_" else ""
|
||||
val fileName = usernamePrepend + baseFileName
|
||||
var saveFile = downloadDir.findFile(fileName)
|
||||
if (saveFile == null) {
|
||||
|
@ -14,13 +14,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import awais.instagrabber.models.StoryModel;
|
||||
import awais.instagrabber.models.enums.MediaItemType;
|
||||
import awais.instagrabber.models.stickers.PollModel;
|
||||
import awais.instagrabber.models.stickers.QuestionModel;
|
||||
import awais.instagrabber.models.stickers.QuizModel;
|
||||
import awais.instagrabber.models.stickers.SliderModel;
|
||||
import awais.instagrabber.models.stickers.SwipeUpModel;
|
||||
import awais.instagrabber.repositories.responses.Caption;
|
||||
import awais.instagrabber.repositories.responses.FriendshipStatus;
|
||||
import awais.instagrabber.repositories.responses.ImageVersions2;
|
||||
@ -276,136 +270,6 @@ public final class ResponseBodyUtils {
|
||||
);
|
||||
}
|
||||
|
||||
public static StoryModel parseStoryItem(final JSONObject data,
|
||||
final boolean isLocOrHashtag,
|
||||
final String username) throws JSONException {
|
||||
final boolean isVideo = data.has("video_duration");
|
||||
final StoryModel model = new StoryModel(data.getString("id"),
|
||||
data.getJSONObject("image_versions2").getJSONArray("candidates").getJSONObject(0)
|
||||
.getString("url"), null,
|
||||
isVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
|
||||
data.optLong("taken_at", 0),
|
||||
isLocOrHashtag ? data.getJSONObject("user").getString("username") : username,
|
||||
data.getJSONObject("user").getLong("pk"),
|
||||
data.optBoolean("can_reply"));
|
||||
|
||||
if (data.getJSONObject("image_versions2").getJSONArray("candidates").length() > 1) {
|
||||
model.setThumbnail(data.getJSONObject("image_versions2").getJSONArray("candidates").getJSONObject(1)
|
||||
.getString("url"));
|
||||
}
|
||||
|
||||
final JSONArray videoResources = data.optJSONArray("video_versions");
|
||||
if (isVideo && videoResources != null)
|
||||
model.setVideoUrl(ResponseBodyUtils.getHighQualityPost(videoResources, true, true, false));
|
||||
|
||||
if (data.has("story_feed_media")) {
|
||||
model.setTappableShortCode(data.getJSONArray("story_feed_media").getJSONObject(0).optString("media_id"));
|
||||
}
|
||||
|
||||
// TODO: this may not be limited to spotify
|
||||
if (!data.isNull("story_app_attribution"))
|
||||
model.setSpotify(data.getJSONObject("story_app_attribution").optString("content_url").split("\\?")[0]);
|
||||
|
||||
if (data.has("story_polls")) {
|
||||
final JSONArray storyPolls = data.optJSONArray("story_polls");
|
||||
JSONObject tappableObject = null;
|
||||
if (storyPolls != null) {
|
||||
tappableObject = storyPolls.getJSONObject(0).optJSONObject("poll_sticker");
|
||||
}
|
||||
if (tappableObject != null) model.setPoll(new PollModel(
|
||||
String.valueOf(tappableObject.getLong("poll_id")),
|
||||
tappableObject.getString("question"),
|
||||
tappableObject.getJSONArray("tallies").getJSONObject(0).getString("text"),
|
||||
tappableObject.getJSONArray("tallies").getJSONObject(0).getInt("count"),
|
||||
tappableObject.getJSONArray("tallies").getJSONObject(1).getString("text"),
|
||||
tappableObject.getJSONArray("tallies").getJSONObject(1).getInt("count"),
|
||||
tappableObject.optInt("viewer_vote", -1)
|
||||
));
|
||||
}
|
||||
if (data.has("story_questions")) {
|
||||
final JSONObject tappableObject = data.getJSONArray("story_questions").getJSONObject(0)
|
||||
.optJSONObject("question_sticker");
|
||||
if (tappableObject != null && !tappableObject.getString("question_type").equals("music"))
|
||||
model.setQuestion(new QuestionModel(
|
||||
String.valueOf(tappableObject.getLong("question_id")),
|
||||
tappableObject.getString("question")
|
||||
));
|
||||
}
|
||||
if (data.has("story_quizs")) {
|
||||
JSONObject tappableObject = data.getJSONArray("story_quizs").getJSONObject(0).optJSONObject("quiz_sticker");
|
||||
if (tappableObject != null) {
|
||||
String[] choices = new String[tappableObject.getJSONArray("tallies").length()];
|
||||
Long[] counts = new Long[choices.length];
|
||||
for (int q = 0; q < choices.length; ++q) {
|
||||
JSONObject tempchoice = tappableObject.getJSONArray("tallies").getJSONObject(q);
|
||||
choices[q] = (q == tappableObject.getInt("correct_answer") ? "*** " : "")
|
||||
+ tempchoice.getString("text");
|
||||
counts[q] = tempchoice.getLong("count");
|
||||
}
|
||||
model.setQuiz(new QuizModel(
|
||||
String.valueOf(tappableObject.getLong("quiz_id")),
|
||||
tappableObject.getString("question"),
|
||||
choices,
|
||||
counts,
|
||||
tappableObject.optInt("viewer_answer", -1)
|
||||
));
|
||||
}
|
||||
}
|
||||
if (data.has("story_cta") && data.has("link_text")) {
|
||||
JSONObject tappableObject = data.getJSONArray("story_cta").getJSONObject(0).getJSONArray("links").getJSONObject(0);
|
||||
String swipeUpUrl = tappableObject.optString("webUri");
|
||||
final String backupSwipeUpUrl = swipeUpUrl;
|
||||
if (swipeUpUrl != null && swipeUpUrl.startsWith("https://l.instagram.com/")) {
|
||||
swipeUpUrl = Uri.parse(swipeUpUrl).getQueryParameter("u");
|
||||
}
|
||||
if (swipeUpUrl != null && swipeUpUrl.startsWith("http"))
|
||||
model.setSwipeUp(new SwipeUpModel(swipeUpUrl, data.getString("link_text")));
|
||||
else if (backupSwipeUpUrl != null && backupSwipeUpUrl.startsWith("http"))
|
||||
model.setSwipeUp(new SwipeUpModel(backupSwipeUpUrl, data.getString("link_text")));
|
||||
}
|
||||
if (data.has("story_sliders")) {
|
||||
final JSONObject tappableObject = data.getJSONArray("story_sliders").getJSONObject(0)
|
||||
.optJSONObject("slider_sticker");
|
||||
if (tappableObject != null)
|
||||
model.setSlider(new SliderModel(
|
||||
String.valueOf(tappableObject.getLong("slider_id")),
|
||||
tappableObject.getString("question"),
|
||||
tappableObject.getString("emoji"),
|
||||
tappableObject.getBoolean("viewer_can_vote"),
|
||||
tappableObject.optDouble("slider_vote_average"),
|
||||
tappableObject.getInt("slider_vote_count"),
|
||||
tappableObject.optDouble("viewer_vote")
|
||||
));
|
||||
}
|
||||
JSONArray hashtags = data.optJSONArray("story_hashtags");
|
||||
JSONArray locations = data.optJSONArray("story_locations");
|
||||
JSONArray atmarks = data.optJSONArray("reel_mentions");
|
||||
String[] mentions = new String[(hashtags == null ? 0 : hashtags.length())
|
||||
+ (atmarks == null ? 0 : atmarks.length())
|
||||
+ (locations == null ? 0 : locations.length())];
|
||||
if (hashtags != null) {
|
||||
for (int h = 0; h < hashtags.length(); ++h) {
|
||||
mentions[h] = "#" + hashtags.getJSONObject(h).getJSONObject("hashtag").getString("name");
|
||||
}
|
||||
}
|
||||
if (atmarks != null) {
|
||||
for (int h = 0; h < atmarks.length(); ++h) {
|
||||
mentions[h + (hashtags == null ? 0 : hashtags.length())] =
|
||||
"@" + atmarks.getJSONObject(h).getJSONObject("user").getString("username");
|
||||
}
|
||||
}
|
||||
if (locations != null) {
|
||||
for (int h = 0; h < locations.length(); ++h) {
|
||||
mentions[h + (hashtags == null ? 0 : hashtags.length()) + (atmarks == null ? 0 : atmarks.length())] =
|
||||
locations.getJSONObject(h).getJSONObject("location").getString("short_name")
|
||||
+ " (" + locations.getJSONObject(h).getJSONObject("location").getLong("pk") + ")";
|
||||
}
|
||||
}
|
||||
if (mentions.length != 0) model.setMentions(mentions);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
public static String getThumbUrl(final Object media) {
|
||||
return getImageCandidate(media, CandidateType.THUMBNAIL);
|
||||
}
|
||||
@ -415,6 +279,7 @@ public final class ResponseBodyUtils {
|
||||
}
|
||||
|
||||
private static String getImageCandidate(final Object rawMedia, final CandidateType type) {
|
||||
if (rawMedia == null) return null;
|
||||
final ImageVersions2 imageVersions2;
|
||||
final int originalWidth, originalHeight;
|
||||
if (rawMedia instanceof StoryMedia) {
|
||||
@ -453,22 +318,34 @@ public final class ResponseBodyUtils {
|
||||
return getVideoCandidate(media, CandidateType.VIDEO_THUMBNAIL);
|
||||
}
|
||||
|
||||
public static String getVideoUrl(final Media media) {
|
||||
public static String getVideoUrl(final Object media) {
|
||||
return getVideoCandidate(media, CandidateType.DOWNLOAD);
|
||||
}
|
||||
|
||||
// TODO: merge with getImageCandidate when Kotlin
|
||||
private static String getVideoCandidate(final Media media, final CandidateType type) {
|
||||
if (media == null) return null;
|
||||
final List<MediaCandidate> candidates = media.getVideoVersions();
|
||||
private static String getVideoCandidate(final Object rawMedia, final CandidateType type) {
|
||||
if (rawMedia == null) return null;
|
||||
final List<MediaCandidate> candidates;
|
||||
final int originalWidth, originalHeight;
|
||||
if (rawMedia instanceof StoryMedia) {
|
||||
candidates = ((StoryMedia) rawMedia).getVideoVersions();
|
||||
originalWidth = ((StoryMedia) rawMedia).getOriginalWidth();
|
||||
originalHeight = ((StoryMedia) rawMedia).getOriginalHeight();
|
||||
}
|
||||
else if (rawMedia instanceof Media) {
|
||||
candidates = ((Media) rawMedia).getVideoVersions();
|
||||
originalWidth = ((Media) rawMedia).getOriginalWidth();
|
||||
originalHeight = ((Media) rawMedia).getOriginalHeight();
|
||||
}
|
||||
else return null;
|
||||
if (candidates == null || candidates.isEmpty()) return null;
|
||||
final boolean isSquare = Integer.compare(media.getOriginalWidth(), media.getOriginalHeight()) == 0;
|
||||
final boolean isSquare = Integer.compare(originalWidth, originalHeight) == 0;
|
||||
final List<MediaCandidate> sortedCandidates = candidates.stream()
|
||||
.sorted((c1, c2) -> Integer.compare(c2.getWidth(), c1.getWidth()))
|
||||
.collect(Collectors.toList());
|
||||
final List<MediaCandidate> filteredCandidates = sortedCandidates.stream()
|
||||
.filter(c ->
|
||||
c.getWidth() <= media.getOriginalWidth()
|
||||
c.getWidth() <= originalWidth
|
||||
&& c.getWidth() <= type.getValue()
|
||||
&& (isSquare || Integer
|
||||
.compare(c.getWidth(), c.getHeight()) != 0)
|
||||
@ -480,19 +357,6 @@ public final class ResponseBodyUtils {
|
||||
return candidate.getUrl();
|
||||
}
|
||||
|
||||
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("broadcast_owner").getString("username"),
|
||||
data.getJSONObject("broadcast_owner").getLong("pk"),
|
||||
false);
|
||||
model.setVideoUrl(data.getString("dash_playback_url"));
|
||||
return model;
|
||||
}
|
||||
|
||||
private enum CandidateType {
|
||||
VIDEO_THUMBNAIL(700),
|
||||
THUMBNAIL(1000),
|
||||
|
@ -8,7 +8,6 @@ import awais.instagrabber.db.entities.Favorite
|
||||
import awais.instagrabber.db.repositories.FavoriteRepository
|
||||
import awais.instagrabber.managers.DirectMessagesManager
|
||||
import awais.instagrabber.models.Resource
|
||||
import awais.instagrabber.models.StoryModel
|
||||
import awais.instagrabber.models.enums.BroadcastItemType
|
||||
import awais.instagrabber.models.enums.FavoriteType
|
||||
import awais.instagrabber.repositories.requests.StoryViewerOptions
|
||||
@ -17,6 +16,7 @@ import awais.instagrabber.repositories.responses.User
|
||||
import awais.instagrabber.repositories.responses.UserProfileContextLink
|
||||
import awais.instagrabber.repositories.responses.directmessages.RankedRecipient
|
||||
import awais.instagrabber.repositories.responses.stories.Story
|
||||
import awais.instagrabber.repositories.responses.stories.StoryMedia
|
||||
import awais.instagrabber.utils.ControlledRunner
|
||||
import awais.instagrabber.utils.Event
|
||||
import awais.instagrabber.utils.SingleRunner
|
||||
@ -153,9 +153,9 @@ class ProfileFragmentViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
private val storyFetchControlledRunner = ControlledRunner<List<StoryModel>?>()
|
||||
val userStories: LiveData<Resource<List<StoryModel>?>> = currentUserProfileActionLiveData.switchMap { currentUserAndProfilePair ->
|
||||
liveData<Resource<List<StoryModel>?>>(context = viewModelScope.coroutineContext + ioDispatcher) {
|
||||
private val storyFetchControlledRunner = ControlledRunner<List<StoryMedia>?>()
|
||||
val userStories: LiveData<Resource<List<StoryMedia>?>> = currentUserProfileActionLiveData.switchMap { currentUserAndProfilePair ->
|
||||
liveData<Resource<List<StoryMedia>?>>(context = viewModelScope.coroutineContext + ioDispatcher) {
|
||||
val (currentUserResource, profileResource, action) = currentUserAndProfilePair
|
||||
if (action != INIT && action != REFRESH) {
|
||||
return@liveData
|
||||
@ -231,7 +231,7 @@ class ProfileFragmentViewModel(
|
||||
return graphQLRepository.fetchUser(stateUsername)
|
||||
}
|
||||
|
||||
private suspend fun fetchUserStory(fetchedUser: User): List<StoryModel> = storiesRepository.getUserStory(
|
||||
private suspend fun fetchUserStory(fetchedUser: User): List<StoryMedia> = storiesRepository.getStories(
|
||||
StoryViewerOptions.forUser(fetchedUser.pk, fetchedUser.fullName)
|
||||
)
|
||||
|
||||
|
@ -5,12 +5,12 @@ import androidx.lifecycle.ViewModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.models.StoryModel;
|
||||
import awais.instagrabber.repositories.responses.stories.StoryMedia;
|
||||
|
||||
public class StoriesViewModel extends ViewModel {
|
||||
private MutableLiveData<List<StoryModel>> list;
|
||||
private MutableLiveData<List<StoryMedia>> list;
|
||||
|
||||
public MutableLiveData<List<StoryModel>> getList() {
|
||||
public MutableLiveData<List<StoryMedia>> getList() {
|
||||
if (list == null) {
|
||||
list = new MutableLiveData<>();
|
||||
}
|
||||
|
@ -1,26 +1,22 @@
|
||||
package awais.instagrabber.webservices
|
||||
|
||||
import awais.instagrabber.fragments.settings.PreferenceKeys
|
||||
import awais.instagrabber.models.StoryModel
|
||||
import awais.instagrabber.repositories.StoriesService
|
||||
import awais.instagrabber.repositories.requests.StoryViewerOptions
|
||||
import awais.instagrabber.repositories.responses.stories.ArchiveResponse
|
||||
import awais.instagrabber.repositories.responses.stories.Story
|
||||
import awais.instagrabber.repositories.responses.stories.StoryMedia
|
||||
import awais.instagrabber.repositories.responses.stories.StoryStickerResponse
|
||||
import awais.instagrabber.utils.ResponseBodyUtils
|
||||
import awais.instagrabber.utils.TextUtils.isEmpty
|
||||
import awais.instagrabber.utils.Utils
|
||||
import awais.instagrabber.webservices.RetrofitFactory.retrofit
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
|
||||
open class StoriesRepository(private val service: StoriesService) {
|
||||
|
||||
suspend fun fetch(mediaId: Long): StoryModel {
|
||||
suspend fun fetch(mediaId: Long): StoryMedia? {
|
||||
val response = service.fetch(mediaId)
|
||||
val itemJson = JSONObject(response).getJSONArray("items").getJSONObject(0)
|
||||
return ResponseBodyUtils.parseStoryItem(itemJson, false, null)
|
||||
return response.items?.get(0)
|
||||
}
|
||||
|
||||
suspend fun getFeedStories(): List<Story> {
|
||||
@ -70,31 +66,30 @@ open class StoriesRepository(private val service: StoriesService) {
|
||||
return service.fetchArchive(form)
|
||||
}
|
||||
|
||||
open suspend fun getUserStory(options: StoryViewerOptions): List<StoryModel> {
|
||||
val url = buildUrl(options) ?: return emptyList()
|
||||
val response = service.getUserStory(url)
|
||||
val isLocOrHashtag = options.type == StoryViewerOptions.Type.LOCATION || options.type == StoryViewerOptions.Type.HASHTAG
|
||||
val isHighlight = options.type == StoryViewerOptions.Type.HIGHLIGHT || options.type == StoryViewerOptions.Type.STORY_ARCHIVE
|
||||
var data: JSONObject? = JSONObject(response)
|
||||
data = if (!isHighlight) {
|
||||
data?.optJSONObject(if (isLocOrHashtag) "story" else "reel")
|
||||
} else {
|
||||
data?.getJSONObject("reels")?.optJSONObject(options.name)
|
||||
open suspend fun getStories(options: StoryViewerOptions): List<StoryMedia> {
|
||||
return when (options.type) {
|
||||
StoryViewerOptions.Type.HIGHLIGHT,
|
||||
StoryViewerOptions.Type.STORY_ARCHIVE
|
||||
-> {
|
||||
val response = service.getReelsMedia(options.name)
|
||||
val story: Story? = response.reels?.get(options.name)
|
||||
story?.items ?: emptyList()
|
||||
}
|
||||
var username: String? = null
|
||||
if (data != null && !isLocOrHashtag) {
|
||||
username = data.getJSONObject("user").getString("username")
|
||||
StoryViewerOptions.Type.USER -> {
|
||||
val response = service.getUserStories(options.id.toString())
|
||||
response.reel?.items ?: emptyList()
|
||||
}
|
||||
val media: JSONArray? = data?.optJSONArray("items")
|
||||
return if (media?.length() ?: 0 > 0 && media?.optJSONObject(0) != null) {
|
||||
val mediaLen = media.length()
|
||||
val models: MutableList<StoryModel> = ArrayList()
|
||||
for (i in 0 until mediaLen) {
|
||||
data = media.getJSONObject(i)
|
||||
models.add(ResponseBodyUtils.parseStoryItem(data, isLocOrHashtag, username))
|
||||
// should not reach beyond this point
|
||||
StoryViewerOptions.Type.LOCATION -> {
|
||||
val response = service.getStories("locations", options.id.toString())
|
||||
response.story?.items ?: emptyList()
|
||||
}
|
||||
StoryViewerOptions.Type.HASHTAG -> {
|
||||
val response = service.getStories("tags", options.name)
|
||||
response.story?.items ?: emptyList()
|
||||
}
|
||||
else -> emptyList()
|
||||
}
|
||||
models
|
||||
} else emptyList()
|
||||
}
|
||||
|
||||
private suspend fun respondToSticker(
|
||||
@ -102,7 +97,7 @@ open class StoriesRepository(private val service: StoriesService) {
|
||||
userId: Long,
|
||||
deviceUuid: String,
|
||||
storyId: String,
|
||||
stickerId: String,
|
||||
stickerId: Long,
|
||||
action: String,
|
||||
arg1: String,
|
||||
arg2: String,
|
||||
@ -125,7 +120,7 @@ open class StoriesRepository(private val service: StoriesService) {
|
||||
userId: Long,
|
||||
deviceUuid: String,
|
||||
storyId: String,
|
||||
stickerId: String,
|
||||
stickerId: Long,
|
||||
answer: String,
|
||||
): StoryStickerResponse = respondToSticker(csrfToken, userId, deviceUuid, storyId, stickerId, "story_question_response", "response", answer)
|
||||
|
||||
@ -134,7 +129,7 @@ open class StoriesRepository(private val service: StoriesService) {
|
||||
userId: Long,
|
||||
deviceUuid: String,
|
||||
storyId: String,
|
||||
stickerId: String,
|
||||
stickerId: Long,
|
||||
answer: Int,
|
||||
): StoryStickerResponse {
|
||||
return respondToSticker(csrfToken, userId, deviceUuid, storyId, stickerId, "story_quiz_answer", "answer", answer.toString())
|
||||
@ -145,7 +140,7 @@ open class StoriesRepository(private val service: StoriesService) {
|
||||
userId: Long,
|
||||
deviceUuid: String,
|
||||
storyId: String,
|
||||
stickerId: String,
|
||||
stickerId: Long,
|
||||
answer: Int,
|
||||
): StoryStickerResponse = respondToSticker(csrfToken, userId, deviceUuid, storyId, stickerId, "story_poll_vote", "vote", answer.toString())
|
||||
|
||||
@ -154,7 +149,7 @@ open class StoriesRepository(private val service: StoriesService) {
|
||||
userId: Long,
|
||||
deviceUuid: String,
|
||||
storyId: String,
|
||||
stickerId: String,
|
||||
stickerId: Long,
|
||||
answer: Double,
|
||||
): StoryStickerResponse = respondToSticker(csrfToken, userId, deviceUuid, storyId, stickerId, "story_slider_vote", "vote", answer.toString())
|
||||
|
||||
@ -182,43 +177,6 @@ open class StoriesRepository(private val service: StoriesService) {
|
||||
return service.seen(queryMap, signedForm)
|
||||
}
|
||||
|
||||
private fun buildUrl(options: StoryViewerOptions): String? {
|
||||
val builder = StringBuilder()
|
||||
builder.append("https://i.instagram.com/api/v1/")
|
||||
val type = options.type
|
||||
var id: String? = null
|
||||
when (type) {
|
||||
StoryViewerOptions.Type.HASHTAG -> {
|
||||
builder.append("tags/")
|
||||
id = options.name
|
||||
}
|
||||
StoryViewerOptions.Type.LOCATION -> {
|
||||
builder.append("locations/")
|
||||
id = options.id.toString()
|
||||
}
|
||||
StoryViewerOptions.Type.USER -> {
|
||||
builder.append("feed/user/")
|
||||
id = options.id.toString()
|
||||
}
|
||||
StoryViewerOptions.Type.HIGHLIGHT, StoryViewerOptions.Type.STORY_ARCHIVE -> {
|
||||
builder.append("feed/reels_media/?user_ids=")
|
||||
id = options.name
|
||||
}
|
||||
StoryViewerOptions.Type.STORY -> {
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
if (id == null) {
|
||||
return null
|
||||
}
|
||||
builder.append(id)
|
||||
if (type != StoryViewerOptions.Type.HIGHLIGHT && type != StoryViewerOptions.Type.STORY_ARCHIVE) {
|
||||
builder.append("/story/")
|
||||
}
|
||||
return builder.toString()
|
||||
}
|
||||
|
||||
private fun sort(list: List<Story>): List<Story> {
|
||||
val listCopy = ArrayList(list)
|
||||
listCopy.sortWith { o1, o2 ->
|
||||
|
@ -10,12 +10,12 @@ import awais.instagrabber.db.entities.Favorite
|
||||
import awais.instagrabber.db.repositories.FavoriteRepository
|
||||
import awais.instagrabber.getOrAwaitValue
|
||||
import awais.instagrabber.models.Resource
|
||||
import awais.instagrabber.models.StoryModel
|
||||
import awais.instagrabber.models.enums.FavoriteType
|
||||
import awais.instagrabber.repositories.requests.StoryViewerOptions
|
||||
import awais.instagrabber.repositories.responses.FriendshipStatus
|
||||
import awais.instagrabber.repositories.responses.User
|
||||
import awais.instagrabber.repositories.responses.stories.Story
|
||||
import awais.instagrabber.repositories.responses.stories.StoryMedia
|
||||
import awais.instagrabber.webservices.*
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import org.json.JSONException
|
||||
@ -320,13 +320,13 @@ internal class ProfileFragmentViewModelTest {
|
||||
"username" to testPublicUser.username
|
||||
)
|
||||
)
|
||||
val testUserStories = listOf(StoryModel())
|
||||
val testUserStories = listOf(StoryMedia())
|
||||
val testUserHighlights = listOf(Story())
|
||||
val userRepository = object : UserRepository(UserServiceAdapter()) {
|
||||
override suspend fun getUsernameInfo(username: String): User = testPublicUser
|
||||
}
|
||||
val storiesRepository = object : StoriesRepository(StoriesServiceAdapter()) {
|
||||
override suspend fun getUserStory(options: StoryViewerOptions): List<StoryModel> = testUserStories
|
||||
override suspend fun getStories(options: StoryViewerOptions): List<StoryMedia> = testUserStories
|
||||
override suspend fun fetchHighlights(profileId: Long): List<Story> = testUserHighlights
|
||||
}
|
||||
val viewModel = ProfileFragmentViewModel(
|
||||
|
Loading…
Reference in New Issue
Block a user