convert HighlightModel usages (as archives) to Story

This commit is contained in:
Austin Huang 2021-06-29 11:06:03 -04:00
parent f7ce2eeea2
commit 7ead5046d9
No known key found for this signature in database
GPG Key ID: 84C23AA04587A91F
10 changed files with 45 additions and 69 deletions

View File

@ -9,19 +9,19 @@ import androidx.recyclerview.widget.ListAdapter;
import awais.instagrabber.adapters.viewholder.StoryListViewHolder;
import awais.instagrabber.databinding.ItemNotificationBinding;
import awais.instagrabber.models.HighlightModel;
import awais.instagrabber.repositories.responses.stories.Story;
public final class HighlightStoriesListAdapter extends ListAdapter<HighlightModel, StoryListViewHolder> {
public final class HighlightStoriesListAdapter extends ListAdapter<Story, StoryListViewHolder> {
private final OnHighlightStoryClickListener listener;
private static final DiffUtil.ItemCallback<HighlightModel> diffCallback = new DiffUtil.ItemCallback<HighlightModel>() {
private static final DiffUtil.ItemCallback<Story> diffCallback = new DiffUtil.ItemCallback<Story>() {
@Override
public boolean areItemsTheSame(@NonNull final HighlightModel oldItem, @NonNull final HighlightModel newItem) {
public boolean areItemsTheSame(@NonNull final Story oldItem, @NonNull final Story newItem) {
return oldItem.getId().equals(newItem.getId());
}
@Override
public boolean areContentsTheSame(@NonNull final HighlightModel oldItem, @NonNull final HighlightModel newItem) {
public boolean areContentsTheSame(@NonNull final Story oldItem, @NonNull final Story newItem) {
return oldItem.getId().equals(newItem.getId());
}
};
@ -41,12 +41,12 @@ public final class HighlightStoriesListAdapter extends ListAdapter<HighlightMode
@Override
public void onBindViewHolder(@NonNull final StoryListViewHolder holder, final int position) {
final HighlightModel model = getItem(position);
final Story model = getItem(position);
holder.bind(model, position, listener);
}
public interface OnHighlightStoryClickListener {
void onHighlightClick(final HighlightModel model, final int position);
void onHighlightClick(final Story model, final int position);
void onProfileClick(final String username);
}

View File

@ -8,7 +8,6 @@ import awais.instagrabber.R;
import awais.instagrabber.adapters.FeedStoriesListAdapter.OnFeedStoryClickListener;
import awais.instagrabber.adapters.HighlightStoriesListAdapter.OnHighlightStoryClickListener;
import awais.instagrabber.databinding.ItemNotificationBinding;
import awais.instagrabber.models.HighlightModel;
import awais.instagrabber.repositories.responses.stories.Story;
import awais.instagrabber.utils.ResponseBodyUtils;
@ -58,7 +57,7 @@ public final class StoryListViewHolder extends RecyclerView.ViewHolder {
});
}
public void bind(final HighlightModel model,
public void bind(final Story model,
final int position,
final OnHighlightStoryClickListener notificationClickListener) {
if (model == null) return;
@ -74,7 +73,7 @@ public final class StoryListViewHolder extends RecyclerView.ViewHolder {
binding.ivProfilePic.setVisibility(View.GONE);
binding.ivPreviewPic.setVisibility(View.VISIBLE);
binding.ivPreviewPic.setImageURI(model.getThumbnailUrl());
binding.ivPreviewPic.setImageURI(model.getCoverImageVersion().getUrl());
itemView.setOnClickListener(v -> {
if (notificationClickListener == null) return;

View File

@ -38,8 +38,8 @@ import awais.instagrabber.adapters.HighlightStoriesListAdapter.OnHighlightStoryC
import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
import awais.instagrabber.databinding.FragmentStoryListViewerBinding;
import awais.instagrabber.fragments.settings.MorePreferencesFragmentDirections;
import awais.instagrabber.models.HighlightModel;
import awais.instagrabber.repositories.requests.StoryViewerOptions;
import awais.instagrabber.repositories.responses.stories.ArchiveResponse;
import awais.instagrabber.repositories.responses.stories.Story;
import awais.instagrabber.utils.AppExecutors;
import awais.instagrabber.utils.CoroutineUtilsKt;
@ -48,7 +48,6 @@ import awais.instagrabber.viewmodels.ArchivesViewModel;
import awais.instagrabber.viewmodels.FeedStoriesViewModel;
import awais.instagrabber.webservices.ServiceCallback;
import awais.instagrabber.webservices.StoriesRepository;
import awais.instagrabber.webservices.StoriesRepository.ArchiveFetchResponse;
import kotlinx.coroutines.Dispatchers;
public final class StoryListViewerFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
@ -88,7 +87,7 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr
private final OnHighlightStoryClickListener archiveClickListener = new OnHighlightStoryClickListener() {
@Override
public void onHighlightClick(final HighlightModel model, final int position) {
public void onHighlightClick(final Story model, final int position) {
if (model == null) return;
final NavDirections action = StoryListViewerFragmentDirections
.actionStoryListFragmentToStoryViewerFragment(StoryViewerOptions.forStoryArchive(position));
@ -101,9 +100,9 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr
}
};
private final ServiceCallback<ArchiveFetchResponse> cb = new ServiceCallback<ArchiveFetchResponse>() {
private final ServiceCallback<ArchiveResponse> cb = new ServiceCallback<ArchiveResponse>() {
@Override
public void onSuccess(final ArchiveFetchResponse result) {
public void onSuccess(final ArchiveResponse result) {
binding.swipeRefreshLayout.setRefreshing(false);
if (result == null) {
try {
@ -111,10 +110,10 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr
Toast.makeText(context, R.string.empty_list, Toast.LENGTH_SHORT).show();
} catch (Exception ignored) {}
} else {
endCursor = result.getNextCursor();
final List<HighlightModel> models = archivesViewModel.getList().getValue();
final List<HighlightModel> modelsCopy = models == null ? new ArrayList<>() : new ArrayList<>(models);
modelsCopy.addAll(result.getResult());
endCursor = result.getMaxId();
final List<Story> models = archivesViewModel.getList().getValue();
final List<Story> modelsCopy = models == null ? new ArrayList<>() : new ArrayList<>(models);
modelsCopy.addAll(result.getItems());
archivesViewModel.getList().postValue(modelsCopy);
}
}

View File

@ -75,7 +75,6 @@ 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.HighlightModel;
import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.models.stickers.PollModel;
@ -760,12 +759,12 @@ public class StoryViewerFragment extends Fragment {
}
case STORY_ARCHIVE: {
final ArchivesViewModel archivesViewModel = (ArchivesViewModel) viewModel;
final List<HighlightModel> models = archivesViewModel.getList().getValue();
final List<Story> models = archivesViewModel.getList().getValue();
if (models == null || models.isEmpty() || currentFeedStoryIndex >= models.size() || currentFeedStoryIndex < 0) {
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
return;
}
final HighlightModel model = models.get(currentFeedStoryIndex);
final Story model = models.get(currentFeedStoryIndex);
currentStoryMediaId = parseStoryMediaId(model.getId());
currentStoryUsername = model.getTitle();
fetchOptions = StoryViewerOptions.forStoryArchive(model.getId());

View File

@ -1,14 +0,0 @@
package awais.instagrabber.models
import awais.instagrabber.utils.TextUtils
data class HighlightModel(
val title: String? = null,
val id: String = "",
val thumbnailUrl: String = "",
val timestamp: Long = 0,
val mediaCount: Int = 0,
) {
val dateTime: String
get() = TextUtils.epochSecondToString(timestamp)
}

View File

@ -1,5 +1,6 @@
package awais.instagrabber.repositories
import awais.instagrabber.repositories.responses.stories.ArchiveResponse
import awais.instagrabber.repositories.responses.stories.ReelsTrayResponse
import awais.instagrabber.repositories.responses.stories.StoryStickerResponse
import retrofit2.http.*
@ -16,7 +17,7 @@ interface StoriesService {
suspend fun fetchHighlights(@Path("uid") uid: Long): ReelsTrayResponse
@GET("/api/v1/archive/reel/day_shells/")
suspend fun fetchArchive(@QueryMap queryParams: Map<String, String>): String
suspend fun fetchArchive(@QueryMap queryParams: Map<String, String>): ArchiveResponse?
@GET
suspend fun getUserStory(@Url url: String): String

View File

@ -0,0 +1,9 @@
package awais.instagrabber.repositories.responses.stories
data class ArchiveResponse(
val numResults: Int,
val maxId: String?,
val moreAvailable: Boolean,
val status: String,
val items: List<Story>
)

View File

@ -1,6 +1,7 @@
package awais.instagrabber.repositories.responses.stories
import java.io.Serializable
import awais.instagrabber.repositories.responses.ImageUrl
import awais.instagrabber.repositories.responses.User
import awais.instagrabber.utils.TextUtils
@ -8,19 +9,23 @@ data class Story(
// universal
val id: String?,
val latestReelMedia: Long?, // = timestamp
val mediaCount: Int?,
// for stories and highlights
var seen: Long?,
val user: User?,
// for stories
val mediaCount: Int?,
val muted: Boolean?,
val hasBestiesMedia: Boolean?,
val items: List<StoryMedia>?, // may be null
// for highlights
val coverMedia: CoverMedia?,
val title: String?,
// for archives
val coverImageVersion: ImageUrl?,
// invented fields
val broadcast: Broadcast? // does not naturally occur
) : Serializable {
val dateTime: String
get() = if (latestReelMedia != null) TextUtils.epochSecondToString(latestReelMedia) else ""
// note that archives have property "timestamp" but is ignored
}

View File

@ -5,12 +5,12 @@ import androidx.lifecycle.ViewModel;
import java.util.List;
import awais.instagrabber.models.HighlightModel;
import awais.instagrabber.repositories.responses.stories.Story;
public class ArchivesViewModel extends ViewModel {
private MutableLiveData<List<HighlightModel>> list;
private MutableLiveData<List<Story>> list;
public MutableLiveData<List<HighlightModel>> getList() {
public MutableLiveData<List<Story>> getList() {
if (list == null) {
list = new MutableLiveData<>();
}

View File

@ -1,10 +1,10 @@
package awais.instagrabber.webservices
import awais.instagrabber.fragments.settings.PreferenceKeys
import awais.instagrabber.models.HighlightModel
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.StoryStickerResponse
import awais.instagrabber.utils.Constants
@ -35,14 +35,15 @@ open class StoriesRepository(private val service: StoriesService) {
Story(
broadcast.id,
broadcast.publishedTime,
1,
0L,
broadcast.broadcastOwner,
1,
broadcast.muted,
false, // unclear
null,
null,
null,
null,
broadcast
)
)
@ -53,11 +54,11 @@ open class StoriesRepository(private val service: StoriesService) {
open suspend fun fetchHighlights(profileId: Long): List<Story> {
val response = service.fetchHighlights(profileId)
val highlightModels = response.tray ?: listOf()
val highlightModels = response?.tray ?: listOf()
return highlightModels
}
suspend fun fetchArchive(maxId: String): ArchiveFetchResponse {
suspend fun fetchArchive(maxId: String): ArchiveResponse? {
val form = mutableMapOf(
"include_suggested_highlights" to "false",
"is_in_archive_home" to "true",
@ -66,24 +67,7 @@ open class StoriesRepository(private val service: StoriesService) {
if (!isEmpty(maxId)) {
form["max_id"] = maxId // NOT TESTED
}
val response = service.fetchArchive(form)
val data = JSONObject(response)
val highlightsReel = data.getJSONArray("items")
val length = highlightsReel.length()
val highlightModels: MutableList<HighlightModel> = ArrayList()
for (i in 0 until length) {
val highlightNode = highlightsReel.getJSONObject(i)
highlightModels.add(
HighlightModel(
null,
highlightNode.getString(Constants.EXTRAS_ID),
highlightNode.getJSONObject("cover_image_version").getString("url"),
highlightNode.getLong("latest_reel_media"),
highlightNode.getInt("media_count")
)
)
}
return ArchiveFetchResponse(highlightModels, data.getBoolean("more_available"), data.getString("max_id"))
return service.fetchArchive(form)
}
open suspend fun getUserStory(options: StoryViewerOptions): List<StoryModel> {
@ -248,12 +232,6 @@ open class StoriesRepository(private val service: StoriesService) {
return listCopy
}
class ArchiveFetchResponse(val result: List<HighlightModel>, val hasNextPage: Boolean, val nextCursor: String) {
fun hasNextPage(): Boolean {
return hasNextPage
}
}
companion object {
@Volatile
private var INSTANCE: StoriesRepository? = null