From a2ebcfca3407a9457e2dcff626bcc4deaae93c20 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 7 Jun 2021 10:15:56 +0000 Subject: [PATCH 01/26] Update dependency io.sentry:sentry-android to v5 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 284981a4..7dfdbc0d 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -234,7 +234,7 @@ dependencies { debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7' - githubImplementation 'io.sentry:sentry-android:4.3.0' + githubImplementation 'io.sentry:sentry-android:5.0.1' testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2' testImplementation "androidx.test.ext:junit-ktx:1.1.2" From 252cf1aefb9b1927be8d51ac05885b809502bc9f Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 21 Jun 2021 22:16:20 +0000 Subject: [PATCH 02/26] Update dependency androidx.camera:camera-camera2 to v1.1.0-alpha05 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index d1755725..5fb1f293 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -202,7 +202,7 @@ dependencies { annotationProcessor "androidx.room:room-compiler:$room_version" // CameraX - def camerax_version = "1.1.0-alpha04" + def camerax_version = "1.1.0-alpha05" implementation "androidx.camera:camera-camera2:$camerax_version" implementation "androidx.camera:camera-lifecycle:$camerax_version" implementation "androidx.camera:camera-view:1.0.0-alpha24" From 14c98ba5cfa592f5eb2d87b93f74409105978fb1 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 22 Jun 2021 00:27:54 +0000 Subject: [PATCH 03/26] Update dependency androidx.camera:camera-view to v1.0.0-alpha25 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index d1755725..e15d8793 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -205,7 +205,7 @@ dependencies { def camerax_version = "1.1.0-alpha04" implementation "androidx.camera:camera-camera2:$camerax_version" implementation "androidx.camera:camera-lifecycle:$camerax_version" - implementation "androidx.camera:camera-view:1.0.0-alpha24" + implementation "androidx.camera:camera-view:1.0.0-alpha25" // EmojiCompat def emoji_compat_version = "1.1.0" From 8959fc43a8a23313a646b3be27bf87f263b711ff Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 24 Jun 2021 08:56:55 +0000 Subject: [PATCH 04/26] Update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v1.5.20 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 93e0391d..e1d7b4a7 100755 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.5.0' + ext.kotlin_version = '1.5.20' repositories { google() From 9c811a629153b44258d8680f2033724f08fe4747 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Sat, 26 Jun 2021 13:56:47 -0400 Subject: [PATCH 05/26] show documentprovider error details --- .../activities/DirectorySelectActivity.java | 2 +- .../settings/DownloadsPreferencesFragment.java | 2 +- .../java/awais/instagrabber/utils/DownloadUtils.kt | 12 +++++------- app/src/main/res/values/strings.xml | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/activities/DirectorySelectActivity.java b/app/src/main/java/awais/instagrabber/activities/DirectorySelectActivity.java index e0c72194..681e92df 100644 --- a/app/src/main/java/awais/instagrabber/activities/DirectorySelectActivity.java +++ b/app/src/main/java/awais/instagrabber/activities/DirectorySelectActivity.java @@ -82,7 +82,7 @@ public class DirectorySelectActivity extends BaseLanguageActivity { return; } if (!"com.android.externalstorage.documents".equals(data.getData().getAuthority())) { - showErrorDialog(getString(R.string.dir_select_no_download_folder)); + showErrorDialog(getString(R.string.dir_select_no_download_folder, data.getData().getAuthority())); return; } AppExecutors.INSTANCE.getMainThread().execute(() -> { diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/DownloadsPreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/DownloadsPreferencesFragment.java index 5a2a2de0..16f0e902 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/DownloadsPreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/DownloadsPreferencesFragment.java @@ -111,7 +111,7 @@ public class DownloadsPreferencesFragment extends BasePreferencesFragment { R.string.error, "com.android.externalstorage.documents".equals(data.getData().getAuthority()) ? "Please report this error to the developers:\n\n" + sw.toString() - : getString(R.string.dir_select_no_download_folder), + : getString(R.string.dir_select_no_download_folder, data.getData().getAuthority()), R.string.ok, 0, 0 diff --git a/app/src/main/java/awais/instagrabber/utils/DownloadUtils.kt b/app/src/main/java/awais/instagrabber/utils/DownloadUtils.kt index 31157157..e7674a90 100644 --- a/app/src/main/java/awais/instagrabber/utils/DownloadUtils.kt +++ b/app/src/main/java/awais/instagrabber/utils/DownloadUtils.kt @@ -38,8 +38,6 @@ object DownloadUtils { private const val DIR_TEMP = "Temp" private const val DIR_BACKUPS = "Backups" private var root: DocumentFile? = null - const val WRITE_PERMISSION = Manifest.permission.WRITE_EXTERNAL_STORAGE - val PERMS = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE) @JvmStatic @Throws(ReselectDocumentTreeException::class) fun init( @@ -49,11 +47,11 @@ object DownloadUtils { if (isEmpty(barinstaDirUri)) { throw ReselectDocumentTreeException("folder path is null or empty") } + val uri = Uri.parse(barinstaDirUri) if (!barinstaDirUri!!.startsWith("content://com.android.externalstorage.documents")) { // reselect the folder in selector view - throw ReselectDocumentTreeException(Uri.parse(barinstaDirUri)) + throw ReselectDocumentTreeException(uri) } - val uri = Uri.parse(barinstaDirUri) val existingPermissions = context.contentResolver.persistedUriPermissions if (existingPermissions.isEmpty()) { // reselect the folder in selector view @@ -150,7 +148,7 @@ object DownloadUtils { list.add(DIR_DOWNLOADS) return list } - val finalUsername = if (username!!.startsWith("@")) username.substring(1) else username + val finalUsername = if (username.startsWith("@")) username.substring(1) else username list.add(DIR_DOWNLOADS) list.add(finalUsername) return list @@ -337,7 +335,7 @@ object DownloadUtils { private fun checkPathExists(paths: List, context: Context): Boolean { if (root == null) return false - val uri = root!!.getUri() + val uri = root!!.uri var found = false var docId = DocumentsContract.getTreeDocumentId(uri) for (path in paths) { @@ -349,7 +347,7 @@ object DownloadUtils { ), null, null, null ) if (docCursor == null) return false - while (docCursor!!.moveToNext() && !found) { + while (docCursor.moveToNext() && !found) { if (path.equals(docCursor.getString(0))) { docId = docCursor.getString(1) found = true diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 41bdfa11..dc29288c 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -512,7 +512,7 @@ The previously selected folder does not exist now: Re-select the directory or select a new directory by clicking the button below. No folder selected! - Please choose a directory from your storage, not a category on the sidebar. + Please choose a directory from your storage, not a category on the sidebar.\n(%s) Success! Please wait. Starting app… Barinsta folder Top From 5e016e3210dff5479cb3b1d926287ec76e6dc264 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Sat, 26 Jun 2021 15:30:20 -0400 Subject: [PATCH 06/26] close #1447 --- .../adapters/MediaItemsAdapter.java | 111 ----- .../MediaPickerBottomDialogFragment.java | 194 --------- .../DirectMessageThreadFragment.java | 41 +- .../instagrabber/managers/ThreadManager.kt | 11 - .../instagrabber/utils/MediaController.java | 386 ------------------ .../viewmodels/DirectThreadViewModel.kt | 4 - .../viewmodels/MediaPickerViewModel.java | 41 -- .../main/res/layout/layout_media_picker.xml | 30 -- 8 files changed, 28 insertions(+), 790 deletions(-) delete mode 100644 app/src/main/java/awais/instagrabber/adapters/MediaItemsAdapter.java delete mode 100644 app/src/main/java/awais/instagrabber/dialogs/MediaPickerBottomDialogFragment.java delete mode 100644 app/src/main/java/awais/instagrabber/utils/MediaController.java delete mode 100644 app/src/main/java/awais/instagrabber/viewmodels/MediaPickerViewModel.java delete mode 100644 app/src/main/res/layout/layout_media_picker.xml diff --git a/app/src/main/java/awais/instagrabber/adapters/MediaItemsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/MediaItemsAdapter.java deleted file mode 100644 index e76429ef..00000000 --- a/app/src/main/java/awais/instagrabber/adapters/MediaItemsAdapter.java +++ /dev/null @@ -1,111 +0,0 @@ -package awais.instagrabber.adapters; - -import android.net.Uri; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.DiffUtil; -import androidx.recyclerview.widget.ListAdapter; -import androidx.recyclerview.widget.RecyclerView; - -import com.facebook.drawee.backends.pipeline.Fresco; -import com.facebook.drawee.backends.pipeline.PipelineDraweeControllerBuilder; -import com.facebook.drawee.controller.BaseControllerListener; -import com.facebook.imagepipeline.common.ResizeOptions; -import com.facebook.imagepipeline.image.ImageInfo; -import com.facebook.imagepipeline.request.ImageRequest; -import com.facebook.imagepipeline.request.ImageRequestBuilder; - -import java.io.File; - -import awais.instagrabber.databinding.ItemMediaBinding; -import awais.instagrabber.utils.MediaController.MediaEntry; -import awais.instagrabber.utils.TextUtils; -import awais.instagrabber.utils.Utils; - -public class MediaItemsAdapter extends ListAdapter { - - private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() { - @Override - public boolean areItemsTheSame(@NonNull final MediaEntry oldItem, @NonNull final MediaEntry newItem) { - return oldItem.imageId == newItem.imageId; - } - - @Override - public boolean areContentsTheSame(@NonNull final MediaEntry oldItem, @NonNull final MediaEntry newItem) { - return oldItem.imageId == newItem.imageId; - } - }; - - private final OnItemClickListener onItemClickListener; - - public MediaItemsAdapter(final OnItemClickListener onItemClickListener) { - super(diffCallback); - this.onItemClickListener = onItemClickListener; - } - - @NonNull - @Override - public MediaItemViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) { - final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); - final ItemMediaBinding binding = ItemMediaBinding.inflate(layoutInflater, parent, false); - return new MediaItemViewHolder(binding, onItemClickListener); - } - - @Override - public void onBindViewHolder(@NonNull final MediaItemViewHolder holder, final int position) { - holder.bind(getItem(position)); - } - - public static class MediaItemViewHolder extends RecyclerView.ViewHolder { - private static final String TAG = MediaItemViewHolder.class.getSimpleName(); - private static final int size = Utils.displayMetrics.widthPixels / 3; - - private final ItemMediaBinding binding; - private final OnItemClickListener onItemClickListener; - - public MediaItemViewHolder(@NonNull final ItemMediaBinding binding, - final OnItemClickListener onItemClickListener) { - super(binding.getRoot()); - this.binding = binding; - this.onItemClickListener = onItemClickListener; - } - - public void bind(final MediaEntry item) { - final Uri uri = Uri.fromFile(new File(item.path)); - if (onItemClickListener != null) { - itemView.setOnClickListener(v -> onItemClickListener.onItemClick(item)); - } - final BaseControllerListener controllerListener = new BaseControllerListener() { - @Override - public void onFailure(final String id, final Throwable throwable) { - Log.e(TAG, "onFailure: ", throwable); - } - }; - final ImageRequest request = ImageRequestBuilder - .newBuilderWithSource(uri) - .setLocalThumbnailPreviewsEnabled(true) - .setProgressiveRenderingEnabled(false) - .setResizeOptions(ResizeOptions.forDimensions(size, size)) - .build(); - final PipelineDraweeControllerBuilder builder = Fresco.newDraweeControllerBuilder() - .setImageRequest(request) - .setControllerListener(controllerListener); - binding.item.setController(builder.build()); - if (item.isVideo && item.duration >= 0) { - final String timeString = TextUtils.millisToTimeString(item.duration); - binding.duration.setVisibility(View.VISIBLE); - binding.duration.setText(timeString); - } else { - binding.duration.setVisibility(View.GONE); - } - } - } - - public interface OnItemClickListener { - void onItemClick(MediaEntry entry); - } -} diff --git a/app/src/main/java/awais/instagrabber/dialogs/MediaPickerBottomDialogFragment.java b/app/src/main/java/awais/instagrabber/dialogs/MediaPickerBottomDialogFragment.java deleted file mode 100644 index d36cb9dd..00000000 --- a/app/src/main/java/awais/instagrabber/dialogs/MediaPickerBottomDialogFragment.java +++ /dev/null @@ -1,194 +0,0 @@ -package awais.instagrabber.dialogs; - -import android.app.Dialog; -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.DialogFragment; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.GridLayoutManager; - -import com.google.android.material.bottomsheet.BottomSheetDialog; -import com.google.android.material.bottomsheet.BottomSheetDialogFragment; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import awais.instagrabber.R; -import awais.instagrabber.adapters.MediaItemsAdapter; -import awais.instagrabber.databinding.LayoutMediaPickerBinding; -import awais.instagrabber.utils.MediaController; -import awais.instagrabber.utils.PermissionUtils; -import awais.instagrabber.utils.TextUtils; -import awais.instagrabber.viewmodels.MediaPickerViewModel; - -public class MediaPickerBottomDialogFragment extends BottomSheetDialogFragment { - private static final String TAG = MediaPickerBottomDialogFragment.class.getSimpleName(); - private static final int ATTACH_MEDIA_REQUEST_CODE = 100; - // private static final int HEIGHT_PIXELS = Utils.displayMetrics.heightPixels; - - private LayoutMediaPickerBinding binding; - private MediaPickerViewModel viewModel; - private MediaItemsAdapter mediaItemsAdapter; - private OnSelectListener onSelectListener; - // private int actionBarHeight; - // private int statusBarHeight; - - // private final BottomSheetBehavior.BottomSheetCallback bottomSheetCallback = new BottomSheetBehavior.BottomSheetCallback() { - // @Override - // public void onStateChanged(@NonNull final View bottomSheet, final int newState) { - // - // } - // - // @Override - // public void onSlide(@NonNull final View bottomSheet, final float slideOffset) { - // // Log.d(TAG, "onSlide: " + slideOffset); - // final float sheetHeight = HEIGHT_PIXELS * slideOffset; - // final Context context = getContext(); - // if (context == null) return; - // final float remaining = HEIGHT_PIXELS - sheetHeight - statusBarHeight; - // if (remaining <= actionBarHeight) { - // final ViewGroup.LayoutParams layoutParams = binding.toolbar.getLayoutParams(); - // layoutParams.height = (int) (actionBarHeight - remaining); - // binding.toolbar.requestLayout(); - // } - // } - // }; - - public static MediaPickerBottomDialogFragment newInstance() { - final Bundle args = new Bundle(); - final MediaPickerBottomDialogFragment fragment = new MediaPickerBottomDialogFragment(); - fragment.setArguments(args); - return fragment; - } - - @Override - public void onCreate(@Nullable final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setStyle(DialogFragment.STYLE_NORMAL, R.style.ThemeOverlay_Rounded_BottomSheetDialog); - } - - @Nullable - @Override - public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) { - binding = LayoutMediaPickerBinding.inflate(inflater, container, false); - viewModel = new ViewModelProvider(this).get(MediaPickerViewModel.class); - // final Context context = getContext(); - // if (context == null) return binding.getRoot(); - // actionBarHeight = Utils.getActionBarHeight(context); - // statusBarHeight = Utils.getStatusBarHeight(context); - return binding.getRoot(); - } - - @Override - public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { - init(); - // final Dialog dialog = getDialog(); - // if (dialog == null) return; - // dialog.setOnShowListener(dialog1 -> { - // final BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialog; - // final View bottomSheetInternal = bottomSheetDialog.findViewById(com.google.android.material.R.id.design_bottom_sheet); - // if (bottomSheetInternal == null) return; - // final BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheetInternal); - // behavior.setState(BottomSheetBehavior.STATE_EXPANDED); - // }); - } - - @Override - public void onStart() { - super.onStart(); - final Dialog dialog = getDialog(); - if (dialog == null) return; - final BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialog; - final View bottomSheetInternal = bottomSheetDialog.findViewById(com.google.android.material.R.id.design_bottom_sheet); - if (bottomSheetInternal == null) return; - bottomSheetInternal.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT; - bottomSheetInternal.requestLayout(); - // final BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheetInternal); - // behavior.addBottomSheetCallback(bottomSheetCallback); - } - - @Override - public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) { - if (requestCode == ATTACH_MEDIA_REQUEST_CODE) { - final Context context = getContext(); - if (context == null) return; - final boolean hasAttachMediaPerms = PermissionUtils.hasAttachMediaPerms(context); - if (hasAttachMediaPerms) { - viewModel.loadMedia(context); - } - } - } - - private void init() { - setupList(); - setupAlbumPicker(); - final Context context = getContext(); - if (context == null) return; - if (!PermissionUtils.hasAttachMediaPerms(context)) { - PermissionUtils.requestAttachMediaPerms(this, ATTACH_MEDIA_REQUEST_CODE); - return; - } - viewModel.loadMedia(context); - } - - private void setupList() { - final Context context = getContext(); - if (context == null) return; - binding.mediaList.setLayoutManager(new GridLayoutManager(context, 3)); - binding.mediaList.setHasFixedSize(true); - mediaItemsAdapter = new MediaItemsAdapter(entry -> { - if (onSelectListener == null) return; - onSelectListener.onSelect(entry); - }); - binding.mediaList.setAdapter(mediaItemsAdapter); - } - - private void setupAlbumPicker() { - final Context context = getContext(); - if (context == null) return; - final ArrayAdapter albumPickerAdapter = new ArrayAdapter<>(context, android.R.layout.simple_spinner_item); - albumPickerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - binding.albumPicker.setAdapter(albumPickerAdapter); - binding.albumPicker.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(final AdapterView parent, final View view, final int position, final long id) { - final List albumEntries = viewModel.getAllAlbums().getValue(); - if (albumEntries == null) return; - final MediaController.AlbumEntry albumEntry = albumEntries.get(position); - mediaItemsAdapter.submitList(albumEntry.photos, () -> binding.mediaList.scrollToPosition(0)); - } - - @Override - public void onNothingSelected(final AdapterView parent) { - mediaItemsAdapter.submitList(Collections.emptyList()); - } - }); - viewModel.getAllAlbums().observe(getViewLifecycleOwner(), albums -> { - albumPickerAdapter.clear(); - albumPickerAdapter.addAll(albums.stream() - .map(albumEntry -> albumEntry.bucketName) - .filter(name -> !TextUtils.isEmpty(name)) - .collect(Collectors.toList())); - albumPickerAdapter.notifyDataSetChanged(); - if (albums.isEmpty()) return; - mediaItemsAdapter.submitList(albums.get(0).photos); - }); - } - - public void setOnSelectListener(final OnSelectListener onSelectListener) { - this.onSelectListener = onSelectListener; - } - - public interface OnSelectListener { - void onSelect(MediaController.MediaEntry entry); - } -} diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java index 72a8568b..b9b91fa1 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java @@ -8,11 +8,11 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.content.pm.PackageManager; import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; +import android.provider.DocumentsContract; import android.text.Editable; import android.util.Log; import android.util.Pair; @@ -32,7 +32,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.view.menu.ActionMenuItemView; -import androidx.core.content.ContextCompat; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsAnimationCompat; import androidx.core.view.WindowInsetsAnimationControlListenerCompat; @@ -97,7 +96,6 @@ import awais.instagrabber.customviews.helpers.TranslateDeferringInsetsAnimationC import awais.instagrabber.databinding.FragmentDirectMessagesThreadBinding; import awais.instagrabber.dialogs.DirectItemReactionDialogFragment; import awais.instagrabber.dialogs.GifPickerBottomDialogFragment; -import awais.instagrabber.dialogs.MediaPickerBottomDialogFragment; import awais.instagrabber.fragments.PostViewV2Fragment; import awais.instagrabber.fragments.UserSearchFragment; import awais.instagrabber.fragments.UserSearchFragmentDirections; @@ -130,6 +128,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact private static final String TAG = DirectMessageThreadFragment.class.getSimpleName(); private static final int AUDIO_RECORD_PERM_REQUEST_CODE = 1000; private static final int CAMERA_REQUEST_CODE = 200; + private static final int FILE_PICKER_REQUEST_CODE = 500; private static final String TRANSLATION_Y = "translationY"; private DirectItemsAdapter itemsAdapter; @@ -474,6 +473,24 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact @Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); + if (requestCode == FILE_PICKER_REQUEST_CODE && resultCode == Activity.RESULT_OK) { + if (data == null || data.getData() == null) { + Log.w(TAG, "data is null!"); + return; + } + final Context context = getContext(); + if (context == null) { + Log.w(TAG, "conetxt is null!"); + return; + } + final Uri uri = data.getData(); + final String mimeType = Utils.getMimeType(uri, context.getContentResolver()); + if (mimeType.startsWith("image")) { + navigateToImageEditFragment(uri); + return; + } + handleSentMessage(viewModel.sendUri(uri)); + } if (requestCode == CAMERA_REQUEST_CODE && resultCode == Activity.RESULT_OK) { if (data == null || data.getData() == null) { Log.w(TAG, "data is null!"); @@ -1109,17 +1126,15 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact setupInsetsCallback(); setupEmojiPicker(); binding.gallery.setOnClickListener(v -> { - final MediaPickerBottomDialogFragment mediaPicker = MediaPickerBottomDialogFragment.newInstance(); - mediaPicker.setOnSelectListener(entry -> { - mediaPicker.dismiss(); - if (!isAdded()) return; - if (!entry.isVideo) { - navigateToImageEditFragment(entry.path); - return; - } - handleSentMessage(viewModel.sendUri(entry)); + final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + intent.setType("*/*"); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{ + "image/*", + "video/mp4" }); - mediaPicker.show(getChildFragmentManager(), "MediaPicker"); + startActivityForResult(intent, FILE_PICKER_REQUEST_CODE); }); binding.gif.setOnClickListener(v -> { final GifPickerBottomDialogFragment gifPicker = GifPickerBottomDialogFragment.newInstance(); diff --git a/app/src/main/java/awais/instagrabber/managers/ThreadManager.kt b/app/src/main/java/awais/instagrabber/managers/ThreadManager.kt index 88517de9..40c52457 100644 --- a/app/src/main/java/awais/instagrabber/managers/ThreadManager.kt +++ b/app/src/main/java/awais/instagrabber/managers/ThreadManager.kt @@ -367,17 +367,6 @@ class ThreadManager( return data } - fun sendUri(entry: MediaController.MediaEntry, scope: CoroutineScope): LiveData> { - val data = MutableLiveData>() - val uri = Uri.fromFile(File(entry.path)) - if (!entry.isVideo) { - sendPhoto(data, uri, entry.width, entry.height, scope) - return data - } - sendVideo(data, uri, entry.size, entry.duration, entry.width, entry.height, scope) - return data - } - fun sendUri(uri: Uri, scope: CoroutineScope): LiveData> { val data = MutableLiveData>() val mimeType = Utils.getMimeType(uri, contentResolver) diff --git a/app/src/main/java/awais/instagrabber/utils/MediaController.java b/app/src/main/java/awais/instagrabber/utils/MediaController.java deleted file mode 100644 index cbfec5c5..00000000 --- a/app/src/main/java/awais/instagrabber/utils/MediaController.java +++ /dev/null @@ -1,386 +0,0 @@ -package awais.instagrabber.utils; - -import android.content.Context; -import android.database.Cursor; -import android.os.Build; -import android.os.Environment; -import android.provider.MediaStore; -import android.util.Log; -import android.util.SparseArray; - -import java.util.ArrayList; -import java.util.Collections; - -import awais.instagrabber.R; - -/* - * This is the source code of Telegram for Android v. 1.3.x. - * It is licensed under GNU GPL v. 2 or later. - * You should have received a copy of the license in this archive (see LICENSE). - * - * Copyright Nikolai Kudashov, 2013-2018. - */ -public class MediaController { - private static final String TAG = MediaController.class.getSimpleName(); - private static final String[] PROJECTION_PHOTOS = { - MediaStore.Images.Media._ID, - MediaStore.Images.Media.BUCKET_ID, - MediaStore.Images.Media.BUCKET_DISPLAY_NAME, - MediaStore.Images.Media.DATA, - Build.VERSION.SDK_INT > 28 ? MediaStore.Images.Media.DATE_TAKEN : MediaStore.Images.Media.DATE_MODIFIED, - MediaStore.Images.Media.ORIENTATION, - MediaStore.Images.Media.WIDTH, - MediaStore.Images.Media.HEIGHT, - MediaStore.Images.Media.SIZE - }; - private static final String[] PROJECTION_VIDEO = { - MediaStore.Video.Media._ID, - MediaStore.Video.Media.BUCKET_ID, - MediaStore.Video.Media.BUCKET_DISPLAY_NAME, - MediaStore.Video.Media.DATA, - Build.VERSION.SDK_INT > 28 ? MediaStore.Video.Media.DATE_TAKEN : MediaStore.Images.Media.DATE_MODIFIED, - MediaStore.Video.Media.DURATION, - MediaStore.Video.Media.WIDTH, - MediaStore.Video.Media.HEIGHT, - MediaStore.Video.Media.SIZE - }; - - private final Context context; - private final OnLoadListener onLoadListener; - private final AppExecutors appExecutors; - - private static Runnable broadcastPhotosRunnable; - - private ArrayList allMediaAlbums; - private ArrayList allPhotoAlbums; - private AlbumEntry allPhotosAlbumEntry; - private AlbumEntry allMediaAlbumEntry; - private AlbumEntry allVideosAlbumEntry; - - public MediaController(final Context context, final OnLoadListener onLoadListener) { - this.context = context; - this.onLoadListener = onLoadListener; - appExecutors = AppExecutors.INSTANCE; - } - - public void load() { - loadGalleryAlbums(); - } - - private void loadGalleryAlbums() { - final Thread thread = new Thread(() -> { - final ArrayList mediaAlbumsSorted = new ArrayList<>(); - final ArrayList photoAlbumsSorted = new ArrayList<>(); - SparseArray mediaAlbums = new SparseArray<>(); - SparseArray photoAlbums = new SparseArray<>(); - AlbumEntry allPhotosAlbum = null; - AlbumEntry allVideosAlbum = null; - AlbumEntry allMediaAlbum = null; - String cameraFolder = null; - try { - cameraFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath() + "/" + "Camera/"; - } catch (Exception e) { - Log.e(TAG, "loadGalleryAlbums: ", e); - } - Integer mediaCameraAlbumId = null; - Integer photoCameraAlbumId = null; - - Cursor cursor = null; - try { - if (PermissionUtils.hasAttachMediaPerms(context)) { - cursor = MediaStore.Images.Media.query(context.getContentResolver(), - MediaStore.Images.Media.EXTERNAL_CONTENT_URI, - PROJECTION_PHOTOS, - null, - null, - (Build.VERSION.SDK_INT > 28 - ? MediaStore.Images.Media.DATE_TAKEN - : MediaStore.Images.Media.DATE_MODIFIED) + " DESC"); - if (cursor != null) { - int imageIdColumn = cursor.getColumnIndex(MediaStore.Images.Media._ID); - int bucketIdColumn = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID); - int bucketNameColumn = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME); - int dataColumn = cursor.getColumnIndex(MediaStore.Images.Media.DATA); - int dateColumn = cursor.getColumnIndex(Build.VERSION.SDK_INT > 28 ? MediaStore.Images.Media.DATE_TAKEN - : MediaStore.Images.Media.DATE_MODIFIED); - int orientationColumn = cursor.getColumnIndex(MediaStore.Images.Media.ORIENTATION); - int widthColumn = cursor.getColumnIndex(MediaStore.Images.Media.WIDTH); - int heightColumn = cursor.getColumnIndex(MediaStore.Images.Media.HEIGHT); - int sizeColumn = cursor.getColumnIndex(MediaStore.Images.Media.SIZE); - - while (cursor.moveToNext()) { - String path = cursor.getString(dataColumn); - if (TextUtils.isEmpty(path)) { - continue; - } - - int imageId = cursor.getInt(imageIdColumn); - int bucketId = cursor.getInt(bucketIdColumn); - String bucketName = cursor.getString(bucketNameColumn); - long dateTaken = cursor.getLong(dateColumn); - int orientation = cursor.getInt(orientationColumn); - int width = cursor.getInt(widthColumn); - int height = cursor.getInt(heightColumn); - long size = cursor.getLong(sizeColumn); - - MediaEntry mediaEntry = new MediaEntry(bucketId, imageId, dateTaken, path, orientation, -1, false, width, height, size); - - if (allPhotosAlbum == null) { - allPhotosAlbum = new AlbumEntry(0, context.getString(R.string.all_photos), mediaEntry); - photoAlbumsSorted.add(0, allPhotosAlbum); - } - if (allMediaAlbum == null) { - allMediaAlbum = new AlbumEntry(0, context.getString(R.string.all_media), mediaEntry); - mediaAlbumsSorted.add(0, allMediaAlbum); - } - allPhotosAlbum.addPhoto(mediaEntry); - allMediaAlbum.addPhoto(mediaEntry); - - AlbumEntry albumEntry = mediaAlbums.get(bucketId); - if (albumEntry == null) { - albumEntry = new AlbumEntry(bucketId, bucketName, mediaEntry); - mediaAlbums.put(bucketId, albumEntry); - if (mediaCameraAlbumId == null && cameraFolder != null && path.startsWith(cameraFolder)) { - mediaAlbumsSorted.add(0, albumEntry); - mediaCameraAlbumId = bucketId; - } else { - mediaAlbumsSorted.add(albumEntry); - } - } - albumEntry.addPhoto(mediaEntry); - - albumEntry = photoAlbums.get(bucketId); - if (albumEntry == null) { - albumEntry = new AlbumEntry(bucketId, bucketName, mediaEntry); - photoAlbums.put(bucketId, albumEntry); - if (photoCameraAlbumId == null && cameraFolder != null && path.startsWith(cameraFolder)) { - photoAlbumsSorted.add(0, albumEntry); - photoCameraAlbumId = bucketId; - } else { - photoAlbumsSorted.add(albumEntry); - } - } - albumEntry.addPhoto(mediaEntry); - } - } - } - } catch (Throwable e) { - Log.e(TAG, "loadGalleryAlbums: ", e); - } finally { - if (cursor != null) { - try { - cursor.close(); - } catch (Exception e) { - Log.e(TAG, "loadGalleryAlbums: ", e); - } - } - } - - try { - if (PermissionUtils.hasAttachMediaPerms(context)) { - cursor = MediaStore.Images.Media.query(context.getContentResolver(), - MediaStore.Video.Media.EXTERNAL_CONTENT_URI, - PROJECTION_VIDEO, - MediaStore.Video.Media.MIME_TYPE + "=?", - new String[]{"video/mp4"}, - (Build.VERSION.SDK_INT > 28 - ? MediaStore.Video.Media.DATE_TAKEN - : MediaStore.Video.Media.DATE_MODIFIED) + " DESC"); - if (cursor != null) { - int imageIdColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID); - int bucketIdColumn = cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_ID); - int bucketNameColumn = cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_DISPLAY_NAME); - int dataColumn = cursor.getColumnIndex(MediaStore.Video.Media.DATA); - int dateColumn = cursor.getColumnIndex(Build.VERSION.SDK_INT > 28 ? MediaStore.Video.Media.DATE_TAKEN - : MediaStore.Video.Media.DATE_MODIFIED); - int durationColumn = cursor.getColumnIndex(MediaStore.Video.Media.DURATION); - int widthColumn = cursor.getColumnIndex(MediaStore.Video.Media.WIDTH); - int heightColumn = cursor.getColumnIndex(MediaStore.Video.Media.HEIGHT); - int sizeColumn = cursor.getColumnIndex(MediaStore.Video.Media.SIZE); - - while (cursor.moveToNext()) { - String path = cursor.getString(dataColumn); - if (TextUtils.isEmpty(path)) { - continue; - } - - int imageId = cursor.getInt(imageIdColumn); - int bucketId = cursor.getInt(bucketIdColumn); - String bucketName = cursor.getString(bucketNameColumn); - long dateTaken = cursor.getLong(dateColumn); - long duration = cursor.getLong(durationColumn); - int width = cursor.getInt(widthColumn); - int height = cursor.getInt(heightColumn); - long size = cursor.getLong(sizeColumn); - - MediaEntry mediaEntry = new MediaEntry(bucketId, imageId, dateTaken, path, -1, duration, true, width, height, size); - - if (allVideosAlbum == null) { - allVideosAlbum = new AlbumEntry(0, context.getString(R.string.all_videos), mediaEntry); - allVideosAlbum.videoOnly = true; - int index = 0; - if (allMediaAlbum != null) { - index++; - } - if (allPhotosAlbum != null) { - index++; - } - mediaAlbumsSorted.add(index, allVideosAlbum); - } - if (allMediaAlbum == null) { - allMediaAlbum = new AlbumEntry(0, context.getString(R.string.all_media), mediaEntry); - mediaAlbumsSorted.add(0, allMediaAlbum); - } - allVideosAlbum.addPhoto(mediaEntry); - allMediaAlbum.addPhoto(mediaEntry); - - AlbumEntry albumEntry = mediaAlbums.get(bucketId); - if (albumEntry == null) { - albumEntry = new AlbumEntry(bucketId, bucketName, mediaEntry); - mediaAlbums.put(bucketId, albumEntry); - if (mediaCameraAlbumId == null && cameraFolder != null && path.startsWith(cameraFolder)) { - mediaAlbumsSorted.add(0, albumEntry); - mediaCameraAlbumId = bucketId; - } else { - mediaAlbumsSorted.add(albumEntry); - } - } - - albumEntry.addPhoto(mediaEntry); - } - } - } - } catch (Throwable e) { - Log.e(TAG, "loadGalleryAlbums: ", e); - } finally { - if (cursor != null) { - try { - cursor.close(); - } catch (Exception e) { - Log.e(TAG, "loadGalleryAlbums: ", e); - } - } - } - for (int a = 0; a < mediaAlbumsSorted.size(); a++) { - Collections.sort(mediaAlbumsSorted.get(a).photos, (o1, o2) -> { - if (o1.dateTaken < o2.dateTaken) { - return 1; - } else if (o1.dateTaken > o2.dateTaken) { - return -1; - } - return 0; - }); - } - broadcastNewPhotos(mediaAlbumsSorted, photoAlbumsSorted, mediaCameraAlbumId, allMediaAlbum, allPhotosAlbum, allVideosAlbum, 0); - }); - thread.setPriority(Thread.MIN_PRIORITY); - thread.start(); - } - - private void broadcastNewPhotos(final ArrayList mediaAlbumsSorted, - final ArrayList photoAlbumsSorted, - final Integer cameraAlbumIdFinal, - final AlbumEntry allMediaAlbumFinal, - final AlbumEntry allPhotosAlbumFinal, - final AlbumEntry allVideosAlbumFinal, - int delay) { - if (broadcastPhotosRunnable != null) { - appExecutors.getMainThread().cancel(broadcastPhotosRunnable); - } - appExecutors.getMainThread().execute(broadcastPhotosRunnable = () -> { - allMediaAlbums = mediaAlbumsSorted; - allPhotoAlbums = photoAlbumsSorted; - broadcastPhotosRunnable = null; - allPhotosAlbumEntry = allPhotosAlbumFinal; - allMediaAlbumEntry = allMediaAlbumFinal; - allVideosAlbumEntry = allVideosAlbumFinal; - if (onLoadListener != null) { - onLoadListener.onLoad(); - } - }, delay); - } - - public AlbumEntry getAllMediaAlbumEntry() { - return allMediaAlbumEntry; - } - - public AlbumEntry getAllPhotosAlbumEntry() { - return allPhotosAlbumEntry; - } - - public AlbumEntry getAllVideosAlbumEntry() { - return allVideosAlbumEntry; - } - - public ArrayList getAllMediaAlbums() { - return allMediaAlbums; - } - - public ArrayList getAllPhotoAlbums() { - return allPhotoAlbums; - } - - public static class AlbumEntry { - public int bucketId; - public boolean videoOnly; - public String bucketName; - public MediaEntry coverPhoto; - public ArrayList photos = new ArrayList<>(); - public SparseArray photosByIds = new SparseArray<>(); - - public AlbumEntry(int bucketId, String bucketName, MediaEntry coverPhoto) { - this.bucketId = bucketId; - this.bucketName = bucketName; - this.coverPhoto = coverPhoto; - } - - public void addPhoto(MediaEntry mediaEntry) { - photos.add(mediaEntry); - photosByIds.put(mediaEntry.imageId, mediaEntry); - } - } - - public static class MediaEntry { - public int bucketId; - public int imageId; - public long dateTaken; - public long duration; - public int width; - public int height; - public long size; - public String path; - public int orientation; - public boolean isVideo; - public boolean isMuted; - public boolean canDeleteAfter; - - public MediaEntry(int bucketId, - int imageId, - long dateTaken, - String path, - int orientation, - long duration, - boolean isVideo, - int width, - int height, - long size) { - this.bucketId = bucketId; - this.imageId = imageId; - this.dateTaken = dateTaken; - this.path = path; - this.width = width; - this.height = height; - this.size = size; - if (isVideo) { - this.duration = duration; - } else { - this.orientation = orientation; - } - this.isVideo = isVideo; - } - } - - public interface OnLoadListener { - void onLoad(); - } -} diff --git a/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.kt b/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.kt index 70407c06..c28f4463 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.kt +++ b/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.kt @@ -76,10 +76,6 @@ class DirectThreadViewModel( return threadManager.sendText(text, viewModelScope) } - fun sendUri(entry: MediaController.MediaEntry): LiveData> { - return threadManager.sendUri(entry, viewModelScope) - } - fun sendUri(uri: Uri): LiveData> { return threadManager.sendUri(uri, viewModelScope) } diff --git a/app/src/main/java/awais/instagrabber/viewmodels/MediaPickerViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/MediaPickerViewModel.java deleted file mode 100644 index 12858851..00000000 --- a/app/src/main/java/awais/instagrabber/viewmodels/MediaPickerViewModel.java +++ /dev/null @@ -1,41 +0,0 @@ -package awais.instagrabber.viewmodels; - -import android.content.Context; - -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.ViewModel; - -import java.util.Collections; -import java.util.List; - -import awais.instagrabber.utils.MediaController; -import awais.instagrabber.utils.MediaController.AlbumEntry; - -public class MediaPickerViewModel extends ViewModel implements MediaController.OnLoadListener { - private final MutableLiveData> allAlbums = new MutableLiveData<>(Collections.emptyList()); - - private MediaController mediaController; - - public MediaPickerViewModel() { - - } - - public void loadMedia(final Context context) { - mediaController = new MediaController(context, this); - mediaController.load(); - } - - @Override - public void onLoad() { - if (mediaController == null) { - return; - } - final List allPhotoAlbums = mediaController.getAllMediaAlbums(); - this.allAlbums.postValue(allPhotoAlbums); - } - - public LiveData> getAllAlbums() { - return allAlbums; - } -} diff --git a/app/src/main/res/layout/layout_media_picker.xml b/app/src/main/res/layout/layout_media_picker.xml deleted file mode 100644 index e8a314e6..00000000 --- a/app/src/main/res/layout/layout_media_picker.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file From 463be0ec2e0307b2772b8f5b507bf447dfc914a7 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Sat, 26 Jun 2021 16:28:44 -0400 Subject: [PATCH 07/26] close #1475 --- app/src/main/res/color/ic_read_button_tint.xml | 5 +++++ app/src/main/res/drawable/ic_check_all_24.xml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/color/ic_read_button_tint.xml diff --git a/app/src/main/res/color/ic_read_button_tint.xml b/app/src/main/res/color/ic_read_button_tint.xml new file mode 100644 index 00000000..a9d12381 --- /dev/null +++ b/app/src/main/res/color/ic_read_button_tint.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_check_all_24.xml b/app/src/main/res/drawable/ic_check_all_24.xml index 648f00d7..0e8dfc69 100644 --- a/app/src/main/res/drawable/ic_check_all_24.xml +++ b/app/src/main/res/drawable/ic_check_all_24.xml @@ -3,7 +3,7 @@ android:height="24dp" android:viewportWidth="24" android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:tint="@color/ic_read_button_tint"> From 786c567cca27725f236d19f0cfe65ac861ee908a Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Mon, 28 Jun 2021 12:02:34 -0400 Subject: [PATCH 08/26] allow replying to replies --- .../fragments/comments/RepliesFragment.java | 13 +++++++++++-- .../viewmodels/CommentsViewerViewModel.java | 19 ++++++++++++------- app/src/main/res/values/strings.xml | 1 + 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/fragments/comments/RepliesFragment.java b/app/src/main/java/awais/instagrabber/fragments/comments/RepliesFragment.java index 67c0f95c..e799e673 100644 --- a/app/src/main/java/awais/instagrabber/fragments/comments/RepliesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/comments/RepliesFragment.java @@ -174,7 +174,7 @@ public class RepliesFragment extends Fragment { } private void setupToolbar() { - binding.toolbar.setTitle("Replies"); + binding.toolbar.setTitle(R.string.title_replies); binding.toolbar.setNavigationIcon(R.drawable.ic_round_arrow_back_24); binding.toolbar.setNavigationOnClickListener(v -> { final FragmentManager fragmentManager = getParentFragmentManager(); @@ -187,7 +187,16 @@ public class RepliesFragment extends Fragment { if (context == null) return; commentsAdapter = new CommentsAdapter(currentUserId, true, - Helper.getCommentCallback(context, getViewLifecycleOwner(), getNavController(), viewModel, null)); + Helper.getCommentCallback(context, + getViewLifecycleOwner(), + getNavController(), + viewModel, + (comment, focusInput) -> { + viewModel.setReplyTo(comment); + binding.commentText.setText(String.format("@%s ", comment.getUser().getUsername())); + if (focusInput) Utils.showKeyboard(binding.commentText); + return null; + })); binding.comments.setAdapter(commentsAdapter); final Resource> listResource = viewModel.getReplyList().getValue(); commentsAdapter.submitList(listResource != null ? listResource.data : Collections.emptyList()); diff --git a/app/src/main/java/awais/instagrabber/viewmodels/CommentsViewerViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/CommentsViewerViewModel.java index a8bdedeb..16a7b0d2 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/CommentsViewerViewModel.java +++ b/app/src/main/java/awais/instagrabber/viewmodels/CommentsViewerViewModel.java @@ -54,7 +54,7 @@ public class CommentsViewerViewModel extends ViewModel { private String postId; private String rootCursor; private boolean rootHasNext = true; - private Comment repliesParent; + private Comment repliesParent, replyTo; private String repliesCursor; private boolean repliesHasNext = true; private final CommentService commentService; @@ -153,6 +153,11 @@ public class CommentsViewerViewModel extends ViewModel { return repliesParent; } + @Nullable + public void setReplyTo(final Comment replyTo) { + this.replyTo = replyTo; + } + public LiveData>> getRootList() { return rootList; } @@ -297,6 +302,7 @@ public class CommentsViewerViewModel extends ViewModel { if (comment == null) return; if (repliesParent == null || !Objects.equals(repliesParent.getPk(), comment.getPk())) { repliesParent = comment; + replyTo = comment; prevReplies = null; prevRepliesCursor = null; prevRepliesHasNext = true; @@ -368,8 +374,8 @@ public class CommentsViewerViewModel extends ViewModel { final boolean isReply) { final MutableLiveData> data = new MutableLiveData<>(Resource.loading(null)); String replyToId = null; - if (isReply && repliesParent != null) { - replyToId = repliesParent.getPk(); + if (isReply && replyTo != null) { + replyToId = replyTo.getPk(); } if (isReply && replyToId == null) { data.postValue(Resource.error(null, null)); @@ -399,10 +405,9 @@ public class CommentsViewerViewModel extends ViewModel { final List list = getPrevList(isReply ? replyList : rootList); final ImmutableList.Builder builder = ImmutableList.builder(); if (isReply) { - // in a reply list the first comment is the parent comment - builder.add(list.get(0)) - .add(comment) - .addAll(list.subList(1, list.size())); + // replies are added to the bottom of the list to preserve chronological order + builder.addAll(list) + .add(comment); } else { builder.add(comment) .addAll(list); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dc29288c..24449cdd 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -22,6 +22,7 @@ Favorites Discover Comments + Replies Activity Check for updates at startup Block screenshots & app preview From efb460d9c33824a58602fb8db777aa04631a63aa Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 28 Jun 2021 16:21:44 +0000 Subject: [PATCH 09/26] Update dependency androidx.core:core to v1.6.0-rc01 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index e7fbcbfd..b6d68806 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -183,7 +183,7 @@ dependencies { implementation 'com.google.guava:guava:27.0.1-android' - def core_version = "1.6.0-beta01" + def core_version = "1.6.0-rc01" implementation "androidx.core:core:$core_version" // Fragment From 10447cd633a340447944c76dfae4a591284b1c7a Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Mon, 28 Jun 2021 14:19:06 -0400 Subject: [PATCH 10/26] expand broadcasting rich message by 1 argument for stories and post children --- .../awais/instagrabber/managers/DirectMessagesManager.kt | 8 +++++--- .../awais/instagrabber/viewmodels/PostViewV2ViewModel.kt | 4 ++-- .../instagrabber/viewmodels/ProfileFragmentViewModel.kt | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/managers/DirectMessagesManager.kt b/app/src/main/java/awais/instagrabber/managers/DirectMessagesManager.kt index bd56b2b1..b1b4685c 100644 --- a/app/src/main/java/awais/instagrabber/managers/DirectMessagesManager.kt +++ b/app/src/main/java/awais/instagrabber/managers/DirectMessagesManager.kt @@ -68,20 +68,21 @@ object DirectMessagesManager { suspend fun createThread(userPk: Long): DirectThread = DirectMessagesService.createThread(csrfToken, viewerId, deviceUuid, listOf(userPk), null) - fun sendMedia(recipient: RankedRecipient, mediaId: String, itemType: BroadcastItemType, scope: CoroutineScope) { - sendMedia(setOf(recipient), mediaId, itemType, scope) + fun sendMedia(recipient: RankedRecipient, mediaId: String, secondId: String?, itemType: BroadcastItemType, scope: CoroutineScope) { + sendMedia(setOf(recipient), mediaId, secondId, itemType, scope) } fun sendMedia( recipients: Set, mediaId: String, + secondId: String?, itemType: BroadcastItemType, scope: CoroutineScope, ) { val threadIds = recipients.mapNotNull{ it.thread?.threadId } val userIdsTemp = recipients.mapNotNull{ it.user?.pk } val userIds = userIdsTemp.map{ listOf(it.toString(10)) } - sendMedia(threadIds, userIds, mediaId, itemType, scope) { + sendMedia(threadIds, userIds, mediaId, secondId, itemType, scope) { inboxManager.refresh(scope) } } @@ -90,6 +91,7 @@ object DirectMessagesManager { threadIds: List, userIds: List>, mediaId: String, + secondId: String?, itemType: BroadcastItemType, scope: CoroutineScope, callback: (() -> Unit)?, diff --git a/app/src/main/java/awais/instagrabber/viewmodels/PostViewV2ViewModel.kt b/app/src/main/java/awais/instagrabber/viewmodels/PostViewV2ViewModel.kt index 51f12618..e8dbd563 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/PostViewV2ViewModel.kt +++ b/app/src/main/java/awais/instagrabber/viewmodels/PostViewV2ViewModel.kt @@ -336,7 +336,7 @@ class PostViewV2ViewModel : ViewModel() { messageManager = DirectMessagesManager } val mediaId = media.id ?: return - messageManager?.sendMedia(result, mediaId, BroadcastItemType.MEDIA_SHARE, viewModelScope) + messageManager?.sendMedia(result, mediaId, null, BroadcastItemType.MEDIA_SHARE, viewModelScope) } fun shareDm(recipients: Set) { @@ -344,6 +344,6 @@ class PostViewV2ViewModel : ViewModel() { messageManager = DirectMessagesManager } val mediaId = media.id ?: return - messageManager?.sendMedia(recipients, mediaId, BroadcastItemType.MEDIA_SHARE, viewModelScope) + messageManager?.sendMedia(recipients, mediaId, null, BroadcastItemType.MEDIA_SHARE, viewModelScope) } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/viewmodels/ProfileFragmentViewModel.kt b/app/src/main/java/awais/instagrabber/viewmodels/ProfileFragmentViewModel.kt index 8594212d..bc0e185b 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/ProfileFragmentViewModel.kt +++ b/app/src/main/java/awais/instagrabber/viewmodels/ProfileFragmentViewModel.kt @@ -214,7 +214,7 @@ class ProfileFragmentViewModel( messageManager = DirectMessagesManager } val mediaId = profile.value?.data?.pk ?: return - messageManager?.sendMedia(result, mediaId.toString(10), BroadcastItemType.PROFILE, viewModelScope) + messageManager?.sendMedia(result, mediaId.toString(10), null, BroadcastItemType.PROFILE, viewModelScope) } fun shareDm(recipients: Set) { @@ -222,7 +222,7 @@ class ProfileFragmentViewModel( messageManager = DirectMessagesManager } val mediaId = profile.value?.data?.pk ?: return - messageManager?.sendMedia(recipients, mediaId.toString(10), BroadcastItemType.PROFILE, viewModelScope) + messageManager?.sendMedia(recipients, mediaId.toString(10), null, BroadcastItemType.PROFILE, viewModelScope) } } From 21b5c122ee6557f13c3e61e0f3f7aa69cc1c0636 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 28 Jun 2021 18:54:35 +0000 Subject: [PATCH 11/26] Update dependency androidx.fragment:fragment-ktx to v1.3.5 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 0434eda0..56f8ff08 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -187,7 +187,7 @@ dependencies { implementation "androidx.core:core:$core_version" // Fragment - implementation "androidx.fragment:fragment-ktx:1.3.4" + implementation "androidx.fragment:fragment-ktx:1.3.5" // Lifecycle implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" From bf1a05a38cf649404d5f64d18f68c4985b263049 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Mon, 28 Jun 2021 15:29:02 -0400 Subject: [PATCH 12/26] restore slider position on resume --- .../java/awais/instagrabber/fragments/PostViewV2Fragment.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java index 8948b831..dbd53aa3 100644 --- a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java @@ -294,7 +294,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme return; } final Media media = (Media) feedModelSerializable; - if (media.getMediaType() == MediaItemType.MEDIA_TYPE_SLIDER) { + if (media.getMediaType() == MediaItemType.MEDIA_TYPE_SLIDER && sliderPosition == -1) { sliderPosition = arguments.getInt(ARG_SLIDER_POSITION, 0); } viewModel.setMedia(media); @@ -1039,6 +1039,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme final String text = "1/" + carouselMedia.size(); binding.mediaCounter.setText(text); sliderItemsAdapter.submitList(media.getCarouselMedia()); + sliderParent.setCurrentItem(sliderPosition); } private void pauseSliderPlayer() { From 3f6ed5f78bd1bdab30699c277c9e6a20d154dd90 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Mon, 28 Jun 2021 15:29:37 -0400 Subject: [PATCH 13/26] sending dm media shares with exact child https://t.me/barinsta_app/21890 --- .../instagrabber/fragments/PostViewV2Fragment.java | 4 ++-- .../instagrabber/managers/DirectMessagesManager.kt | 3 ++- .../directmessages/MediaShareBroadcastOptions.kt | 8 ++++++-- .../instagrabber/viewmodels/PostViewV2ViewModel.kt | 10 ++++++---- .../instagrabber/webservices/DirectMessagesService.kt | 3 ++- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java index dbd53aa3..f8a2b584 100644 --- a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java @@ -152,7 +152,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme if (context != null) { Toast.makeText(context, R.string.sending, Toast.LENGTH_SHORT).show(); } - viewModel.shareDm((RankedRecipient) result); + viewModel.shareDm((RankedRecipient) result, sliderPosition); } else if ((result instanceof Set)) { try { // Log.d(TAG, "result: " + result); @@ -161,7 +161,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme Toast.makeText(context, R.string.sending, Toast.LENGTH_SHORT).show(); } //noinspection unchecked - viewModel.shareDm((Set) result); + viewModel.shareDm((Set) result, sliderPosition); } catch (Exception e) { Log.e(TAG, "share: ", e); } diff --git a/app/src/main/java/awais/instagrabber/managers/DirectMessagesManager.kt b/app/src/main/java/awais/instagrabber/managers/DirectMessagesManager.kt index b1b4685c..d30a2e25 100644 --- a/app/src/main/java/awais/instagrabber/managers/DirectMessagesManager.kt +++ b/app/src/main/java/awais/instagrabber/managers/DirectMessagesManager.kt @@ -107,7 +107,8 @@ object DirectMessagesManager { deviceUuid, UUID.randomUUID().toString(), ThreadIdsOrUserIds(threadIds, userIds), - mediaId + mediaId, + secondId ) if (itemType == BroadcastItemType.PROFILE) DirectMessagesService.broadcastProfile( diff --git a/app/src/main/java/awais/instagrabber/repositories/requests/directmessages/MediaShareBroadcastOptions.kt b/app/src/main/java/awais/instagrabber/repositories/requests/directmessages/MediaShareBroadcastOptions.kt index 89b74998..c83ef73b 100644 --- a/app/src/main/java/awais/instagrabber/repositories/requests/directmessages/MediaShareBroadcastOptions.kt +++ b/app/src/main/java/awais/instagrabber/repositories/requests/directmessages/MediaShareBroadcastOptions.kt @@ -5,12 +5,16 @@ import awais.instagrabber.models.enums.BroadcastItemType class MediaShareBroadcastOptions( clientContext: String, threadIdsOrUserIds: ThreadIdsOrUserIds, - val mediaId: String + val mediaId: String, + val childId: String? ) : BroadcastOptions( clientContext, threadIdsOrUserIds, BroadcastItemType.MEDIA_SHARE ) { override val formMap: Map - get() = mapOf("media_id" to mediaId) + get() = listOfNotNull( + "media_id" to mediaId, + if (childId != null) "carousel_share_child_media_id" to childId else null + ).toMap() } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/viewmodels/PostViewV2ViewModel.kt b/app/src/main/java/awais/instagrabber/viewmodels/PostViewV2ViewModel.kt index e8dbd563..df6972ea 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/PostViewV2ViewModel.kt +++ b/app/src/main/java/awais/instagrabber/viewmodels/PostViewV2ViewModel.kt @@ -331,19 +331,21 @@ class PostViewV2ViewModel : ViewModel() { return data } - fun shareDm(result: RankedRecipient) { + fun shareDm(result: RankedRecipient, child: Int) { if (messageManager == null) { messageManager = DirectMessagesManager } val mediaId = media.id ?: return - messageManager?.sendMedia(result, mediaId, null, BroadcastItemType.MEDIA_SHARE, viewModelScope) + val childId = if (child == -1) null else media.carouselMedia?.get(child)?.id + messageManager?.sendMedia(result, mediaId, childId, BroadcastItemType.MEDIA_SHARE, viewModelScope) } - fun shareDm(recipients: Set) { + fun shareDm(recipients: Set, child: Int) { if (messageManager == null) { messageManager = DirectMessagesManager } val mediaId = media.id ?: return - messageManager?.sendMedia(recipients, mediaId, null, BroadcastItemType.MEDIA_SHARE, viewModelScope) + val childId = if (child == -1) null else media.carouselMedia?.get(child)?.id + messageManager?.sendMedia(recipients, mediaId, childId, BroadcastItemType.MEDIA_SHARE, viewModelScope) } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/webservices/DirectMessagesService.kt b/app/src/main/java/awais/instagrabber/webservices/DirectMessagesService.kt index 7af8dd65..0d0aca64 100644 --- a/app/src/main/java/awais/instagrabber/webservices/DirectMessagesService.kt +++ b/app/src/main/java/awais/instagrabber/webservices/DirectMessagesService.kt @@ -164,8 +164,9 @@ object DirectMessagesService { clientContext: String, threadIdsOrUserIds: ThreadIdsOrUserIds, mediaId: String, + childId: String?, ): DirectThreadBroadcastResponse = - broadcast(csrfToken, userId, deviceUuid, MediaShareBroadcastOptions(clientContext, threadIdsOrUserIds, mediaId)) + broadcast(csrfToken, userId, deviceUuid, MediaShareBroadcastOptions(clientContext, threadIdsOrUserIds, mediaId, childId)) suspend fun broadcastProfile( csrfToken: String, From 8bf9f5f2cca0d9d26f55b11ce0631b099ab75ae8 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Mon, 28 Jun 2021 16:14:28 -0400 Subject: [PATCH 14/26] reading exact child from dm media shares https://t.me/barinsta_app/21890 --- .../adapters/DirectItemsAdapter.java | 2 +- .../DirectItemMediaShareViewHolder.java | 25 +++++++++++++------ .../DirectItemMediaViewHolder.java | 2 +- .../DirectItemRavenMediaViewHolder.java | 2 +- .../DirectItemReelShareViewHolder.java | 2 +- .../directmessages/DirectItemViewHolder.java | 4 +-- .../DirectMessageThreadFragment.java | 3 ++- .../repositories/responses/Media.kt | 3 ++- .../instagrabber/utils/ResponseBodyUtils.java | 1 + 9 files changed, 29 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java index 40624082..49339863 100644 --- a/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java +++ b/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java @@ -401,7 +401,7 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter media.getCarouselShareChildMediaId() != null && + media.getCarouselShareChildMediaId().equals(m.getId())) + .findAny() + .orElse(media.getCarouselMedia().get(0)); + index = media.getCarouselMedia().indexOf(toDisplay); + break; + default: + toDisplay = media; + index = 0; + } itemView.post(() -> { - final MediaItemType mediaType = media.getMediaType(); setupTypeIndicator(mediaType); - if (mediaType == MediaItemType.MEDIA_TYPE_SLIDER) { - setupPreview(media.getCarouselMedia().get(0), messageDirection); - return; - } - setupPreview(media, messageDirection); + setupPreview(toDisplay, messageDirection); }); - itemView.setOnClickListener(v -> openMedia(media)); + itemView.setOnClickListener(v -> openMedia(media, index)); } private void setupTypeIndicator(final MediaItemType mediaType) { diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaViewHolder.java index 769548a8..d2a7a5ee 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaViewHolder.java @@ -47,7 +47,7 @@ public class DirectItemMediaViewHolder extends DirectItemViewHolder { .setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP) .build()); final Media media = directItemModel.getMedia(); - itemView.setOnClickListener(v -> openMedia(media)); + itemView.setOnClickListener(v -> openMedia(media, -1)); final MediaItemType modelMediaType = media.getMediaType(); binding.typeIcon.setVisibility(modelMediaType == MediaItemType.MEDIA_TYPE_VIDEO || modelMediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemRavenMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemRavenMediaViewHolder.java index 9778d046..3f8f0ed7 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemRavenMediaViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemRavenMediaViewHolder.java @@ -50,7 +50,7 @@ public class DirectItemRavenMediaViewHolder extends DirectItemViewHolder { setPreview(visualMedia, messageDirection); final boolean expired = TextUtils.isEmpty(media.getId()); if (expired) return; - itemView.setOnClickListener(v -> openMedia(media)); + itemView.setOnClickListener(v -> openMedia(media, -1)); /*final boolean isExpired = visualMedia == null || (mediaModel = visualMedia.getMedia()) == null || TextUtils.isEmpty(mediaModel.getThumbUrl()) && mediaModel.getPk() < 1; diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemReelShareViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemReelShareViewHolder.java index aa1666ab..1c755881 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemReelShareViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemReelShareViewHolder.java @@ -76,7 +76,7 @@ public class DirectItemReelShareViewHolder extends DirectItemViewHolder { } if (!expired) { setPreview(media); - itemView.setOnClickListener(v -> openMedia(media)); + itemView.setOnClickListener(v -> openMedia(media, -1)); } } diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemViewHolder.java index f61c45ef..e969e183 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemViewHolder.java @@ -501,8 +501,8 @@ public abstract class DirectItemViewHolder extends RecyclerView.ViewHolder imple callback.onURLClick(url); } - protected void openMedia(final Media media) { - callback.onMediaClick(media); + protected void openMedia(final Media media, final int index) { + callback.onMediaClick(media, index); } protected void openStory(final DirectItemStoryShare storyShare) { diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java index b9b91fa1..21fea718 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java @@ -220,7 +220,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact } @Override - public void onMediaClick(final Media media) { + public void onMediaClick(final Media media, final int index) { if (media.isReelMedia()) { final String pk = media.getPk(); try { @@ -239,6 +239,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact final NavController navController = NavHostFragment.findNavController(DirectMessageThreadFragment.this); final Bundle bundle = new Bundle(); bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, media); + bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, index); try { navController.navigate(R.id.action_global_post_view, bundle); } catch (Exception e) { diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/Media.kt b/app/src/main/java/awais/instagrabber/repositories/responses/Media.kt index 03d8aba2..05fd19c9 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/Media.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/Media.kt @@ -38,7 +38,8 @@ data class Media( var isSidecarChild: Boolean = false, var hasViewerSaved: Boolean = false, private val injected: Map? = null, - val endOfFeedDemarcator: EndOfFeedDemarcator? = null + val endOfFeedDemarcator: EndOfFeedDemarcator? = null, + val carouselShareChildMediaId: String? = null // which specific child should dm show first ) : Serializable { private var dateString: String? = null diff --git a/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java b/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java index 0330d6e2..530dd208 100644 --- a/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java +++ b/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java @@ -271,6 +271,7 @@ public final class ResponseBodyUtils { false, false, null, + null, null ); } From 283d4ee2d51c85e7eec81a0dea86e4acd5767076 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 28 Jun 2021 20:27:09 +0000 Subject: [PATCH 15/26] Update dependency androidx.recyclerview:recyclerview to v1.2.1 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 0434eda0..fb08d85e 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -172,7 +172,7 @@ dependencies { implementation "com.google.android.exoplayer:exoplayer-dash:$exoplayer_version" implementation "com.google.android.exoplayer:exoplayer-ui:$exoplayer_version" - implementation "androidx.recyclerview:recyclerview:1.2.0" + implementation "androidx.recyclerview:recyclerview:1.2.1" implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation "androidx.viewpager2:viewpager2:1.0.0" implementation "androidx.navigation:navigation-fragment:$nav_version" From b4b91c68e3b8145e2e41f98318140cf3fd82fc04 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Mon, 28 Jun 2021 17:00:39 -0400 Subject: [PATCH 16/26] make placeholders look better --- .../adapters/DirectItemsAdapter.java | 2 +- .../DirectItemPlaceholderViewHolder.java | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java index 49339863..165eddc2 100644 --- a/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java +++ b/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java @@ -171,7 +171,7 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter Date: Mon, 28 Jun 2021 17:04:20 -0400 Subject: [PATCH 17/26] make media shares look better --- .../DirectItemMediaShareViewHolder.java | 11 ---------- .../main/res/layout/layout_dm_media_share.xml | 22 +------------------ 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaShareViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaShareViewHolder.java index 2ffae64a..78f0c8e2 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaShareViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaShareViewHolder.java @@ -65,7 +65,6 @@ public class DirectItemMediaShareViewHolder extends DirectItemViewHolder { if (media == null) return; itemView.post(() -> { setupUser(media); - setupTitle(media); setupCaption(media); }); final int index; @@ -140,16 +139,6 @@ public class DirectItemMediaShareViewHolder extends DirectItemViewHolder { } } - private void setupTitle(@NonNull final Media media) { - final String title = media.getTitle(); - if (!TextUtils.isEmpty(title)) { - binding.title.setVisibility(View.VISIBLE); - binding.title.setText(title); - } else { - binding.title.setVisibility(View.GONE); - } - } - private void setupUser(@NonNull final Media media) { final User user = media.getUser(); if (user != null) { diff --git a/app/src/main/res/layout/layout_dm_media_share.xml b/app/src/main/res/layout/layout_dm_media_share.xml index 6e4f74de..b59b7f17 100644 --- a/app/src/main/res/layout/layout_dm_media_share.xml +++ b/app/src/main/res/layout/layout_dm_media_share.xml @@ -76,26 +76,7 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="@id/title" /> - - + app:layout_constraintTop_toTopOf="@id/caption" /> \ No newline at end of file From a97104adb90e378499f990f8022de56d7ef5aedf Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 28 Jun 2021 21:13:39 +0000 Subject: [PATCH 18/26] Update dependency com.google.android.material:material to v1.4.0-rc01 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 56f8ff08..b461f539 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -166,7 +166,7 @@ dependencies { def nav_version = '2.3.5' def exoplayer_version = '2.14.1' - implementation 'com.google.android.material:material:1.4.0-beta01' + implementation 'com.google.android.material:material:1.4.0-rc01' implementation "com.google.android.exoplayer:exoplayer-core:$exoplayer_version" implementation "com.google.android.exoplayer:exoplayer-dash:$exoplayer_version" From aa175c510114ad74c971bdd25dc32655175c0d3d Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Mon, 28 Jun 2021 22:34:01 -0400 Subject: [PATCH 19/26] Rename .java to .kt --- .../StoryStickerResponse.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/src/main/java/awais/instagrabber/repositories/responses/{StoryStickerResponse.java => stories/StoryStickerResponse.kt} (100%) diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/StoryStickerResponse.java b/app/src/main/java/awais/instagrabber/repositories/responses/stories/StoryStickerResponse.kt similarity index 100% rename from app/src/main/java/awais/instagrabber/repositories/responses/StoryStickerResponse.java rename to app/src/main/java/awais/instagrabber/repositories/responses/stories/StoryStickerResponse.kt From 817a16873cb511b710b06f8ee2daf0640efc4a91 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Mon, 28 Jun 2021 22:34:02 -0400 Subject: [PATCH 20/26] convert FeedStoryModel to Story and Broadcast response data classes there seems to be a toolbar problem with live stories, will check tomorrow --- .../adapters/FeedStoriesAdapter.java | 20 +-- .../adapters/FeedStoriesListAdapter.java | 30 ++--- .../viewholder/FeedStoryViewHolder.java | 17 ++- .../viewholder/StoryListViewHolder.java | 18 +-- .../fragments/StoryListViewerFragment.java | 14 +- .../fragments/StoryViewerFragment.java | 120 +++++++++++------- .../fragments/main/FeedFragment.java | 12 +- .../instagrabber/models/FeedStoryModel.kt | 20 --- .../repositories/StoriesService.kt | 5 +- .../responses/stories/Broadcast.kt | 2 +- .../repositories/responses/stories/Story.kt | 13 +- .../responses/stories/StoryMedia.kt | 1 + .../responses/stories/StoryStickerResponse.kt | 21 +-- .../instagrabber/utils/ResponseBodyUtils.java | 26 +++- .../viewmodels/FeedStoriesViewModel.java | 6 +- .../webservices/StoriesRepository.kt | 101 ++++----------- .../main/res/layout/fragment_story_viewer.xml | 6 +- .../awais/instagrabber/common/Adapters.kt | 1 + 18 files changed, 197 insertions(+), 236 deletions(-) delete mode 100644 app/src/main/java/awais/instagrabber/models/FeedStoryModel.kt diff --git a/app/src/main/java/awais/instagrabber/adapters/FeedStoriesAdapter.java b/app/src/main/java/awais/instagrabber/adapters/FeedStoriesAdapter.java index 05966afd..821a1c7b 100755 --- a/app/src/main/java/awais/instagrabber/adapters/FeedStoriesAdapter.java +++ b/app/src/main/java/awais/instagrabber/adapters/FeedStoriesAdapter.java @@ -9,20 +9,20 @@ import androidx.recyclerview.widget.ListAdapter; import awais.instagrabber.adapters.viewholder.FeedStoryViewHolder; import awais.instagrabber.databinding.ItemHighlightBinding; -import awais.instagrabber.models.FeedStoryModel; +import awais.instagrabber.repositories.responses.stories.Story; -public final class FeedStoriesAdapter extends ListAdapter { +public final class FeedStoriesAdapter extends ListAdapter { private final OnFeedStoryClickListener listener; - private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() { + private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() { @Override - public boolean areItemsTheSame(@NonNull final FeedStoryModel oldItem, @NonNull final FeedStoryModel newItem) { - return oldItem.getStoryMediaId().equals(newItem.getStoryMediaId()); + public boolean areItemsTheSame(@NonNull final Story oldItem, @NonNull final Story newItem) { + return oldItem.getId().equals(newItem.getId()); } @Override - public boolean areContentsTheSame(@NonNull final FeedStoryModel oldItem, @NonNull final FeedStoryModel newItem) { - return oldItem.getStoryMediaId().equals(newItem.getStoryMediaId()) && oldItem.isFullyRead() == newItem.isFullyRead(); + public boolean areContentsTheSame(@NonNull final Story oldItem, @NonNull final Story newItem) { + return oldItem.getId().equals(newItem.getId()) && oldItem.getSeen() == newItem.getSeen(); } }; @@ -41,13 +41,13 @@ public final class FeedStoriesAdapter extends ListAdapter implements Filterable { +public final class FeedStoriesListAdapter extends ListAdapter implements Filterable { private final OnFeedStoryClickListener listener; - private List list; + private List list; private final Filter filter = new Filter() { @NonNull @Override protected FilterResults performFiltering(final CharSequence filter) { final String query = TextUtils.isEmpty(filter) ? null : filter.toString().toLowerCase(); - List filteredList = list; + List filteredList = list; if (list != null && query != null) { filteredList = list.stream() - .filter(feedStoryModel -> feedStoryModel.getProfileModel() + .filter(feedStoryModel -> feedStoryModel.getUser() .getUsername() .toLowerCase() .contains(query)) @@ -45,19 +45,19 @@ public final class FeedStoriesListAdapter extends ListAdapter) results.values, true); + submitList((List) results.values, true); } }; - private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() { + private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() { @Override - public boolean areItemsTheSame(@NonNull final FeedStoryModel oldItem, @NonNull final FeedStoryModel newItem) { - return oldItem.getStoryMediaId().equals(newItem.getStoryMediaId()); + public boolean areItemsTheSame(@NonNull final Story oldItem, @NonNull final Story newItem) { + return oldItem.getId().equals(newItem.getId()); } @Override - public boolean areContentsTheSame(@NonNull final FeedStoryModel oldItem, @NonNull final FeedStoryModel newItem) { - return oldItem.getStoryMediaId().equals(newItem.getStoryMediaId()) && oldItem.isFullyRead() == newItem.isFullyRead(); + public boolean areContentsTheSame(@NonNull final Story oldItem, @NonNull final Story newItem) { + return oldItem.getId().equals(newItem.getId()) && oldItem.getSeen() == newItem.getSeen(); } }; @@ -71,7 +71,7 @@ public final class FeedStoriesListAdapter extends ListAdapter list, final boolean isFiltered) { + private void submitList(@Nullable final List list, final boolean isFiltered) { if (!isFiltered) { this.list = list; } @@ -79,7 +79,7 @@ public final class FeedStoriesListAdapter extends ListAdapter list) { + public void submitList(final List list) { submitList(list, false); } @@ -93,12 +93,12 @@ public final class FeedStoriesListAdapter extends ListAdapter { if (notificationClickListener == null) return; - notificationClickListener.onProfileClick(model.getProfileModel().getUsername()); + notificationClickListener.onProfileClick(model.getUser().getUsername()); }); - if (model.getFirstStoryModel() != null) { + if (model.getItems() != null && model.getItems().size() > 0) { binding.ivPreviewPic.setVisibility(View.VISIBLE); - binding.ivPreviewPic.setImageURI(model.getFirstStoryModel().getThumbnail()); + binding.ivPreviewPic.setImageURI(ResponseBodyUtils.getThumbUrl(model.getItems().get(0))); } else binding.ivPreviewPic.setVisibility(View.INVISIBLE); - float alpha = model.isFullyRead() ? 0.5F : 1.0F; + float alpha = model.getSeen() != null && model.getSeen().equals(model.getLatestReelMedia()) + ? 0.5F : 1.0F; binding.ivProfilePic.setAlpha(alpha); binding.ivPreviewPic.setAlpha(alpha); binding.tvUsername.setAlpha(alpha); diff --git a/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java index 8bdfd548..c259b1c4 100644 --- a/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java @@ -38,9 +38,9 @@ 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.FeedStoryModel; import awais.instagrabber.models.HighlightModel; import awais.instagrabber.repositories.requests.StoryViewerOptions; +import awais.instagrabber.repositories.responses.stories.Story; import awais.instagrabber.utils.AppExecutors; import awais.instagrabber.utils.CoroutineUtilsKt; import awais.instagrabber.utils.TextUtils; @@ -69,12 +69,12 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr private final OnFeedStoryClickListener clickListener = new OnFeedStoryClickListener() { @Override - public void onFeedStoryClick(final FeedStoryModel model) { + public void onFeedStoryClick(final Story model) { if (model == null) return; - final List feedStoryModels = feedStoriesViewModel.getList().getValue(); + final List feedStoryModels = feedStoriesViewModel.getList().getValue(); if (feedStoryModels == null) return; final int position = Iterables.indexOf(feedStoryModels, feedStoryModel -> feedStoryModel != null - && Objects.equals(feedStoryModel.getStoryMediaId(), model.getStoryMediaId())); + && Objects.equals(feedStoryModel.getId(), model.getId())); final NavDirections action = StoryListViewerFragmentDirections .actionStoryListFragmentToStoryViewerFragment(StoryViewerOptions.forFeedStoryPosition(position)); NavHostFragment.findNavController(StoryListViewerFragment.this).navigate(action); @@ -236,7 +236,7 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr binding.swipeRefreshLayout.setRefreshing(true); if (type.equals("feed") && firstRefresh) { binding.swipeRefreshLayout.setRefreshing(false); - final List value = feedStoriesViewModel.getList().getValue(); + final List value = feedStoriesViewModel.getList().getValue(); if (value != null) { adapter.submitList(value); } @@ -250,9 +250,9 @@ public final class StoryListViewerFragment extends Fragment implements SwipeRefr return; } //noinspection unchecked - feedStoriesViewModel.getList().postValue((List) feedStoryModels); + feedStoriesViewModel.getList().postValue((List) feedStoryModels); //noinspection unchecked - adapter.submitList((List) feedStoryModels); + adapter.submitList((List) feedStoryModels); binding.swipeRefreshLayout.setRefreshing(false); }), Dispatchers.getIO()) ); diff --git a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java index b24ad0f2..a4acc407 100644 --- a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java @@ -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.FeedStoryModel; import awais.instagrabber.models.HighlightModel; import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.enums.MediaItemType; @@ -87,6 +86,8 @@ 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.utils.AppExecutors; import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.CookieUtils; @@ -125,6 +126,7 @@ public class StoryViewerFragment extends Fragment { private StoriesRepository storiesRepository; private MediaRepository mediaRepository; private StoryModel currentStory; + private Broadcast live; private int slidePos; private int lastSlidePos; private String url; @@ -717,7 +719,7 @@ public class StoryViewerFragment extends Fragment { private void resetView() { final Context context = getContext(); if (context == null) return; - StoryModel live = null; + live = null; slidePos = 0; lastSlidePos = 0; if (menuDownload != null) menuDownload.setVisible(false); @@ -747,15 +749,13 @@ public class StoryViewerFragment extends Fragment { } case FEED_STORY_POSITION: { final FeedStoriesViewModel feedStoriesViewModel = (FeedStoriesViewModel) viewModel; - final List models = feedStoriesViewModel.getList().getValue(); + final List models = feedStoriesViewModel.getList().getValue(); if (models == null || currentFeedStoryIndex >= models.size() || currentFeedStoryIndex < 0) return; - final FeedStoryModel model = models.get(currentFeedStoryIndex); - currentStoryMediaId = model.getStoryMediaId(); - currentStoryUsername = model.getProfileModel().getUsername(); + final Story model = models.get(currentFeedStoryIndex); + currentStoryMediaId = model.getId(); + currentStoryUsername = model.getUser().getUsername(); fetchOptions = StoryViewerOptions.forUser(Long.parseLong(currentStoryMediaId), currentStoryUsername); - if (model.isLive()) { - live = model.getFirstStoryModel(); - } + live = model.getBroadcast(); break; } case STORY_ARCHIVE: { @@ -803,6 +803,11 @@ public class StoryViewerFragment extends Fragment { return; } if (currentStoryMediaId == null) return; + if (live != null) { + currentStory = null; + refreshLive(); + return; + } final ServiceCallback> storyCallback = new ServiceCallback>() { @Override public void onSuccess(final List storyModels) { @@ -829,10 +834,6 @@ public class StoryViewerFragment extends Fragment { Log.e(TAG, "Error", t); } }; - if (live != null) { - storyCallback.onSuccess(Collections.singletonList(live)); - return; - } storiesRepository.getUserStory( fetchOptions, CoroutineUtilsKt.getContinuation((storyModels, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { @@ -864,6 +865,30 @@ public class StoryViewerFragment extends Fragment { } } + private synchronized void refreshLive() { + binding.storiesList.setVisibility(View.INVISIBLE); + binding.viewStoryPost.setVisibility(View.GONE); + binding.spotify.setVisibility(View.GONE); + binding.poll.setVisibility(View.GONE); + binding.answer.setVisibility(View.GONE); + binding.mention.setVisibility(View.GONE); + binding.quiz.setVisibility(View.GONE); + binding.slider.setVisibility(View.GONE); + lastSlidePos = slidePos; + releasePlayer(); + url = live.getDashPlaybackUrl(); + setupLive(); + final ActionBar actionBar = fragmentActivity.getSupportActionBar(); + actionBarSubtitle = TextUtils.epochSecondToString(live.getPublishedTime()); + if (actionBar != null) { + try { + actionBar.setSubtitle(actionBarSubtitle); + } catch (Exception e) { + Log.e(TAG, "refreshLive: ", e); + } + } + } + private synchronized void refreshStory() { if (binding.storiesList.getVisibility() == View.VISIBLE) { final List storyModels = storiesViewModel.getList().getValue(); @@ -886,42 +911,40 @@ public class StoryViewerFragment extends Fragment { url = itemType == MediaItemType.MEDIA_TYPE_IMAGE ? currentStory.getStoryUrl() : currentStory.getVideoUrl(); - 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 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) ? View.VISIBLE : View.GONE); - binding.answer.setTag(question); + question = currentStory.getQuestion(); + binding.answer.setVisibility((question != null) ? View.VISIBLE : View.GONE); + binding.answer.setTag(question); - mentions = currentStory.getMentions(); - binding.mention.setVisibility((mentions != null && mentions.length > 0) ? View.VISIBLE : View.GONE); - binding.mention.setTag(mentions); + mentions = currentStory.getMentions(); + binding.mention.setVisibility((mentions != null && mentions.length > 0) ? View.VISIBLE : View.GONE); + binding.mention.setTag(mentions); - quiz = currentStory.getQuiz(); - binding.quiz.setVisibility(quiz != null ? View.VISIBLE : View.GONE); - binding.quiz.setTag(quiz); + quiz = currentStory.getQuiz(); + binding.quiz.setVisibility(quiz != null ? View.VISIBLE : View.GONE); + binding.quiz.setTag(quiz); - slider = currentStory.getSlider(); - binding.slider.setVisibility(slider != null ? View.VISIBLE : View.GONE); - binding.slider.setTag(slider); + slider = currentStory.getSlider(); + binding.slider.setVisibility(slider != null ? View.VISIBLE : View.GONE); + binding.slider.setTag(slider); - final SwipeUpModel swipeUp = currentStory.getSwipeUp(); - if (swipeUp != null) { - binding.swipeUp.setVisibility(View.VISIBLE); - binding.swipeUp.setText(swipeUp.getText()); - binding.swipeUp.setTag(swipeUp.getUrl()); - } else binding.swipeUp.setVisibility(View.GONE); - } + final SwipeUpModel swipeUp = currentStory.getSwipeUp(); + if (swipeUp != null) { + binding.swipeUp.setVisibility(View.VISIBLE); + binding.swipeUp.setText(swipeUp.getText()); + binding.swipeUp.setTag(swipeUp.getUrl()); + } else binding.swipeUp.setVisibility(View.GONE); releasePlayer(); final Type type = options.getType(); @@ -933,7 +956,6 @@ 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(); @@ -1205,14 +1227,14 @@ public class StoryViewerFragment extends Fragment { return; } if (settingsHelper.getBoolean(MARK_AS_SEEN) - && oldFeedStory instanceof FeedStoryModel + && oldFeedStory instanceof Story && viewModel instanceof FeedStoriesViewModel) { final FeedStoriesViewModel feedStoriesViewModel = (FeedStoriesViewModel) viewModel; - final FeedStoryModel oldFeedStoryModel = (FeedStoryModel) oldFeedStory; - if (!oldFeedStoryModel.isFullyRead()) { - oldFeedStoryModel.setFullyRead(true); - final List models = feedStoriesViewModel.getList().getValue(); - final List modelsCopy = models == null ? new ArrayList<>() : new ArrayList<>(models); + final Story oldFeedStoryModel = (Story) oldFeedStory; + if (oldFeedStoryModel.getSeen() == null || !oldFeedStoryModel.getSeen().equals(oldFeedStoryModel.getLatestReelMedia())) { + oldFeedStoryModel.setSeen(oldFeedStoryModel.getLatestReelMedia()); + final List models = feedStoriesViewModel.getList().getValue(); + final List modelsCopy = models == null ? new ArrayList<>() : new ArrayList<>(models); modelsCopy.set(currentFeedStoryIndex, oldFeedStoryModel); feedStoriesViewModel.getList().postValue(models); } diff --git a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java index 25a354ea..c791823c 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java @@ -43,9 +43,9 @@ import awais.instagrabber.customviews.PrimaryActionModeCallback; import awais.instagrabber.databinding.FragmentFeedBinding; import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment; import awais.instagrabber.fragments.PostViewV2Fragment; -import awais.instagrabber.models.FeedStoryModel; import awais.instagrabber.models.PostsLayoutPreferences; import awais.instagrabber.repositories.requests.StoryViewerOptions; +import awais.instagrabber.repositories.responses.stories.Story; import awais.instagrabber.repositories.responses.Media; import awais.instagrabber.utils.AppExecutors; import awais.instagrabber.utils.Constants; @@ -76,7 +76,7 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre private final FeedStoriesAdapter feedStoriesAdapter = new FeedStoriesAdapter( new FeedStoriesAdapter.OnFeedStoryClickListener() { @Override - public void onFeedStoryClick(FeedStoryModel model, int position) { + public void onFeedStoryClick(Story model, int position) { final NavController navController = NavHostFragment.findNavController(FeedFragment.this); if (isSafeToNavigate(navController)) { final NavDirections action = FeedFragmentDirections @@ -86,8 +86,8 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre } @Override - public void onFeedStoryLongClick(FeedStoryModel model, int position) { - navigateToProfile("@" + model.getProfileModel().getUsername()); + public void onFeedStoryLongClick(Story model, int position) { + navigateToProfile("@" + model.getUser().getUsername()); } } ); @@ -399,9 +399,9 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre } storiesFetching = false; //noinspection unchecked - feedStoriesViewModel.getList().postValue((List) feedStoryModels); + feedStoriesViewModel.getList().postValue((List) feedStoryModels); //noinspection unchecked - feedStoriesAdapter.submitList((List) feedStoryModels); + feedStoriesAdapter.submitList((List) feedStoryModels); if (storyListMenu != null) storyListMenu.setVisible(true); updateSwipeRefreshState(); }), Dispatchers.getIO()) diff --git a/app/src/main/java/awais/instagrabber/models/FeedStoryModel.kt b/app/src/main/java/awais/instagrabber/models/FeedStoryModel.kt deleted file mode 100644 index 8040b36a..00000000 --- a/app/src/main/java/awais/instagrabber/models/FeedStoryModel.kt +++ /dev/null @@ -1,20 +0,0 @@ -package awais.instagrabber.models - -import awais.instagrabber.repositories.responses.User -import awais.instagrabber.utils.TextUtils -import java.io.Serializable -import java.util.* - -data class FeedStoryModel( - val storyMediaId: String, - val profileModel: User, - var isFullyRead: Boolean, - val timestamp: Long, - val firstStoryModel: StoryModel?, - val mediaCount: Int, - val isLive: Boolean, - val isBestie: Boolean -) : Serializable { - val dateTime: String - get() = TextUtils.epochSecondToString(timestamp) -} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt b/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt index 51f271f4..a55315e9 100644 --- a/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt +++ b/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt @@ -1,6 +1,7 @@ package awais.instagrabber.repositories -import awais.instagrabber.repositories.responses.StoryStickerResponse +import awais.instagrabber.repositories.responses.stories.ReelsTrayResponse +import awais.instagrabber.repositories.responses.stories.StoryStickerResponse import retrofit2.http.* interface StoriesService { @@ -9,7 +10,7 @@ interface StoriesService { suspend fun fetch(@Path("mediaId") mediaId: Long): String @GET("/api/v1/feed/reels_tray/") - suspend fun getFeedStories(): String + suspend fun getFeedStories(): ReelsTrayResponse @GET("/api/v1/highlights/{uid}/highlights_tray/") suspend fun fetchHighlights(@Path("uid") uid: Long): String diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/stories/Broadcast.kt b/app/src/main/java/awais/instagrabber/repositories/responses/stories/Broadcast.kt index 0037d73e..e5172d69 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/stories/Broadcast.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/stories/Broadcast.kt @@ -4,7 +4,7 @@ import java.io.Serializable import awais.instagrabber.repositories.responses.User data class Broadcast( - val id: Long?, + val id: String?, val dashPlaybackUrl: String?, val dashAbrPlaybackUrl: String?, // adaptive quality val viewerCount: Double?, // always .0 diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/stories/Story.kt b/app/src/main/java/awais/instagrabber/repositories/responses/stories/Story.kt index 3c2312c1..81e3d0d1 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/stories/Story.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/stories/Story.kt @@ -3,14 +3,19 @@ package awais.instagrabber.repositories.responses.stories import java.io.Serializable import awais.instagrabber.repositories.responses.Media import awais.instagrabber.repositories.responses.User +import awais.instagrabber.utils.TextUtils data class Story( - val id: Long?, + val id: String?, val latestReelMedia: Long?, // = timestamp - val seen: Long?, + var seen: Long?, val user: User?, val muted: Boolean?, val hasBestiesMedia: Boolean?, val mediaCount: Int?, - val items: List? // may be null -) : Serializable \ No newline at end of file + val items: List?, // may be null + val broadcast: Broadcast? // does not naturally occur +) : Serializable { + val dateTime: String + get() = if (latestReelMedia != null) TextUtils.epochSecondToString(latestReelMedia) else "" +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/stories/StoryMedia.kt b/app/src/main/java/awais/instagrabber/repositories/responses/stories/StoryMedia.kt index 4fa49d3d..b9374cdc 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/stories/StoryMedia.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/stories/StoryMedia.kt @@ -3,6 +3,7 @@ package awais.instagrabber.repositories.responses.stories import awais.instagrabber.models.enums.MediaItemType import awais.instagrabber.utils.TextUtils import awais.instagrabber.repositories.responses.ImageVersions2 +import awais.instagrabber.repositories.responses.Media import awais.instagrabber.repositories.responses.User import awais.instagrabber.repositories.responses.MediaCandidate import java.io.Serializable diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/stories/StoryStickerResponse.kt b/app/src/main/java/awais/instagrabber/repositories/responses/stories/StoryStickerResponse.kt index 8ac2f4a9..9a765ec2 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/stories/StoryStickerResponse.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/stories/StoryStickerResponse.kt @@ -1,20 +1,3 @@ -package awais.instagrabber.repositories.responses; +package awais.instagrabber.repositories.responses.stories -public class StoryStickerResponse { - private final String status; - - public StoryStickerResponse(final String status) { - this.status = status; - } - - public String getStatus() { - return status; - } - - @Override - public String toString() { - return "StoryStickerResponse{" + - "status='" + status + '\'' + - '}'; - } -} +data class StoryStickerResponse(val status: String?) \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java b/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java index 530dd208..5c625a6f 100644 --- a/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java +++ b/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java @@ -21,6 +21,7 @@ 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.stories.StoryMedia; import awais.instagrabber.repositories.responses.Caption; import awais.instagrabber.repositories.responses.FriendshipStatus; import awais.instagrabber.repositories.responses.ImageVersions2; @@ -406,27 +407,38 @@ public final class ResponseBodyUtils { return model; } - public static String getThumbUrl(final Media media) { + public static String getThumbUrl(final Object media) { return getImageCandidate(media, CandidateType.THUMBNAIL); } - public static String getImageUrl(final Media media) { + public static String getImageUrl(final Object media) { return getImageCandidate(media, CandidateType.DOWNLOAD); } - private static String getImageCandidate(final Media media, final CandidateType type) { - if (media == null) return null; - final ImageVersions2 imageVersions2 = media.getImageVersions2(); + private static String getImageCandidate(final Object rawMedia, final CandidateType type) { + final ImageVersions2 imageVersions2; + final int originalWidth, originalHeight; + if (rawMedia instanceof StoryMedia) { + imageVersions2 = ((StoryMedia) rawMedia).getImageVersions2(); + originalWidth = ((StoryMedia) rawMedia).getOriginalWidth(); + originalHeight = ((StoryMedia) rawMedia).getOriginalHeight(); + } + else if (rawMedia instanceof Media) { + imageVersions2 = ((Media) rawMedia).getImageVersions2(); + originalWidth = ((Media) rawMedia).getOriginalWidth(); + originalHeight = ((Media) rawMedia).getOriginalHeight(); + } + else return null; if (imageVersions2 == null) return null; final List candidates = imageVersions2.getCandidates(); 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 sortedCandidates = candidates.stream() .sorted((c1, c2) -> Integer.compare(c2.getWidth(), c1.getWidth())) .collect(Collectors.toList()); final List filteredCandidates = sortedCandidates.stream() .filter(c -> - c.getWidth() <= media.getOriginalWidth() + c.getWidth() <= originalWidth && c.getWidth() <= type.getValue() && (isSquare || Integer .compare(c.getWidth(), c.getHeight()) != 0) diff --git a/app/src/main/java/awais/instagrabber/viewmodels/FeedStoriesViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/FeedStoriesViewModel.java index f4bd3b41..6387d184 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/FeedStoriesViewModel.java +++ b/app/src/main/java/awais/instagrabber/viewmodels/FeedStoriesViewModel.java @@ -6,12 +6,12 @@ import androidx.lifecycle.ViewModel; import java.util.ArrayList; import java.util.List; -import awais.instagrabber.models.FeedStoryModel; +import awais.instagrabber.repositories.responses.stories.Story; public class FeedStoriesViewModel extends ViewModel { - private MutableLiveData> list; + private MutableLiveData> list; - public MutableLiveData> getList() { + public MutableLiveData> getList() { if (list == null) { list = new MutableLiveData<>(); } diff --git a/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt b/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt index 7235ace1..89603777 100644 --- a/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt +++ b/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt @@ -1,19 +1,16 @@ package awais.instagrabber.webservices -import android.util.Log import awais.instagrabber.fragments.settings.PreferenceKeys -import awais.instagrabber.models.FeedStoryModel 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.StoryStickerResponse -import awais.instagrabber.repositories.responses.User +import awais.instagrabber.repositories.responses.stories.Story +import awais.instagrabber.repositories.responses.stories.StoryStickerResponse import awais.instagrabber.utils.Constants import awais.instagrabber.utils.ResponseBodyUtils import awais.instagrabber.utils.TextUtils.isEmpty import awais.instagrabber.utils.Utils -import awais.instagrabber.utils.extensions.TAG import awais.instagrabber.webservices.RetrofitFactory.retrofit import org.json.JSONArray import org.json.JSONObject @@ -27,76 +24,29 @@ open class StoriesRepository(private val service: StoriesService) { return ResponseBodyUtils.parseStoryItem(itemJson, false, null) } - suspend fun getFeedStories(): List { + suspend fun getFeedStories(): List { val response = service.getFeedStories() - return parseStoriesBody(response) - } - - private fun parseStoriesBody(body: String): List { - val feedStoryModels: MutableList = ArrayList() - val feedStoriesReel = JSONObject(body).getJSONArray("tray") - for (i in 0 until feedStoriesReel.length()) { - val node = feedStoriesReel.getJSONObject(i) - if (node.optBoolean("hide_from_feed_unit") && Utils.settingsHelper.getBoolean(PreferenceKeys.HIDE_MUTED_REELS)) continue - val userJson = node.getJSONObject(if (node.has("user")) "user" else "owner") - try { - val user = User( - userJson.getLong("pk"), - userJson.getString("username"), - userJson.optString("full_name"), - userJson.optBoolean("is_private"), - userJson.getString("profile_pic_url"), - userJson.optBoolean("is_verified") - ) - val timestamp = node.getLong("latest_reel_media") - val fullyRead = !node.isNull("seen") && node.getLong("seen") == timestamp - val itemJson = if (node.has("items")) node.getJSONArray("items").optJSONObject(0) else null - var firstStoryModel: StoryModel? = null - if (itemJson != null) { - firstStoryModel = ResponseBodyUtils.parseStoryItem(itemJson, false, null) - } - feedStoryModels.add( - FeedStoryModel( - node.getString("id"), - user, - fullyRead, - timestamp, - firstStoryModel, - node.getInt("media_count"), - false, - node.optBoolean("has_besties_media") + val result = response.tray?.toMutableList() ?: mutableListOf() + if (response.broadcasts != null) { + val length = response.broadcasts.size + for (i in 0 until length) { + val broadcast = response.broadcasts.get(i) + result.add( + Story( + broadcast.id, + broadcast.publishedTime, + 0L, + broadcast.broadcastOwner, + broadcast.muted, + false, // unclear + 1, + null, + broadcast ) ) - } catch (e: Exception) { - Log.e(TAG, "parseStoriesBody: ", e) - } // to cover promotional reels with non-long user pk's + } } - val broadcasts = JSONObject(body).getJSONArray("broadcasts") - for (i in 0 until broadcasts.length()) { - val node = broadcasts.getJSONObject(i) - val userJson = node.getJSONObject("broadcast_owner") - val user = User( - userJson.getLong("pk"), - userJson.getString("username"), - userJson.optString("full_name"), - userJson.optBoolean("is_private"), - userJson.getString("profile_pic_url"), - userJson.optBoolean("is_verified") - ) - feedStoryModels.add( - FeedStoryModel( - node.getString("id"), - user, - false, - node.getLong("published_time"), - ResponseBodyUtils.parseBroadcastItem(node), - 1, - isLive = true, - isBestie = false - ) - ) - } - return sort(feedStoryModels) + return sort(result.toList()) } open suspend fun fetchHighlights(profileId: Long): List { @@ -299,12 +249,13 @@ open class StoriesRepository(private val service: StoriesService) { return builder.toString() } - private fun sort(list: List): List { + private fun sort(list: List): List { val listCopy = ArrayList(list) listCopy.sortWith { o1, o2 -> - when (Utils.settingsHelper.getString(PreferenceKeys.STORY_SORT)) { - "1" -> return@sortWith o2.timestamp.compareTo(o1.timestamp) - "2" -> return@sortWith o1.timestamp.compareTo(o2.timestamp) + if (o1.latestReelMedia == null || o2.latestReelMedia == null) return@sortWith 0 + else when (Utils.settingsHelper.getString(PreferenceKeys.STORY_SORT)) { + "1" -> return@sortWith o2.latestReelMedia.compareTo(o1.latestReelMedia) + "2" -> return@sortWith o1.latestReelMedia.compareTo(o2.latestReelMedia) else -> return@sortWith 0 } } diff --git a/app/src/main/res/layout/fragment_story_viewer.xml b/app/src/main/res/layout/fragment_story_viewer.xml index 4495cab6..e56f5a7a 100644 --- a/app/src/main/res/layout/fragment_story_viewer.xml +++ b/app/src/main/res/layout/fragment_story_viewer.xml @@ -133,7 +133,7 @@ android:id="@+id/btnBackward" style="@style/Widget.MaterialComponents.Button.TextButton" android:layout_width="40dp" - android:layout_height="0dp" + android:layout_height="@dimen/story_item_height" android:visibility="visible" app:icon="@drawable/exo_ic_skip_previous" app:iconGravity="textStart" @@ -146,7 +146,7 @@ Date: Mon, 28 Jun 2021 23:01:46 -0400 Subject: [PATCH 21/26] partially revert 817a1687 on layout --- app/src/main/res/layout/fragment_story_viewer.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/layout/fragment_story_viewer.xml b/app/src/main/res/layout/fragment_story_viewer.xml index e56f5a7a..cb6b66ed 100644 --- a/app/src/main/res/layout/fragment_story_viewer.xml +++ b/app/src/main/res/layout/fragment_story_viewer.xml @@ -146,7 +146,7 @@ Date: Tue, 29 Jun 2021 09:54:13 -0400 Subject: [PATCH 22/26] Rename .java to .kt --- .../{HdProfilePicUrlInfo.java => HdProfilePicUrlInfo.kt} | 0 .../responses/{ImageVersions2.java => ImageVersions2.kt} | 0 .../responses/{LikersResponse.java => LikersResponse.kt} | 0 .../responses/{MediaCandidate.java => MediaCandidate.kt} | 0 .../responses/{MediaInfoResponse.java => MediaInfoResponse.kt} | 0 .../responses/{NewsInboxResponse.java => NewsInboxResponse.kt} | 0 .../instagrabber/repositories/responses/{Place.java => Place.kt} | 0 .../responses/{PostsFetchResponse.java => PostsFetchResponse.kt} | 0 .../responses/{TagFeedResponse.java => TagFeedResponse.kt} | 0 .../responses/{UserFeedResponse.java => UserFeedResponse.kt} | 0 .../{UserProfileContextLink.java => UserProfileContextLink.kt} | 0 .../repositories/responses/{WrappedMedia.java => WrappedMedia.kt} | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename app/src/main/java/awais/instagrabber/repositories/responses/{HdProfilePicUrlInfo.java => HdProfilePicUrlInfo.kt} (100%) rename app/src/main/java/awais/instagrabber/repositories/responses/{ImageVersions2.java => ImageVersions2.kt} (100%) rename app/src/main/java/awais/instagrabber/repositories/responses/{LikersResponse.java => LikersResponse.kt} (100%) rename app/src/main/java/awais/instagrabber/repositories/responses/{MediaCandidate.java => MediaCandidate.kt} (100%) rename app/src/main/java/awais/instagrabber/repositories/responses/{MediaInfoResponse.java => MediaInfoResponse.kt} (100%) rename app/src/main/java/awais/instagrabber/repositories/responses/{NewsInboxResponse.java => NewsInboxResponse.kt} (100%) rename app/src/main/java/awais/instagrabber/repositories/responses/{Place.java => Place.kt} (100%) rename app/src/main/java/awais/instagrabber/repositories/responses/{PostsFetchResponse.java => PostsFetchResponse.kt} (100%) rename app/src/main/java/awais/instagrabber/repositories/responses/{TagFeedResponse.java => TagFeedResponse.kt} (100%) rename app/src/main/java/awais/instagrabber/repositories/responses/{UserFeedResponse.java => UserFeedResponse.kt} (100%) rename app/src/main/java/awais/instagrabber/repositories/responses/{UserProfileContextLink.java => UserProfileContextLink.kt} (100%) rename app/src/main/java/awais/instagrabber/repositories/responses/{WrappedMedia.java => WrappedMedia.kt} (100%) diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/HdProfilePicUrlInfo.java b/app/src/main/java/awais/instagrabber/repositories/responses/HdProfilePicUrlInfo.kt similarity index 100% rename from app/src/main/java/awais/instagrabber/repositories/responses/HdProfilePicUrlInfo.java rename to app/src/main/java/awais/instagrabber/repositories/responses/HdProfilePicUrlInfo.kt diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/ImageVersions2.java b/app/src/main/java/awais/instagrabber/repositories/responses/ImageVersions2.kt similarity index 100% rename from app/src/main/java/awais/instagrabber/repositories/responses/ImageVersions2.java rename to app/src/main/java/awais/instagrabber/repositories/responses/ImageVersions2.kt diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/LikersResponse.java b/app/src/main/java/awais/instagrabber/repositories/responses/LikersResponse.kt similarity index 100% rename from app/src/main/java/awais/instagrabber/repositories/responses/LikersResponse.java rename to app/src/main/java/awais/instagrabber/repositories/responses/LikersResponse.kt diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/MediaCandidate.java b/app/src/main/java/awais/instagrabber/repositories/responses/MediaCandidate.kt similarity index 100% rename from app/src/main/java/awais/instagrabber/repositories/responses/MediaCandidate.java rename to app/src/main/java/awais/instagrabber/repositories/responses/MediaCandidate.kt diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/MediaInfoResponse.java b/app/src/main/java/awais/instagrabber/repositories/responses/MediaInfoResponse.kt similarity index 100% rename from app/src/main/java/awais/instagrabber/repositories/responses/MediaInfoResponse.java rename to app/src/main/java/awais/instagrabber/repositories/responses/MediaInfoResponse.kt diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/NewsInboxResponse.java b/app/src/main/java/awais/instagrabber/repositories/responses/NewsInboxResponse.kt similarity index 100% rename from app/src/main/java/awais/instagrabber/repositories/responses/NewsInboxResponse.java rename to app/src/main/java/awais/instagrabber/repositories/responses/NewsInboxResponse.kt diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/Place.java b/app/src/main/java/awais/instagrabber/repositories/responses/Place.kt similarity index 100% rename from app/src/main/java/awais/instagrabber/repositories/responses/Place.java rename to app/src/main/java/awais/instagrabber/repositories/responses/Place.kt diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/PostsFetchResponse.java b/app/src/main/java/awais/instagrabber/repositories/responses/PostsFetchResponse.kt similarity index 100% rename from app/src/main/java/awais/instagrabber/repositories/responses/PostsFetchResponse.java rename to app/src/main/java/awais/instagrabber/repositories/responses/PostsFetchResponse.kt diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/TagFeedResponse.java b/app/src/main/java/awais/instagrabber/repositories/responses/TagFeedResponse.kt similarity index 100% rename from app/src/main/java/awais/instagrabber/repositories/responses/TagFeedResponse.java rename to app/src/main/java/awais/instagrabber/repositories/responses/TagFeedResponse.kt diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/UserFeedResponse.java b/app/src/main/java/awais/instagrabber/repositories/responses/UserFeedResponse.kt similarity index 100% rename from app/src/main/java/awais/instagrabber/repositories/responses/UserFeedResponse.java rename to app/src/main/java/awais/instagrabber/repositories/responses/UserFeedResponse.kt diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/UserProfileContextLink.java b/app/src/main/java/awais/instagrabber/repositories/responses/UserProfileContextLink.kt similarity index 100% rename from app/src/main/java/awais/instagrabber/repositories/responses/UserProfileContextLink.java rename to app/src/main/java/awais/instagrabber/repositories/responses/UserProfileContextLink.kt diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/WrappedMedia.java b/app/src/main/java/awais/instagrabber/repositories/responses/WrappedMedia.kt similarity index 100% rename from app/src/main/java/awais/instagrabber/repositories/responses/WrappedMedia.java rename to app/src/main/java/awais/instagrabber/repositories/responses/WrappedMedia.kt From dbf0c66b4160dd373af802530e838e9ae9e7c2f4 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Tue, 29 Jun 2021 10:12:07 -0400 Subject: [PATCH 23/26] convert stuff to kotlin --- .../asyncs/FeedPostFetchService.java | 2 +- .../asyncs/HashtagPostFetchService.java | 2 +- .../asyncs/LocationPostFetchService.java | 2 +- .../asyncs/ProfilePostFetchService.java | 2 +- .../asyncs/SavedPostFetchService.java | 2 +- .../responses/HdProfilePicUrlInfo.kt | 17 +---- .../repositories/responses/ImageVersions2.kt | 31 +-------- .../repositories/responses/LikersResponse.kt | 28 +------- .../repositories/responses/MediaCandidate.kt | 44 +----------- .../responses/MediaInfoResponse.kt | 16 +---- .../responses/NewsInboxResponse.kt | 38 +++-------- .../repositories/responses/Place.kt | 68 +++---------------- .../responses/PostsFetchResponse.kt | 32 ++------- .../repositories/responses/TagFeedResponse.kt | 50 +++----------- .../responses/UserFeedResponse.kt | 50 +++----------- .../responses/UserProfileContextLink.kt | 22 +----- .../repositories/responses/WrappedMedia.kt | 14 +--- .../webservices/ProfileService.java | 6 +- .../instagrabber/webservices/TagsService.java | 2 +- 19 files changed, 65 insertions(+), 363 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/asyncs/FeedPostFetchService.java b/app/src/main/java/awais/instagrabber/asyncs/FeedPostFetchService.java index 4fe91772..96643339 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/FeedPostFetchService.java +++ b/app/src/main/java/awais/instagrabber/asyncs/FeedPostFetchService.java @@ -39,7 +39,7 @@ public class FeedPostFetchService implements PostFetcher.PostFetchService { return; } else if (result == null) return; nextCursor = result.getNextCursor(); - hasNextPage = result.hasNextPage(); + hasNextPage = result.getHasNextPage(); final List mediaResults = result.getFeedModels(); feedModels.addAll(mediaResults); diff --git a/app/src/main/java/awais/instagrabber/asyncs/HashtagPostFetchService.java b/app/src/main/java/awais/instagrabber/asyncs/HashtagPostFetchService.java index 87b38bb7..7b26d79b 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/HashtagPostFetchService.java +++ b/app/src/main/java/awais/instagrabber/asyncs/HashtagPostFetchService.java @@ -35,7 +35,7 @@ public class HashtagPostFetchService implements PostFetcher.PostFetchService { public void onSuccess(final PostsFetchResponse result) { if (result == null) return; nextMaxId = result.getNextCursor(); - moreAvailable = result.hasNextPage(); + moreAvailable = result.getHasNextPage(); if (fetchListener != null) { fetchListener.onResult(result.getFeedModels()); } diff --git a/app/src/main/java/awais/instagrabber/asyncs/LocationPostFetchService.java b/app/src/main/java/awais/instagrabber/asyncs/LocationPostFetchService.java index 31b9f90c..11f5dce3 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/LocationPostFetchService.java +++ b/app/src/main/java/awais/instagrabber/asyncs/LocationPostFetchService.java @@ -35,7 +35,7 @@ public class LocationPostFetchService implements PostFetcher.PostFetchService { public void onSuccess(final PostsFetchResponse result) { if (result == null) return; nextMaxId = result.getNextCursor(); - moreAvailable = result.hasNextPage(); + moreAvailable = result.getHasNextPage(); if (fetchListener != null) { fetchListener.onResult(result.getFeedModels()); } diff --git a/app/src/main/java/awais/instagrabber/asyncs/ProfilePostFetchService.java b/app/src/main/java/awais/instagrabber/asyncs/ProfilePostFetchService.java index 2c609dcb..9bff389e 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/ProfilePostFetchService.java +++ b/app/src/main/java/awais/instagrabber/asyncs/ProfilePostFetchService.java @@ -36,7 +36,7 @@ public class ProfilePostFetchService implements PostFetcher.PostFetchService { public void onSuccess(final PostsFetchResponse result) { if (result == null) return; nextMaxId = result.getNextCursor(); - moreAvailable = result.hasNextPage(); + moreAvailable = result.getHasNextPage(); if (fetchListener != null) { fetchListener.onResult(result.getFeedModels()); } diff --git a/app/src/main/java/awais/instagrabber/asyncs/SavedPostFetchService.java b/app/src/main/java/awais/instagrabber/asyncs/SavedPostFetchService.java index a84f960a..e4650a77 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/SavedPostFetchService.java +++ b/app/src/main/java/awais/instagrabber/asyncs/SavedPostFetchService.java @@ -40,7 +40,7 @@ public class SavedPostFetchService implements PostFetcher.PostFetchService { public void onSuccess(final PostsFetchResponse result) { if (result == null) return; nextMaxId = result.getNextCursor(); - moreAvailable = result.hasNextPage(); + moreAvailable = result.getHasNextPage(); if (fetchListener != null) { fetchListener.onResult(result.getFeedModels()); } diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/HdProfilePicUrlInfo.kt b/app/src/main/java/awais/instagrabber/repositories/responses/HdProfilePicUrlInfo.kt index 86787880..e31a6027 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/HdProfilePicUrlInfo.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/HdProfilePicUrlInfo.kt @@ -1,16 +1,5 @@ -package awais.instagrabber.repositories.responses; +package awais.instagrabber.repositories.responses -public class HdProfilePicUrlInfo { - private final String url; - private final int width, height; +import java.io.Serializable - public HdProfilePicUrlInfo(final String url, final int width, final int height) { - this.url = url; - this.width = width; - this.height = height; - } - - public String getUrl() { - return url; - } -} +data class HdProfilePicUrlInfo(val url: String, private val width: Int, private val height: Int) : Serializable \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/ImageVersions2.kt b/app/src/main/java/awais/instagrabber/repositories/responses/ImageVersions2.kt index d71d8a00..6bed8a10 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/ImageVersions2.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/ImageVersions2.kt @@ -1,30 +1,5 @@ -package awais.instagrabber.repositories.responses; +package awais.instagrabber.repositories.responses -import java.io.Serializable; -import java.util.List; -import java.util.Objects; +import java.io.Serializable -public class ImageVersions2 implements Serializable { - private final List candidates; - - public ImageVersions2(final List candidates) { - this.candidates = candidates; - } - - public List getCandidates() { - return candidates; - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final ImageVersions2 that = (ImageVersions2) o; - return Objects.equals(candidates, that.candidates); - } - - @Override - public int hashCode() { - return Objects.hash(candidates); - } -} +data class ImageVersions2(val candidates: List) : Serializable \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/LikersResponse.kt b/app/src/main/java/awais/instagrabber/repositories/responses/LikersResponse.kt index da750b04..8ea2aeb6 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/LikersResponse.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/LikersResponse.kt @@ -1,27 +1,3 @@ -package awais.instagrabber.repositories.responses; +package awais.instagrabber.repositories.responses -import java.util.List; - -public class LikersResponse { - private final List users; - private final long userCount; - private final String status; - - public LikersResponse(final List users, final long userCount, final String status) { - this.users = users; - this.userCount = userCount; - this.status = status; - } - - public List getUsers() { - return users; - } - - public long getUserCount() { - return userCount; - } - - public String getStatus() { - return status; - } -} +data class LikersResponse(val users: List, val userCount: Long, val status: String) \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/MediaCandidate.kt b/app/src/main/java/awais/instagrabber/repositories/responses/MediaCandidate.kt index 3a243497..5de5ea88 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/MediaCandidate.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/MediaCandidate.kt @@ -1,43 +1,5 @@ -package awais.instagrabber.repositories.responses; +package awais.instagrabber.repositories.responses -import java.io.Serializable; -import java.util.Objects; +import java.io.Serializable -public class MediaCandidate implements Serializable { - private final int width; - private final int height; - private final String url; - - public MediaCandidate(final int width, final int height, final String url) { - this.width = width; - this.height = height; - this.url = url; - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public String getUrl() { - return url; - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final MediaCandidate that = (MediaCandidate) o; - return width == that.width && - height == that.height && - Objects.equals(url, that.url); - } - - @Override - public int hashCode() { - return Objects.hash(width, height, url); - } -} +data class MediaCandidate(val width: Int, val height: Int, val url: String) : Serializable \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/MediaInfoResponse.kt b/app/src/main/java/awais/instagrabber/repositories/responses/MediaInfoResponse.kt index 2112f48c..139d3c4a 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/MediaInfoResponse.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/MediaInfoResponse.kt @@ -1,15 +1,3 @@ -package awais.instagrabber.repositories.responses; +package awais.instagrabber.repositories.responses -import java.util.List; - -public class MediaInfoResponse { - private final List items; - - public MediaInfoResponse(final List items) { - this.items = items; - } - - public List getItems() { - return items; - } -} +data class MediaInfoResponse(val items: List) \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/NewsInboxResponse.kt b/app/src/main/java/awais/instagrabber/repositories/responses/NewsInboxResponse.kt index a6339e20..74c1417d 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/NewsInboxResponse.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/NewsInboxResponse.kt @@ -1,32 +1,10 @@ -package awais.instagrabber.repositories.responses; +package awais.instagrabber.repositories.responses -import java.util.List; +import awais.instagrabber.repositories.responses.notification.Notification +import awais.instagrabber.repositories.responses.notification.NotificationCounts -import awais.instagrabber.repositories.responses.notification.Notification; -import awais.instagrabber.repositories.responses.notification.NotificationCounts; - -public class NewsInboxResponse { - private final NotificationCounts counts; - private final List newStories; - private final List oldStories; - - public NewsInboxResponse(final NotificationCounts counts, - final List newStories, - final List oldStories) { - this.counts = counts; - this.newStories = newStories; - this.oldStories = oldStories; - } - - public NotificationCounts getCounts() { - return counts; - } - - public List getNewStories() { - return newStories; - } - - public List getOldStories() { - return oldStories; - } -} +data class NewsInboxResponse( + val counts: NotificationCounts, + val newStories: List, + val oldStories: List +) \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/Place.kt b/app/src/main/java/awais/instagrabber/repositories/responses/Place.kt index 3f10ffd4..a0004a59 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/Place.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/Place.kt @@ -1,62 +1,12 @@ -package awais.instagrabber.repositories.responses; +package awais.instagrabber.repositories.responses -import java.util.Objects; - -public class Place { - private final Location location; +data class Place( + val location: Location, // for search - private final String title; // those are repeated within location - private final String subtitle; // address - private final String slug; // browser only; for end of address + val title: String, // those are repeated within location + val subtitle: String?, // address + // browser only; for end of address + val slug: String?, // for location info - private final String status; - - public Place(final Location location, - final String title, - final String subtitle, - final String slug, - final String status) { - this.location = location; - this.title = title; - this.subtitle = subtitle; - this.slug = slug; - this.status = status; - } - - public Location getLocation() { - return location; - } - - public String getTitle() { - return title; - } - - public String getSubtitle() { - return subtitle; - } - - public String getSlug() { - return slug; - } - - public String getStatus() { - return status; - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final Place place = (Place) o; - return Objects.equals(location, place.location) && - Objects.equals(title, place.title) && - Objects.equals(subtitle, place.subtitle) && - Objects.equals(slug, place.slug) && - Objects.equals(status, place.status); - } - - @Override - public int hashCode() { - return Objects.hash(location, title, subtitle, slug, status); - } -} + val status: String? +) \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/PostsFetchResponse.kt b/app/src/main/java/awais/instagrabber/repositories/responses/PostsFetchResponse.kt index c5b24016..64082fce 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/PostsFetchResponse.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/PostsFetchResponse.kt @@ -1,27 +1,7 @@ -package awais.instagrabber.repositories.responses; +package awais.instagrabber.repositories.responses -import java.util.List; - -public class PostsFetchResponse { - private final List feedModels; - private final boolean hasNextPage; - private final String nextCursor; - - public PostsFetchResponse(final List feedModels, final boolean hasNextPage, final String nextCursor) { - this.feedModels = feedModels; - this.hasNextPage = hasNextPage; - this.nextCursor = nextCursor; - } - - public List getFeedModels() { - return feedModels; - } - - public boolean hasNextPage() { - return hasNextPage; - } - - public String getNextCursor() { - return nextCursor; - } -} +class PostsFetchResponse( + val feedModels: List, + val hasNextPage: Boolean, + val nextCursor: String? +) \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/TagFeedResponse.kt b/app/src/main/java/awais/instagrabber/repositories/responses/TagFeedResponse.kt index f597beea..d9bfb37e 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/TagFeedResponse.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/TagFeedResponse.kt @@ -1,43 +1,9 @@ -package awais.instagrabber.repositories.responses; +package awais.instagrabber.repositories.responses -import java.util.List; - -public class TagFeedResponse { - private final int numResults; - private final String nextMaxId; - private final boolean moreAvailable; - private final String status; - private final List items; - - public TagFeedResponse(final int numResults, - final String nextMaxId, - final boolean moreAvailable, - final String status, - final List items) { - this.numResults = numResults; - this.nextMaxId = nextMaxId; - this.moreAvailable = moreAvailable; - this.status = status; - this.items = items; - } - - public int getNumResults() { - return numResults; - } - - public String getNextMaxId() { - return nextMaxId; - } - - public boolean isMoreAvailable() { - return moreAvailable; - } - - public String getStatus() { - return status; - } - - public List getItems() { - return items; - } -} +class TagFeedResponse( + val numResults: Int, + val nextMaxId: String?, + val moreAvailable: Boolean, + val status: String, + val items: List +) \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/UserFeedResponse.kt b/app/src/main/java/awais/instagrabber/repositories/responses/UserFeedResponse.kt index bc912bed..9a68fa4e 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/UserFeedResponse.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/UserFeedResponse.kt @@ -1,43 +1,9 @@ -package awais.instagrabber.repositories.responses; +package awais.instagrabber.repositories.responses -import java.util.List; - -public class UserFeedResponse { - private final int numResults; - private final String nextMaxId; - private final boolean moreAvailable; - private final String status; - private final List items; - - public UserFeedResponse(final int numResults, - final String nextMaxId, - final boolean moreAvailable, - final String status, - final List items) { - this.numResults = numResults; - this.nextMaxId = nextMaxId; - this.moreAvailable = moreAvailable; - this.status = status; - this.items = items; - } - - public int getNumResults() { - return numResults; - } - - public String getNextMaxId() { - return nextMaxId; - } - - public boolean isMoreAvailable() { - return moreAvailable; - } - - public String getStatus() { - return status; - } - - public List getItems() { - return items; - } -} +class UserFeedResponse( + val numResults: Int, + val nextMaxId: String?, + val moreAvailable: Boolean, + val status: String, + val items: List +) \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/UserProfileContextLink.kt b/app/src/main/java/awais/instagrabber/repositories/responses/UserProfileContextLink.kt index 7beb954d..ea8d1a66 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/UserProfileContextLink.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/UserProfileContextLink.kt @@ -1,21 +1,3 @@ -package awais.instagrabber.repositories.responses; +package awais.instagrabber.repositories.responses -public class UserProfileContextLink { - private final String username; - private final int start; - private final int end; - - public UserProfileContextLink(final String username, final int start, final int end) { - this.username = username; - this.start = start; - this.end = end; - } - - public String getUsername() { - return username; - } - - public int getStart() { - return start; - } -} +class UserProfileContextLink(val username: String, val start: Int, private val end: Int) \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/WrappedMedia.kt b/app/src/main/java/awais/instagrabber/repositories/responses/WrappedMedia.kt index 2bfb1fa1..e09a20bc 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/WrappedMedia.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/WrappedMedia.kt @@ -1,13 +1,3 @@ -package awais.instagrabber.repositories.responses; +package awais.instagrabber.repositories.responses -public class WrappedMedia { - private final Media media; - - public WrappedMedia(final Media media) { - this.media = media; - } - - public Media getMedia() { - return media; - } -} +class WrappedMedia(val media: Media) \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/webservices/ProfileService.java b/app/src/main/java/awais/instagrabber/webservices/ProfileService.java index 1e491906..e8f6884c 100644 --- a/app/src/main/java/awais/instagrabber/webservices/ProfileService.java +++ b/app/src/main/java/awais/instagrabber/webservices/ProfileService.java @@ -63,7 +63,7 @@ public class ProfileService { } callback.onSuccess(new PostsFetchResponse( body.getItems(), - body.isMoreAvailable(), + body.getMoreAvailable(), body.getNextMaxId() )); } @@ -204,7 +204,7 @@ public class ProfileService { } callback.onSuccess(new PostsFetchResponse( userFeedResponse.getItems(), - userFeedResponse.isMoreAvailable(), + userFeedResponse.getMoreAvailable(), userFeedResponse.getNextMaxId() )); } @@ -237,7 +237,7 @@ public class ProfileService { } callback.onSuccess(new PostsFetchResponse( userFeedResponse.getItems(), - userFeedResponse.isMoreAvailable(), + userFeedResponse.getMoreAvailable(), userFeedResponse.getNextMaxId() )); } diff --git a/app/src/main/java/awais/instagrabber/webservices/TagsService.java b/app/src/main/java/awais/instagrabber/webservices/TagsService.java index fa4f3dce..f207dcad 100644 --- a/app/src/main/java/awais/instagrabber/webservices/TagsService.java +++ b/app/src/main/java/awais/instagrabber/webservices/TagsService.java @@ -122,7 +122,7 @@ public class TagsService { } callback.onSuccess(new PostsFetchResponse( body.getItems(), - body.isMoreAvailable(), + body.getMoreAvailable(), body.getNextMaxId() )); } From f7ce2eeea2f67c561ddd65f3a8ada9445c31b67f Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Tue, 29 Jun 2021 10:28:32 -0400 Subject: [PATCH 24/26] convert HighlightModel usages (as highlights) to Story --- .../adapters/HighlightsAdapter.java | 14 +++++------ .../viewholder/HighlightViewHolder.java | 6 ++--- .../fragments/StoryViewerFragment.java | 4 ++-- .../fragments/main/ProfileFragment.java | 4 ++-- .../repositories/StoriesService.kt | 2 +- .../responses/HdProfilePicUrlInfo.kt | 5 ---- .../repositories/responses/ImageUrl.kt | 5 ++++ .../repositories/responses/User.kt | 2 +- .../responses/stories/CoverMedia.kt | 5 ++++ .../repositories/responses/stories/Story.kt | 9 +++++-- .../viewmodels/HighlightsViewModel.java | 6 ++--- .../viewmodels/ProfileFragmentViewModel.kt | 10 ++++---- .../webservices/StoriesRepository.kt | 24 ++++--------------- .../ProfileFragmentViewModelTest.kt | 4 ++-- 14 files changed, 48 insertions(+), 52 deletions(-) delete mode 100644 app/src/main/java/awais/instagrabber/repositories/responses/HdProfilePicUrlInfo.kt create mode 100644 app/src/main/java/awais/instagrabber/repositories/responses/ImageUrl.kt create mode 100644 app/src/main/java/awais/instagrabber/repositories/responses/stories/CoverMedia.kt diff --git a/app/src/main/java/awais/instagrabber/adapters/HighlightsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/HighlightsAdapter.java index 41cbb3db..f97c6094 100755 --- a/app/src/main/java/awais/instagrabber/adapters/HighlightsAdapter.java +++ b/app/src/main/java/awais/instagrabber/adapters/HighlightsAdapter.java @@ -9,20 +9,20 @@ import androidx.recyclerview.widget.ListAdapter; import awais.instagrabber.adapters.viewholder.HighlightViewHolder; import awais.instagrabber.databinding.ItemHighlightBinding; -import awais.instagrabber.models.HighlightModel; +import awais.instagrabber.repositories.responses.stories.Story; -public final class HighlightsAdapter extends ListAdapter { +public final class HighlightsAdapter extends ListAdapter { private final OnHighlightClickListener clickListener; - private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() { + private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() { @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()); } }; @@ -42,7 +42,7 @@ public final class HighlightsAdapter extends ListAdapter clickListener.onHighlightClick(highlightModel, position)); } @@ -50,6 +50,6 @@ public final class HighlightsAdapter extends ListAdapter { // if (listener == null) return; // listener.onFeedStoryClick(model, position); diff --git a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java index a4acc407..b67487b2 100644 --- a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java @@ -736,12 +736,12 @@ public class StoryViewerFragment extends Fragment { switch (type) { case HIGHLIGHT: { final HighlightsViewModel highlightsViewModel = (HighlightsViewModel) viewModel; - final List models = highlightsViewModel.getList().getValue(); + final List models = highlightsViewModel.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 = model.getId(); fetchOptions = StoryViewerOptions.forHighlight(model.getId()); highlightTitle = model.getTitle(); diff --git a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java index 1f2d7638..2ef21ed6 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java @@ -73,7 +73,6 @@ import awais.instagrabber.fragments.UserSearchFragment; import awais.instagrabber.fragments.UserSearchFragmentDirections; import awais.instagrabber.managers.DirectMessagesManager; import awais.instagrabber.managers.InboxManager; -import awais.instagrabber.models.HighlightModel; import awais.instagrabber.models.PostsLayoutPreferences; import awais.instagrabber.models.enums.FavoriteType; import awais.instagrabber.models.enums.PostItemType; @@ -84,6 +83,7 @@ import awais.instagrabber.repositories.responses.Media; 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.utils.AppExecutors; import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.CookieUtils; @@ -1121,7 +1121,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe if (highlightModels != null) { profileDetailsBinding.highlightsList.setVisibility(View.VISIBLE); //noinspection unchecked - highlightsViewModel.getList().postValue((List) highlightModels); + highlightsViewModel.getList().postValue((List) highlightModels); } else { profileDetailsBinding.highlightsList.setVisibility(View.GONE); } diff --git a/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt b/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt index a55315e9..205830c0 100644 --- a/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt +++ b/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt @@ -13,7 +13,7 @@ interface StoriesService { suspend fun getFeedStories(): ReelsTrayResponse @GET("/api/v1/highlights/{uid}/highlights_tray/") - suspend fun fetchHighlights(@Path("uid") uid: Long): String + suspend fun fetchHighlights(@Path("uid") uid: Long): ReelsTrayResponse @GET("/api/v1/archive/reel/day_shells/") suspend fun fetchArchive(@QueryMap queryParams: Map): String diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/HdProfilePicUrlInfo.kt b/app/src/main/java/awais/instagrabber/repositories/responses/HdProfilePicUrlInfo.kt deleted file mode 100644 index e31a6027..00000000 --- a/app/src/main/java/awais/instagrabber/repositories/responses/HdProfilePicUrlInfo.kt +++ /dev/null @@ -1,5 +0,0 @@ -package awais.instagrabber.repositories.responses - -import java.io.Serializable - -data class HdProfilePicUrlInfo(val url: String, private val width: Int, private val height: Int) : Serializable \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/ImageUrl.kt b/app/src/main/java/awais/instagrabber/repositories/responses/ImageUrl.kt new file mode 100644 index 00000000..0c2362d1 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/repositories/responses/ImageUrl.kt @@ -0,0 +1,5 @@ +package awais.instagrabber.repositories.responses + +import java.io.Serializable + +data class ImageUrl(val url: String, private val width: Int, private val height: Int) : Serializable \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/User.kt b/app/src/main/java/awais/instagrabber/repositories/responses/User.kt index b46e3dab..6f465fb6 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/User.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/User.kt @@ -27,7 +27,7 @@ data class User @JvmOverloads constructor( val externalUrl: String? = null, val usertagsCount: Long = 0, val publicEmail: String? = null, - val hdProfilePicUrlInfo: HdProfilePicUrlInfo? = null, + val hdProfilePicUrlInfo: ImageUrl? = null, val profileContext: String? = null, // "also followed by" your friends val profileContextLinksWithUserIds: List? = null, // ^ val socialContext: String? = null, // AYML diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/stories/CoverMedia.kt b/app/src/main/java/awais/instagrabber/repositories/responses/stories/CoverMedia.kt new file mode 100644 index 00000000..47d7a641 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/repositories/responses/stories/CoverMedia.kt @@ -0,0 +1,5 @@ +package awais.instagrabber.repositories.responses.stories + +import awais.instagrabber.repositories.responses.ImageUrl + +data class CoverMedia(val croppedImageVersion: ImageUrl) \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/stories/Story.kt b/app/src/main/java/awais/instagrabber/repositories/responses/stories/Story.kt index 81e3d0d1..57f8b095 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/stories/Story.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/stories/Story.kt @@ -1,19 +1,24 @@ package awais.instagrabber.repositories.responses.stories import java.io.Serializable -import awais.instagrabber.repositories.responses.Media import awais.instagrabber.repositories.responses.User import awais.instagrabber.utils.TextUtils data class Story( + // universal val id: String?, val latestReelMedia: Long?, // = timestamp var seen: Long?, val user: User?, + // for stories + val mediaCount: Int?, val muted: Boolean?, val hasBestiesMedia: Boolean?, - val mediaCount: Int?, val items: List?, // may be null + // for highlights + val coverMedia: CoverMedia?, + val title: String?, + // invented fields val broadcast: Broadcast? // does not naturally occur ) : Serializable { val dateTime: String diff --git a/app/src/main/java/awais/instagrabber/viewmodels/HighlightsViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/HighlightsViewModel.java index d78b9ef4..ccc8b843 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/HighlightsViewModel.java +++ b/app/src/main/java/awais/instagrabber/viewmodels/HighlightsViewModel.java @@ -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 HighlightsViewModel extends ViewModel { - private MutableLiveData> list; + private MutableLiveData> list; - public MutableLiveData> getList() { + public MutableLiveData> getList() { if (list == null) { list = new MutableLiveData<>(); } diff --git a/app/src/main/java/awais/instagrabber/viewmodels/ProfileFragmentViewModel.kt b/app/src/main/java/awais/instagrabber/viewmodels/ProfileFragmentViewModel.kt index bc0e185b..736cdc7b 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/ProfileFragmentViewModel.kt +++ b/app/src/main/java/awais/instagrabber/viewmodels/ProfileFragmentViewModel.kt @@ -8,7 +8,6 @@ import awais.instagrabber.db.entities.Favorite import awais.instagrabber.db.repositories.AccountRepository import awais.instagrabber.db.repositories.FavoriteRepository import awais.instagrabber.managers.DirectMessagesManager -import awais.instagrabber.models.HighlightModel import awais.instagrabber.models.Resource import awais.instagrabber.models.StoryModel import awais.instagrabber.models.enums.BroadcastItemType @@ -16,6 +15,7 @@ import awais.instagrabber.models.enums.FavoriteType import awais.instagrabber.repositories.requests.StoryViewerOptions import awais.instagrabber.repositories.responses.User import awais.instagrabber.repositories.responses.directmessages.RankedRecipient +import awais.instagrabber.repositories.responses.stories.Story import awais.instagrabber.utils.ControlledRunner import awais.instagrabber.utils.extensions.TAG import awais.instagrabber.webservices.* @@ -119,9 +119,9 @@ class ProfileFragmentViewModel( } } - private val highlightsFetchControlledRunner = ControlledRunner?>() - val userHighlights: LiveData?>> = profile.switchMap { userResource -> - liveData?>>(context = viewModelScope.coroutineContext + ioDispatcher) { + private val highlightsFetchControlledRunner = ControlledRunner?>() + val userHighlights: LiveData?>> = profile.switchMap { userResource -> + liveData?>>(context = viewModelScope.coroutineContext + ioDispatcher) { // don't fetch if not logged in if (isLoggedIn.value != true) { emit(Resource.success(null)) @@ -165,7 +165,7 @@ class ProfileFragmentViewModel( StoryViewerOptions.forUser(fetchedUser.pk, fetchedUser.fullName) ) - private suspend fun fetchUserHighlights(fetchedUser: User): List = storiesRepository.fetchHighlights(fetchedUser.pk) + private suspend fun fetchUserHighlights(fetchedUser: User): List = storiesRepository.fetchHighlights(fetchedUser.pk) private suspend fun checkAndInsertFavorite(fetchedUser: User) { try { diff --git a/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt b/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt index 89603777..d4f080cd 100644 --- a/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt +++ b/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt @@ -37,9 +37,11 @@ open class StoriesRepository(private val service: StoriesService) { broadcast.publishedTime, 0L, broadcast.broadcastOwner, + 1, broadcast.muted, false, // unclear - 1, + null, + null, null, broadcast ) @@ -49,25 +51,9 @@ open class StoriesRepository(private val service: StoriesService) { return sort(result.toList()) } - open suspend fun fetchHighlights(profileId: Long): List { + open suspend fun fetchHighlights(profileId: Long): List { val response = service.fetchHighlights(profileId) - val highlightsReel = JSONObject(response).getJSONArray("tray") - val length = highlightsReel.length() - val highlightModels: MutableList = ArrayList() - for (i in 0 until length) { - val highlightNode = highlightsReel.getJSONObject(i) - highlightModels.add( - HighlightModel( - highlightNode.getString("title"), - highlightNode.getString(Constants.EXTRAS_ID), - highlightNode.getJSONObject("cover_media") - .getJSONObject("cropped_image_version") - .getString("url"), - highlightNode.getLong("latest_reel_media"), - highlightNode.getInt("media_count") - ) - ) - } + val highlightModels = response.tray ?: listOf() return highlightModels } diff --git a/app/src/test/java/awais/instagrabber/viewmodels/ProfileFragmentViewModelTest.kt b/app/src/test/java/awais/instagrabber/viewmodels/ProfileFragmentViewModelTest.kt index 471b9c2a..bdaf8515 100644 --- a/app/src/test/java/awais/instagrabber/viewmodels/ProfileFragmentViewModelTest.kt +++ b/app/src/test/java/awais/instagrabber/viewmodels/ProfileFragmentViewModelTest.kt @@ -11,13 +11,13 @@ import awais.instagrabber.db.entities.Favorite import awais.instagrabber.db.repositories.AccountRepository import awais.instagrabber.db.repositories.FavoriteRepository import awais.instagrabber.getOrAwaitValue -import awais.instagrabber.models.HighlightModel 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.webservices.* import kotlinx.coroutines.ExperimentalCoroutinesApi import org.json.JSONException @@ -296,7 +296,7 @@ internal class ProfileFragmentViewModelTest { ) ) val testUserStories = listOf(StoryModel()) - val testUserHighlights = listOf(HighlightModel()) + val testUserHighlights = listOf(Story()) val userRepository = object : UserRepository(UserServiceAdapter()) { override suspend fun getUsernameInfo(username: String): User = testPublicUser } From 7ead5046d9e22e20a45a0ea8c54d352b81626916 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Tue, 29 Jun 2021 11:06:03 -0400 Subject: [PATCH 25/26] convert HighlightModel usages (as archives) to Story --- .../adapters/HighlightStoriesListAdapter.java | 14 ++++---- .../viewholder/StoryListViewHolder.java | 5 ++- .../fragments/StoryListViewerFragment.java | 17 +++++----- .../fragments/StoryViewerFragment.java | 5 ++- .../instagrabber/models/HighlightModel.kt | 14 -------- .../repositories/StoriesService.kt | 3 +- .../responses/stories/ArchiveResponse.kt | 9 +++++ .../repositories/responses/stories/Story.kt | 7 +++- .../viewmodels/ArchivesViewModel.java | 6 ++-- .../webservices/StoriesRepository.kt | 34 ++++--------------- 10 files changed, 45 insertions(+), 69 deletions(-) delete mode 100644 app/src/main/java/awais/instagrabber/models/HighlightModel.kt create mode 100644 app/src/main/java/awais/instagrabber/repositories/responses/stories/ArchiveResponse.kt diff --git a/app/src/main/java/awais/instagrabber/adapters/HighlightStoriesListAdapter.java b/app/src/main/java/awais/instagrabber/adapters/HighlightStoriesListAdapter.java index 9547b9c1..eabfe737 100755 --- a/app/src/main/java/awais/instagrabber/adapters/HighlightStoriesListAdapter.java +++ b/app/src/main/java/awais/instagrabber/adapters/HighlightStoriesListAdapter.java @@ -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 { +public final class HighlightStoriesListAdapter extends ListAdapter { private final OnHighlightStoryClickListener listener; - private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() { + private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() { @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 { if (notificationClickListener == null) return; diff --git a/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java index c259b1c4..77ef289a 100644 --- a/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/StoryListViewerFragment.java @@ -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 cb = new ServiceCallback() { + private final ServiceCallback cb = new ServiceCallback() { @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 models = archivesViewModel.getList().getValue(); - final List modelsCopy = models == null ? new ArrayList<>() : new ArrayList<>(models); - modelsCopy.addAll(result.getResult()); + endCursor = result.getMaxId(); + final List models = archivesViewModel.getList().getValue(); + final List modelsCopy = models == null ? new ArrayList<>() : new ArrayList<>(models); + modelsCopy.addAll(result.getItems()); archivesViewModel.getList().postValue(modelsCopy); } } diff --git a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java index b67487b2..7f951c6c 100644 --- a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java @@ -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 models = archivesViewModel.getList().getValue(); + final List 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()); diff --git a/app/src/main/java/awais/instagrabber/models/HighlightModel.kt b/app/src/main/java/awais/instagrabber/models/HighlightModel.kt deleted file mode 100644 index 73ac96eb..00000000 --- a/app/src/main/java/awais/instagrabber/models/HighlightModel.kt +++ /dev/null @@ -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) -} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt b/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt index 205830c0..f9190548 100644 --- a/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt +++ b/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt @@ -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 + suspend fun fetchArchive(@QueryMap queryParams: Map): ArchiveResponse? @GET suspend fun getUserStory(@Url url: String): String diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/stories/ArchiveResponse.kt b/app/src/main/java/awais/instagrabber/repositories/responses/stories/ArchiveResponse.kt new file mode 100644 index 00000000..d9c990dd --- /dev/null +++ b/app/src/main/java/awais/instagrabber/repositories/responses/stories/ArchiveResponse.kt @@ -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 +) \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/stories/Story.kt b/app/src/main/java/awais/instagrabber/repositories/responses/stories/Story.kt index 57f8b095..1b2df16c 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/stories/Story.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/stories/Story.kt @@ -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?, // 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 } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/viewmodels/ArchivesViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/ArchivesViewModel.java index 18802826..be70eac0 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/ArchivesViewModel.java +++ b/app/src/main/java/awais/instagrabber/viewmodels/ArchivesViewModel.java @@ -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; + private MutableLiveData> list; - public MutableLiveData> getList() { + public MutableLiveData> getList() { if (list == null) { list = new MutableLiveData<>(); } diff --git a/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt b/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt index d4f080cd..bc5b18ff 100644 --- a/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt +++ b/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt @@ -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 { 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 = 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 { @@ -248,12 +232,6 @@ open class StoriesRepository(private val service: StoriesService) { return listCopy } - class ArchiveFetchResponse(val result: List, val hasNextPage: Boolean, val nextCursor: String) { - fun hasNextPage(): Boolean { - return hasNextPage - } - } - companion object { @Volatile private var INSTANCE: StoriesRepository? = null From c326356accb9de24f359b0b770fb92a057a88194 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Tue, 29 Jun 2021 11:07:38 -0400 Subject: [PATCH 26/26] some story touch-ups --- .../java/awais/instagrabber/repositories/StoriesService.kt | 4 ++-- .../java/awais/instagrabber/webservices/StoriesRepository.kt | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt b/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt index f9190548..4d217fef 100644 --- a/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt +++ b/app/src/main/java/awais/instagrabber/repositories/StoriesService.kt @@ -11,10 +11,10 @@ interface StoriesService { suspend fun fetch(@Path("mediaId") mediaId: Long): String @GET("/api/v1/feed/reels_tray/") - suspend fun getFeedStories(): ReelsTrayResponse + suspend fun getFeedStories(): ReelsTrayResponse? @GET("/api/v1/highlights/{uid}/highlights_tray/") - suspend fun fetchHighlights(@Path("uid") uid: Long): ReelsTrayResponse + suspend fun fetchHighlights(@Path("uid") uid: Long): ReelsTrayResponse? @GET("/api/v1/archive/reel/day_shells/") suspend fun fetchArchive(@QueryMap queryParams: Map): ArchiveResponse? diff --git a/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt b/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt index bc5b18ff..6d82d70f 100644 --- a/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt +++ b/app/src/main/java/awais/instagrabber/webservices/StoriesRepository.kt @@ -26,8 +26,8 @@ open class StoriesRepository(private val service: StoriesService) { suspend fun getFeedStories(): List { val response = service.getFeedStories() - val result = response.tray?.toMutableList() ?: mutableListOf() - if (response.broadcasts != null) { + val result: MutableList = mutableListOf() + if (response?.broadcasts != null) { val length = response.broadcasts.size for (i in 0 until length) { val broadcast = response.broadcasts.get(i) @@ -49,6 +49,7 @@ open class StoriesRepository(private val service: StoriesService) { ) } } + if (response?.tray != null) result.addAll(response.tray) return sort(result.toList()) }