diff --git a/.idea/runConfigurations/app.xml b/.idea/runConfigurations/app.xml
index aeebe8e5..fe1ee5d0 100755
--- a/.idea/runConfigurations/app.xml
+++ b/.idea/runConfigurations/app.xml
@@ -45,7 +45,7 @@
-
+
diff --git a/app/build.gradle b/app/build.gradle
index 4e841c32..9eb639d7 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -5,13 +5,13 @@ android {
compileSdkVersion 29
defaultConfig {
- applicationId 'me.austinhuang.instagrabber'
+ applicationId 'me.austinhuang.instagrabbr'
minSdkVersion 16
targetSdkVersion 29
- versionCode 49
- versionName '18.3'
+ versionCode 50
+ versionName '19.0-a1'
multiDexEnabled true
@@ -37,19 +37,30 @@ android {
}
dependencies {
- implementation('androidx.appcompat:appcompat:1.3.0-alpha01@aar') { transitive true }
- implementation "androidx.recyclerview:recyclerview:1.1.0"
- implementation('com.google.android.material:material:1.3.0-alpha01@aar') { transitive true }
- implementation('androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-rc01') { transitive true }
-
+ def appcompat_version = "1.2.0"
def nav_version = "2.3.0"
+ def preference_version = "1.1.1"
+
+ implementation 'com.google.android.material:material:1.2.1'
+ implementation 'com.google.android.exoplayer:exoplayer:2.11.1'
+
+ implementation "androidx.appcompat:appcompat:$appcompat_version"
+ implementation "androidx.appcompat:appcompat-resources:$appcompat_version"
+ implementation "androidx.recyclerview:recyclerview:1.2.0-alpha05"
+ implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
+ implementation "androidx.viewpager2:viewpager2:1.0.0"
implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"
+ implementation "androidx.constraintlayout:constraintlayout:2.0.1"
+ implementation "androidx.preference:preference:$preference_version"
- annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
- implementation('org.jsoup:jsoup:1.13.1') { transitive true }
- implementation('com.github.bumptech.glide:glide:4.11.0') { transitive true }
- implementation('com.github.chrisbanes:PhotoView:v2.0.0@aar') { transitive true }
- implementation('com.google.android.exoplayer:exoplayer:2.11.1@aar') { transitive true }
+ implementation 'org.jsoup:jsoup:1.13.1'
+ implementation 'com.facebook.fresco:fresco:2.3.0'
+
+ implementation 'com.squareup.retrofit2:retrofit:2.9.0'
+ implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
+ implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
+
+ debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.4'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 1b29f327..23bc499b 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -8,18 +8,17 @@
-
@@ -29,18 +28,15 @@
-
-
-
-
+
+
-
@@ -49,18 +45,15 @@
-
-
-
-
-
-
@@ -121,7 +111,6 @@
-
@@ -131,96 +120,13 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:parentActivityName=".activities.MainActivity">
-
-
-
-
-
+ android:value=".activities.MainActivity" />
+
\ No newline at end of file
diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png
index 27d562c8..46241e2f 100644
Binary files a/app/src/main/ic_launcher-playstore.png and b/app/src/main/ic_launcher-playstore.png differ
diff --git a/app/src/main/java/awais/instagrabber/InstaApp.java b/app/src/main/java/awais/instagrabber/InstaGrabberApplication.java
old mode 100755
new mode 100644
similarity index 66%
rename from app/src/main/java/awais/instagrabber/InstaApp.java
rename to app/src/main/java/awais/instagrabber/InstaGrabberApplication.java
index 05cdce20..dbff1a60
--- a/app/src/main/java/awais/instagrabber/InstaApp.java
+++ b/app/src/main/java/awais/instagrabber/InstaGrabberApplication.java
@@ -4,9 +4,11 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.util.Log;
-import androidx.core.app.NotificationManagerCompat;
import androidx.multidex.MultiDexApplication;
+import com.facebook.drawee.backends.pipeline.Fresco;
+import com.facebook.imagepipeline.core.ImagePipelineConfig;
+
import java.net.CookieHandler;
import java.text.SimpleDateFormat;
import java.util.UUID;
@@ -18,28 +20,33 @@ import awais.instagrabber.utils.SettingsHelper;
import awaisomereport.CrashReporter;
import awaisomereport.LogCollector;
-import static awais.instagrabber.utils.Utils.NET_COOKIE_MANAGER;
+import static awais.instagrabber.utils.CookieUtils.NET_COOKIE_MANAGER;
import static awais.instagrabber.utils.Utils.clipboardManager;
import static awais.instagrabber.utils.Utils.dataBox;
import static awais.instagrabber.utils.Utils.datetimeParser;
-import static awais.instagrabber.utils.Utils.getInstalledTelegramPackage;
import static awais.instagrabber.utils.Utils.logCollector;
-import static awais.instagrabber.utils.Utils.notificationManager;
import static awais.instagrabber.utils.Utils.settingsHelper;
-import static awais.instagrabber.utils.Utils.telegramPackage;
-public final class InstaApp extends MultiDexApplication {
+public final class InstaGrabberApplication extends MultiDexApplication {
+ private static final String TAG = "InstaGrabberApplication";
+
@Override
public void onCreate() {
super.onCreate();
+ final ImagePipelineConfig imagePipelineConfig = ImagePipelineConfig
+ .newBuilder(this)
+ // .setMainDiskCacheConfig(diskCacheConfig)
+ .setDownsampleEnabled(true)
+ .build();
+ Fresco.initialize(this, imagePipelineConfig);
if (BuildConfig.DEBUG) {
try {
Class.forName("dalvik.system.CloseGuard")
- .getMethod("setEnabled", boolean.class)
- .invoke(null, true);
+ .getMethod("setEnabled", boolean.class)
+ .invoke(null, true);
} catch (Exception e) {
- Log.e("InstaApp", "Error", e);
+ Log.e(TAG, "Error", e);
}
}
@@ -50,8 +57,6 @@ public final class InstaApp extends MultiDexApplication {
final Context appContext = getApplicationContext();
- telegramPackage = getInstalledTelegramPackage(appContext);
-
if (dataBox == null)
dataBox = DataBox.getInstance(appContext);
@@ -60,17 +65,14 @@ public final class InstaApp extends MultiDexApplication {
LocaleUtils.setLocale(getBaseContext());
- if (notificationManager == null)
- notificationManager = NotificationManagerCompat.from(appContext);
-
if (clipboardManager == null)
clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
if (datetimeParser == null)
datetimeParser = new SimpleDateFormat(
settingsHelper.getBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED) ?
- settingsHelper.getString(Constants.CUSTOM_DATE_TIME_FORMAT) :
- settingsHelper.getString(Constants.DATE_TIME_FORMAT), LocaleUtils.getCurrentLocale());
+ settingsHelper.getString(Constants.CUSTOM_DATE_TIME_FORMAT) :
+ settingsHelper.getString(Constants.DATE_TIME_FORMAT), LocaleUtils.getCurrentLocale());
settingsHelper.putString(Constants.DEVICE_UUID, UUID.randomUUID().toString());
}
diff --git a/app/src/main/java/awais/instagrabber/MainHelper.java b/app/src/main/java/awais/instagrabber/MainHelper.java
deleted file mode 100755
index 8f7c4b47..00000000
--- a/app/src/main/java/awais/instagrabber/MainHelper.java
+++ /dev/null
@@ -1,1326 +0,0 @@
-package awais.instagrabber;
-
-import android.content.Intent;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Typeface;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.text.SpannableStringBuilder;
-import android.text.method.LinkMovementMethod;
-import android.text.style.RelativeSizeSpan;
-import android.text.style.StyleSpan;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.AlertDialog;
-import androidx.core.content.ContextCompat;
-import androidx.core.view.GravityCompat;
-import androidx.core.widget.ImageViewCompat;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-
-import com.google.android.exoplayer2.SimpleExoPlayer;
-
-import java.io.DataOutputStream;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Arrays;
-
-import awais.instagrabber.activities.FollowViewer;
-import awais.instagrabber.activities.Main;
-import awais.instagrabber.activities.PostViewer;
-import awais.instagrabber.activities.SavedViewer;
-import awais.instagrabber.activities.StoryViewer;
-import awais.instagrabber.adapters.DiscoverAdapter;
-import awais.instagrabber.adapters.FeedAdapter;
-import awais.instagrabber.adapters.FeedStoriesAdapter;
-import awais.instagrabber.adapters.PostsAdapter;
-import awais.instagrabber.asyncs.DiscoverFetcher;
-import awais.instagrabber.asyncs.FeedFetcher;
-import awais.instagrabber.asyncs.FeedStoriesFetcher;
-import awais.instagrabber.asyncs.HashtagFetcher;
-import awais.instagrabber.asyncs.HighlightsFetcher;
-import awais.instagrabber.asyncs.LocationFetcher;
-import awais.instagrabber.asyncs.PostsFetcher;
-import awais.instagrabber.asyncs.ProfileFetcher;
-import awais.instagrabber.asyncs.i.iStoryStatusFetcher;
-import awais.instagrabber.asyncs.i.iTopicFetcher;
-import awais.instagrabber.customviews.MouseDrawer;
-import awais.instagrabber.customviews.RamboTextView;
-import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager;
-import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
-import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
-import awais.instagrabber.customviews.helpers.VideoAwareRecyclerScroller;
-import awais.instagrabber.interfaces.FetchListener;
-import awais.instagrabber.interfaces.MentionClickListener;
-import awais.instagrabber.models.BasePostModel;
-import awais.instagrabber.models.DiscoverItemModel;
-import awais.instagrabber.models.DiscoverTopicModel;
-import awais.instagrabber.models.FeedModel;
-import awais.instagrabber.models.FeedStoryModel;
-import awais.instagrabber.models.IntentModel;
-import awais.instagrabber.models.PostModel;
-import awais.instagrabber.models.enums.IntentModelType;
-import awais.instagrabber.models.enums.ItemGetType;
-import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.DataBox;
-import awais.instagrabber.utils.Utils;
-import awaisomereport.LogCollector;
-
-import static awais.instagrabber.utils.Constants.AUTOLOAD_POSTS;
-import static awais.instagrabber.utils.Constants.BOTTOM_TOOLBAR;
-import static awais.instagrabber.utils.Utils.logCollector;
-import static awais.instagrabber.utils.Utils.settingsHelper;
-
-public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
- private static AsyncTask, ?, ?> currentlyExecuting;
- private AsyncTask prevStoriesFetcher;
- private final boolean autoloadPosts;
- private FeedStoryModel[] stories;
- private boolean hasNextPage = false, feedHasNextPage = false, discoverHasMore = false;
- private String endCursor = null, feedEndCursor = null, discoverEndMaxId = null, topic = null, rankToken = null;
- private String[] topicIds = null;
- private final FetchListener postsFetchListener = new FetchListener() {
- @Override
- public void onResult(final PostModel[] result) {
- if (result != null) {
- final int oldSize = main.allItems.size();
- main.allItems.addAll(Arrays.asList(result));
-
- postsAdapter.notifyItemRangeInserted(oldSize, result.length);
-
- main.mainBinding.profileView.mainPosts.post(() -> {
- main.mainBinding.profileView.mainPosts.setNestedScrollingEnabled(true);
- main.mainBinding.profileView.mainPosts.setVisibility(View.VISIBLE);
- });
-
- if (isHashtag)
- main.mainBinding.toolbar.toolbar.setTitle(main.userQuery);
- else if (isLocation)
- main.mainBinding.toolbar.toolbar.setTitle(main.locationModel.getName());
- else main.mainBinding.toolbar.toolbar.setTitle("@"+main.profileModel.getUsername());
-
- final PostModel model = result[result.length - 1];
- if (model != null) {
- endCursor = model.getEndCursor();
- hasNextPage = model.hasNextPage();
- if (autoloadPosts && hasNextPage)
- currentlyExecuting = new PostsFetcher(
- main.profileModel != null ? main.profileModel.getId()
- : (main.hashtagModel != null ? main.userQuery : main.locationModel.getId()), endCursor, this)
- .setUsername((isLocation || isHashtag) ? null : main.profileModel.getUsername())
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- else {
- main.mainBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- }
- model.setPageCursor(false, null);
- }
- }
- else {
- main.mainBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- main.mainBinding.profileView.privatePage1.setImageResource(R.drawable.ic_cancel);
- main.mainBinding.profileView.privatePage2.setText(R.string.empty_acc);
- main.mainBinding.profileView.privatePage.setVisibility(View.VISIBLE);
- }
- }
- };
- private final FetchListener feedFetchListener = new FetchListener() {
- @Override
- public void doBefore() {
- main.mainBinding.feedView.feedSwipeRefreshLayout.post(() -> main.mainBinding.feedView.feedSwipeRefreshLayout.setRefreshing(true));
- }
-
- @Override
- public void onResult(final FeedModel[] result) {
- if (result != null) {
- final int oldSize = main.feedItems.size();
- main.feedItems.addAll(Arrays.asList(result));
- feedAdapter.notifyItemRangeInserted(oldSize, result.length);
-
- main.mainBinding.feedView.feedPosts.post(() -> main.mainBinding.feedView.feedPosts.setNestedScrollingEnabled(true));
-
- final PostModel feedPostModel = result[result.length - 1];
- if (feedPostModel != null) {
- feedEndCursor = feedPostModel.getEndCursor();
- feedHasNextPage = feedPostModel.hasNextPage();
- feedPostModel.setPageCursor(false, null);
- }
- }
-
- main.mainBinding.feedView.feedSwipeRefreshLayout.setRefreshing(false);
- }
- };
- private final FetchListener discoverFetchListener = new FetchListener() {
- @Override
- public void doBefore() {
- main.mainBinding.discoverSwipeRefreshLayout.setRefreshing(true);
- }
-
- @Override
- public void onResult(final DiscoverItemModel[] result) {
- if (result == null || result.length == 0) {
- Toast.makeText(main, R.string.discover_empty, Toast.LENGTH_SHORT).show();
- }
- else if (result != null) {
- final int oldSize = main.discoverItems.size();
- main.discoverItems.addAll(Arrays.asList(result));
- discoverAdapter.notifyItemRangeInserted(oldSize, result.length);
-
- final DiscoverItemModel discoverItemModel = result[result.length - 1];
- if (discoverItemModel != null) {
- discoverEndMaxId = discoverItemModel.getNextMaxId();
- discoverHasMore = discoverItemModel.hasMore();
- discoverItemModel.setMore(false, null);
- }
- }
-
- main.mainBinding.discoverSwipeRefreshLayout.setRefreshing(false);
- }
- };
- private final FetchListener topicFetchListener = new FetchListener() {
- @Override
- public void doBefore() {}
-
- @Override
- public void onResult(final DiscoverTopicModel result) {
- if (result != null) {
- topicIds = result.getIds();
- rankToken = result.getToken();
- ArrayAdapter spinnerArrayAdapter = new ArrayAdapter(
- main, android.R.layout.simple_spinner_dropdown_item, result.getNames() );
- main.mainBinding.discoverType.setAdapter(spinnerArrayAdapter);
- }
- }
- };
- private final FetchListener feedStoriesListener = new FetchListener() {
- @Override
- public void doBefore() {
- main.mainBinding.feedView.feedStories.setVisibility(View.GONE);
- }
-
- @Override
- public void onResult(final FeedStoryModel[] result) {
- feedStoriesAdapter.setData(result);
- if (result != null && result.length > 0) {
- main.mainBinding.feedView.feedStories.setVisibility(View.VISIBLE);
- stories = result;
- }
- }
- };
- private final MentionClickListener mentionClickListener = new MentionClickListener() {
- @Override
- public void onClick(final RamboTextView view, final String text, final boolean isHashtag) {
- new AlertDialog.Builder(main).setMessage(isHashtag ? R.string.comment_view_mention_hash_search : R.string.comment_view_mention_user_search)
- .setTitle(text).setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.ok, (dialog, which) -> {
- if (Main.scanHack != null) Main.scanHack.onResult(text);
- }).show();
- }
- };
- private final FeedStoriesAdapter feedStoriesAdapter = new FeedStoriesAdapter(null, new View.OnClickListener() {
- @Override
- public void onClick(final View v) {
- final Object tag = v.getTag();
- if (tag instanceof FeedStoryModel) {
- final FeedStoryModel feedStoryModel = (FeedStoryModel) tag;
- final int index = indexOfIntArray(stories, feedStoryModel);
- new iStoryStatusFetcher(feedStoryModel.getStoryMediaId(), null, false, false, false, false, result -> {
- if (result != null && result.length > 0)
- main.startActivity(new Intent(main, StoryViewer.class)
- .putExtra(Constants.EXTRAS_STORIES, result)
- .putExtra(Constants.EXTRAS_USERNAME, feedStoryModel.getProfileModel().getUsername())
- .putExtra(Constants.FEED, stories)
- .putExtra(Constants.FEED_ORDER, index)
- );
- else Toast.makeText(main, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
- });
- @NonNull
- private final Main main;
- private Resources resources;
- private final View collapsingToolbar;
- private final RecyclerLazyLoader lazyLoader;
- private boolean isHashtag, isUser, isLocation;
- private PostsAdapter postsAdapter;
- private FeedAdapter feedAdapter;
- private RecyclerLazyLoader feedLazyLoader, discoverLazyLoader;
- private DiscoverAdapter discoverAdapter;
- public SimpleExoPlayer currentFeedPlayer; // hack for remix drawer layout
- private String cookie = settingsHelper.getString(Constants.COOKIE);
- public boolean isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null;
-
- public MainHelper(@NonNull final Main main) {
- stopCurrentExecutor();
-
- this.main = main;
- this.resources = main.getResources();
- this.autoloadPosts = settingsHelper.getBoolean(AUTOLOAD_POSTS);
-
- main.mainBinding.profileView.swipeRefreshLayout.setOnRefreshListener(this);
- main.mainBinding.profileView.mainUrl.setMovementMethod(new LinkMovementMethod());
-
- final LinearLayout iconSlider = main.findViewById(R.id.iconSlider);
- final ImageView iconFeed = (ImageView) iconSlider.getChildAt(0);
- final ImageView iconProfile = (ImageView) iconSlider.getChildAt(1);
- final ImageView iconDiscover = (ImageView) iconSlider.getChildAt(2);
-
- final boolean isBottomToolbar = settingsHelper.getBoolean(BOTTOM_TOOLBAR);
- isLoggedIn = !Utils.isEmpty(cookie);
- if (!isLoggedIn) {
- main.mainBinding.drawerLayout.removeView(main.mainBinding.feedView.feedLayout);
- main.mainBinding.drawerLayout.removeView(main.mainBinding.discoverLayout);
- iconFeed.setAlpha(0.4f);
- iconDiscover.setAlpha(0.4f);
- } else {
- iconFeed.setAlpha(1f);
- iconDiscover.setAlpha(1f);
-
- setupExplore();
-
- setupFeed();
-
- final TypedValue resolvedAttr = new TypedValue();
- main.getTheme().resolveAttribute(android.R.attr.textColorPrimary, resolvedAttr, true);
-
- final int selectedItem = ContextCompat.getColor(main, resolvedAttr.resourceId != 0 ? resolvedAttr.resourceId : resolvedAttr.data);
- final ColorStateList colorStateList = ColorStateList.valueOf(selectedItem);
-
- main.mainBinding.toolbar.toolbar.measure(0, -1);
- final int toolbarMeasuredHeight = main.mainBinding.toolbar.toolbar.getMeasuredHeight();
-
- final ViewGroup.LayoutParams layoutParams = main.mainBinding.toolbar.toolbar.getLayoutParams();
- final MouseDrawer.DrawerListener simpleDrawerListener = new MouseDrawer.DrawerListener() {
- private final String titleDiscover = resources.getString(R.string.title_discover);
-
- @Override
- public void onDrawerSlide(final View drawerView, @MouseDrawer.EdgeGravity final int gravity, final float slideOffset) {
- final int currentIconAlpha = (int) Math.max(100, 255 - 255 * slideOffset);
- final int otherIconAlpha = (int) Math.max(100, 255 * slideOffset);
-
- ImageViewCompat.setImageTintList(iconProfile, colorStateList.withAlpha(currentIconAlpha));
-
- final boolean drawerOpening = slideOffset > 0.0f;
- final int alpha;
- final ColorStateList imageTintList;
-
- if (gravity == GravityCompat.START) {
- // this helps hide the toolbar when opening feed
-
- final int roundedToolbarHeight;
- final float toolbarHeight;
-
- if (isBottomToolbar) {
- toolbarHeight = toolbarMeasuredHeight * slideOffset;
- roundedToolbarHeight = -Math.round(toolbarHeight);
- } else {
- toolbarHeight = -toolbarMeasuredHeight * slideOffset;
- roundedToolbarHeight = Math.round(toolbarHeight);
- }
-
- layoutParams.height = Math.max(0, Math.min(toolbarMeasuredHeight, toolbarMeasuredHeight + roundedToolbarHeight));
- main.mainBinding.toolbar.toolbar.setLayoutParams(layoutParams);
- main.mainBinding.toolbar.toolbar.setTranslationY(toolbarHeight);
-
- imageTintList = ImageViewCompat.getImageTintList(iconDiscover);
- alpha = imageTintList != null ? (imageTintList.getDefaultColor() & 0xFF_000000) >> 24 : 0;
-
- if (drawerOpening && alpha > 100)
- ImageViewCompat.setImageTintList(iconDiscover, colorStateList.withAlpha(currentIconAlpha));
-
- ImageViewCompat.setImageTintList(iconFeed, colorStateList.withAlpha(otherIconAlpha));
- } else {
- // this changes toolbar title
- main.mainBinding.toolbar.toolbar.setTitle(slideOffset >= 0.466 ? titleDiscover :
- (main.userQuery == null ? resources.getString(R.string.app_name) : main.userQuery));
-
- imageTintList = ImageViewCompat.getImageTintList(iconFeed);
- alpha = imageTintList != null ? (imageTintList.getDefaultColor() & 0xFF_000000) >> 24 : 0;
-
- if (drawerOpening && alpha > 100)
- ImageViewCompat.setImageTintList(iconFeed, colorStateList.withAlpha(currentIconAlpha));
-
- ImageViewCompat.setImageTintList(iconDiscover, colorStateList.withAlpha(otherIconAlpha));
- }
- }
-
- @Override
- public void onDrawerOpened(@NonNull final View drawerView, @MouseDrawer.EdgeGravity final int gravity) {
- if (gravity == GravityCompat.START || drawerView == main.mainBinding.feedView.feedLayout) {
- if (currentFeedPlayer != null) {
- final boolean shouldAutoplay = settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS);
- currentFeedPlayer.setPlayWhenReady(shouldAutoplay);
- }
- } else {
- // clear selection
- isSelectionCleared();
- }
- }
-
- @Override
- public void onDrawerClosed(@NonNull final View drawerView, @MouseDrawer.EdgeGravity final int gravity) {
- if (gravity == GravityCompat.START || drawerView == main.mainBinding.feedView.feedLayout) {
- if (currentFeedPlayer != null) {
- currentFeedPlayer.setPlayWhenReady(false);
- }
- } else {
- // clear selection
- isSelectionCleared();
- }
- }
- };
-
- ImageViewCompat.setImageTintList(iconFeed, colorStateList.withAlpha(100)); // to change colors when created
- ImageViewCompat.setImageTintList(iconProfile, colorStateList.withAlpha(255)); // to change colors when created
- ImageViewCompat.setImageTintList(iconDiscover, colorStateList.withAlpha(100)); // to change colors when created
-
- main.mainBinding.drawerLayout.addDrawerListener(simpleDrawerListener);
- }
-
- collapsingToolbar = main.mainBinding.profileView.appBarLayout.getChildAt(0);
-
- main.mainBinding.profileView.mainPosts.setNestedScrollingEnabled(false);
- main.mainBinding.profileView.highlightsList.setLayoutManager(new LinearLayoutManager(main, LinearLayoutManager.HORIZONTAL, false));
- main.mainBinding.profileView.highlightsList.setAdapter(main.highlightsAdapter);
-
- // int color = -1;
- // final Drawable background = main.mainBinding.profileView.appBarLayout.getBackground();
- // if (background instanceof MaterialShapeDrawable) {
- // final MaterialShapeDrawable drawable = (MaterialShapeDrawable) background;
- // final ColorStateList fillColor = drawable.getFillColor();
- // if (fillColor != null) color = fillColor.getDefaultColor();
- // } else {
- // final Bitmap bitmap = Bitmap.createBitmap(9, 9, Bitmap.Config.ARGB_8888);
- // final Canvas canvas = new Canvas();
- // canvas.setBitmap(bitmap);
- // background.draw(canvas);
- // color = bitmap.getPixel(4, 4);
- // if (!bitmap.isRecycled()) bitmap.recycle();
- // }
- // if (color == -1 || color == 0) color = resources.getBoolean(R.bool.isNight) ? 0xff212121 : 0xfff5f5f5;
- // main.mainBinding.profileView.profileInfo.setBackgroundColor(color);
- // if (!isBottomToolbar) main.mainBinding.toolbar.toolbar.setBackgroundColor(color);
-
- // main.mainBinding.profileView.appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
- // private int height;
- //
- // @Override
- // public void onOffsetChanged(final AppBarLayout appBarLayout, final int verticalOffset) {
- // if (height == 0) {
- // height = main.mainBinding.profileView.profileInfo.getHeight();
- // collapsingToolbar.setMinimumHeight(height);
- // }
- // main.mainBinding.profileView.profileInfo.setTranslationY(-Math.min(0, verticalOffset));
- // }
- // });
-
- main.setSupportActionBar(main.mainBinding.toolbar.toolbar);
- if (isBottomToolbar) {
- final LinearLayout linearLayout = (LinearLayout) main.mainBinding.toolbar.toolbar.getParent();
- linearLayout.removeView(main.mainBinding.toolbar.toolbar);
- linearLayout.addView(main.mainBinding.toolbar.toolbar, linearLayout.getChildCount());
- }
-
- // change the next number to adjust grid
- final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(main, Utils.convertDpToPx(110));
- main.mainBinding.profileView.mainPosts.setLayoutManager(layoutManager);
- main.mainBinding.profileView.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4)));
- main.mainBinding.profileView.mainPosts.setAdapter(postsAdapter = new PostsAdapter(main.allItems, v -> {
- final Object tag = v.getTag();
- if (tag instanceof PostModel) {
- final PostModel postModel = (PostModel) tag;
-
- if (postsAdapter.isSelecting) toggleSelection(postModel);
- else main.startActivity(new Intent(main, PostViewer.class)
- .putExtra(Constants.EXTRAS_INDEX, postModel.getPosition())
- .putExtra(Constants.EXTRAS_POST, postModel)
- .putExtra(Constants.EXTRAS_USER, main.userQuery)
- .putExtra(Constants.EXTRAS_TYPE, ItemGetType.MAIN_ITEMS));
- }
- }, v -> { // long click listener
- final Object tag = v.getTag();
- if (tag instanceof PostModel) {
- postsAdapter.isSelecting = true;
- toggleSelection((PostModel) tag);
- }
- return true;
- }));
-
- this.lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
- if ((!autoloadPosts || isHashtag) && hasNextPage) {
- main.mainBinding.profileView.swipeRefreshLayout.setRefreshing(true);
- stopCurrentExecutor();
- currentlyExecuting = new PostsFetcher(main.profileModel != null ? main.profileModel.getId()
- : (main.hashtagModel != null ? main.userQuery : main.locationModel.getId()), endCursor, postsFetchListener)
- .setUsername((isHashtag || isLocation) ? null : main.profileModel.getUsername())
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- endCursor = null;
- }
- });
- main.mainBinding.profileView.mainPosts.addOnScrollListener(lazyLoader);
- }
-
- private void setupFeed() {
- main.mainBinding.feedView.feedStories.setLayoutManager(new LinearLayoutManager(main, LinearLayoutManager.HORIZONTAL, false));
- main.mainBinding.feedView.feedStories.setAdapter(feedStoriesAdapter);
- refreshFeedStories();
-
- final LinearLayoutManager layoutManager = new LinearLayoutManager(main);
- main.mainBinding.feedView.feedPosts.setLayoutManager(layoutManager);
- main.mainBinding.feedView.feedPosts.setAdapter(feedAdapter = new FeedAdapter(main, main.feedItems, (view, text, isHashtag) ->
- new AlertDialog.Builder(main).setMessage(isHashtag ? R.string.comment_view_mention_hash_search : R.string.comment_view_mention_user_search)
- .setTitle(text).setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.ok, (dialog, which) -> {
- if (Main.scanHack != null) {
- main.mainBinding.drawerLayout.closeDrawers();
- Main.scanHack.onResult(text);
- }
- }).show()));
-
- main.mainBinding.feedView.feedSwipeRefreshLayout.setOnRefreshListener(() -> {
- refreshFeedStories();
-
- if (feedLazyLoader != null) feedLazyLoader.resetState();
- main.feedItems.clear();
- if (feedAdapter != null) feedAdapter.notifyDataSetChanged();
- new FeedFetcher(feedFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- });
-
- main.mainBinding.feedView.feedPosts.addOnScrollListener(feedLazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
- if (feedHasNextPage) {
- main.mainBinding.feedView.feedSwipeRefreshLayout.setRefreshing(true);
- new FeedFetcher(feedEndCursor, feedFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- feedEndCursor = null;
- }
- }));
-
- main.mainBinding.feedView.feedPosts.addOnScrollListener(new VideoAwareRecyclerScroller(main, main.feedItems,
- (itemPos, player) -> currentFeedPlayer = player));
-
- new FeedFetcher(feedFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- private void refreshFeedStories() {
- // todo setup feed stories
- if (prevStoriesFetcher != null) {
- try {
- prevStoriesFetcher.cancel(true);
- } catch (final Exception e) {
- // ignore
- }
- }
- prevStoriesFetcher = new FeedStoriesFetcher(feedStoriesListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- private void setupExplore() {
- final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(main, Utils.convertDpToPx(110));
- main.mainBinding.discoverPosts.setLayoutManager(layoutManager);
- main.mainBinding.discoverPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4)));
-
- new iTopicFetcher(topicFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- main.mainBinding.discoverType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView> parent, View view, int pos, long id) {
- if (topicIds != null) {
- topic = topicIds[pos];
- main.mainBinding.discoverSwipeRefreshLayout.setRefreshing(true);
- if (discoverLazyLoader != null) discoverLazyLoader.resetState();
- main.discoverItems.clear();
- if (discoverAdapter != null) discoverAdapter.notifyDataSetChanged();
- new DiscoverFetcher(topic, null, rankToken, discoverFetchListener, false).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView> parent) {
- }
- });
-
- main.mainBinding.discoverSwipeRefreshLayout.setOnRefreshListener(() -> {
- if (discoverLazyLoader != null) discoverLazyLoader.resetState();
- main.discoverItems.clear();
- if (discoverAdapter != null) discoverAdapter.notifyDataSetChanged();
- new DiscoverFetcher(topic, null, rankToken, discoverFetchListener, false).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- });
-
- main.mainBinding.discoverPosts.setAdapter(discoverAdapter = new DiscoverAdapter(main.discoverItems, v -> {
- final Object tag = v.getTag();
- if (tag instanceof DiscoverItemModel) {
- final DiscoverItemModel itemModel = (DiscoverItemModel) tag;
-
- if (discoverAdapter.isSelecting) toggleDiscoverSelection(itemModel);
- else main.startActivity(new Intent(main, PostViewer.class)
- .putExtra(Constants.EXTRAS_INDEX, itemModel.getPosition())
- .putExtra(Constants.EXTRAS_TYPE, ItemGetType.DISCOVER_ITEMS)
- .putExtra(Constants.EXTRAS_POST, new PostModel(itemModel.getShortCode(), false)));
- }
- }, v -> {
- final Object tag = v.getTag();
- if (tag instanceof DiscoverItemModel) {
- discoverAdapter.isSelecting = true;
- toggleDiscoverSelection((DiscoverItemModel) tag);
- }
- return true;
- }));
-
- main.mainBinding.discoverPosts.addOnScrollListener(discoverLazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
- if (discoverHasMore) {
- main.mainBinding.discoverSwipeRefreshLayout.setRefreshing(true);
- new DiscoverFetcher(topic, discoverEndMaxId, rankToken, discoverFetchListener, false).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- discoverEndMaxId = null;
- }
- }));
- }
-
- public void onIntent(final Intent intent) {
- if (intent != null) {
- final String action = intent.getAction();
- if (!Utils.isEmpty(action) && !Intent.ACTION_MAIN.equals(action)) {
- intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
-
- boolean error = true;
-
- String data = null;
- final Bundle extras = intent.getExtras();
- if (extras != null) {
- final Object extraData = extras.get(Intent.EXTRA_TEXT);
- if (extraData != null) {
- error = false;
- data = extraData.toString();
- }
- }
-
- if (error) {
- final Uri intentData = intent.getData();
- if (intentData != null) data = intentData.toString();
- }
-
- if (data != null && !Utils.isEmpty(data)) {
- if (data.indexOf('\n') > 0) data = data.substring(data.lastIndexOf('\n') + 1);
-
- final IntentModel model = Utils.stripString(data);
- if (model != null) {
- final String modelText = model.getText();
- final IntentModelType modelType = model.getType();
-
- if (modelType == IntentModelType.POST) {
- main.startActivityForResult(new Intent(main, PostViewer.class)
- .putExtra(Constants.EXTRAS_USER, main.userQuery)
- .putExtra(Constants.EXTRAS_POST, new PostModel(modelText, false)), 9629);
- } else {
- main.addToStack();
- main.userQuery = modelType == IntentModelType.HASHTAG ? ('#' + modelText) :
- (modelType == IntentModelType.LOCATION ? modelText : ('@'+modelText));
- onRefresh();
- }
- }
- }
- }
- }
- }
-
- @Override
- public void onRefresh() {
- main.mainBinding.drawerLayout.closeDrawers();
- if (lazyLoader != null) lazyLoader.resetState();
- stopCurrentExecutor();
- main.allItems.clear();
- main.selectedItems.clear();
- if (postsAdapter != null) {
- postsAdapter.isSelecting = false;
- postsAdapter.notifyDataSetChanged();
- }
- main.mainBinding.profileView.appBarLayout.setExpanded(true, true);
- main.mainBinding.profileView.privatePage.setVisibility(View.GONE);
- main.mainBinding.profileView.privatePage2.setTextSize(28);
- main.mainBinding.profileView.mainProfileImage.setImageBitmap(null);
- main.mainBinding.profileView.mainHashtagImage.setImageBitmap(null);
- main.mainBinding.profileView.mainLocationImage.setImageBitmap(null);
- main.mainBinding.profileView.mainUrl.setText(null);
- main.mainBinding.profileView.locationUrl.setText(null);
- main.mainBinding.profileView.mainFullName.setText(null);
- main.mainBinding.profileView.locationFullName.setText(null);
- main.mainBinding.profileView.mainPostCount.setText(null);
- main.mainBinding.profileView.mainLocPostCount.setText(null);
- main.mainBinding.profileView.mainTagPostCount.setText(null);
- main.mainBinding.profileView.mainFollowers.setText(null);
- main.mainBinding.profileView.mainFollowing.setText(null);
- main.mainBinding.profileView.mainBiography.setText(null);
- main.mainBinding.profileView.locationBiography.setText(null);
- main.mainBinding.profileView.mainBiography.setEnabled(false);
- main.mainBinding.profileView.locationBiography.setEnabled(false);
- main.mainBinding.profileView.mainProfileImage.setEnabled(false);
- main.mainBinding.profileView.mainLocationImage.setEnabled(false);
- main.mainBinding.profileView.mainHashtagImage.setEnabled(false);
- main.mainBinding.profileView.mainBiography.setMentionClickListener(null);
- main.mainBinding.profileView.locationBiography.setMentionClickListener(null);
- main.mainBinding.profileView.mainUrl.setVisibility(View.GONE);
- main.mainBinding.profileView.locationUrl.setVisibility(View.GONE);
- main.mainBinding.profileView.isVerified.setVisibility(View.GONE);
- main.mainBinding.profileView.btnFollow.setVisibility(View.GONE);
- main.mainBinding.profileView.btnRestrict.setVisibility(View.GONE);
- main.mainBinding.profileView.btnBlock.setVisibility(View.GONE);
- main.mainBinding.profileView.btnSaved.setVisibility(View.GONE);
- main.mainBinding.profileView.btnLiked.setVisibility(View.GONE);
- main.mainBinding.profileView.btnTagged.setVisibility(View.GONE);
- main.mainBinding.profileView.btnMap.setVisibility(View.GONE);
-
- main.mainBinding.profileView.btnFollow.setOnClickListener(profileActionListener);
- main.mainBinding.profileView.btnRestrict.setOnClickListener(profileActionListener);
- main.mainBinding.profileView.btnBlock.setOnClickListener(profileActionListener);
- main.mainBinding.profileView.btnSaved.setOnClickListener(profileActionListener);
- main.mainBinding.profileView.btnLiked.setOnClickListener(profileActionListener);
- main.mainBinding.profileView.btnTagged.setOnClickListener(profileActionListener);
- main.mainBinding.profileView.btnFollowTag.setOnClickListener(profileActionListener);
-
- main.mainBinding.profileView.infoContainer.setVisibility(View.GONE);
- main.mainBinding.profileView.tagInfoContainer.setVisibility(View.GONE);
- main.mainBinding.profileView.locInfoContainer.setVisibility(View.GONE);
-
- main.mainBinding.profileView.mainPosts.setNestedScrollingEnabled(false);
- main.mainBinding.profileView.highlightsList.setVisibility(View.GONE);
- collapsingToolbar.setVisibility(View.GONE);
- main.highlightsAdapter.setData(null);
-
- main.mainBinding.profileView.swipeRefreshLayout.setRefreshing(main.userQuery != null);
- if (main.userQuery == null) {
- main.mainBinding.toolbar.toolbar.setTitle(R.string.app_name);
- return;
- }
-
- isHashtag = main.userQuery.charAt(0) == '#';
- isUser = main.userQuery.charAt(0) == '@';
- isLocation = main.userQuery.contains("/");
- collapsingToolbar.setVisibility(isUser ? View.VISIBLE : View.GONE);
-
- if (isHashtag) {
- main.profileModel = null;
- main.locationModel = null;
- main.mainBinding.toolbar.toolbar.setTitle(main.userQuery);
- main.mainBinding.profileView.tagInfoContainer.setVisibility(View.VISIBLE);
- main.mainBinding.profileView.btnFollowTag.setVisibility(View.GONE);
-
- currentlyExecuting = new HashtagFetcher(main.userQuery.substring(1), hashtagModel -> {
- main.hashtagModel = hashtagModel;
-
- if (hashtagModel == null) {
- main.mainBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- Toast.makeText(main, R.string.error_loading_profile, Toast.LENGTH_SHORT).show();
- main.mainBinding.toolbar.toolbar.setTitle(R.string.app_name);
- return;
- }
-
- currentlyExecuting = new PostsFetcher(main.userQuery, postsFetchListener)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-
- main.mainBinding.profileView.btnFollowTag.setVisibility(View.VISIBLE);
-
- if (isLoggedIn) {
- new iStoryStatusFetcher(hashtagModel.getName(), null, false, true, false, false, result -> {
- main.storyModels = result;
- if (result != null && result.length > 0) main.mainBinding.profileView.mainHashtagImage.setStoriesBorder();
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-
- if (hashtagModel.getFollowing() == true) {
- main.mainBinding.profileView.btnFollowTag.setText(R.string.unfollow);
- main.mainBinding.profileView.btnFollowTag.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_purple_background)));
- }
- else {
- main.mainBinding.profileView.btnFollowTag.setText(R.string.follow);
- main.mainBinding.profileView.btnFollowTag.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_pink_background)));
- }
- } else {
- if (Utils.dataBox.getFavorite(main.userQuery) != null) {
- main.mainBinding.profileView.btnFollowTag.setText(R.string.unfavorite_short);
- main.mainBinding.profileView.btnFollowTag.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_purple_background)));
- }
- else {
- main.mainBinding.profileView.btnFollowTag.setText(R.string.favorite_short);
- main.mainBinding.profileView.btnFollowTag.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_pink_background)));
- }
- }
-
- main.mainBinding.profileView.mainHashtagImage.setEnabled(false);
- new MyTask().execute();
- main.mainBinding.profileView.mainHashtagImage.setEnabled(true);
-
- final String postCount = String.valueOf(hashtagModel.getPostCount());
-
- SpannableStringBuilder span = new SpannableStringBuilder(resources.getString(R.string.main_posts_count, postCount));
- span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
- span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
- main.mainBinding.profileView.mainTagPostCount.setText(span);
- main.mainBinding.profileView.mainTagPostCount.setVisibility(View.VISIBLE);
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- } else if (isUser) {
- main.hashtagModel = null;
- main.locationModel = null;
- main.mainBinding.toolbar.toolbar.setTitle(main.userQuery);
- main.mainBinding.profileView.infoContainer.setVisibility(View.VISIBLE);
- main.mainBinding.profileView.btnFollowTag.setVisibility(View.GONE);
-
- currentlyExecuting = new ProfileFetcher(main.userQuery.substring(1), profileModel -> {
- main.profileModel = profileModel;
-
- if (profileModel == null) {
- main.mainBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- Toast.makeText(main, R.string.error_loading_profile, Toast.LENGTH_SHORT).show();
- main.mainBinding.toolbar.toolbar.setTitle(R.string.app_name);
- return;
- }
-
- main.mainBinding.profileView.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE);
- final String profileId = profileModel.getId();
-
- if (isLoggedIn || settingsHelper.getBoolean(Constants.STORIESIG)) {
- new iStoryStatusFetcher(profileId, profileModel.getUsername(), false, false,
- (!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)), false,
- result -> {
- main.storyModels = result;
- if (result != null && result.length > 0) main.mainBinding.profileView.mainProfileImage.setStoriesBorder();
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-
- new HighlightsFetcher(profileId, (!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)), result -> {
- if (result != null && result.length > 0) {
- main.mainBinding.profileView.highlightsList.setVisibility(View.VISIBLE);
- main.highlightsAdapter.setData(result);
- }
- else main.mainBinding.profileView.highlightsList.setVisibility(View.GONE);
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- if (isLoggedIn) {
- final String myId = Utils.getUserIdFromCookie(cookie);
- if (!profileId.equals(myId)) {
- main.mainBinding.profileView.btnTagged.setVisibility(View.GONE);
- main.mainBinding.profileView.btnSaved.setVisibility(View.GONE);
- main.mainBinding.profileView.btnLiked.setVisibility(View.GONE);
- main.mainBinding.profileView.btnFollow.setVisibility(View.VISIBLE);
- if (profileModel.getFollowing() == true) {
- main.mainBinding.profileView.btnFollow.setText(R.string.unfollow);
- main.mainBinding.profileView.btnFollow.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_purple_background)));
- }
- else if (profileModel.getRequested() == true) {
- main.mainBinding.profileView.btnFollow.setText(R.string.cancel);
- main.mainBinding.profileView.btnFollow.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_purple_background)));
- }
- else {
- main.mainBinding.profileView.btnFollow.setText(R.string.follow);
- main.mainBinding.profileView.btnFollow.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_pink_background)));
- }
- main.mainBinding.profileView.btnRestrict.setVisibility(View.VISIBLE);
- if (profileModel.getRestricted() == true) {
- main.mainBinding.profileView.btnRestrict.setText(R.string.unrestrict);
- main.mainBinding.profileView.btnRestrict.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_green_background)));
- }
- else {
- main.mainBinding.profileView.btnRestrict.setText(R.string.restrict);
- main.mainBinding.profileView.btnRestrict.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_orange_background)));
- }
- if (profileModel.isReallyPrivate()) {
- main.mainBinding.profileView.btnBlock.setVisibility(View.VISIBLE);
- main.mainBinding.profileView.btnTagged.setVisibility(View.GONE);
- if (profileModel.getBlocked() == true) {
- main.mainBinding.profileView.btnBlock.setText(R.string.unblock);
- main.mainBinding.profileView.btnBlock.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_green_background)));
- } else {
- main.mainBinding.profileView.btnBlock.setText(R.string.block);
- main.mainBinding.profileView.btnBlock.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_red_background)));
- }
- } else {
- main.mainBinding.profileView.btnBlock.setVisibility(View.GONE);
- main.mainBinding.profileView.btnSaved.setVisibility(View.VISIBLE);
- main.mainBinding.profileView.btnTagged.setVisibility(View.VISIBLE);
- if (profileModel.getBlocked() == true) {
- main.mainBinding.profileView.btnSaved.setText(R.string.unblock);
- main.mainBinding.profileView.btnSaved.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_green_background)));
- } else {
- main.mainBinding.profileView.btnSaved.setText(R.string.block);
- main.mainBinding.profileView.btnSaved.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_red_background)));
- }
- }
- }
- else {
- main.mainBinding.profileView.btnTagged.setVisibility(View.VISIBLE);
- main.mainBinding.profileView.btnSaved.setVisibility(View.VISIBLE);
- main.mainBinding.profileView.btnLiked.setVisibility(View.VISIBLE);
- main.mainBinding.profileView.btnSaved.setText(R.string.saved);
- main.mainBinding.profileView.btnSaved.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_orange_background)));
- }
- } else {
- if (Utils.dataBox.getFavorite(main.userQuery) != null) {
- main.mainBinding.profileView.btnFollow.setText(R.string.unfavorite_short);
- main.mainBinding.profileView.btnFollow.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_purple_background)));
- }
- else {
- main.mainBinding.profileView.btnFollow.setText(R.string.favorite_short);
- main.mainBinding.profileView.btnFollow.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_pink_background)));
- }
- main.mainBinding.profileView.btnFollow.setVisibility(View.VISIBLE);
- if (!profileModel.isReallyPrivate()) {
- main.mainBinding.profileView.btnRestrict.setVisibility(View.VISIBLE);
- main.mainBinding.profileView.btnRestrict.setText(R.string.tagged);
- main.mainBinding.profileView.btnRestrict.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- main, R.color.btn_blue_background)));
- }
- }
-
- main.mainBinding.profileView.mainProfileImage.setEnabled(false);
- new MyTask().execute();
- main.mainBinding.profileView.mainProfileImage.setEnabled(true);
-
- final long followersCount = profileModel.getFollowersCount();
- final long followingCount = profileModel.getFollowingCount();
-
- final String postCount = String.valueOf(profileModel.getPostCount());
-
- SpannableStringBuilder span = new SpannableStringBuilder(resources.getString(R.string.main_posts_count, postCount));
- span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
- span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
- main.mainBinding.profileView.mainPostCount.setText(span);
-
- final String followersCountStr = String.valueOf(followersCount);
- final int followersCountStrLen = followersCountStr.length();
- span = new SpannableStringBuilder(resources.getString(R.string.main_posts_followers, followersCountStr));
- span.setSpan(new RelativeSizeSpan(1.2f), 0, followersCountStrLen, 0);
- span.setSpan(new StyleSpan(Typeface.BOLD), 0, followersCountStrLen, 0);
- main.mainBinding.profileView.mainFollowers.setText(span);
-
- final String followingCountStr = String.valueOf(followingCount);
- final int followingCountStrLen = followingCountStr.length();
- span = new SpannableStringBuilder(resources.getString(R.string.main_posts_following, followingCountStr));
- span.setSpan(new RelativeSizeSpan(1.2f), 0, followingCountStrLen, 0);
- span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0);
- main.mainBinding.profileView.mainFollowing.setText(span);
-
- main.mainBinding.profileView.mainFullName.setText(Utils.isEmpty(profileModel.getName()) ? profileModel.getUsername() : profileModel.getName());
-
- CharSequence biography = profileModel.getBiography();
- main.mainBinding.profileView.mainBiography.setCaptionIsExpandable(true);
- main.mainBinding.profileView.mainBiography.setCaptionIsExpanded(true);
- if (Utils.hasMentions(biography)) {
- biography = Utils.getMentionText(biography);
- main.mainBinding.profileView.mainBiography.setText(biography, TextView.BufferType.SPANNABLE);
- main.mainBinding.profileView.mainBiography.setMentionClickListener(mentionClickListener);
- } else {
- main.mainBinding.profileView.mainBiography.setText(biography);
- main.mainBinding.profileView.mainBiography.setMentionClickListener(null);
- }
-
- final String url = profileModel.getUrl();
- if (Utils.isEmpty(url)) {
- main.mainBinding.profileView.mainUrl.setVisibility(View.GONE);
- } else {
- main.mainBinding.profileView.mainUrl.setVisibility(View.VISIBLE);
- main.mainBinding.profileView.mainUrl.setText(Utils.getSpannableUrl(url));
- }
-
- main.mainBinding.profileView.mainFullName.setSelected(true);
- main.mainBinding.profileView.mainBiography.setEnabled(true);
-
- if (!profileModel.isReallyPrivate()) {
- main.mainBinding.profileView.mainFollowing.setClickable(true);
- main.mainBinding.profileView.mainFollowers.setClickable(true);
-
- if (isLoggedIn) {
- final View.OnClickListener followClickListener = v -> main.startActivity(new Intent(main, FollowViewer.class)
- .putExtra(Constants.EXTRAS_FOLLOWERS, v == main.mainBinding.profileView.mainFollowers)
- .putExtra(Constants.EXTRAS_NAME, profileModel.getUsername())
- .putExtra(Constants.EXTRAS_ID, profileId));
-
- main.mainBinding.profileView.mainFollowers.setOnClickListener(followersCount > 0 ? followClickListener : null);
- main.mainBinding.profileView.mainFollowing.setOnClickListener(followingCount > 0 ? followClickListener : null);
- }
-
- if (profileModel.getPostCount() == 0) {
- main.mainBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- main.mainBinding.profileView.privatePage1.setImageResource(R.drawable.ic_cancel);
- main.mainBinding.profileView.privatePage2.setText(R.string.empty_acc);
- main.mainBinding.profileView.privatePage.setVisibility(View.VISIBLE);
- }
- else {
- main.mainBinding.profileView.swipeRefreshLayout.setRefreshing(true);
- main.mainBinding.profileView.mainPosts.setVisibility(View.VISIBLE);
- currentlyExecuting = new PostsFetcher(profileId, postsFetchListener).setUsername(profileModel.getUsername())
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- } else {
- main.mainBinding.profileView.mainFollowers.setClickable(false);
- main.mainBinding.profileView.mainFollowing.setClickable(false);
- main.mainBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- // error
- main.mainBinding.profileView.privatePage1.setImageResource(R.drawable.lock);
- main.mainBinding.profileView.privatePage2.setText(R.string.priv_acc);
- main.mainBinding.profileView.privatePage.setVisibility(View.VISIBLE);
- main.mainBinding.profileView.mainPosts.setVisibility(View.GONE);
- }
- }
- ).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- else if (isLocation) {
- main.profileModel = null;
- main.hashtagModel = null;
- main.mainBinding.toolbar.toolbar.setTitle(main.userQuery);
- main.mainBinding.profileView.locInfoContainer.setVisibility(View.VISIBLE);
-
- currentlyExecuting = new LocationFetcher(main.userQuery.split("/")[0], locationModel -> {
- main.locationModel = locationModel;
-
- if (locationModel == null) {
- main.mainBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- Toast.makeText(main, R.string.error_loading_profile, Toast.LENGTH_SHORT).show();
- main.mainBinding.toolbar.toolbar.setTitle(R.string.app_name);
- return;
- }
- main.mainBinding.toolbar.toolbar.setTitle(locationModel.getName());
-
- final String profileId = locationModel.getId();
-
- if (isLoggedIn) {
- new iStoryStatusFetcher(profileId.split("/")[0], null, true, false, false, false, result -> {
- main.storyModels = result;
- if (result != null && result.length > 0) main.mainBinding.profileView.mainLocationImage.setStoriesBorder();
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- main.mainBinding.profileView.mainLocationImage.setEnabled(false);
- new MyTask().execute();
- main.mainBinding.profileView.mainLocationImage.setEnabled(true);
-
- final String postCount = String.valueOf(locationModel.getPostCount());
-
- SpannableStringBuilder span = new SpannableStringBuilder(resources.getString(R.string.main_posts_count, postCount));
- span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
- span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
- main.mainBinding.profileView.mainLocPostCount.setText(span);
-
- main.mainBinding.profileView.locationFullName.setText(locationModel.getName());
-
- CharSequence biography = locationModel.getBio();
- main.mainBinding.profileView.locationBiography.setCaptionIsExpandable(true);
- main.mainBinding.profileView.locationBiography.setCaptionIsExpanded(true);
-
- if (Utils.isEmpty(biography)) {
- main.mainBinding.profileView.locationBiography.setVisibility(View.GONE);
- }
- else if (Utils.hasMentions(biography)) {
- main.mainBinding.profileView.locationBiography.setVisibility(View.VISIBLE);
- biography = Utils.getMentionText(biography);
- main.mainBinding.profileView.locationBiography.setText(biography, TextView.BufferType.SPANNABLE);
- main.mainBinding.profileView.locationBiography.setMentionClickListener(mentionClickListener);
- } else {
- main.mainBinding.profileView.locationBiography.setVisibility(View.VISIBLE);
- main.mainBinding.profileView.locationBiography.setText(biography);
- main.mainBinding.profileView.locationBiography.setMentionClickListener(null);
- }
-
- if (!locationModel.getGeo().startsWith("geo:0.0,0.0?z=17")) {
- main.mainBinding.profileView.btnMap.setVisibility(View.VISIBLE);
- main.mainBinding.profileView.btnMap.setOnClickListener(v -> {
- final Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(locationModel.getGeo()));
- main.startActivity(intent);
- });
- }
- else {
- main.mainBinding.profileView.btnMap.setVisibility(View.GONE);
- main.mainBinding.profileView.btnMap.setOnClickListener(null);
- }
-
- final String url = locationModel.getUrl();
- if (Utils.isEmpty(url)) {
- main.mainBinding.profileView.locationUrl.setVisibility(View.GONE);
- } else if (!url.startsWith("http")) {
- main.mainBinding.profileView.locationUrl.setVisibility(View.VISIBLE);
- main.mainBinding.profileView.locationUrl.setText(Utils.getSpannableUrl("http://"+url));
- } else {
- main.mainBinding.profileView.locationUrl.setVisibility(View.VISIBLE);
- main.mainBinding.profileView.locationUrl.setText(Utils.getSpannableUrl(url));
- }
-
- main.mainBinding.profileView.locationFullName.setSelected(true);
- main.mainBinding.profileView.locationBiography.setEnabled(true);
-
- if (locationModel.getPostCount() == 0) {
- main.mainBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- main.mainBinding.profileView.privatePage1.setImageResource(R.drawable.ic_cancel);
- main.mainBinding.profileView.privatePage2.setText(R.string.empty_acc);
- main.mainBinding.profileView.privatePage.setVisibility(View.VISIBLE);
- }
- else {
- main.mainBinding.profileView.swipeRefreshLayout.setRefreshing(true);
- main.mainBinding.profileView.mainPosts.setVisibility(View.VISIBLE);
- currentlyExecuting = new PostsFetcher(profileId, postsFetchListener)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
- ).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
-
- public static void stopCurrentExecutor() {
- if (currentlyExecuting != null) {
- try {
- currentlyExecuting.cancel(true);
- } catch (final Exception e) {
- if (logCollector != null)
- logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
- }
- }
- }
-
- private void toggleSelection(final PostModel postModel) {
- if (postModel != null && postsAdapter != null && main.selectedItems.size() >= 100) {
- Toast.makeText(main, R.string.downloader_too_many, Toast.LENGTH_SHORT);
- }
- else if (postModel != null && postsAdapter != null) {
- if (postModel.isSelected()) main.selectedItems.remove(postModel);
- else if (main.selectedItems.size() >= 100) {
- Toast.makeText(main, R.string.downloader_too_many, Toast.LENGTH_SHORT);
- return;
- }
- else main.selectedItems.add(postModel);
- postModel.setSelected(!postModel.isSelected());
- notifyAdapter(postModel);
- }
- }
-
- private void notifyAdapter(final PostModel postModel) {
- if (main.selectedItems.size() < 1) postsAdapter.isSelecting = false;
- if (postModel.getPosition() < 0) postsAdapter.notifyDataSetChanged();
- else postsAdapter.notifyItemChanged(postModel.getPosition(), postModel);
-
- if (main.downloadAction != null) main.downloadAction.setVisible(postsAdapter.isSelecting);
- }
-
- ///////////////////////////////////////////////////
- private void toggleDiscoverSelection(final DiscoverItemModel itemModel) {
- if (itemModel != null && discoverAdapter != null) {
- if (itemModel.isSelected()) main.selectedDiscoverItems.remove(itemModel);
- else main.selectedDiscoverItems.add(itemModel);
- itemModel.setSelected(!itemModel.isSelected());
- notifyDiscoverAdapter(itemModel);
- }
- }
-
- private void notifyDiscoverAdapter(final DiscoverItemModel itemModel) {
- if (main.selectedDiscoverItems.size() < 1) discoverAdapter.isSelecting = false;
- if (itemModel.getPosition() < 0) discoverAdapter.notifyDataSetChanged();
- else discoverAdapter.notifyItemChanged(itemModel.getPosition(), itemModel);
-
- if (main.downloadAction != null) main.downloadAction.setVisible(discoverAdapter.isSelecting);
- }
-
- public boolean isSelectionCleared() {
- if (postsAdapter != null && postsAdapter.isSelecting) {
- for (final PostModel postModel : main.selectedItems) postModel.setSelected(false);
- main.selectedItems.clear();
- postsAdapter.isSelecting = false;
- postsAdapter.notifyDataSetChanged();
- if (main.downloadAction != null) main.downloadAction.setVisible(false);
- return false;
- } else if (discoverAdapter != null && discoverAdapter.isSelecting) {
- for (final DiscoverItemModel itemModel : main.selectedDiscoverItems) itemModel.setSelected(false);
- main.selectedDiscoverItems.clear();
- discoverAdapter.isSelecting = false;
- discoverAdapter.notifyDataSetChanged();
- if (main.downloadAction != null) main.downloadAction.setVisible(false);
- return false;
- }
- return true;
- }
-
- public void deselectSelection(final BasePostModel postModel) {
- if (postModel instanceof PostModel) {
- main.selectedItems.remove(postModel);
- postModel.setSelected(false);
- if (postsAdapter != null) notifyAdapter((PostModel) postModel);
- } else if (postModel instanceof DiscoverItemModel) {
- main.selectedDiscoverItems.remove(postModel);
- postModel.setSelected(false);
- if (discoverAdapter != null) notifyDiscoverAdapter((DiscoverItemModel) postModel);
- }
- }
-
- public void onPause() {
- if (currentFeedPlayer != null) {
- currentFeedPlayer.setPlayWhenReady(false);
- }
- }
-
- public void onResume() {
- if (currentFeedPlayer != null) {
- final boolean shouldAutoplay = settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS);
- currentFeedPlayer.setPlayWhenReady(shouldAutoplay);
- }
- }
-
- public static int indexOfIntArray(Object[] array, Object key) {
- int returnvalue = -1;
- for (int i = 0; i < array.length; ++i) {
- if (key == array[i]) {
- returnvalue = i;
- break;
- }
- }
- return returnvalue;
- }
-
- class MyTask extends AsyncTask {
- private Bitmap mIcon_val;
-
- protected Void doInBackground(Void... voids) {
- try {
- mIcon_val = BitmapFactory.decodeStream((InputStream) new URL(
- (main.hashtagModel != null) ? main.hashtagModel.getSdProfilePic() : (
- (main.locationModel != null) ? main.locationModel.getSdProfilePic() :
- main.profileModel.getSdProfilePic())
- ).getContent());
- } catch (Throwable ex) {
- Log.e("austin_debug", "bitmap: " + ex);
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- if (main.hashtagModel != null) main.mainBinding.profileView.mainHashtagImage.setImageBitmap(mIcon_val);
- else if (main.locationModel != null) main.mainBinding.profileView.mainLocationImage.setImageBitmap(mIcon_val);
- else main.mainBinding.profileView.mainProfileImage.setImageBitmap(mIcon_val);
- }
- }
-
- private final View.OnClickListener profileActionListener = new View.OnClickListener() {
- @Override
- public void onClick(final View v) {
- final boolean iamme = (isLoggedIn && main.profileModel != null) && Utils.getUserIdFromCookie(cookie).equals(main.profileModel.getId());
- if (!isLoggedIn && Utils.dataBox.getFavorite(main.userQuery) != null && v == main.mainBinding.profileView.btnFollow) {
- Utils.dataBox.delFavorite(new DataBox.FavoriteModel(main.userQuery,
- Long.parseLong(Utils.dataBox.getFavorite(main.userQuery).split("/")[1]),
- main.locationModel != null ? main.locationModel.getName() : main.userQuery.replaceAll("^@", "")));
- onRefresh();
- } else if (!isLoggedIn && (v == main.mainBinding.profileView.btnFollow || v == main.mainBinding.profileView.btnFollowTag)) {
- Utils.dataBox.addFavorite(new DataBox.FavoriteModel(main.userQuery, System.currentTimeMillis(),
- main.locationModel != null ? main.locationModel.getName() : main.userQuery.replaceAll("^@", "")));
- onRefresh();
- } else if (v == main.mainBinding.profileView.btnFollow) {
- if (main.profileModel.isPrivate() && main.profileModel.getFollowing()) {
- new AlertDialog.Builder(main)
- .setTitle(R.string.priv_acc)
- .setMessage(R.string.priv_acc_confirm)
- .setNegativeButton(R.string.no, null)
- .setPositiveButton(R.string.yes, (dialog, which) -> new ProfileAction().execute("follow"))
- .show();
- }
- else {
- new ProfileAction().execute("follow");
- }
- } else if (v == main.mainBinding.profileView.btnRestrict && isLoggedIn) {
- new ProfileAction().execute("restrict");
- } else if (v == main.mainBinding.profileView.btnSaved && !iamme) {
- new ProfileAction().execute("block");
- } else if (v == main.mainBinding.profileView.btnFollowTag) {
- new ProfileAction().execute("followtag");
- } else if (v == main.mainBinding.profileView.btnTagged || (v == main.mainBinding.profileView.btnRestrict && !isLoggedIn)) {
- main.startActivity(new Intent(main, SavedViewer.class)
- .putExtra(Constants.EXTRAS_INDEX, "%"+main.profileModel.getId())
- .putExtra(Constants.EXTRAS_USER, "@"+main.profileModel.getUsername())
- );
- } else if (v == main.mainBinding.profileView.btnSaved) {
- main.startActivity(new Intent(main, SavedViewer.class)
- .putExtra(Constants.EXTRAS_INDEX, "$"+main.profileModel.getId())
- .putExtra(Constants.EXTRAS_USER, "@"+main.profileModel.getUsername())
- );
- } else if (v == main.mainBinding.profileView.btnLiked) {
- main.startActivity(new Intent(main, SavedViewer.class)
- .putExtra(Constants.EXTRAS_INDEX, "^"+main.profileModel.getId())
- .putExtra(Constants.EXTRAS_USER, "@"+main.profileModel.getUsername())
- );
- }
- }
- };
-
- class ProfileAction extends AsyncTask {
- boolean ok = false;
- String action;
-
- protected Void doInBackground(String... rawAction) {
- action = rawAction[0];
- final String url = "https://www.instagram.com/web/"+
- ((action == "followtag" && main.hashtagModel != null) ? ("tags/"+
- (main.hashtagModel.getFollowing() ? "unfollow/" : "follow/")+main.hashtagModel.getName()+"/") : (
- ((action == "restrict" && main.profileModel != null) ? "restrict_action" : ("friendships/"+main.profileModel.getId()))+"/"+
- ((action == "follow" && main.profileModel != null) ?
- ((main.profileModel.getFollowing() ||
- (main.profileModel.getFollowing() == false && main.profileModel.getRequested() == true))
- ? "unfollow/" : "follow/") :
- ((action == "restrict" && main.profileModel != null) ?
- (main.profileModel.getRestricted() ? "unrestrict/" : "restrict/") :
- (main.profileModel.getBlocked() ? "unblock/" : "block/")))));
- try {
- final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT);
- urlConnection.setRequestProperty("x-csrftoken", cookie.split("csrftoken=")[1].split(";")[0]);
- if (action == "restrict") {
- final String urlParameters = "target_user_id="+main.profileModel.getId();
- urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- urlConnection.setRequestProperty("Content-Length", "" +
- urlParameters.getBytes().length);
- urlConnection.setDoOutput(true);
- DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
- wr.writeBytes(urlParameters);
- wr.flush();
- wr.close();
- }
- else urlConnection.connect();
- if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
- ok = true;
- }
- else Toast.makeText(main, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- urlConnection.disconnect();
- } catch (Throwable ex) {
- Log.e("austin_debug", action+": " + ex);
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- if (ok == true) {
- onRefresh();
- }
- }
- }
-}
diff --git a/app/src/main/java/awais/instagrabber/activities/BaseLanguageActivity.java b/app/src/main/java/awais/instagrabber/activities/BaseLanguageActivity.java
index 81dc4bf8..aeaad606 100755
--- a/app/src/main/java/awais/instagrabber/activities/BaseLanguageActivity.java
+++ b/app/src/main/java/awais/instagrabber/activities/BaseLanguageActivity.java
@@ -6,7 +6,7 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import awais.instagrabber.utils.LocaleUtils;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.ThemeUtils;
public abstract class BaseLanguageActivity extends AppCompatActivity {
protected BaseLanguageActivity() {
@@ -15,7 +15,7 @@ public abstract class BaseLanguageActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
- Utils.changeTheme(this);
+ ThemeUtils.changeTheme(this);
super.onCreate(savedInstanceState);
}
}
diff --git a/app/src/main/java/awais/instagrabber/activities/CommentsViewer.java b/app/src/main/java/awais/instagrabber/activities/CommentsViewer.java
deleted file mode 100755
index 73352b6b..00000000
--- a/app/src/main/java/awais/instagrabber/activities/CommentsViewer.java
+++ /dev/null
@@ -1,302 +0,0 @@
-package awais.instagrabber.activities;
-
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.style.RelativeSizeSpan;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.ArrayAdapter;
-import android.widget.Toast;
-
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.widget.SearchView;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-
-import java.io.DataOutputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLEncoder;
-
-import awais.instagrabber.R;
-import awais.instagrabber.adapters.CommentsAdapter;
-import awais.instagrabber.asyncs.CommentsFetcher;
-import awais.instagrabber.databinding.ActivityCommentsBinding;
-import awais.instagrabber.interfaces.FetchListener;
-import awais.instagrabber.interfaces.MentionClickListener;
-import awais.instagrabber.models.CommentModel;
-import awais.instagrabber.models.ProfileModel;
-import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
-
-public final class CommentsViewer extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener {
- private CommentsAdapter commentsAdapter;
- private CommentModel commentModel;
- private ActivityCommentsBinding commentsBinding;
- private ArrayAdapter commmentDialogAdapter;
- private String shortCode, postId, userId;
- private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
- private Resources resources;
- private InputMethodManager imm;
- private View focus;
-
- @Override
- protected void onCreate(@Nullable final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- commentsBinding = ActivityCommentsBinding.inflate(getLayoutInflater());
- setContentView(commentsBinding.getRoot());
- commentsBinding.swipeRefreshLayout.setOnRefreshListener(this);
-
- final Intent intent = getIntent();
- if (intent == null || !intent.hasExtra(Constants.EXTRAS_SHORTCODE)
- || Utils.isEmpty((shortCode = intent.getStringExtra(Constants.EXTRAS_SHORTCODE)))
- || !intent.hasExtra(Constants.EXTRAS_POST)
- || Utils.isEmpty((postId = intent.getStringExtra(Constants.EXTRAS_POST)))
- || !intent.hasExtra(Constants.EXTRAS_USER)
- || Utils.isEmpty((userId = intent.getStringExtra(Constants.EXTRAS_USER)))) {
- Utils.errorFinish(this);
- return;
- }
-
- commentsBinding.swipeRefreshLayout.setRefreshing(true);
- setSupportActionBar(commentsBinding.toolbar.toolbar);
- commentsBinding.toolbar.toolbar.setTitle(R.string.title_comments);
- commentsBinding.toolbar.toolbar.setSubtitle(shortCode);
-
- resources = getResources();
-
- if (!Utils.isEmpty(cookie)) {
- commentsBinding.commentText.setVisibility(View.VISIBLE);
- commentsBinding.commentSend.setVisibility(View.VISIBLE);
-
- commentsBinding.commentSend.setOnClickListener(newCommentListener);
- commentsBinding.commentCancelParent.setOnClickListener(newCommentListener);
- }
-
- new CommentsFetcher(shortCode, new FetchListener() {
- @Override
- public void onResult(final CommentModel[] commentModels) {
- commentsAdapter = new CommentsAdapter(commentModels, true, clickListener, mentionClickListener);
-
- commentsBinding.rvComments.setAdapter(commentsAdapter);
- commentsBinding.swipeRefreshLayout.setRefreshing(false);
- }
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- @Override
- public void onRefresh() {
- commentsBinding.swipeRefreshLayout.setRefreshing(true);
- new CommentsFetcher(shortCode, new FetchListener() {
- @Override
- public void onResult(final CommentModel[] commentModels) {
- commentsBinding.swipeRefreshLayout.setRefreshing(false);
-
- commentsAdapter = new CommentsAdapter(commentModels, true, clickListener, mentionClickListener);
-
- commentsBinding.rvComments.setAdapter(commentsAdapter);
- }
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
- final ProfileModel profileModel = commentModel.getProfileModel();
-
- if (which == 0) {
- searchUsername(profileModel.getUsername());
- } else if (which == 1) {
- startActivity(new Intent(this, ProfilePicViewer.class).putExtra(Constants.EXTRAS_PROFILE, profileModel));
- } else if (which == 2) {
- Utils.copyText(this, profileModel.getUsername());
- } else if (which == 3) {
- Utils.copyText(this, commentModel.getText().toString());
- } else if (which == 4) {
- if (commentModel == null) {
- Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }
- else {
- focus = commentsBinding.rvComments.findViewWithTag(commentModel);
- focus.setBackgroundColor(0x80888888);
- commentsBinding.commentCancelParent.setVisibility(View.VISIBLE);
- String mention = "@" + profileModel.getUsername() + " ";
- commentsBinding.commentText.setText(mention);
- commentsBinding.commentText.requestFocus();
- commentsBinding.commentText.setSelection(mention.length());
- commentsBinding.commentText.postDelayed(new Runnable() {
- @Override
- public void run() {
- imm = (InputMethodManager) getSystemService(getApplicationContext().INPUT_METHOD_SERVICE);
- imm.showSoftInput(commentsBinding.commentText, 0);
- }
- }, 200);
- }
- } else if (which == 5) {
- new CommentAction().execute((commentModel.getLiked() ? "unlike/" : "like/")+commentModel.getId());
- } else if (which == 6) {
- new CommentAction().execute("delete/"+commentModel.getId());
- }
- };
-
- private final View.OnClickListener clickListener = v -> {
- final Object tag = v.getTag();
- if (tag instanceof CommentModel) {
- commentModel = (CommentModel) tag;
-
- final String username = commentModel.getProfileModel().getUsername();
- final SpannableString title = new SpannableString(username + ":\n" + commentModel.getText());
- title.setSpan(new RelativeSizeSpan(1.23f), 0, username.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
-
- String[] commentDialogList;
-
- if (!Utils.isEmpty(cookie) &&
- (Utils.getUserIdFromCookie(cookie).equals(commentModel.getProfileModel().getId()) ||
- Utils.getUserIdFromCookie(cookie).equals(userId))) commentDialogList = new String[]{
- resources.getString(R.string.open_profile),
- resources.getString(R.string.view_pfp),
- resources.getString(R.string.comment_viewer_copy_user),
- resources.getString(R.string.comment_viewer_copy_comment),
- resources.getString(R.string.comment_viewer_reply_comment),
- commentModel.getLiked() ? resources.getString(R.string.comment_viewer_unlike_comment) : resources.getString(R.string.comment_viewer_like_comment),
- resources.getString(R.string.comment_viewer_delete_comment)
- };
- else if (!Utils.isEmpty(cookie)) commentDialogList = new String[]{
- resources.getString(R.string.open_profile),
- resources.getString(R.string.view_pfp),
- resources.getString(R.string.comment_viewer_copy_user),
- resources.getString(R.string.comment_viewer_copy_comment),
- resources.getString(R.string.comment_viewer_reply_comment),
- commentModel.getLiked() ? resources.getString(R.string.comment_viewer_unlike_comment) : resources.getString(R.string.comment_viewer_like_comment),
- };
- else commentDialogList = new String[]{
- resources.getString(R.string.open_profile),
- resources.getString(R.string.view_pfp),
- resources.getString(R.string.comment_viewer_copy_user),
- resources.getString(R.string.comment_viewer_copy_comment)
- };
-
- commmentDialogAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, commentDialogList);
-
- new AlertDialog.Builder(this).setTitle(title)
- .setAdapter(commmentDialogAdapter, profileDialogListener)
- .setNeutralButton(R.string.cancel, null)
- .show();
- }
- };
-
- private final MentionClickListener mentionClickListener = (view, text, isHashtag) ->
- new AlertDialog.Builder(this).setTitle(text)
- .setMessage(isHashtag ? R.string.comment_view_mention_hash_search : R.string.comment_view_mention_user_search)
- .setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.ok,
- (dialog, which) -> searchUsername(text)).show();
-
- private final View.OnClickListener newCommentListener = v -> {
- if (Utils.isEmpty(commentsBinding.commentText.getText().toString()) && v == commentsBinding.commentSend)
- Toast.makeText(getApplicationContext(), R.string.comment_send_empty_comment, Toast.LENGTH_SHORT).show();
- else if (v == commentsBinding.commentSend) new CommentAction().execute("add");
- else if (v == commentsBinding.commentCancelParent) {
- focus.setBackgroundColor(commentModel.getLiked() ? 0x40FF69B4 : 0x00000000);
- commentsBinding.commentCancelParent.setVisibility(View.GONE);
- commentsBinding.commentText.setText("");
- commentModel = null;
- focus = null;
- }
- };
-
- private void searchUsername(final String text) {
- startActivity(
- new Intent(getApplicationContext(), ProfileViewer.class)
- .putExtra(Constants.EXTRAS_USERNAME, text)
- );
- }
-
- @Override
- public boolean onCreateOptionsMenu(final Menu menu) {
- getMenuInflater().inflate(R.menu.follow, menu);
-
- final MenuItem menuSearch = menu.findItem(R.id.action_search);
- final SearchView searchView = (SearchView) menuSearch.getActionView();
- searchView.setQueryHint(getResources().getString(R.string.action_search));
- searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(final String query) {
- return false;
- }
-
- @Override
- public boolean onQueryTextChange(final String query) {
- if (commentsAdapter != null) commentsAdapter.getFilter().filter(query);
- return true;
- }
- });
-
- menu.findItem(R.id.action_compare).setVisible(false);
-
- return true;
- }
-
- class CommentAction extends AsyncTask {
- boolean ok = false;
-
- protected Void doInBackground(String... rawAction) {
- final String action = rawAction[0];
- final String url = "https://www.instagram.com/web/comments/"+postId+"/"+action+"/";
- try {
- final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT);
- urlConnection.setRequestProperty("x-csrftoken", cookie.split("csrftoken=")[1].split(";")[0]);
- if (action == "add") {
- // https://stackoverflow.com/questions/14321873/java-url-encoding-urlencoder-vs-uri
- final String commentText = URLEncoder.encode(commentsBinding.commentText.getText().toString(), "UTF-8")
- .replaceAll("\\+", "%20").replaceAll("\\%21", "!").replaceAll("\\%27", "'")
- .replaceAll("\\%28", "(").replaceAll("\\%29", ")").replaceAll("\\%7E", "~");
- final String urlParameters = "comment_text="+commentText+"&replied_to_comment_id="+
- (commentModel == null ? "" : commentModel.getId());
- urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- urlConnection.setRequestProperty("Content-Length", "" +
- urlParameters.getBytes().length);
- urlConnection.setDoOutput(true);
- DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
- wr.writeBytes(urlParameters);
- wr.flush();
- wr.close();
- }
- urlConnection.connect();
- if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
- ok = true;
- if (action == "add") {
- commentsBinding.commentText.setText("");
- commentsBinding.commentText.clearFocus();
- }
- }
- urlConnection.disconnect();
- } catch (Throwable ex) {
- Log.e("austin_debug", action+": " + ex);
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- if (ok == true) {
- if (focus != null) {
- focus.setBackgroundColor(commentModel.getLiked() ? 0x40FF69B4 : 0x00000000);
- commentsBinding.commentCancelParent.setVisibility(View.GONE);
- commentModel = null;
- focus = null;
- }
- onRefresh();
- }
- else Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/activities/DirectMessagesActivity.java b/app/src/main/java/awais/instagrabber/activities/DirectMessagesActivity.java
deleted file mode 100644
index d8043469..00000000
--- a/app/src/main/java/awais/instagrabber/activities/DirectMessagesActivity.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package awais.instagrabber.activities;
-
-import android.os.Bundle;
-import android.view.View;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.widget.AppCompatImageView;
-import androidx.appcompat.widget.Toolbar;
-import androidx.coordinatorlayout.widget.CoordinatorLayout;
-import androidx.navigation.NavController;
-import androidx.navigation.NavDestination;
-import androidx.navigation.Navigation;
-import androidx.navigation.ui.AppBarConfiguration;
-import androidx.navigation.ui.NavigationUI;
-
-import awais.instagrabber.R;
-import awais.instagrabber.databinding.ActivityDirectMessagesBinding;
-import awais.instagrabber.fragments.directmessages.DirectMessageThreadFragmentArgs;
-import awais.instagrabber.utils.Constants;
-import static awais.instagrabber.utils.Utils.settingsHelper;
-
-public class DirectMessagesActivity extends BaseLanguageActivity implements NavController.OnDestinationChangedListener {
-
- private TextView toolbarTitle;
- private AppCompatImageView dmInfo, dmSeen;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- final ActivityDirectMessagesBinding binding = ActivityDirectMessagesBinding.inflate(getLayoutInflater());
- final CoordinatorLayout root = binding.getRoot();
- setContentView(root);
-
- toolbarTitle = binding.toolbarTitle;
-
- final Toolbar toolbar = binding.toolbar;
- setSupportActionBar(toolbar);
-
- dmInfo = binding.dmInfo;
- dmSeen = binding.dmSeen;
-
- final NavController navController = Navigation.findNavController(this, R.id.direct_messages_nav_host_fragment);
- navController.addOnDestinationChangedListener(this);
- final AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
- NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration);
- }
-
- @Override
- public void onDestinationChanged(@NonNull final NavController controller,
- @NonNull final NavDestination destination,
- @Nullable final Bundle arguments) {
- switch (destination.getId()) {
- case R.id.directMessagesInboxFragment:
- setToolbarTitle(R.string.action_dms);
- dmInfo.setVisibility(View.GONE);
- dmSeen.setVisibility(View.GONE);
- return;
- case R.id.directMessagesThreadFragment:
- if (arguments == null) {
- return;
- }
- final String title = DirectMessageThreadFragmentArgs.fromBundle(arguments).getTitle();
- setToolbarTitle(title);
- dmInfo.setVisibility(View.VISIBLE);
- dmSeen.setVisibility(settingsHelper.getBoolean(Constants.DM_MARK_AS_SEEN) ? View.GONE : View.VISIBLE);
- return;
- case R.id.directMessagesSettingsFragment:
- if (arguments == null) {
- return;
- }
- setToolbarTitle(R.string.action_settings);
- dmInfo.setVisibility(View.GONE);
- dmSeen.setVisibility(View.GONE);
- return;
- }
- }
-
- private void setToolbarTitle(final String text) {
- if (toolbarTitle == null) {
- return;
- }
- toolbarTitle.setText(text);
- }
-
- private void setToolbarTitle(final int resourceId) {
- if (toolbarTitle == null) {
- return;
- }
- toolbarTitle.setText(resourceId);
- }
-}
diff --git a/app/src/main/java/awais/instagrabber/activities/FollowViewer.java b/app/src/main/java/awais/instagrabber/activities/FollowViewer.java
deleted file mode 100755
index 95491188..00000000
--- a/app/src/main/java/awais/instagrabber/activities/FollowViewer.java
+++ /dev/null
@@ -1,333 +0,0 @@
-package awais.instagrabber.activities;
-
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-import androidx.appcompat.widget.SearchView;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import awais.instagrabber.BuildConfig;
-import awais.instagrabber.R;
-import awais.instagrabber.adapters.FollowAdapter;
-import awais.instagrabber.asyncs.FollowFetcher;
-import awais.instagrabber.databinding.ActivityFollowBinding;
-import awais.instagrabber.interfaces.FetchListener;
-import awais.instagrabber.models.FollowModel;
-import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
-import awaisomereport.LogCollector;
-import thoughtbot.expandableadapter.ExpandableGroup;
-
-import static awais.instagrabber.utils.Utils.logCollector;
-
-public final class FollowViewer extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener {
- private final ArrayList followModels = new ArrayList<>();
- private final ArrayList followingModels = new ArrayList<>();
- private final ArrayList followersModels = new ArrayList<>();
- private final ArrayList allFollowing = new ArrayList<>();
- private boolean followers, isCompare = false;
- private String id, name, namePost, type;
- private Resources resources;
- private FollowModel model;
- private FollowAdapter adapter;
- private View.OnClickListener clickListener;
- private ActivityFollowBinding followBinding;
- private AsyncTask currentlyExecuting;
-
- @Override
- protected void onCreate(@Nullable final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- followBinding = ActivityFollowBinding.inflate(getLayoutInflater());
- setContentView(followBinding.getRoot());
-
- final Intent intent = getIntent();
- if (intent == null || Utils.isEmpty(id = intent.getStringExtra(Constants.EXTRAS_ID))) {
- Utils.errorFinish(this);
- return;
- }
-
- setSupportActionBar(followBinding.toolbar.toolbar);
-
- followers = intent.getBooleanExtra(Constants.EXTRAS_FOLLOWERS, false);
- name = intent.getStringExtra(Constants.EXTRAS_NAME);
- namePost = name;
- if (Utils.isEmpty(name)) {
- // this usually should not occur
- name = "You";
- namePost = "You're";
- }
-
- followBinding.toolbar.toolbar.setTitle(name);
-
- resources = getResources();
-
- clickListener = v -> {
- final Object tag = v.getTag();
- if (tag instanceof FollowModel) {
- model = (FollowModel) tag;
- startActivity(
- new Intent(getApplicationContext(), ProfileViewer.class)
- .putExtra(Constants.EXTRAS_USERNAME, model.getUsername())
- );
- }
- };
-
- followBinding.swipeRefreshLayout.setOnRefreshListener(this);
-
- onRefresh();
- }
-
- @Override
- public void onRefresh() {
- if (isCompare) listCompare();
- else listFollows();
- }
-
- private void listFollows() {
- stopCurrentExecutor();
-
- type = resources.getString(followers ? R.string.followers_type_followers : R.string.followers_type_following);
- followBinding.toolbar.toolbar.setSubtitle(type);
-
- followModels.clear();
-
- final FetchListener fetchListener = new FetchListener() {
- @Override
- public void doBefore() {
- followBinding.swipeRefreshLayout.setRefreshing(true);
- }
-
- @Override
- public void onResult(final FollowModel[] result) {
- if (result == null) followBinding.swipeRefreshLayout.setRefreshing(false);
- else {
- followModels.addAll(Arrays.asList(result));
-
- final FollowModel model = result[result.length - 1];
- if (model != null && model.hasNextPage()) {
- stopCurrentExecutor();
- currentlyExecuting = new FollowFetcher(id, followers, model.getEndCursor(), this)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- model.setPageCursor(false, null);
- } else {
- followBinding.swipeRefreshLayout.setRefreshing(false);
-
- refreshAdapter(followModels, null, null, null);
- }
- }
- }
- };
-
- currentlyExecuting = new FollowFetcher(id, followers, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- private void listCompare() {
- stopCurrentExecutor();
-
- followBinding.toolbar.toolbar.setSubtitle(R.string.followers_compare);
-
- allFollowing.clear();
- followersModels.clear();
- followingModels.clear();
-
- final FetchListener followingFetchListener = new FetchListener() {
- @Override
- public void onResult(final FollowModel[] result) {
- if (result != null) {
- followingModels.addAll(Arrays.asList(result));
-
- final FollowModel model = result[result.length - 1];
- if (model != null && model.hasNextPage()) {
- stopCurrentExecutor();
- currentlyExecuting = new FollowFetcher(id, false, model.getEndCursor(), this)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- model.setPageCursor(false, null);
- } else {
- allFollowing.addAll(followersModels);
- allFollowing.retainAll(followingModels);
-
- for (final FollowModel followModel : allFollowing) {
- followersModels.remove(followModel);
- followingModels.remove(followModel);
- }
-
- allFollowing.trimToSize();
- followersModels.trimToSize();
- followingModels.trimToSize();
-
- followBinding.swipeRefreshLayout.setRefreshing(false);
-
- refreshAdapter(null, followingModels, followersModels, allFollowing);
- }
- } else followBinding.swipeRefreshLayout.setRefreshing(false);
- }
- };
- final FetchListener followersFetchListener = new FetchListener() {
- @Override
- public void doBefore() {
- followBinding.swipeRefreshLayout.setRefreshing(true);
- }
-
- @Override
- public void onResult(final FollowModel[] result) {
- if (result != null) {
- followersModels.addAll(Arrays.asList(result));
- final FollowModel model = result[result.length - 1];
- if (model == null || !model.hasNextPage()) {
- stopCurrentExecutor();
- currentlyExecuting = new FollowFetcher(id, false, followingFetchListener)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- } else {
- stopCurrentExecutor();
- currentlyExecuting = new FollowFetcher(id, true, model.getEndCursor(), this)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- model.setPageCursor(false, null);
- }
- }
- }
- };
-
- currentlyExecuting = new FollowFetcher(id, true, followersFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- @Override
- public boolean onCreateOptionsMenu(final Menu menu) {
- getMenuInflater().inflate(R.menu.follow, menu);
-
- final MenuItem menuSearch = menu.findItem(R.id.action_search);
-
- final SearchView searchView = (SearchView) menuSearch.getActionView();
- searchView.setQueryHint(getResources().getString(R.string.action_search));
- searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
-// private final Filter filter = new Filter() {
-// private final ArrayList searchFollowModels = new ArrayList<>(followModels.size() / 2);
-// private final ArrayList searchFollowingModels = new ArrayList<>(followingModels.size() / 2);
-// private final ArrayList searchFollowersModels = new ArrayList<>(followersModels.size() / 2);
-// private final ArrayList searchAllFollowing = new ArrayList<>(allFollowing.size() / 2);
-//
-// @Nullable
-// @Override
-// protected FilterResults performFiltering(@NonNull final CharSequence constraint) {
-// searchFollowModels.clear();
-// searchFollowingModels.clear();
-// searchFollowersModels.clear();
-// searchAllFollowing.clear();
-//
-// final int followModelsSize = followModels.size();
-// final int followingModelsSize = followingModels.size();
-// final int followersModelsSize = followersModels.size();
-// final int allFollowingSize = allFollowing.size();
-//
-// int maxSize = followModelsSize;
-// if (maxSize < followingModelsSize) maxSize = followingModelsSize;
-// if (maxSize < followersModelsSize) maxSize = followersModelsSize;
-// if (maxSize < allFollowingSize) maxSize = allFollowingSize;
-//
-// final String query = constraint.toString().toLowerCase();
-// FollowModel followModel;
-// while (maxSize != -1) {
-// if (maxSize < followModelsSize) {
-// followModel = followModels.get(maxSize);
-// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName()))
-// searchFollowModels.add(followModel);
-// }
-//
-// if (maxSize < followingModelsSize) {
-// followModel = followingModels.get(maxSize);
-// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName()))
-// searchFollowingModels.add(followModel);
-// }
-//
-// if (maxSize < followersModelsSize) {
-// followModel = followersModels.get(maxSize);
-// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName()))
-// searchFollowersModels.add(followModel);
-// }
-//
-// if (maxSize < allFollowingSize) {
-// followModel = allFollowing.get(maxSize);
-// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName()))
-// searchAllFollowing.add(followModel);
-// }
-//
-// --maxSize;
-// }
-//
-// return null;
-// }
-//
-// @Override
-// protected void publishResults(final CharSequence query, final FilterResults results) {
-// refreshAdapter(searchFollowModels, searchFollowingModels, searchFollowersModels, searchAllFollowing);
-// }
-// };
-
- @Override
- public boolean onQueryTextSubmit(final String query) {
- return false;
- }
-
- @Override
- public boolean onQueryTextChange(final String query) {
-// if (Utils.isEmpty(query)) refreshAdapter(followModels, followingModels, followersModels, allFollowing);
-// else filter.filter(query.toLowerCase());
- if (adapter != null) adapter.getFilter().filter(query);
- return true;
- }
- });
-
- final MenuItem menuCompare = menu.findItem(R.id.action_compare);
- menuCompare.setOnMenuItemClickListener(item -> {
- followBinding.rvFollow.setAdapter(null);
- if (isCompare) listFollows();
- else listCompare();
- isCompare = !isCompare;
- return true;
- });
-
- return true;
- }
-
- private void refreshAdapter(final ArrayList followModels, final ArrayList followingModels,
- final ArrayList followersModels, final ArrayList allFollowing) {
- final ArrayList groups = new ArrayList<>(1);
-
- if (isCompare) {
- if (followingModels != null && followingModels.size() > 0)
- groups.add(new ExpandableGroup(resources.getString(R.string.followers_not_following, name), followingModels));
- if (followersModels != null && followersModels.size() > 0)
- groups.add(new ExpandableGroup(resources.getString(R.string.followers_not_follower, namePost), followersModels));
- if (allFollowing != null && allFollowing.size() > 0)
- groups.add(new ExpandableGroup(resources.getString(R.string.followers_both_following), allFollowing));
- } else {
- final ExpandableGroup group = new ExpandableGroup(type, followModels);
- groups.add(group);
- }
-
- adapter = new FollowAdapter(this, clickListener, groups);
- adapter.toggleGroup(0);
- followBinding.rvFollow.setAdapter(adapter);
- }
-
- public void stopCurrentExecutor() {
- if (currentlyExecuting != null) {
- try {
- currentlyExecuting.cancel(true);
- } catch (final Exception e) {
- if (logCollector != null)
- logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/activities/Login.java b/app/src/main/java/awais/instagrabber/activities/Login.java
index 55c30ca6..a7f06b67 100755
--- a/app/src/main/java/awais/instagrabber/activities/Login.java
+++ b/app/src/main/java/awais/instagrabber/activities/Login.java
@@ -1,6 +1,7 @@
package awais.instagrabber.activities;
import android.annotation.SuppressLint;
+import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
@@ -19,9 +20,8 @@ import androidx.annotation.Nullable;
import awais.instagrabber.R;
import awais.instagrabber.databinding.ActivityLoginBinding;
import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
-
-import static awais.instagrabber.utils.Utils.settingsHelper;
+import awais.instagrabber.utils.CookieUtils;
+import awais.instagrabber.utils.TextUtils;
public final class Login extends BaseLanguageActivity implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
private final WebViewClient webViewClient = new WebViewClient() {
@@ -33,16 +33,24 @@ public final class Login extends BaseLanguageActivity implements View.OnClickLis
@Override
public void onPageFinished(final WebView view, final String url) {
webViewUrl = url;
- final String mainCookie = Utils.getCookie(url);
- if (Utils.isEmpty(mainCookie) || !mainCookie.contains("; ds_user_id=")) ready = true;
- else if (mainCookie.contains("; ds_user_id=") && ready) {
- Utils.setupCookies(mainCookie);
- settingsHelper.putString(Constants.COOKIE, mainCookie);
- Toast.makeText(getApplicationContext(), R.string.login_success_loading_cookies, Toast.LENGTH_SHORT).show();
- finish();
+ final String mainCookie = CookieUtils.getCookie(url);
+ if (TextUtils.isEmpty(mainCookie) || !mainCookie.contains("; ds_user_id=")) {
+ ready = true;
+ return;
+ }
+ if (mainCookie.contains("; ds_user_id=") && ready) {
+ returnCookieResult(mainCookie);
}
}
};
+
+ private void returnCookieResult(final String mainCookie) {
+ final Intent intent = new Intent();
+ intent.putExtra("cookie", mainCookie);
+ setResult(Constants.LOGIN_RESULT_CODE, intent);
+ finish();
+ }
+
private final WebChromeClient webChromeClient = new WebChromeClient();
private String webViewUrl, defaultUserAgent;
private boolean ready = false;
@@ -65,16 +73,15 @@ public final class Login extends BaseLanguageActivity implements View.OnClickLis
public void onClick(final View v) {
if (v == loginBinding.refresh) {
loginBinding.webView.loadUrl("https://instagram.com/");
- } else if (v == loginBinding.cookies) {
- final String mainCookie = Utils.getCookie(webViewUrl);
- if (Utils.isEmpty(mainCookie) || !mainCookie.contains("; ds_user_id="))
+ return;
+ }
+ if (v == loginBinding.cookies) {
+ final String mainCookie = CookieUtils.getCookie(webViewUrl);
+ if (TextUtils.isEmpty(mainCookie) || !mainCookie.contains("; ds_user_id=")) {
Toast.makeText(this, R.string.login_error_loading_cookies, Toast.LENGTH_SHORT).show();
- else {
- Utils.setupCookies(mainCookie);
- settingsHelper.putString(Constants.COOKIE, mainCookie);
- Toast.makeText(this, R.string.login_success_loading_cookies, Toast.LENGTH_SHORT).show();
- finish();
+ return;
}
+ returnCookieResult(mainCookie);
}
}
@@ -82,8 +89,9 @@ public final class Login extends BaseLanguageActivity implements View.OnClickLis
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
final WebSettings webSettings = loginBinding.webView.getSettings();
- final String newUserAgent = isChecked ? "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
- : defaultUserAgent;
+ final String newUserAgent = isChecked
+ ? "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
+ : defaultUserAgent;
webSettings.setUserAgentString(newUserAgent);
webSettings.setUseWideViewPort(isChecked);
@@ -95,7 +103,6 @@ public final class Login extends BaseLanguageActivity implements View.OnClickLis
}
@SuppressLint("SetJavaScriptEnabled")
- @SuppressWarnings("deprecation")
private void initWebView() {
if (loginBinding != null) {
loginBinding.webView.setWebChromeClient(webChromeClient);
diff --git a/app/src/main/java/awais/instagrabber/activities/Main.java b/app/src/main/java/awais/instagrabber/activities/Main.java
deleted file mode 100755
index f3c19720..00000000
--- a/app/src/main/java/awais/instagrabber/activities/Main.java
+++ /dev/null
@@ -1,602 +0,0 @@
-package awais.instagrabber.activities;
-
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.database.MatrixCursor;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.PersistableBundle;
-import android.provider.BaseColumns;
-import android.text.TextUtils;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.AutoCompleteTextView;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.widget.SearchView;
-import androidx.core.app.NotificationCompat;
-import androidx.fragment.app.FragmentManager;
-import androidx.recyclerview.widget.GridLayoutManager;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Stack;
-
-import awais.instagrabber.BuildConfig;
-import awais.instagrabber.MainHelper;
-import awais.instagrabber.R;
-import awais.instagrabber.adapters.HighlightsAdapter;
-import awais.instagrabber.adapters.SuggestionsAdapter;
-import awais.instagrabber.asyncs.GetActivityAsyncTask;
-import awais.instagrabber.asyncs.SuggestionsFetcher;
-import awais.instagrabber.asyncs.UsernameFetcher;
-import awais.instagrabber.asyncs.i.iStoryStatusFetcher;
-import awais.instagrabber.customviews.MouseDrawer;
-import awais.instagrabber.databinding.ActivityMainBinding;
-import awais.instagrabber.dialogs.AboutDialog;
-import awais.instagrabber.dialogs.QuickAccessDialog;
-import awais.instagrabber.dialogs.SettingsDialog;
-import awais.instagrabber.interfaces.FetchListener;
-import awais.instagrabber.interfaces.ItemGetter;
-import awais.instagrabber.models.DiscoverItemModel;
-import awais.instagrabber.models.FeedModel;
-import awais.instagrabber.models.HashtagModel;
-import awais.instagrabber.models.HighlightModel;
-import awais.instagrabber.models.LocationModel;
-import awais.instagrabber.models.PostModel;
-import awais.instagrabber.models.ProfileModel;
-import awais.instagrabber.models.StoryModel;
-import awais.instagrabber.models.SuggestionModel;
-import awais.instagrabber.models.enums.DownloadMethod;
-import awais.instagrabber.models.enums.ItemGetType;
-import awais.instagrabber.models.enums.SuggestionType;
-import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.DataBox;
-import awais.instagrabber.utils.FlavorTown;
-import awais.instagrabber.utils.Utils;
-
-import static awais.instagrabber.utils.Utils.CHANNEL_ID;
-import static awais.instagrabber.utils.Utils.notificationManager;
-import static awais.instagrabber.utils.Utils.settingsHelper;
-
-public final class Main extends BaseLanguageActivity {
- private static final int INITIAL_DELAY_MILLIS = 200;
- private static final int DELAY_MILLIS = 60000;
- public static FetchListener scanHack;
- public static ItemGetter itemGetter;
- // -------- items --------
- public final ArrayList allItems = new ArrayList<>();
- public final ArrayList feedItems = new ArrayList<>();
- public final ArrayList discoverItems = new ArrayList<>();
- // -------- items --------
- public final ArrayList selectedItems = new ArrayList<>();
- public final ArrayList selectedDiscoverItems = new ArrayList<>();
- // -------- items --------
- public final HighlightsAdapter highlightsAdapter = new HighlightsAdapter(null, new View.OnClickListener() {
- @Override
- public void onClick(final View v) {
- final Object tag = v.getTag();
- if (tag instanceof HighlightModel) {
- final HighlightModel highlightModel = (HighlightModel) tag;
- new iStoryStatusFetcher(highlightModel.getId(), null, false, false,
- (!mainHelper.isLoggedIn && Utils.settingsHelper.getBoolean(Constants.STORIESIG)), true, result -> {
- if (result != null && result.length > 0)
- startActivity(new Intent(Main.this, StoryViewer.class)
- .putExtra(Constants.EXTRAS_USERNAME, userQuery.replace("@", ""))
- .putExtra(Constants.EXTRAS_HIGHLIGHT, highlightModel.getTitle())
- .putExtra(Constants.EXTRAS_STORIES, result)
- );
- else
- Toast.makeText(Main.this, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
- });
- private SuggestionsAdapter suggestionAdapter;
- private MenuItem searchAction;
- public ActivityMainBinding mainBinding;
- public SearchView searchView;
- public MenuItem downloadAction, settingsAction, dmsAction, notifAction;
- public StoryModel[] storyModels;
- public String userQuery = null, cookie, uid = null;
- public MainHelper mainHelper;
- public ProfileModel profileModel;
- public HashtagModel hashtagModel;
- public LocationModel locationModel;
- private AutoCompleteTextView searchAutoComplete;
- private ArrayAdapter profileDialogAdapter;
- private DialogInterface.OnClickListener profileDialogListener;
- private Stack queriesStack;
- private DataBox.CookieModel cookieModel;
- private Runnable runnable;
- private Handler handler;
-
- @Override
- protected void onCreate(@Nullable final Bundle bundle) {
- super.onCreate(bundle);
- mainBinding = ActivityMainBinding.inflate(getLayoutInflater());
- setContentView(mainBinding.getRoot());
-
- if (settingsHelper.getBoolean(Constants.CHECK_UPDATES)) FlavorTown.updateCheck(this);
- FlavorTown.changelogCheck(this);
-
- cookie = settingsHelper.getString(Constants.COOKIE);
- uid = Utils.getUserIdFromCookie(cookie);
- Utils.setupCookies(cookie);
-
- MainHelper.stopCurrentExecutor();
- mainHelper = new MainHelper(this);
- if (bundle == null) {
- queriesStack = new Stack<>();
- userQuery = null;
- } else {
- setStack(bundle);
- userQuery = bundle.getString("query");
- }
- mainHelper.isLoggedIn = !Utils.isEmpty(Utils.settingsHelper.getString(Constants.COOKIE));
-
- itemGetter = itemGetType -> {
- if (itemGetType == ItemGetType.MAIN_ITEMS) return allItems;
- if (itemGetType == ItemGetType.DISCOVER_ITEMS) return discoverItems;
- if (itemGetType == ItemGetType.FEED_ITEMS) return feedItems;
- return null;
- };
-
- scanHack = result -> {
- if (mainHelper != null && !Utils.isEmpty(result)) {
- closeAnyOpenDrawer();
- addToStack();
- userQuery = (result.contains("/") || result.startsWith("#") || result.startsWith("@")) ? result : ("@" + result);
- mainHelper.onRefresh();
- }
- };
-
- // searches for your userid and returns username
- if (uid != null) {
- final FetchListener fetchListener = username -> {
- if (!Utils.isEmpty(username)) {
- if (!BuildConfig.DEBUG) {
- userQuery = username;
- if (mainHelper != null && !mainBinding.profileView.swipeRefreshLayout.isRefreshing())
- mainHelper.onRefresh();
- }
- // adds cookies to database for quick access
- cookieModel = Utils.dataBox.getCookie(uid);
- if (Utils.dataBox.getCookieCount() == 0 || cookieModel == null || Utils.isEmpty(cookieModel.getUsername()))
- Utils.dataBox.addUserCookie(new DataBox.CookieModel(uid, username, cookie));
- }
- };
- boolean found = false;
- cookieModel = Utils.dataBox.getCookie(uid);
- if (cookieModel != null) {
- final String username = cookieModel.getUsername();
- if (username != null) {
- found = true;
- fetchListener.onResult("@" + username);
- }
- }
-
- if (!found) // if not in database, fetch info from instagram
- new UsernameFetcher(uid, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- suggestionAdapter = new SuggestionsAdapter(this, v -> {
- final Object tag = v.getTag();
- if (tag instanceof CharSequence) {
- addToStack();
- userQuery = tag.toString();
- mainHelper.onRefresh();
- }
- if (searchView != null && !searchView.isIconified()) {
- if (searchAction != null) searchAction.collapseActionView();
- searchView.setIconified(true);
- searchView.setIconified(true);
- }
- });
-
- final Resources resources = getResources();
- profileDialogAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
- new String[]{resources.getString(R.string.view_pfp), resources.getString(R.string.show_stories)});
- profileDialogListener = (dialog, which) -> {
- final Intent intent;
- if (which == 0 || storyModels == null || storyModels.length < 1) {
- intent = new Intent(this, ProfilePicViewer.class).putExtra(
- ((hashtagModel != null) ? Constants.EXTRAS_HASHTAG : (locationModel != null ? Constants.EXTRAS_LOCATION : Constants.EXTRAS_PROFILE)),
- ((hashtagModel != null) ? hashtagModel : (locationModel != null ? locationModel : profileModel)));
- } else
- intent = new Intent(this, StoryViewer.class).putExtra(Constants.EXTRAS_USERNAME, userQuery.replace("@", ""))
- .putExtra(Constants.EXTRAS_STORIES, storyModels)
- .putExtra(Constants.EXTRAS_HASHTAG, (hashtagModel != null));
- startActivity(intent);
- };
-
- final View.OnClickListener onClickListener = v -> {
- if (v == mainBinding.profileView.mainBiography) {
- Utils.copyText(this, mainBinding.profileView.mainBiography.getText().toString());
- } else if (v == mainBinding.profileView.locationBiography) {
- Utils.copyText(this, mainBinding.profileView.locationBiography.getText().toString());
- } else if (v == mainBinding.profileView.mainProfileImage || v == mainBinding.profileView.mainHashtagImage || v == mainBinding.profileView.mainLocationImage) {
- if (storyModels == null || storyModels.length <= 0) {
- profileDialogListener.onClick(null, 0);
- } else {
- // because sometimes configuration changes made this crash on some phones
- new AlertDialog.Builder(this).setAdapter(profileDialogAdapter, profileDialogListener)
- .setNeutralButton(R.string.cancel, null).show();
- }
- }
- };
-
- mainBinding.profileView.mainBiography.setOnClickListener(onClickListener);
- mainBinding.profileView.locationBiography.setOnClickListener(onClickListener);
- mainBinding.profileView.mainProfileImage.setOnClickListener(onClickListener);
- mainBinding.profileView.mainHashtagImage.setOnClickListener(onClickListener);
- mainBinding.profileView.mainLocationImage.setOnClickListener(onClickListener);
-
- mainBinding.profileView.mainBiography.setEnabled(false);
- mainBinding.profileView.mainProfileImage.setEnabled(false);
- mainBinding.profileView.mainHashtagImage.setEnabled(false);
- mainBinding.profileView.mainLocationImage.setEnabled(false);
-
- final boolean isQueryNull = userQuery == null;
- if (isQueryNull) {
- allItems.clear();
- mainBinding.profileView.privatePage1.setImageResource(R.drawable.ic_info);
- mainBinding.profileView.privatePage2.setTextSize(20);
- mainBinding.profileView.privatePage2.setText(mainHelper.isLoggedIn ? R.string.no_acc_logged_in : R.string.no_acc);
- mainBinding.profileView.privatePage.setVisibility(View.VISIBLE);
- }
- if (!mainBinding.profileView.swipeRefreshLayout.isRefreshing() && userQuery != null)
- mainHelper.onRefresh();
-
- mainHelper.onIntent(getIntent());
-
- handler = new Handler();
- runnable = () -> {
- final GetActivityAsyncTask activityAsyncTask = new GetActivityAsyncTask(uid, cookie, result -> {
- if (result == null || notificationManager == null) {
- return;
- }
- final List list = new ArrayList<>();
- if (result.getRelationshipsCount() != 0) {
- list.add(getString(R.string.activity_count_relationship, result.getRelationshipsCount()));
- }
- if (result.getUserTagsCount() != 0) {
- list.add(getString(R.string.activity_count_usertags, result.getUserTagsCount()));
- }
- if (result.getCommentsCount() != 0) {
- list.add(getString(R.string.activity_count_comments, result.getCommentsCount()));
- }
- if (result.getCommentLikesCount() != 0) {
- list.add(getString(R.string.activity_count_commentlikes, result.getCommentLikesCount()));
- }
- if (result.getLikesCount() != 0) {
- list.add(getString(R.string.activity_count_likes, result.getLikesCount()));
- }
- if (list.isEmpty()) {
- return;
- }
- final String join = TextUtils.join(", ", list);
- final String notificationString = getString(R.string.activity_count_prefix) + " " + join + ".";
- final Intent intent = new Intent(getApplicationContext(), NotificationsViewer.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- final Notification notification = new NotificationCompat.Builder(Main.this, CHANNEL_ID)
- .setCategory(NotificationCompat.CATEGORY_STATUS)
- .setSmallIcon(R.drawable.ic_notif)
- .setAutoCancel(true)
- .setPriority(NotificationCompat.PRIORITY_MIN)
- .setContentText(notificationString)
- .setContentIntent(PendingIntent.getActivity(getApplicationContext(), 1738, intent, PendingIntent.FLAG_UPDATE_CURRENT))
- .build();
- notificationManager.cancel(1800000000);
- notificationManager.notify(1800000000, notification);
- });
- if (!Utils.isEmpty(cookie) && Utils.settingsHelper.getBoolean(Constants.CHECK_ACTIVITY)) activityAsyncTask.execute();
- handler.postDelayed(runnable, DELAY_MILLIS);
- };
- handler.postDelayed(runnable, INITIAL_DELAY_MILLIS);
- }
-
- private void downloadSelectedItems() {
- if (selectedItems.size() > 0) {
- Utils.batchDownload(this, userQuery, DownloadMethod.DOWNLOAD_MAIN, selectedItems);
- } else if (selectedDiscoverItems.size() > 0) {
- Utils.batchDownload(this, null, DownloadMethod.DOWNLOAD_DISCOVER, selectedDiscoverItems);
- }
- }
-
- @Override
- protected void onNewIntent(final Intent intent) {
- super.onNewIntent(intent);
- mainHelper.onIntent(intent);
- }
-
- @Override
- public void onSaveInstanceState(@NonNull final Bundle outState, @NonNull final PersistableBundle outPersistentState) {
- outState.putString("query", userQuery);
- outState.putSerializable("stack", queriesStack);
- super.onSaveInstanceState(outState, outPersistentState);
- }
-
- @Override
- public void onRestoreInstanceState(@Nullable final Bundle savedInstanceState, @Nullable final PersistableBundle persistentState) {
- super.onRestoreInstanceState(savedInstanceState, persistentState);
- if (savedInstanceState != null) {
- userQuery = savedInstanceState.getString("query");
- setStack(savedInstanceState);
- }
- }
-
- @Override
- protected void onSaveInstanceState(@NonNull final Bundle outState) {
- outState.putString("query", userQuery);
- outState.putSerializable("stack", queriesStack);
- super.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) {
- super.onRestoreInstanceState(savedInstanceState);
- userQuery = savedInstanceState.getString("query");
- setStack(savedInstanceState);
- }
-
- @Override
- public boolean onCreateOptionsMenu(final Menu menu) {
- getMenuInflater().inflate(R.menu.menu, menu);
-
- final FragmentManager fragmentManager = getSupportFragmentManager();
- final MenuItem quickAccessAction = menu.findItem(R.id.action_quickaccess).setVisible(true);
-
- final MenuItem.OnMenuItemClickListener clickListener = item -> {
- if (item == downloadAction)
- downloadSelectedItems();
- else if (item == dmsAction)
- startActivity(new Intent(this, DirectMessagesActivity.class));
- else if (item == notifAction)
- startActivity(new Intent(this, NotificationsViewer.class));
- else if (item == settingsAction)
- new SettingsDialog().show(fragmentManager, "settings");
- else if (item == quickAccessAction)
- new QuickAccessDialog()
- .setQuery(userQuery, locationModel != null ? locationModel.getName() : userQuery)
- .show(fragmentManager, "quickAccess");
- else
- new AboutDialog().show(fragmentManager, "about");
- return true;
- };
-
- quickAccessAction.setOnMenuItemClickListener(clickListener);
- menu.findItem(R.id.action_about).setVisible(true).setOnMenuItemClickListener(clickListener);
- dmsAction = menu.findItem(R.id.action_dms).setOnMenuItemClickListener(clickListener);
- notifAction = menu.findItem(R.id.action_notif).setOnMenuItemClickListener(clickListener);
- settingsAction = menu.findItem(R.id.action_settings).setVisible(true).setOnMenuItemClickListener(clickListener);
- downloadAction = menu.findItem(R.id.action_download).setOnMenuItemClickListener(clickListener);
-
- if (!Utils.isEmpty(Utils.settingsHelper.getString(Constants.COOKIE))) {
- notifAction.setVisible(true);
- dmsAction.setVisible(true).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
- }
-
- searchAction = menu.findItem(R.id.action_search);
- searchView = (SearchView) searchAction.getActionView();
- final View searchText = searchView.findViewById(R.id.search_src_text);
- if (searchText instanceof AutoCompleteTextView)
- searchAutoComplete = (AutoCompleteTextView) searchText;
-
- searchView.setQueryHint(getResources().getString(R.string.action_search));
- searchView.setSuggestionsAdapter(suggestionAdapter);
- searchView.setOnSearchClickListener(v -> {
- searchView.setQuery((cookieModel != null && userQuery != null && userQuery.equals("@" + cookieModel.getUsername())) ? "" : userQuery, false);
- menu.findItem(R.id.action_about).setVisible(false);
- menu.findItem(R.id.action_settings).setVisible(false);
- menu.findItem(R.id.action_dms).setVisible(false);
- menu.findItem(R.id.action_quickaccess).setVisible(false);
- menu.findItem(R.id.action_notif).setVisible(false);
- });
- searchAction.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
- @Override
- public boolean onMenuItemActionExpand(MenuItem item) {
- return true;
- }
-
- @Override
- public boolean onMenuItemActionCollapse(MenuItem item) {
- menu.findItem(R.id.action_about).setVisible(true);
- menu.findItem(R.id.action_settings).setVisible(true);
- menu.findItem(R.id.action_dms).setVisible(!Utils.isEmpty(Utils.settingsHelper.getString(Constants.COOKIE)));
- menu.findItem(R.id.action_quickaccess).setVisible(true);
- menu.findItem(R.id.action_notif).setVisible(true);
- return true;
- }
- });
- searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
- private boolean searchUser, searchHash;
- private AsyncTask, ?, ?> prevSuggestionAsync;
- private final String[] COLUMNS = {BaseColumns._ID, Constants.EXTRAS_USERNAME, Constants.EXTRAS_NAME,
- Constants.EXTRAS_TYPE, "pfp", "verified"};
- private final FetchListener fetchListener = new FetchListener() {
- @Override
- public void doBefore() {
- suggestionAdapter.changeCursor(null);
- }
-
- @Override
- public void onResult(final SuggestionModel[] result) {
- final MatrixCursor cursor;
- if (result == null) cursor = null;
- else {
- cursor = new MatrixCursor(COLUMNS, 0);
- for (int i = 0; i < result.length; i++) {
- final SuggestionModel suggestionModel = result[i];
- if (suggestionModel != null) {
- final SuggestionType suggestionType = suggestionModel.getSuggestionType();
- final Object[] objects = {i,
- (suggestionType == SuggestionType.TYPE_LOCATION) ? suggestionModel.getName() : suggestionModel.getUsername(),
- (suggestionType == SuggestionType.TYPE_LOCATION) ? suggestionModel.getUsername() : suggestionModel.getName(),
- suggestionType, suggestionModel.getProfilePic(), suggestionModel.isVerified()};
-
- if (!searchHash && !searchUser) cursor.addRow(objects);
- else {
- final boolean isCurrHash = suggestionType == SuggestionType.TYPE_HASHTAG;
- if (searchHash && isCurrHash || !searchHash && !isCurrHash)
- cursor.addRow(objects);
- }
- }
- }
- }
- suggestionAdapter.changeCursor(cursor);
- }
- };
-
- private void cancelSuggestionsAsync() {
- if (prevSuggestionAsync != null)
- try {
- prevSuggestionAsync.cancel(true);
- } catch (final Exception ignored) {
- }
- }
-
- @Override
- public boolean onQueryTextSubmit(final String query) {
- cancelSuggestionsAsync();
- menu.findItem(R.id.action_about).setVisible(true);
- menu.findItem(R.id.action_settings).setVisible(true);
-
- closeAnyOpenDrawer();
- addToStack();
- userQuery = (query.contains("@") || query.contains("#")) ? query : ("@" + query);
- searchAction.collapseActionView();
- searchView.setIconified(true);
- searchView.setIconified(true);
- mainHelper.onRefresh();
- return false;
- }
-
- @Override
- public boolean onQueryTextChange(final String newText) {
- cancelSuggestionsAsync();
-
- if (!Utils.isEmpty(newText)) {
- searchUser = newText.charAt(0) == '@';
- searchHash = newText.charAt(0) == '#';
-
- if (newText.length() == 1 && (searchHash || searchUser)) {
- if (searchAutoComplete != null) searchAutoComplete.setThreshold(2);
- } else {
- if (searchAutoComplete != null) searchAutoComplete.setThreshold(1);
- prevSuggestionAsync = new SuggestionsFetcher(fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
- searchUser || searchHash ? newText.substring(1) : newText);
- }
- }
- return true;
- }
- });
-
- return true;
- }
-
- @Override
- public void onBackPressed() {
- if (closeAnyOpenDrawer()) return;
-
- if (searchView != null && !searchView.isIconified()) {
- if (searchAction != null) searchAction.collapseActionView();
- searchView.setIconified(true);
- searchView.setIconified(true);
- return;
- }
-
- if (!mainHelper.isSelectionCleared()) return;
-
- final GridLayoutManager layoutManager = (GridLayoutManager) mainBinding.profileView.mainPosts.getLayoutManager();
- if (layoutManager != null && layoutManager.findFirstCompletelyVisibleItemPosition() >= layoutManager.getSpanCount()) {
- mainBinding.profileView.mainPosts.smoothScrollToPosition(0);
- mainBinding.profileView.appBarLayout.setExpanded(true, true);
- return;
- }
-
- if (queriesStack != null && queriesStack.size() > 0) {
- userQuery = queriesStack.pop();
- if (userQuery != null) {
- mainHelper.onRefresh();
- return;
- }
- } else {
- finish();
- }
- }
-
- @Override
- public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- if (requestCode == 8020 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
- downloadSelectedItems();
- }
-
- @Override
- protected void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == 9629 && (resultCode == 1692 || resultCode == RESULT_CANCELED))
- finish();
- else if (requestCode == 6007)
- Utils.showImportExportDialog(this);
- else if (requestCode == 6969 && mainHelper.currentFeedPlayer != null)
- mainHelper.currentFeedPlayer.setPlayWhenReady(true);
- }
-
- @Override
- protected void onPause() {
- if (mainHelper != null) mainHelper.onPause();
- if (handler != null && runnable != null) {
- handler.removeCallbacks(runnable);
- }
- super.onPause();
- }
-
- @Override
- protected void onResume() {
- if (mainHelper != null) mainHelper.onResume();
- if (handler != null && runnable != null) {
- handler.postDelayed(runnable, INITIAL_DELAY_MILLIS);
- }
- super.onResume();
- }
-
- private void setStack(final Bundle bundle) {
- final Object stack = bundle != null ? bundle.get("stack") : null;
- if (stack instanceof Stack) //noinspection unchecked
- queriesStack = (Stack) stack;
- }
-
- public void addToStack() {
- if (userQuery != null) {
- if (queriesStack == null) queriesStack = new Stack<>();
- queriesStack.add(userQuery);
- }
- }
-
- private boolean closeAnyOpenDrawer() {
- final int childCount = mainBinding.drawerLayout.getChildCount();
- for (int i = 0; i < childCount; i++) {
- final View child = mainBinding.drawerLayout.getChildAt(i);
- final MouseDrawer.LayoutParams childLp = (MouseDrawer.LayoutParams) child.getLayoutParams();
-
- if ((childLp.openState & MouseDrawer.LayoutParams.FLAG_IS_OPENED) == 1 ||
- (childLp.openState & MouseDrawer.LayoutParams.FLAG_IS_OPENING) == 2 ||
- childLp.onScreen >= 0.6 || childLp.isPeeking) {
- mainBinding.drawerLayout.closeDrawer(child);
- return true;
- }
- }
- return false;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/activities/MainActivity.java b/app/src/main/java/awais/instagrabber/activities/MainActivity.java
new file mode 100644
index 00000000..7f9338b8
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/activities/MainActivity.java
@@ -0,0 +1,585 @@
+package awais.instagrabber.activities;
+
+
+import android.annotation.SuppressLint;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.res.TypedArray;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.provider.BaseColumns;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AutoCompleteTextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.SearchView;
+import androidx.appcompat.widget.Toolbar;
+import androidx.coordinatorlayout.widget.CoordinatorLayout;
+import androidx.core.app.NotificationManagerCompat;
+import androidx.lifecycle.LiveData;
+import androidx.navigation.NavBackStackEntry;
+import androidx.navigation.NavController;
+import androidx.navigation.NavDestination;
+import androidx.navigation.NavDirections;
+import androidx.navigation.ui.NavigationUI;
+
+import com.google.android.material.appbar.AppBarLayout;
+import com.google.android.material.appbar.CollapsingToolbarLayout;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import awais.instagrabber.R;
+import awais.instagrabber.adapters.SuggestionsAdapter;
+import awais.instagrabber.asyncs.SuggestionsFetcher;
+import awais.instagrabber.customviews.helpers.CustomHideBottomViewOnScrollBehavior;
+import awais.instagrabber.databinding.ActivityMainBinding;
+import awais.instagrabber.fragments.settings.MorePreferencesFragmentDirections;
+import awais.instagrabber.interfaces.FetchListener;
+import awais.instagrabber.models.IntentModel;
+import awais.instagrabber.models.SuggestionModel;
+import awais.instagrabber.models.enums.SuggestionType;
+import awais.instagrabber.services.ActivityCheckerService;
+import awais.instagrabber.utils.Constants;
+import awais.instagrabber.utils.CookieUtils;
+import awais.instagrabber.utils.FlavorTown;
+import awais.instagrabber.utils.IntentUtils;
+import awais.instagrabber.utils.TextUtils;
+
+import static awais.instagrabber.utils.NavigationExtensions.setupWithNavController;
+import static awais.instagrabber.utils.Utils.settingsHelper;
+
+public class MainActivity extends BaseLanguageActivity {
+ private static final String TAG = "MainActivity";
+
+ private static final List SHOW_BOTTOM_VIEW_DESTINATIONS = Arrays.asList(
+ R.id.directMessagesInboxFragment,
+ R.id.feedFragment,
+ R.id.profileFragment,
+ R.id.discoverFragment,
+ R.id.morePreferencesFragment);
+ private static final List KEEP_SCROLL_BEHAVIOUR_DESTINATIONS = Arrays.asList(
+ R.id.directMessagesInboxFragment,
+ R.id.feedFragment,
+ R.id.profileFragment,
+ R.id.discoverFragment,
+ R.id.morePreferencesFragment,
+ R.id.settingsPreferencesFragment,
+ R.id.aboutFragment,
+ R.id.hashTagFragment,
+ R.id.locationFragment,
+ R.id.savedViewerFragment,
+ R.id.commentsViewerFragment,
+ R.id.followViewerFragment,
+ R.id.directMessagesSettingsFragment,
+ R.id.notificationsViewer,
+ R.id.themePreferencesFragment);
+ private static final Map NAV_TO_MENU_ID_MAP = new HashMap<>();
+ private static final List REMOVE_COLLAPSING_TOOLBAR_SCROLL_DESTINATIONS = Collections.singletonList(R.id.commentsViewerFragment);
+ private static final String FIRST_FRAGMENT_GRAPH_INDEX_KEY = "firstFragmentGraphIndex";
+
+ private ActivityMainBinding binding;
+ private LiveData currentNavControllerLiveData;
+ private MenuItem searchMenuItem;
+ private SuggestionsAdapter suggestionAdapter;
+ private AutoCompleteTextView searchAutoComplete;
+ private SearchView searchView;
+ private boolean showSearch = true;
+ private Handler suggestionsFetchHandler;
+ private int firstFragmentGraphIndex;
+ private boolean isActivityCheckerServiceBound = false;
+
+ private final ServiceConnection serviceConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(final ComponentName name, final IBinder service) {
+ // final ActivityCheckerService.LocalBinder binder = (ActivityCheckerService.LocalBinder) service;
+ // final ActivityCheckerService activityCheckerService = binder.getService();
+ isActivityCheckerServiceBound = true;
+ }
+
+ @Override
+ public void onServiceDisconnected(final ComponentName name) {
+ isActivityCheckerServiceBound = false;
+ }
+ };
+
+ static {
+ NAV_TO_MENU_ID_MAP.put(R.navigation.direct_messages_nav_graph, R.id.direct_messages_nav_graph);
+ NAV_TO_MENU_ID_MAP.put(R.navigation.feed_nav_graph, R.id.feed_nav_graph);
+ NAV_TO_MENU_ID_MAP.put(R.navigation.profile_nav_graph, R.id.profile_nav_graph);
+ NAV_TO_MENU_ID_MAP.put(R.navigation.discover_nav_graph, R.id.discover_nav_graph);
+ NAV_TO_MENU_ID_MAP.put(R.navigation.more_nav_graph, R.id.more_nav_graph);
+ }
+
+ @Override
+ protected void onCreate(@Nullable final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ binding = ActivityMainBinding.inflate(getLayoutInflater());
+ final String cookie = settingsHelper.getString(Constants.COOKIE);
+ CookieUtils.setupCookies(cookie);
+ setContentView(binding.getRoot());
+ final Toolbar toolbar = binding.toolbar;
+ setSupportActionBar(toolbar);
+ createNotificationChannels();
+ if (savedInstanceState == null) {
+ setupBottomNavigationBar(true);
+ }
+ setupScrollingListener();
+ setupSuggestions();
+ final boolean checkUpdates = settingsHelper.getBoolean(Constants.CHECK_UPDATES);
+ if (checkUpdates) FlavorTown.updateCheck(this);
+ FlavorTown.changelogCheck(this);
+ final Intent intent = getIntent();
+ handleIntent(intent);
+ if (!TextUtils.isEmpty(cookie) && settingsHelper.getBoolean(Constants.CHECK_ACTIVITY)) {
+ bindActivityCheckerService();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(final Menu menu) {
+ getMenuInflater().inflate(R.menu.main_menu, menu);
+ searchMenuItem = menu.findItem(R.id.search);
+ if (showSearch && currentNavControllerLiveData != null && currentNavControllerLiveData.getValue() != null) {
+ final NavController navController = currentNavControllerLiveData.getValue();
+ final NavDestination currentDestination = navController.getCurrentDestination();
+ if (currentDestination != null) {
+ final int destinationId = currentDestination.getId();
+ showSearch = destinationId == R.id.profileFragment;
+ }
+ }
+ if (!showSearch) {
+ searchMenuItem.setVisible(false);
+ return true;
+ }
+ return setupSearchView();
+ }
+
+ @Override
+ protected void onSaveInstanceState(@NonNull final Bundle outState) {
+ outState.putString(FIRST_FRAGMENT_GRAPH_INDEX_KEY, String.valueOf(firstFragmentGraphIndex));
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ final String key = (String) savedInstanceState.get(FIRST_FRAGMENT_GRAPH_INDEX_KEY);
+ if (key != null) {
+ try {
+ firstFragmentGraphIndex = Integer.parseInt(key);
+ } catch (NumberFormatException ignored) { }
+ }
+ setupBottomNavigationBar(false);
+ }
+
+ @Override
+ public boolean onSupportNavigateUp() {
+ if (currentNavControllerLiveData != null && currentNavControllerLiveData.getValue() != null) {
+ return currentNavControllerLiveData.getValue().navigateUp();
+ }
+ return false;
+ }
+
+ @Override
+ protected void onNewIntent(final Intent intent) {
+ super.onNewIntent(intent);
+ handleIntent(intent);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ unbindActivityCheckerService();
+ }
+
+ private void createNotificationChannels() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getApplicationContext());
+ notificationManager.createNotificationChannel(new NotificationChannel(Constants.DOWNLOAD_CHANNEL_ID,
+ Constants.DOWNLOAD_CHANNEL_NAME,
+ NotificationManager.IMPORTANCE_DEFAULT));
+ notificationManager.createNotificationChannel(new NotificationChannel(Constants.ACTIVITY_CHANNEL_ID,
+ Constants.ACTIVITY_CHANNEL_NAME,
+ NotificationManager.IMPORTANCE_DEFAULT));
+ }
+ }
+
+ private void setupSuggestions() {
+ suggestionsFetchHandler = new Handler();
+ suggestionAdapter = new SuggestionsAdapter(this, (type, query) -> {
+ if (searchMenuItem != null) searchMenuItem.collapseActionView();
+ if (searchView != null && !searchView.isIconified()) searchView.setIconified(true);
+ if (currentNavControllerLiveData != null && currentNavControllerLiveData.getValue() != null) {
+ final NavController navController = currentNavControllerLiveData.getValue();
+ final Bundle bundle = new Bundle();
+ switch (type) {
+ case TYPE_LOCATION:
+ bundle.putString("locationId", query);
+ navController.navigate(R.id.action_global_locationFragment, bundle);
+ break;
+ case TYPE_HASHTAG:
+ bundle.putString("hashtag", query);
+ navController.navigate(R.id.action_global_hashTagFragment, bundle);
+ break;
+ case TYPE_USER:
+ bundle.putString("username", query);
+ navController.navigate(R.id.action_global_profileFragment, bundle);
+ break;
+ }
+ }
+ });
+ }
+
+ private void setupScrollingListener() {
+ final CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) binding.bottomNavView.getLayoutParams();
+ layoutParams.setBehavior(new CustomHideBottomViewOnScrollBehavior());
+ binding.bottomNavView.requestLayout();
+ }
+
+ private boolean setupSearchView() {
+ final View actionView = searchMenuItem.getActionView();
+ if (!(actionView instanceof SearchView)) return false;
+ searchView = (SearchView) actionView;
+ searchView.setSuggestionsAdapter(suggestionAdapter);
+ searchView.setMaxWidth(Integer.MAX_VALUE);
+ final View searchText = searchView.findViewById(R.id.search_src_text);
+ if (searchText instanceof AutoCompleteTextView) {
+ searchAutoComplete = (AutoCompleteTextView) searchText;
+ }
+ searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+ private boolean searchUser;
+ private boolean searchHash;
+ private AsyncTask, ?, ?> prevSuggestionAsync;
+ private final String[] COLUMNS = {
+ BaseColumns._ID,
+ Constants.EXTRAS_USERNAME,
+ Constants.EXTRAS_NAME,
+ Constants.EXTRAS_TYPE,
+ "pfp",
+ "verified"
+ };
+ private String currentSearchQuery;
+
+ private final FetchListener fetchListener = new FetchListener() {
+ @Override
+ public void doBefore() {
+ suggestionAdapter.changeCursor(null);
+ }
+
+ @Override
+ public void onResult(final SuggestionModel[] result) {
+ final MatrixCursor cursor;
+ if (result == null) cursor = null;
+ else {
+ cursor = new MatrixCursor(COLUMNS, 0);
+ for (int i = 0; i < result.length; i++) {
+ final SuggestionModel suggestionModel = result[i];
+ if (suggestionModel != null) {
+ final SuggestionType suggestionType = suggestionModel.getSuggestionType();
+ final Object[] objects = {
+ i,
+ suggestionType == SuggestionType.TYPE_LOCATION ? suggestionModel.getName() : suggestionModel.getUsername(),
+ suggestionType == SuggestionType.TYPE_LOCATION ? suggestionModel.getUsername() : suggestionModel.getName(),
+ suggestionType,
+ suggestionModel.getProfilePic(),
+ suggestionModel.isVerified()};
+ if (!searchHash && !searchUser) cursor.addRow(objects);
+ else {
+ final boolean isCurrHash = suggestionType == SuggestionType.TYPE_HASHTAG;
+ if (searchHash && isCurrHash || !searchHash && !isCurrHash)
+ cursor.addRow(objects);
+ }
+ }
+ }
+ }
+ suggestionAdapter.changeCursor(cursor);
+ }
+ };
+
+ private final Runnable runnable = () -> {
+ cancelSuggestionsAsync();
+ if (TextUtils.isEmpty(currentSearchQuery)) {
+ suggestionAdapter.changeCursor(null);
+ return;
+ }
+ searchUser = currentSearchQuery.charAt(0) == '@';
+ searchHash = currentSearchQuery.charAt(0) == '#';
+ if (currentSearchQuery.length() == 1 && (searchHash || searchUser)) {
+ if (searchAutoComplete != null) {
+ searchAutoComplete.setThreshold(2);
+ }
+ } else {
+ if (searchAutoComplete != null) {
+ searchAutoComplete.setThreshold(1);
+ }
+ prevSuggestionAsync = new SuggestionsFetcher(fetchListener).executeOnExecutor(
+ AsyncTask.THREAD_POOL_EXECUTOR,
+ searchUser || searchHash ? currentSearchQuery.substring(1)
+ : currentSearchQuery);
+ }
+ };
+
+ private void cancelSuggestionsAsync() {
+ if (prevSuggestionAsync != null)
+ try {
+ prevSuggestionAsync.cancel(true);
+ } catch (final Exception ignored) {}
+ }
+
+ @Override
+ public boolean onQueryTextSubmit(final String query) {
+ return onQueryTextChange(query);
+ }
+
+ @Override
+ public boolean onQueryTextChange(final String query) {
+ suggestionsFetchHandler.removeCallbacks(runnable);
+ currentSearchQuery = query;
+ suggestionsFetchHandler.postDelayed(runnable, 800);
+ return true;
+ }
+ });
+ return true;
+ }
+
+ private void setupBottomNavigationBar(final boolean setDefaultFromSettings) {
+ int main_nav_ids = R.array.main_nav_ids;
+ final String cookie = settingsHelper.getString(Constants.COOKIE);
+ final boolean isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) != null;
+ if (!isLoggedIn) {
+ main_nav_ids = R.array.logged_out_main_nav_ids;
+ binding.bottomNavView.getMenu().clear();
+ binding.bottomNavView.inflateMenu(R.menu.logged_out_bottom_navigation_menu);
+ }
+ final TypedArray navIds = getResources().obtainTypedArray(main_nav_ids);
+ final List mainNavList = new ArrayList<>(navIds.length());
+ final int length = navIds.length();
+ for (int i = 0; i < length; i++) {
+ final int resourceId = navIds.getResourceId(i, -1);
+ if (resourceId < 0) continue;
+ mainNavList.add(resourceId);
+ }
+ navIds.recycle();
+ if (setDefaultFromSettings || !isLoggedIn) {
+ final String defaultTabIdString = settingsHelper.getString(Constants.DEFAULT_TAB);
+ try {
+ final int defaultNavId = TextUtils.isEmpty(defaultTabIdString) || !isLoggedIn
+ ? R.navigation.profile_nav_graph
+ : Integer.parseInt(defaultTabIdString);
+ final int index = mainNavList.indexOf(defaultNavId);
+ if (index >= 0) {
+ firstFragmentGraphIndex = index;
+ final Integer menuId = NAV_TO_MENU_ID_MAP.get(defaultNavId);
+ if (menuId != null) {
+ binding.bottomNavView.setSelectedItemId(menuId);
+ }
+ }
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "Error parsing id", e);
+ }
+ }
+ final LiveData navControllerLiveData = setupWithNavController(
+ binding.bottomNavView,
+ mainNavList,
+ getSupportFragmentManager(),
+ R.id.main_nav_host,
+ getIntent(),
+ firstFragmentGraphIndex);
+ navControllerLiveData.observe(this, this::setupNavigation);
+ currentNavControllerLiveData = navControllerLiveData;
+ }
+
+ private void setupNavigation(final NavController navController) {
+ NavigationUI.setupWithNavController(binding.toolbar, navController);
+ navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
+ // below is a hack to check if we are at the end of the current stack, to setup the search view
+ binding.appBarLayout.setExpanded(true, true);
+ final int destinationId = destination.getId();
+ @SuppressLint("RestrictedApi") final Deque backStack = navController.getBackStack();
+ setupMenu(backStack.size(), destinationId);
+ binding.bottomNavView.setVisibility(SHOW_BOTTOM_VIEW_DESTINATIONS.contains(destinationId) ? View.VISIBLE : View.GONE);
+ if (KEEP_SCROLL_BEHAVIOUR_DESTINATIONS.contains(destinationId)) {
+ setScrollingBehaviour();
+ } else {
+ removeScrollingBehaviour();
+ }
+ if (REMOVE_COLLAPSING_TOOLBAR_SCROLL_DESTINATIONS.contains(destinationId)) {
+ removeCollapsingToolbarScrollFlags();
+ } else {
+ setCollapsingToolbarScrollFlags();
+ }
+ });
+ }
+
+ private void setupMenu(final int backStackSize, final int destinationId) {
+ if (searchMenuItem == null) return;
+ if (backStackSize >= 2 && destinationId == R.id.profileFragment) {
+ showSearch = true;
+ searchMenuItem.setVisible(true);
+ return;
+ }
+ showSearch = false;
+ searchMenuItem.setVisible(false);
+ }
+
+ private void setScrollingBehaviour() {
+ final CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) binding.mainNavHost.getLayoutParams();
+ layoutParams.setBehavior(new AppBarLayout.ScrollingViewBehavior());
+ binding.mainNavHost.requestLayout();
+ }
+
+ private void removeScrollingBehaviour() {
+ final CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) binding.mainNavHost.getLayoutParams();
+ layoutParams.setBehavior(null);
+ binding.mainNavHost.requestLayout();
+ }
+
+ private void setCollapsingToolbarScrollFlags() {
+ final CollapsingToolbarLayout collapsingToolbarLayout = binding.collapsingToolbarLayout;
+ final AppBarLayout.LayoutParams toolbarLayoutLayoutParams = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams();
+ toolbarLayoutLayoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
+ | AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP
+ | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);
+ binding.collapsingToolbarLayout.requestLayout();
+ }
+
+ private void removeCollapsingToolbarScrollFlags() {
+ final CollapsingToolbarLayout collapsingToolbarLayout = binding.collapsingToolbarLayout;
+ final AppBarLayout.LayoutParams toolbarLayoutLayoutParams = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams();
+ toolbarLayoutLayoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL);
+ binding.collapsingToolbarLayout.requestLayout();
+ }
+
+ private void handleIntent(final Intent intent) {
+ if (intent == null) return;
+ final String action = intent.getAction();
+ final String type = intent.getType();
+ // Log.d(TAG, action + " " + type);
+ if (Intent.ACTION_MAIN.equals(action)) return;
+ if (Constants.ACTION_SHOW_ACTIVITY.equals(action)) {
+ showActivityView();
+ return;
+ }
+ if (Intent.ACTION_SEND.equals(action) && type != null) {
+ if (type.equals("text/plain")) {
+ handleUrl(intent.getStringExtra(Intent.EXTRA_TEXT));
+ }
+ return;
+ }
+ if (Intent.ACTION_VIEW.equals(action)) {
+ final Uri data = intent.getData();
+ if (data == null) return;
+ handleUrl(data.toString());
+ }
+ }
+
+ private void handleUrl(final String url) {
+ if (url == null) return;
+ // Log.d(TAG, url);
+ final IntentModel intentModel = IntentUtils.parseUrl(url);
+ if (intentModel == null) return;
+ showView(intentModel);
+ }
+
+ private void showView(final IntentModel intentModel) {
+ switch (intentModel.getType()) {
+ case USERNAME:
+ showProfileView(intentModel);
+ break;
+ case POST:
+ showPostView(intentModel);
+ break;
+ case LOCATION:
+ showLocationView(intentModel);
+ break;
+ case HASHTAG:
+ showHashtagView(intentModel);
+ break;
+ case UNKNOWN:
+ default:
+ Log.w(TAG, "Unknown model type received!");
+ }
+ }
+
+ private void showProfileView(@NonNull final IntentModel intentModel) {
+ final String username = intentModel.getText();
+ // Log.d(TAG, "username: " + username);
+ final NavController navController = currentNavControllerLiveData.getValue();
+ if (currentNavControllerLiveData == null || navController == null) return;
+ final Bundle bundle = new Bundle();
+ bundle.putString("username", "@" + username);
+ navController.navigate(R.id.action_global_profileFragment, bundle);
+ }
+
+ private void showPostView(@NonNull final IntentModel intentModel) {
+ final String shortCode = intentModel.getText();
+ // Log.d(TAG, "shortCode: " + shortCode);
+ final NavController navController = currentNavControllerLiveData.getValue();
+ if (currentNavControllerLiveData == null || navController == null) return;
+ final Bundle bundle = new Bundle();
+ bundle.putStringArray("idOrCodeArray", new String[]{shortCode});
+ bundle.putInt("index", 0);
+ bundle.putBoolean("isId", false);
+ navController.navigate(R.id.action_global_postViewFragment, bundle);
+ }
+
+ private void showLocationView(@NonNull final IntentModel intentModel) {
+ final String locationId = intentModel.getText();
+ // Log.d(TAG, "locationId: " + locationId);
+ final NavController navController = currentNavControllerLiveData.getValue();
+ if (currentNavControllerLiveData == null || navController == null) return;
+ final Bundle bundle = new Bundle();
+ bundle.putString("locationId", locationId);
+ navController.navigate(R.id.action_global_locationFragment, bundle);
+ }
+
+ private void showHashtagView(@NonNull final IntentModel intentModel) {
+ final String hashtag = intentModel.getText();
+ // Log.d(TAG, "hashtag: " + hashtag);
+ final NavController navController = currentNavControllerLiveData.getValue();
+ if (currentNavControllerLiveData == null || navController == null) return;
+ final Bundle bundle = new Bundle();
+ bundle.putString("hashtag", "#" + hashtag);
+ navController.navigate(R.id.action_global_hashTagFragment, bundle);
+ }
+
+ private void showActivityView() {
+ binding.bottomNavView.setSelectedItemId(R.id.more_nav_graph);
+ binding.bottomNavView.post(() -> {
+ final NavController navController = currentNavControllerLiveData.getValue();
+ if (currentNavControllerLiveData == null || navController == null) return;
+ final NavDirections navDirections = MorePreferencesFragmentDirections.actionMorePreferencesFragmentToNotificationsViewer();
+ navController.navigate(navDirections);
+ });
+ }
+
+ private void bindActivityCheckerService() {
+ bindService(new Intent(this, ActivityCheckerService.class), serviceConnection, Context.BIND_AUTO_CREATE);
+ isActivityCheckerServiceBound = true;
+ }
+
+ private void unbindActivityCheckerService() {
+ if (!isActivityCheckerServiceBound) return;
+ unbindService(serviceConnection);
+ isActivityCheckerServiceBound = false;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/activities/NotificationsViewer.java b/app/src/main/java/awais/instagrabber/activities/NotificationsViewer.java
deleted file mode 100755
index b8117022..00000000
--- a/app/src/main/java/awais/instagrabber/activities/NotificationsViewer.java
+++ /dev/null
@@ -1,189 +0,0 @@
-package awais.instagrabber.activities;
-
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.style.RelativeSizeSpan;
-import android.util.Log;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.Toast;
-
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-
-import java.io.DataOutputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-
-import awais.instagrabber.R;
-import awais.instagrabber.adapters.NotificationsAdapter;
-import awais.instagrabber.asyncs.NotificationsFetcher;
-import awais.instagrabber.databinding.ActivityNotificationBinding;
-import awais.instagrabber.interfaces.FetchListener;
-import awais.instagrabber.interfaces.MentionClickListener;
-import awais.instagrabber.models.NotificationModel;
-import awais.instagrabber.models.PostModel;
-import awais.instagrabber.models.enums.NotificationType;
-import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
-
-import static awais.instagrabber.utils.Utils.notificationManager;
-
-public final class NotificationsViewer extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener {
- private NotificationModel notificationModel;
- private ActivityNotificationBinding notificationsBinding;
- private ArrayAdapter commmentDialogAdapter;
- private String shortCode, postId, userId;
- private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
- private Resources resources;
- String[] commentDialogList;
-
- @Override
- protected void onCreate(@Nullable final Bundle savedInstanceState) {
- notificationManager.cancel(1800000000);
- if (Utils.isEmpty(cookie)) {
- Toast.makeText(this, R.string.activity_notloggedin, Toast.LENGTH_SHORT).show();
- }
- super.onCreate(savedInstanceState);
- notificationsBinding = ActivityNotificationBinding.inflate(getLayoutInflater());
- setContentView(notificationsBinding.getRoot());
- notificationsBinding.swipeRefreshLayout.setOnRefreshListener(this);
- resources = getResources();
- setSupportActionBar(notificationsBinding.toolbar.toolbar);
- notificationsBinding.toolbar.toolbar.setTitle(R.string.action_notif);
- onRefresh();
- }
-
- @Override
- public void onRefresh() {
- notificationsBinding.swipeRefreshLayout.setRefreshing(true);
- new NotificationsFetcher(new FetchListener() {
- @Override
- public void onResult(final NotificationModel[] notificationModels) {
- notificationsBinding.rvComments.setAdapter(new NotificationsAdapter(notificationModels, clickListener, mentionClickListener));
- notificationsBinding.swipeRefreshLayout.setRefreshing(false);
- new SeenAction().execute();
- }
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
- if (which == 0)
- searchUsername(notificationModel.getUsername());
- else if (which == 1 && commentDialogList.length == 2)
- startActivity(new Intent(getApplicationContext(), PostViewer.class)
- .putExtra(Constants.EXTRAS_POST, new PostModel(notificationModel.getShortcode(), false)));
- else if (which == 1) new ProfileAction().execute("/approve/");
- else if (which == 2) new ProfileAction().execute("/ignore/");
- };
-
- private final View.OnClickListener clickListener = v -> {
- final Object tag = v.getTag();
- if (tag instanceof NotificationModel) {
- notificationModel = (NotificationModel) tag;
-
- final String username = notificationModel.getUsername();
- final SpannableString title = new SpannableString(username + ":\n" + notificationModel.getText());
- title.setSpan(new RelativeSizeSpan(1.23f), 0, username.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
-
- if (notificationModel.getShortcode() != null) commentDialogList = new String[]{
- resources.getString(R.string.open_profile),
- resources.getString(R.string.view_post)
- };
- else if (notificationModel.getType() == NotificationType.REQUEST)
- commentDialogList = new String[]{
- resources.getString(R.string.open_profile),
- resources.getString(R.string.request_approve),
- resources.getString(R.string.request_reject)
- };
- else commentDialogList = new String[]{
- resources.getString(R.string.open_profile)
- };
-
- commmentDialogAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, commentDialogList);
-
- new AlertDialog.Builder(this).setTitle(title)
- .setAdapter(commmentDialogAdapter, profileDialogListener)
- .setNeutralButton(R.string.cancel, null)
- .show();
- }
- };
-
- private final MentionClickListener mentionClickListener = (view, text, isHashtag) ->
- new AlertDialog.Builder(this).setTitle(text)
- .setMessage(isHashtag ? R.string.comment_view_mention_hash_search : R.string.comment_view_mention_user_search)
- .setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.ok,
- (dialog, which) -> searchUsername(text)).show();
-
-
- private void searchUsername(final String text) {
- startActivity(new Intent(getApplicationContext(), ProfileViewer.class).putExtra(Constants.EXTRAS_USERNAME, text));
- }
-
- class ProfileAction extends AsyncTask {
- boolean ok = false;
- String action;
-
- protected Void doInBackground(String... rawAction) {
- action = rawAction[0];
- final String url = "https://www.instagram.com/web/friendships/"+notificationModel.getId()+action;
- try {
- final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT);
- urlConnection.setRequestProperty("x-csrftoken",
- Utils.settingsHelper.getString(Constants.COOKIE).split("csrftoken=")[1].split(";")[0]);
- urlConnection.connect();
- if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
- ok = true;
- }
- urlConnection.disconnect();
- } catch (Throwable ex) {
- Log.e("austin_debug", action+": " + ex);
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- if (ok == true) {
- onRefresh();
- }
- else Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }
- }
-
- class SeenAction extends AsyncTask {
- protected Void doInBackground(Void... lmao) {
- try {
- final HttpURLConnection urlConnection =
- (HttpURLConnection) new URL("https://www.instagram.com/web/activity/mark_checked/").openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT);
- urlConnection.setRequestProperty("x-csrftoken",
- Utils.settingsHelper.getString(Constants.COOKIE).split("csrftoken=")[1].split(";")[0]);
- final String urlParameters = "timestamp="+(System.currentTimeMillis()/1000);
- urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- urlConnection.setRequestProperty("Content-Length", "" +
- urlParameters.getBytes().length);
- urlConnection.setDoOutput(true);
- DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
- wr.writeBytes(urlParameters);
- wr.flush();
- wr.close();
- urlConnection.connect();
- } catch (Throwable ex) {
- Log.e("austin_debug", "seen: " + ex);
- }
- return null;
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/activities/PostViewer.java b/app/src/main/java/awais/instagrabber/activities/PostViewer.java
deleted file mode 100755
index 3d463df0..00000000
--- a/app/src/main/java/awais/instagrabber/activities/PostViewer.java
+++ /dev/null
@@ -1,767 +0,0 @@
-package awais.instagrabber.activities;
-
-import android.annotation.SuppressLint;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.text.SpannableString;
-import android.text.method.LinkMovementMethod;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
-import androidx.core.app.ActivityCompat;
-import androidx.core.content.ContextCompat;
-import androidx.core.view.GestureDetectorCompat;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.RequestManager;
-import com.bumptech.glide.load.DataSource;
-import com.bumptech.glide.load.engine.GlideException;
-import com.bumptech.glide.request.RequestListener;
-import com.bumptech.glide.request.target.Target;
-import com.google.android.exoplayer2.SimpleExoPlayer;
-import com.google.android.exoplayer2.source.MediaSource;
-import com.google.android.exoplayer2.source.MediaSourceEventListener;
-import com.google.android.exoplayer2.source.ProgressiveMediaSource;
-import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
-
-import org.json.JSONObject;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import awais.instagrabber.R;
-import awais.instagrabber.adapters.PostsMediaAdapter;
-import awais.instagrabber.asyncs.PostFetcher;
-import awais.instagrabber.asyncs.ProfileFetcher;
-import awais.instagrabber.asyncs.i.iPostFetcher;
-import awais.instagrabber.customviews.CommentMentionClickSpan;
-import awais.instagrabber.customviews.helpers.SwipeGestureListener;
-import awais.instagrabber.databinding.ActivityViewerBinding;
-import awais.instagrabber.interfaces.FetchListener;
-import awais.instagrabber.interfaces.SwipeEvent;
-import awais.instagrabber.models.BasePostModel;
-import awais.instagrabber.models.PostModel;
-import awais.instagrabber.models.ProfileModel;
-import awais.instagrabber.models.ViewerPostModel;
-import awais.instagrabber.models.enums.DownloadMethod;
-import awais.instagrabber.models.enums.ItemGetType;
-import awais.instagrabber.models.enums.MediaItemType;
-import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
-
-import static awais.instagrabber.utils.Utils.settingsHelper;
-
-public final class PostViewer extends BaseLanguageActivity {
- private ActivityViewerBinding viewerBinding;
- private String url, prevUsername, commentsEndCursor;
- private ProfileModel profileModel;
- private BasePostModel postModel;
- private ViewerPostModel viewerPostModel;
- private SimpleExoPlayer player;
- private ArrayAdapter profileDialogAdapter;
- private View viewsContainer, viewerCaptionParent;
- private GestureDetectorCompat gestureDetector;
- private SwipeEvent swipeEvent;
- private CharSequence postCaption = null, postUserId;
- private Resources resources;
- private boolean session = false, isFromShare, liked, saved, ok = false;
- private int slidePos = 0, lastSlidePos = 0;
- private ItemGetType itemGetType;
- @SuppressLint("ClickableViewAccessibility")
- final View.OnTouchListener gestureTouchListener = new View.OnTouchListener() {
- private float startX;
- private float startY;
-
- @Override
- public boolean onTouch(final View v, final MotionEvent event) {
- if (v == viewerCaptionParent) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- startX = event.getX();
- startY = event.getY();
- break;
-
- case MotionEvent.ACTION_UP:
- if (!(Utils.isEmpty(postCaption) ||
- Math.abs(startX - event.getX()) > 50 || Math.abs(startY - event.getY()) > 50)) {
- Utils.copyText(PostViewer.this, postCaption);
- return false;
- }
- }
- }
- return gestureDetector.onTouchEvent(event);
- }
- };
- private final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
- final String username = viewerPostModel.getUsername();
-
- if (which == 0) {
- searchUsername(username);
- } else if (profileModel != null && which == 1) {
- startActivity(new Intent(this, ProfilePicViewer.class)
- .putExtra(Constants.EXTRAS_PROFILE, profileModel));
- }
- };
- private final View.OnClickListener onClickListener = new View.OnClickListener() {
- @Override
- public void onClick(final View v) {
- if (v == viewerBinding.topPanel.ivProfilePic) {
- new AlertDialog.Builder(PostViewer.this).setAdapter(profileDialogAdapter, profileDialogListener)
- .setNeutralButton(R.string.cancel, null).setTitle(viewerPostModel.getUsername()).show();
-
- } else if (v == viewerBinding.ivToggleFullScreen) {
- toggleFullscreen();
-
- final LinearLayout topPanelRoot = viewerBinding.topPanel.getRoot();
- final int iconRes;
-
- if (containerLayoutParams.weight != 3.3f) {
- containerLayoutParams.weight = 3.3f;
- iconRes = R.drawable.ic_fullscreen_exit;
- topPanelRoot.setVisibility(View.GONE);
- viewerBinding.btnDownload.setVisibility(View.VISIBLE);
- viewerBinding.bottomPanel.tvPostDate.setVisibility(View.GONE);
- } else {
- containerLayoutParams.weight = (viewerBinding.mediaList.getVisibility() == View.VISIBLE) ? 1.35f : 1.9f;
- containerLayoutParams.weight += (Utils.isEmpty(settingsHelper.getString(Constants.COOKIE))) ? 0.3f : 0;
- iconRes = R.drawable.ic_fullscreen;
- topPanelRoot.setVisibility(View.VISIBLE);
- viewerBinding.btnDownload.setVisibility(View.GONE);
- viewerBinding.bottomPanel.tvPostDate.setVisibility(View.VISIBLE);
- }
-
- viewerBinding.ivToggleFullScreen.setImageResource(iconRes);
- viewerBinding.container.setLayoutParams(containerLayoutParams);
-
- } else if (v == viewerBinding.bottomPanel.btnMute) {
- if (player != null) {
- final float intVol = player.getVolume() == 0f ? 1f : 0f;
- player.setVolume(intVol);
- viewerBinding.bottomPanel.btnMute.setImageResource(intVol == 0f ? R.drawable.mute : R.drawable.vol);
- Utils.sessionVolumeFull = intVol == 1f;
- }
- } else if (v == viewerBinding.btnLike) {
- new PostAction().execute("likes");
- } else if (v == viewerBinding.btnBookmark) {
- new PostAction().execute("save");
- } else {
- final Object tag = v.getTag();
- if (tag instanceof ViewerPostModel) {
- viewerPostModel = (ViewerPostModel) tag;
- slidePos = Math.max(0, viewerPostModel.getPosition());
- refreshPost();
- }
- }
- }
- };
- private final View.OnClickListener downloadClickListener = v -> {
- if (ContextCompat.checkSelfPermission(this, Utils.PERMS[0]) == PackageManager.PERMISSION_GRANTED)
- showDownloadDialog();
- else
- ActivityCompat.requestPermissions(this, Utils.PERMS, 8020);
- };
- private final PostsMediaAdapter mediaAdapter = new PostsMediaAdapter(null, onClickListener);
- private RequestManager glideRequestManager;
- private LinearLayout.LayoutParams containerLayoutParams;
- private final FetchListener pfl = result -> {
- if (result == null || result.length < 1) {
- Toast.makeText(this, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- return;
- }
-
- viewerPostModel = result[0];
-
- mediaAdapter.setData(result);
- if (result.length > 1) {
- viewerBinding.mediaList.setLayoutParams(new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT, 0, 0.55f
- ));
- containerLayoutParams.weight = 1.35f;
- containerLayoutParams.weight += (Utils.isEmpty(settingsHelper.getString(Constants.COOKIE))) ? 0.3f : 0;
- viewerBinding.container.setLayoutParams(containerLayoutParams);
- viewerBinding.mediaList.setVisibility(View.VISIBLE);
- }
-
- viewerCaptionParent.setOnTouchListener(gestureTouchListener);
- viewerBinding.playerView.setOnTouchListener(gestureTouchListener);
- viewerBinding.imageViewer.setOnSingleFlingListener((e1, e2, velocityX, velocityY) -> {
- final float diffX = e2.getX() - e1.getX();
- if (Math.abs(diffX) > Math.abs(e2.getY() - e1.getY()) && Math.abs(diffX) > SwipeGestureListener.SWIPE_THRESHOLD
- && Math.abs(velocityX) > SwipeGestureListener.SWIPE_VELOCITY_THRESHOLD) {
- swipeEvent.onSwipe(diffX > 0);
- return true;
- }
- return false;
- });
-
- final long commentsCount = viewerPostModel.getCommentsCount();
- viewerBinding.bottomPanel.commentsCount.setText(String.valueOf(commentsCount));
- viewerBinding.bottomPanel.btnComments.setVisibility(View.VISIBLE);
-
- viewerBinding.bottomPanel.btnComments.setOnClickListener(v ->
- startActivityForResult(new Intent(this, CommentsViewer.class)
- .putExtra(Constants.EXTRAS_SHORTCODE, postModel.getShortCode())
- .putExtra(Constants.EXTRAS_POST, viewerPostModel.getPostId())
- .putExtra(Constants.EXTRAS_USER, postUserId), 6969));
- viewerBinding.bottomPanel.btnComments.setClickable(true);
- viewerBinding.bottomPanel.btnComments.setEnabled(true);
-
- if (postModel instanceof PostModel) {
- final PostModel postModel = (PostModel) this.postModel;
- postModel.setPostId(viewerPostModel.getPostId());
- postModel.setTimestamp(viewerPostModel.getTimestamp());
- postModel.setPostCaption(viewerPostModel.getPostCaption());
- if (!ok) {
- liked = viewerPostModel.getLike();
- saved = viewerPostModel.getBookmark();
- }
- }
-
- setupPostInfoBar("@"+viewerPostModel.getUsername(), viewerPostModel.getItemType(),
- viewerPostModel.getLocationName(), viewerPostModel.getLocation());
-
- postCaption = postModel.getPostCaption();
- viewerCaptionParent.setVisibility(View.VISIBLE);
-
- viewerBinding.bottomPanel.btnDownload.setOnClickListener(downloadClickListener);
-
- refreshPost();
- };
-
- @Override
- protected void onCreate(@Nullable final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- viewerBinding = ActivityViewerBinding.inflate(getLayoutInflater());
- setContentView(viewerBinding.getRoot());
-
- glideRequestManager = Glide.with(this);
-
- final Intent intent = getIntent();
- if (intent == null || !intent.hasExtra(Constants.EXTRAS_POST)
- || (postModel = (PostModel) intent.getSerializableExtra(Constants.EXTRAS_POST)) == null) {
- Utils.errorFinish(this);
- return;
- }
-
- containerLayoutParams = (LinearLayout.LayoutParams) viewerBinding.container.getLayoutParams();
-
- if (intent.hasExtra(Constants.EXTRAS_TYPE))
- itemGetType = (ItemGetType) intent.getSerializableExtra(Constants.EXTRAS_TYPE);
-
- resources = getResources();
-
- viewerBinding.topPanel.title.setMovementMethod(new LinkMovementMethod());
- viewerBinding.topPanel.title.setMentionClickListener((view, text, isHashtag) -> searchUsername(text));
- viewerBinding.topPanel.ivProfilePic.setOnClickListener(onClickListener);
-
- viewerBinding.ivToggleFullScreen.setOnClickListener(onClickListener);
- if (Utils.isEmpty(settingsHelper.getString(Constants.COOKIE))) {
- viewerBinding.btnLike.setVisibility(View.GONE);
- viewerBinding.btnBookmark.setVisibility(View.GONE);
- viewerBinding.postActions.setVisibility(View.GONE);
- viewerBinding.postActions.setLayoutParams(new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT, 0, 0
- ));
- containerLayoutParams.weight = (containerLayoutParams.weight == 3.3f) ? 3.3f : 2.2f;
- viewerBinding.container.setLayoutParams(containerLayoutParams);
- }
- else {
- viewerBinding.btnLike.setOnClickListener(onClickListener);
- viewerBinding.btnBookmark.setOnClickListener(onClickListener);
- }
- viewerBinding.btnDownload.setOnClickListener(downloadClickListener);
-
- profileDialogAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
- new String[]{resources.getString(R.string.open_profile), resources.getString(R.string.view_pfp)});
-
- postModel.setPosition(intent.getIntExtra(Constants.EXTRAS_INDEX, -1));
-
- final boolean postIdNull = postModel.getPostId() == null;
- if (!postIdNull)
- setupPostInfoBar(intent.getStringExtra(Constants.EXTRAS_USER), postModel.getItemType(), null, null);
-
- isFromShare = postModel.getPosition() == -1 || postIdNull;
-
- viewerCaptionParent = (View) viewerBinding.bottomPanel.viewerCaption.getParent();
- viewsContainer = (View) viewerBinding.bottomPanel.tvVideoViews.getParent();
-
- viewerBinding.mediaList.setLayoutManager(new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false));
- viewerBinding.mediaList.setAdapter(mediaAdapter);
- viewerBinding.mediaList.setVisibility(View.GONE);
-
- swipeEvent = isRight -> {
- final List extends BasePostModel> itemGetterItems;
- final boolean isMainSwipe;
-
- if (itemGetType == ItemGetType.SAVED_ITEMS && SavedViewer.itemGetter != null) {
- itemGetterItems = SavedViewer.itemGetter.get(itemGetType);
- isMainSwipe = !(itemGetterItems.size() < 1 || itemGetType == ItemGetType.SAVED_ITEMS && isFromShare);
- }
- else if (itemGetType != null && Main.itemGetter != null) {
- itemGetterItems = Main.itemGetter.get(itemGetType);
- isMainSwipe = !(itemGetterItems.size() < 1 || itemGetType == ItemGetType.MAIN_ITEMS && isFromShare);
- } else {
- itemGetterItems = null;
- isMainSwipe = false;
- }
-
- final BasePostModel[] basePostModels = mediaAdapter.getPostModels();
- final int slides = basePostModels.length;
-
- int position = postModel.getPosition();
-
- if (isRight) {
- --slidePos;
- if (!isMainSwipe && slidePos < 0) slidePos = 0;
- if (slides > 0 && slidePos >= 0) {
- if (basePostModels[slidePos] instanceof ViewerPostModel) {
- viewerPostModel = (ViewerPostModel) basePostModels[slidePos];
- }
- refreshPost();
- return;
- }
- if (isMainSwipe && --position < 0) position = itemGetterItems.size() - 1;
- } else {
- ++slidePos;
- if (!isMainSwipe && slidePos >= slides) slidePos = slides - 1;
- if (slides > 0 && slidePos < slides) {
- if (basePostModels[slidePos] instanceof ViewerPostModel) {
- viewerPostModel = (ViewerPostModel) basePostModels[slidePos];
- }
- refreshPost();
- return;
- }
- if (isMainSwipe && ++position >= itemGetterItems.size()) position = 0;
- }
-
- if (isMainSwipe) {
- slidePos = 0;
- ok = false;
- Log.d("AWAISKING_APP", "swipe left <<< post[" + position + "]: " + postModel + " -- " + slides);
- postModel = itemGetterItems.get(position);
- postModel.setPosition(position);
- viewPost();
- }
- };
- gestureDetector = new GestureDetectorCompat(this, new SwipeGestureListener(swipeEvent));
-
- viewPost();
- }
-
- private void viewPost() {
- lastSlidePos = 0;
- mediaAdapter.setData(null);
- viewsContainer.setVisibility(View.GONE);
- viewerCaptionParent.setVisibility(View.GONE);
- viewerBinding.mediaList.setVisibility(View.GONE);
- viewerBinding.btnDownload.setVisibility(View.GONE);
- viewerBinding.bottomPanel.btnMute.setVisibility(View.GONE);
- viewerBinding.bottomPanel.tvPostDate.setVisibility(View.GONE);
- viewerBinding.bottomPanel.btnComments.setVisibility(View.GONE);
- viewerBinding.bottomPanel.btnDownload.setVisibility(View.INVISIBLE);
- viewerBinding.bottomPanel.viewerCaption.setText(null);
- viewerBinding.bottomPanel.viewerCaption.setMentionClickListener(null);
-
- viewerBinding.playerView.setVisibility(View.GONE);
- viewerBinding.playerView.setPlayer(null);
- viewerBinding.imageViewer.setImageResource(0);
- viewerBinding.imageViewer.setImageDrawable(null);
-
- if (postModel.getShortCode() != null)
- new PostFetcher(postModel.getShortCode(), pfl).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- else if (postModel.getPostId() != null)
- new iPostFetcher(postModel.getPostId(), pfl).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- private void searchUsername(final String text) {
- startActivity(
- new Intent(getApplicationContext(), ProfileViewer.class)
- .putExtra(Constants.EXTRAS_USERNAME, text)
- );
- }
-
- private void setupVideo() {
- viewerBinding.playerView.setVisibility(View.VISIBLE);
- viewerBinding.bottomPanel.btnDownload.setVisibility(View.VISIBLE);
- viewerBinding.bottomPanel.btnMute.setVisibility(View.VISIBLE);
- viewerBinding.progressView.setVisibility(View.GONE);
- viewerBinding.imageViewer.setVisibility(View.GONE);
- viewerBinding.imageViewer.setImageDrawable(null);
-
- if (viewerPostModel.getVideoViews() > -1) {
- viewsContainer.setVisibility(View.VISIBLE);
- viewerBinding.bottomPanel.tvVideoViews.setText(String.valueOf(viewerPostModel.getVideoViews()));
- }
-
- player = new SimpleExoPlayer.Builder(this).build();
- viewerBinding.playerView.setPlayer(player);
- float vol = Utils.settingsHelper.getBoolean(Constants.MUTED_VIDEOS) ? 0f : 1f;
- if (vol == 0f && Utils.sessionVolumeFull) vol = 1f;
-
- player.setVolume(vol);
- player.setPlayWhenReady(Utils.settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS));
- final ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(new DefaultDataSourceFactory(this, "instagram"))
- .createMediaSource(Uri.parse(url));
- mediaSource.addEventListener(new Handler(), new MediaSourceEventListener() {
- @Override
- public void onLoadCompleted(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
- viewerBinding.progressView.setVisibility(View.GONE);
- }
-
- @Override
- public void onLoadStarted(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
- viewerBinding.progressView.setVisibility(View.VISIBLE);
- }
-
- @Override
- public void onLoadCanceled(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
- viewerBinding.progressView.setVisibility(View.GONE);
- }
-
- @Override
- public void onLoadError(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData, final IOException error, final boolean wasCanceled) {
- viewerBinding.progressView.setVisibility(View.GONE);
- }
- });
- player.prepare(mediaSource);
-
- player.setVolume(vol);
- viewerBinding.bottomPanel.btnMute.setImageResource(vol == 0f ? R.drawable.vol : R.drawable.mute);
-
- viewerBinding.bottomPanel.btnMute.setOnClickListener(onClickListener);
- }
-
- private void setupImage() {
- viewsContainer.setVisibility(View.GONE);
- viewerBinding.playerView.setVisibility(View.GONE);
- viewerBinding.progressView.setVisibility(View.VISIBLE);
- viewerBinding.bottomPanel.btnMute.setVisibility(View.GONE);
- viewerBinding.bottomPanel.btnDownload.setVisibility(View.VISIBLE);
-
- viewerBinding.imageViewer.setImageDrawable(null);
- viewerBinding.imageViewer.setVisibility(View.VISIBLE);
- viewerBinding.imageViewer.setZoomable(true);
- viewerBinding.imageViewer.setZoomTransitionDuration(420);
- viewerBinding.imageViewer.setMaximumScale(7.2f);
-
- glideRequestManager.load(url).listener(new RequestListener() {
- @Override
- public boolean onLoadFailed(@Nullable final GlideException e, final Object model, final Target target, final boolean isFirstResource) {
- viewerBinding.progressView.setVisibility(View.GONE);
- return false;
- }
-
- @Override
- public boolean onResourceReady(final Drawable resource, final Object model, final Target target, final DataSource dataSource, final boolean isFirstResource) {
- viewerBinding.progressView.setVisibility(View.GONE);
- return false;
- }
- }).into(viewerBinding.imageViewer);
- }
-
- private void showDownloadDialog() {
- final ArrayList postModels = new ArrayList<>();
-
- if (!session && viewerBinding.mediaList.getVisibility() == View.VISIBLE) {
- final DialogInterface.OnClickListener clickListener = (dialog, which) -> {
- postModels.clear();
-
- if (which == DialogInterface.BUTTON_NEGATIVE) {
- final BasePostModel[] adapterPostModels = mediaAdapter.getPostModels();
- for (int i = 0, size = mediaAdapter.getItemCount(); i < size; ++i) {
- if (adapterPostModels[i] instanceof ViewerPostModel)
- postModels.add(adapterPostModels[i]);
- }
- } else if (which == DialogInterface.BUTTON_POSITIVE) {
- postModels.add(viewerPostModel);
- } else {
- session = true;
- postModels.add(viewerPostModel);
- }
-
- if (postModels.size() > 0)
- Utils.batchDownload(this, viewerPostModel.getUsername(), DownloadMethod.DOWNLOAD_POST_VIEWER, postModels);
- };
-
- new AlertDialog.Builder(this).setTitle(R.string.post_viewer_download_dialog_title)
- .setMessage(R.string.post_viewer_download_message)
- .setNeutralButton(R.string.post_viewer_download_session, clickListener).setPositiveButton(R.string.post_viewer_download_current, clickListener)
- .setNegativeButton(R.string.post_viewer_download_album, clickListener).show();
- } else {
- Utils.batchDownload(this, viewerPostModel.getUsername(), DownloadMethod.DOWNLOAD_POST_VIEWER, Collections.singletonList(viewerPostModel));
- }
- }
-
- @Override
- public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- if (requestCode == 8020 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
- showDownloadDialog();
- }
-
- @Override
- protected void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (resultCode == 6969) {
- setResult(RESULT_OK);
- finish();
- }
- }
-
- @Override
- public void onPause() {
- super.onPause();
- if (Build.VERSION.SDK_INT < 24) releasePlayer();
- }
-
- @Override
- public void onStop() {
- super.onStop();
- if (Build.VERSION.SDK_INT >= 24) releasePlayer();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- if (player == null && viewerPostModel != null && viewerPostModel.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO)
- setupVideo();
- else if (player != null) {
- player.setPlayWhenReady(true);
- player.getPlaybackState();
- }
- }
-
- private void refreshPost() {
- if (containerLayoutParams.weight != 3.3f) {
- containerLayoutParams.weight = (viewerBinding.mediaList.getVisibility() == View.VISIBLE) ? 1.35f : 1.9f;
- viewerBinding.container.setLayoutParams(containerLayoutParams);
- }
- if (viewerBinding.mediaList.getVisibility() == View.VISIBLE) {
- ViewerPostModel item = mediaAdapter.getItemAt(lastSlidePos);
- if (item != null) {
- item.setCurrentSlide(false);
- mediaAdapter.notifyItemChanged(lastSlidePos, item);
- }
-
- item = mediaAdapter.getItemAt(slidePos);
- if (item != null) {
- item.setCurrentSlide(true);
- mediaAdapter.notifyItemChanged(slidePos, item);
- }
- }
- lastSlidePos = slidePos;
-
- postCaption = viewerPostModel.getPostCaption();
-
- if (Utils.hasMentions(postCaption)) {
- viewerBinding.bottomPanel.viewerCaption.setText(Utils.getMentionText(postCaption), TextView.BufferType.SPANNABLE);
- viewerBinding.bottomPanel.viewerCaption.setMentionClickListener((view, text, isHashtag) -> searchUsername(text));
- } else {
- viewerBinding.bottomPanel.viewerCaption.setMentionClickListener(null);
- viewerBinding.bottomPanel.viewerCaption.setText(postCaption);
- }
-
- setupPostInfoBar("@"+viewerPostModel.getUsername(), viewerPostModel.getItemType(),
- viewerPostModel.getLocationName(), viewerPostModel.getLocation());
-
- if (postModel instanceof PostModel) {
- final PostModel postModel = (PostModel) this.postModel;
- postModel.setPostId(viewerPostModel.getPostId());
- postModel.setTimestamp(viewerPostModel.getTimestamp());
- postModel.setPostCaption(viewerPostModel.getPostCaption());
- if (liked == true) {
- viewerBinding.btnLike.setText(resources.getString(R.string.unlike, viewerPostModel.getLikes()
- + ((ok && viewerPostModel.getLike() != liked) ? (liked ? 1L : -1L) : 0L)));
- viewerBinding.btnLike.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- getApplicationContext(), R.color.btn_pink_background)));
- }
- else {
- viewerBinding.btnLike.setText(resources.getString(R.string.like, viewerPostModel.getLikes()
- + ((ok && viewerPostModel.getLike() != liked) ? (liked ? 1L : -1L) : 0L)));
- viewerBinding.btnLike.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- getApplicationContext(), R.color.btn_lightpink_background)));
- }
- if (saved == true) {
- viewerBinding.btnBookmark.setText(R.string.unbookmark);
- viewerBinding.btnBookmark.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- getApplicationContext(), R.color.btn_orange_background)));
- }
- else {
- viewerBinding.btnBookmark.setText(R.string.bookmark);
- viewerBinding.btnBookmark.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- getApplicationContext(), R.color.btn_lightorange_background)));
- }
- }
-
- viewerBinding.bottomPanel.tvPostDate.setText(viewerPostModel.getPostDate());
- viewerBinding.bottomPanel.tvPostDate.setVisibility(containerLayoutParams.weight != 3.3f ? View.VISIBLE : View.GONE);
- viewerBinding.bottomPanel.tvPostDate.setSelected(true);
-
- url = viewerPostModel.getDisplayUrl();
- releasePlayer();
-
- viewerBinding.btnDownload.setVisibility(containerLayoutParams.weight == 3.3f ? View.VISIBLE : View.GONE);
- if (viewerPostModel.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO) setupVideo();
- else setupImage();
- }
-
- private void releasePlayer() {
- if (player != null) {
- player.release();
- player = null;
- }
- }
-
- private void setupPostInfoBar(final String from, final MediaItemType mediaItemType, final String locationName, final String location) {
- if (prevUsername == null || !prevUsername.equals(from)) {
- viewerBinding.topPanel.ivProfilePic.setImageBitmap(null);
- viewerBinding.topPanel.ivProfilePic.setImageDrawable(null);
- viewerBinding.topPanel.ivProfilePic.setImageResource(0);
-
- if (!Utils.isEmpty(from) && from.charAt(0) == '@')
- new ProfileFetcher(from.substring(1), result -> {
- profileModel = result;
-
- if (result != null) {
- final String hdProfilePic = result.getHdProfilePic();
- final String sdProfilePic = result.getSdProfilePic();
- postUserId = result.getId();
-
- final boolean hdPicEmpty = Utils.isEmpty(hdProfilePic);
- RequestListener profilePicListener = new RequestListener() {
- @Override
- public boolean onLoadFailed(@Nullable final GlideException e, final Object model, final Target target, final boolean isFirstResource) {
- viewerBinding.topPanel.ivProfilePic.setEnabled(false);
- viewerBinding.topPanel.ivProfilePic.setOnClickListener(null);
- return true;
- }
-
- @Override
- public boolean onResourceReady(final Drawable resource, final Object model, final Target target, final DataSource dataSource, final boolean isFirstResource) {
- viewerBinding.topPanel.ivProfilePic.setEnabled(true);
- viewerBinding.topPanel.ivProfilePic.setOnClickListener(onClickListener);
- return false;
- }
- };
- glideRequestManager.load(hdPicEmpty ? sdProfilePic : hdProfilePic).listener(profilePicListener)
- .error(glideRequestManager.load(sdProfilePic).listener(profilePicListener)).into(viewerBinding.topPanel.ivProfilePic);
-
- final View viewStoryPost = findViewById(R.id.viewStoryPost);
- if (viewStoryPost != null) {
- viewStoryPost.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- if (result.isPrivate())
- Toast.makeText(getApplicationContext(), R.string.share_private_post, Toast.LENGTH_LONG).show();
- Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
- sharingIntent.setType("text/plain");
- sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, "https://instagram.com/p/"+postModel.getShortCode());
- startActivity(Intent.createChooser(sharingIntent,
- (result.isPrivate()) ? getString(R.string.share_private_post) : getString(R.string.share_public_post)));
- }
- });
- }
- }
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- prevUsername = from;
- }
-
- final String titlePrefix = resources.getString(mediaItemType == MediaItemType.MEDIA_TYPE_VIDEO ?
- R.string.post_viewer_video_post : R.string.post_viewer_image_post);
- if (Utils.isEmpty(from)) viewerBinding.topPanel.title.setText(titlePrefix);
- else {
- final int titleLen = from.length();
- final SpannableString spannableString = new SpannableString(from);
- spannableString.setSpan(new CommentMentionClickSpan(), 0, titleLen, 0);
- viewerBinding.topPanel.title.setText(spannableString);
- }
-
- if (location == null) {
- viewerBinding.topPanel.location.setVisibility(View.GONE);
- viewerBinding.topPanel.title.setLayoutParams(new RelativeLayout.LayoutParams(
- RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT
- ));
- }
- else {
- viewerBinding.topPanel.location.setVisibility(View.VISIBLE);
- viewerBinding.topPanel.location.setText(locationName);
- viewerBinding.topPanel.location.setOnClickListener(v -> searchUsername(location));
- viewerBinding.topPanel.title.setLayoutParams(new RelativeLayout.LayoutParams(
- RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT
- ));
- }
- }
-
- private void toggleFullscreen() {
- final View decorView = getWindow().getDecorView();
- int newUiOptions = decorView.getSystemUiVisibility();
- newUiOptions ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
- newUiOptions ^= View.SYSTEM_UI_FLAG_FULLSCREEN;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
- newUiOptions ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
- decorView.setSystemUiVisibility(newUiOptions);
- }
-
- class PostAction extends AsyncTask {
- String action;
-
- protected Void doInBackground(String... rawAction) {
- action = rawAction[0];
- final String url = "https://www.instagram.com/web/"+action+"/"+postModel.getPostId()+"/"+ (action == "save" ?
- (saved ? "unsave/" : "save/") :
- (liked ? "unlike/" : "like/"));
- try {
- final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT);
- urlConnection.setRequestProperty("x-csrftoken",
- settingsHelper.getString(Constants.COOKIE).split("csrftoken=")[1].split(";")[0]);
- urlConnection.connect();
- if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
- ok = true;
- }
- urlConnection.disconnect();
- } catch (Throwable ex) {
- Log.e("austin_debug", action+": " + ex);
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- if (ok == true && action == "likes") {
- liked = !liked;
- refreshPost();
- }
- else if (ok == true && action == "save") {
- saved = !saved;
- refreshPost();
- }
- else Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }
- }
-}
diff --git a/app/src/main/java/awais/instagrabber/activities/ProfilePicViewer.java b/app/src/main/java/awais/instagrabber/activities/ProfilePicViewer.java
deleted file mode 100755
index afdcaab5..00000000
--- a/app/src/main/java/awais/instagrabber/activities/ProfilePicViewer.java
+++ /dev/null
@@ -1,211 +0,0 @@
-package awais.instagrabber.activities;
-
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Environment;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.Toast;
-
-import androidx.annotation.Nullable;
-import androidx.fragment.app.FragmentManager;
-
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.RequestManager;
-import com.bumptech.glide.load.DataSource;
-import com.bumptech.glide.load.engine.GlideException;
-import com.bumptech.glide.request.RequestListener;
-import com.bumptech.glide.request.target.Target;
-
-import java.io.File;
-
-import awais.instagrabber.R;
-import awais.instagrabber.asyncs.DownloadAsync;
-import awais.instagrabber.asyncs.ProfilePictureFetcher;
-import awais.instagrabber.databinding.ActivityProfilepicBinding;
-import awais.instagrabber.interfaces.FetchListener;
-import awais.instagrabber.models.HashtagModel;
-import awais.instagrabber.models.LocationModel;
-import awais.instagrabber.models.ProfileModel;
-import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
-
-public final class ProfilePicViewer extends BaseLanguageActivity {
- private ActivityProfilepicBinding profileBinding;
- private ProfileModel profileModel;
- private HashtagModel hashtagModel;
- private LocationModel locationModel;
- private MenuItem menuItemDownload;
- private String profilePicUrl;
- private FragmentManager fragmentManager;
- private FetchListener fetchListener;
- private boolean errorHandled = false;
- private boolean fallbackToProfile = false;
- private boolean destroyed = false;
-
- @Override
- protected void onCreate(@Nullable final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- profileBinding = ActivityProfilepicBinding.inflate(getLayoutInflater());
- setContentView(profileBinding.getRoot());
-
- setSupportActionBar(profileBinding.toolbar.toolbar);
-
- final Intent intent = getIntent();
- if (intent == null || (!intent.hasExtra(Constants.EXTRAS_PROFILE) && !intent.hasExtra(Constants.EXTRAS_HASHTAG) && !intent.hasExtra(Constants.EXTRAS_LOCATION))
- || ((profileModel = (ProfileModel) intent.getSerializableExtra(Constants.EXTRAS_PROFILE)) == null
- && (hashtagModel = (HashtagModel) intent.getSerializableExtra(Constants.EXTRAS_HASHTAG)) == null
- && (locationModel = (LocationModel) intent.getSerializableExtra(Constants.EXTRAS_LOCATION)) == null)) {
- Utils.errorFinish(this);
- return;
- }
-
- fragmentManager = getSupportFragmentManager();
-
- final String id = hashtagModel != null ? hashtagModel.getId() : (locationModel != null ? locationModel.getId() : profileModel.getId());
- final String username = hashtagModel != null ? hashtagModel.getName() : (locationModel != null ? locationModel.getName() : profileModel.getUsername());
-
- profileBinding.toolbar.toolbar.setTitle(username);
-
- profileBinding.progressView.setVisibility(View.VISIBLE);
- profileBinding.imageViewer.setVisibility(View.VISIBLE);
-
- profileBinding.imageViewer.setZoomable(true);
- profileBinding.imageViewer.setZoomTransitionDuration(420);
- profileBinding.imageViewer.setMaximumScale(7.2f);
-
- fetchListener = profileUrl -> {
- profilePicUrl = profileUrl;
-
- if (!fallbackToProfile && Utils.isEmpty(profilePicUrl)) {
- fallbackToProfile = true;
- new ProfilePictureFetcher(username, id, fetchListener, profilePicUrl, (hashtagModel != null || locationModel != null)).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- return;
- }
-
- if (errorHandled && fallbackToProfile || Utils.isEmpty(profilePicUrl))
- profilePicUrl = hashtagModel != null ? hashtagModel.getSdProfilePic() : (locationModel != null ? locationModel.getSdProfilePic() : profileModel.getHdProfilePic());
-
- if (destroyed == true) return;
-
- final RequestManager glideRequestManager = Glide.with(this);
-
- glideRequestManager.load(profilePicUrl).addListener(new RequestListener() {
- @Override
- public boolean onLoadFailed(@Nullable final GlideException e, final Object model, final Target target, final boolean isFirstResource) {
- fallbackToProfile = true;
- if (!errorHandled) {
- errorHandled = true;
- new ProfilePictureFetcher(username, id, fetchListener, profilePicUrl, (hashtagModel != null || locationModel != null))
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- profileBinding.progressView.setVisibility(View.GONE);
- return false;
- }
-
- @Override
- public boolean onResourceReady(final Drawable resource, final Object model, final Target target, final DataSource dataSource, final boolean isFirstResource) {
- if (menuItemDownload != null) menuItemDownload.setEnabled(true);
- showImageInfo();
- profileBinding.progressView.setVisibility(View.GONE);
- return false;
- }
-
- private void showImageInfo() {
- final Drawable drawable = profileBinding.imageViewer.getDrawable();
- if (drawable != null) {
- final StringBuilder info = new StringBuilder(getString(R.string.profile_viewer_imageinfo, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()));
- if (drawable instanceof BitmapDrawable) {
- final Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
- if (bitmap != null) {
- final String colorDepthPrefix = getString(R.string.profile_viewer_colordepth_prefix);
- switch (bitmap.getConfig()) {
- case ALPHA_8:
- info.append(colorDepthPrefix).append(" 8-bits(A)");
- break;
- case RGB_565:
- info.append(colorDepthPrefix).append(" 16-bits-A");
- break;
- case ARGB_4444:
- info.append(colorDepthPrefix).append(" 16-bits+A");
- break;
- case ARGB_8888:
- info.append(colorDepthPrefix).append(" 32-bits+A");
- break;
- case RGBA_F16:
- info.append(colorDepthPrefix).append(" 64-bits+A");
- break;
- case HARDWARE:
- info.append(colorDepthPrefix).append(" auto");
- break;
- }
- }
- }
- profileBinding.imageInfo.setText(info);
- profileBinding.imageInfo.setVisibility(View.VISIBLE);
- }
- }
- }).error(glideRequestManager.load(profilePicUrl)).into(profileBinding.imageViewer);
- };
-
- new ProfilePictureFetcher(username, id, fetchListener, profilePicUrl, (hashtagModel != null || locationModel != null))
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- private void downloadProfilePicture() {
- int error = 0;
-
- if (profileModel != null) {
- final File dir = new File(Environment.getExternalStorageDirectory(), "Download");
- if (dir.exists() || dir.mkdirs()) {
-
- final File saveFile = new File(dir, profileModel.getUsername() + '_' + System.currentTimeMillis()
- + Utils.getExtensionFromModel(profilePicUrl, profileModel));
-
- new DownloadAsync(this,
- profilePicUrl,
- saveFile,
- result -> {
- final int toastRes = result != null && result.exists() ?
- R.string.downloader_downloaded_in_folder : R.string.downloader_error_download_file;
- Toast.makeText(this, toastRes, Toast.LENGTH_SHORT).show();
- }).setItems(null, profileModel.getUsername()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- } else error = 1;
- } else error = 2;
-
- if (error == 1) Toast.makeText(this, R.string.downloader_error_creating_folder, Toast.LENGTH_SHORT).show();
- else if (error == 2) Toast.makeText(this, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- getDelegate().onDestroy();
- destroyed = true;
- }
-
- @Override
- public boolean onCreateOptionsMenu(final Menu menu) {
- getMenuInflater().inflate(R.menu.menu, menu);
-
- final MenuItem.OnMenuItemClickListener menuItemClickListener = item -> {
- if (item == menuItemDownload) {
- downloadProfilePicture();
- }
- return true;
- };
-
- menu.findItem(R.id.action_search).setVisible(false);
- menuItemDownload = menu.findItem(R.id.action_download);
- menuItemDownload.setVisible(true);
- menuItemDownload.setEnabled(false);
- menuItemDownload.setOnMenuItemClickListener(menuItemClickListener);
-
- return true;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/activities/ProfileViewer.java b/app/src/main/java/awais/instagrabber/activities/ProfileViewer.java
deleted file mode 100755
index 54379a7f..00000000
--- a/app/src/main/java/awais/instagrabber/activities/ProfileViewer.java
+++ /dev/null
@@ -1,930 +0,0 @@
-package awais.instagrabber.activities;
-
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Typeface;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.text.SpannableStringBuilder;
-import android.text.method.LinkMovementMethod;
-import android.text.style.RelativeSizeSpan;
-import android.text.style.StyleSpan;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
-import androidx.core.content.ContextCompat;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-
-import java.io.DataOutputStream;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import awais.instagrabber.BuildConfig;
-import awais.instagrabber.R;
-import awais.instagrabber.adapters.HighlightsAdapter;
-import awais.instagrabber.adapters.PostsAdapter;
-import awais.instagrabber.asyncs.HashtagFetcher;
-import awais.instagrabber.asyncs.HighlightsFetcher;
-import awais.instagrabber.asyncs.LocationFetcher;
-import awais.instagrabber.asyncs.PostsFetcher;
-import awais.instagrabber.asyncs.ProfileFetcher;
-import awais.instagrabber.asyncs.i.iStoryStatusFetcher;
-import awais.instagrabber.customviews.RamboTextView;
-import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager;
-import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
-import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
-import awais.instagrabber.databinding.ActivityProfileBinding;
-import awais.instagrabber.interfaces.FetchListener;
-import awais.instagrabber.interfaces.MentionClickListener;
-import awais.instagrabber.models.BasePostModel;
-import awais.instagrabber.models.HashtagModel;
-import awais.instagrabber.models.HighlightModel;
-import awais.instagrabber.models.LocationModel;
-import awais.instagrabber.models.PostModel;
-import awais.instagrabber.models.ProfileModel;
-import awais.instagrabber.models.StoryModel;
-import awais.instagrabber.models.enums.DownloadMethod;
-import awais.instagrabber.models.enums.ItemGetType;
-import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.DataBox;
-import awais.instagrabber.utils.Utils;
-import awaisomereport.LogCollector;
-
-import static awais.instagrabber.utils.Constants.AUTOLOAD_POSTS;
-import static awais.instagrabber.utils.Utils.logCollector;
-
-public final class ProfileViewer extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener {
- private final ArrayList allItems = new ArrayList<>(), selectedItems = new ArrayList<>();
- private static AsyncTask, ?, ?> currentlyExecuting;
- private final boolean autoloadPosts = Utils.settingsHelper.getBoolean(AUTOLOAD_POSTS);
- private boolean hasNextPage = false;
- private View collapsingToolbar;
- private String endCursor = null;
- private ProfileModel profileModel;
- private HashtagModel hashtagModel;
- private LocationModel locationModel;
- private StoryModel[] storyModels;
- private MenuItem downloadAction, favouriteAction;
- private final FetchListener postsFetchListener = new FetchListener() {
- @Override
- public void onResult(final PostModel[] result) {
- if (result != null) {
- final int oldSize = allItems.size();
- allItems.addAll(Arrays.asList(result));
-
- postsAdapter.notifyItemRangeInserted(oldSize, result.length);
-
- profileBinding.profileView.mainPosts.post(() -> {
- profileBinding.profileView.mainPosts.setNestedScrollingEnabled(true);
- profileBinding.profileView.mainPosts.setVisibility(View.VISIBLE);
- });
-
- if (isHashtag)
- profileBinding.toolbar.toolbar.setTitle(userQuery);
- else if (isLocation)
- profileBinding.toolbar.toolbar.setTitle(locationModel.getName());
- else profileBinding.toolbar.toolbar.setTitle("@"+profileModel.getUsername());
-
- final PostModel model = result[result.length - 1];
- if (model != null) {
- endCursor = model.getEndCursor();
- hasNextPage = model.hasNextPage();
- if (autoloadPosts && hasNextPage)
- currentlyExecuting = new PostsFetcher(
- profileModel != null ? profileModel.getId()
- : (hashtagModel != null ? ("#"+hashtagModel.getName()) : locationModel.getId()), endCursor, this)
- .setUsername((isLocation || isHashtag) ? null : profileModel.getUsername())
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- else {
- profileBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- }
- model.setPageCursor(false, null);
- }
- }
- else {
- profileBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- profileBinding.profileView.privatePage1.setImageResource(R.drawable.ic_cancel);
- profileBinding.profileView.privatePage2.setText(R.string.empty_acc);
- profileBinding.profileView.privatePage.setVisibility(View.VISIBLE);
- }
- }
- };
- private final MentionClickListener mentionClickListener = new MentionClickListener() {
- @Override
- public void onClick(final RamboTextView view, final String text, final boolean isHashtag) {
- startActivity(new Intent(getApplicationContext(), ProfileViewer.class).putExtra(Constants.EXTRAS_USERNAME, text));
- }
- };
- public final HighlightsAdapter highlightsAdapter = new HighlightsAdapter(null, new View.OnClickListener() {
- @Override
- public void onClick(final View v) {
- final Object tag = v.getTag();
- if (tag instanceof HighlightModel) {
- final HighlightModel highlightModel = (HighlightModel) tag;
- new iStoryStatusFetcher(highlightModel.getId(), null, false, false,
- (!isLoggedIn && Utils.settingsHelper.getBoolean(Constants.STORIESIG)), true, result -> {
- if (result != null && result.length > 0)
- startActivity(new Intent(ProfileViewer.this, StoryViewer.class)
- .putExtra(Constants.EXTRAS_USERNAME, userQuery.replace("@", ""))
- .putExtra(Constants.EXTRAS_HIGHLIGHT, highlightModel.getTitle())
- .putExtra(Constants.EXTRAS_STORIES, result)
- );
- else Toast.makeText(ProfileViewer.this, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
- });
- private Resources resources;
- private RecyclerLazyLoader lazyLoader;
- private boolean isHashtag, isUser, isLocation;
- private PostsAdapter postsAdapter;
- private String cookie = Utils.settingsHelper.getString(Constants.COOKIE), userQuery;
- public boolean isLoggedIn = !Utils.isEmpty(cookie);
- private ActivityProfileBinding profileBinding;
- private ArrayAdapter profileDialogAdapter;
- private DialogInterface.OnClickListener profileDialogListener;
-
- protected void onCreate(@Nullable final Bundle savedInstanceState) {
- stopCurrentExecutor();
- super.onCreate(savedInstanceState);
-
- final Intent intent = getIntent();
- if (intent == null || !intent.hasExtra(Constants.EXTRAS_USERNAME)
- || Utils.isEmpty((userQuery = intent.getStringExtra(Constants.EXTRAS_USERNAME)))) {
- Utils.errorFinish(this);
- return;
- }
-
- userQuery = (userQuery.contains("/") || userQuery.startsWith("#") || userQuery.startsWith("@")) ? userQuery : ("@"+userQuery);
-
- profileBinding = ActivityProfileBinding.inflate(getLayoutInflater());
- setContentView(profileBinding.getRoot());
-
- resources = getResources();
-
- profileDialogAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
- new String[]{resources.getString(R.string.view_pfp), resources.getString(R.string.show_stories)});
- profileDialogListener = (dialog, which) -> {
- final Intent newintent;
- if (which == 0 || storyModels == null || storyModels.length < 1) {
- newintent = new Intent(this, ProfilePicViewer.class).putExtra(
- ((hashtagModel != null) ? Constants.EXTRAS_HASHTAG : (locationModel != null ? Constants.EXTRAS_LOCATION : Constants.EXTRAS_PROFILE)),
- ((hashtagModel != null) ? hashtagModel : (locationModel != null ? locationModel : profileModel)));
- }
- else newintent = new Intent(this, StoryViewer.class).putExtra(Constants.EXTRAS_USERNAME, userQuery.replace("@", ""))
- .putExtra(Constants.EXTRAS_STORIES, storyModels)
- .putExtra(Constants.EXTRAS_HASHTAG, (hashtagModel != null));
- startActivity(newintent);
- };
-
- profileBinding.profileView.swipeRefreshLayout.setOnRefreshListener(this);
- profileBinding.profileView.mainUrl.setMovementMethod(new LinkMovementMethod());
-
- isLoggedIn = !Utils.isEmpty(cookie);
-
- collapsingToolbar = profileBinding.profileView.appBarLayout.getChildAt(0);
-
- profileBinding.profileView.mainPosts.setNestedScrollingEnabled(false);
- profileBinding.profileView.highlightsList.setLayoutManager(
- new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false));
- profileBinding.profileView.highlightsList.setAdapter(highlightsAdapter);
-
- setSupportActionBar(profileBinding.toolbar.toolbar);
-
- // change the next number to adjust grid
- final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(ProfileViewer.this, Utils.convertDpToPx(110));
- profileBinding.profileView.mainPosts.setLayoutManager(layoutManager);
- profileBinding.profileView.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4)));
- profileBinding.profileView.mainPosts.setAdapter(postsAdapter = new PostsAdapter(allItems, v -> {
- final Object tag = v.getTag();
- if (tag instanceof PostModel) {
- final PostModel postModel = (PostModel) tag;
-
- if (postsAdapter.isSelecting) toggleSelection(postModel);
- else startActivity(new Intent(ProfileViewer.this, PostViewer.class)
- .putExtra(Constants.EXTRAS_INDEX, postModel.getPosition())
- .putExtra(Constants.EXTRAS_POST, postModel)
- .putExtra(Constants.EXTRAS_USER, userQuery)
- .putExtra(Constants.EXTRAS_TYPE, ItemGetType.MAIN_ITEMS));
- }
- }, v -> { // long click listener
- final Object tag = v.getTag();
- if (tag instanceof PostModel) {
- postsAdapter.isSelecting = true;
- toggleSelection((PostModel) tag);
- }
- return true;
- }));
-
- this.lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
- if ((!autoloadPosts || isHashtag) && hasNextPage) {
- profileBinding.profileView.swipeRefreshLayout.setRefreshing(true);
- stopCurrentExecutor();
- currentlyExecuting = new PostsFetcher(profileModel != null ? profileModel.getId()
- : (hashtagModel != null ? ("#"+hashtagModel.getName()) : locationModel.getId()), endCursor, postsFetchListener)
- .setUsername((isHashtag || isLocation) ? null : profileModel.getUsername())
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- endCursor = null;
- }
- });
- profileBinding.profileView.mainPosts.addOnScrollListener(lazyLoader);
-
- final View.OnClickListener onClickListener = v -> {
- if (v == profileBinding.profileView.mainBiography) {
- Utils.copyText(this, profileBinding.profileView.mainBiography.getText().toString());
- } else if (v == profileBinding.profileView.locationBiography) {
- Utils.copyText(this, profileBinding.profileView.locationBiography.getText().toString());
- } else if (v == profileBinding.profileView.mainProfileImage || v == profileBinding.profileView.mainHashtagImage || v == profileBinding.profileView.mainLocationImage) {
- if (storyModels == null || storyModels.length <= 0) {
- profileDialogListener.onClick(null, 0);
- } else {
- // because sometimes configuration changes made this crash on some phones
- new AlertDialog.Builder(this).setAdapter(profileDialogAdapter, profileDialogListener)
- .setNeutralButton(R.string.cancel, null).show();
- }
- }
- };
-
- profileBinding.profileView.mainBiography.setOnClickListener(onClickListener);
- profileBinding.profileView.locationBiography.setOnClickListener(onClickListener);
- profileBinding.profileView.mainProfileImage.setOnClickListener(onClickListener);
- profileBinding.profileView.mainHashtagImage.setOnClickListener(onClickListener);
- profileBinding.profileView.mainLocationImage.setOnClickListener(onClickListener);
-
- this.onRefresh();
- }
-
- @Override
- public void onRefresh() {
- if (lazyLoader != null) lazyLoader.resetState();
- stopCurrentExecutor();
- allItems.clear();
- selectedItems.clear();
- if (postsAdapter != null) {
- postsAdapter.isSelecting = false;
- postsAdapter.notifyDataSetChanged();
- }
- profileBinding.profileView.appBarLayout.setExpanded(true, true);
- profileBinding.profileView.privatePage.setVisibility(View.GONE);
- profileBinding.profileView.privatePage2.setTextSize(28);
- profileBinding.profileView.mainProfileImage.setImageBitmap(null);
- profileBinding.profileView.mainHashtagImage.setImageBitmap(null);
- profileBinding.profileView.mainLocationImage.setImageBitmap(null);
- profileBinding.profileView.mainUrl.setText(null);
- profileBinding.profileView.locationUrl.setText(null);
- profileBinding.profileView.mainFullName.setText(null);
- profileBinding.profileView.locationFullName.setText(null);
- profileBinding.profileView.mainPostCount.setText(null);
- profileBinding.profileView.mainLocPostCount.setText(null);
- profileBinding.profileView.mainTagPostCount.setText(null);
- profileBinding.profileView.mainFollowers.setText(null);
- profileBinding.profileView.mainFollowing.setText(null);
- profileBinding.profileView.mainBiography.setText(null);
- profileBinding.profileView.locationBiography.setText(null);
- profileBinding.profileView.mainBiography.setEnabled(false);
- profileBinding.profileView.locationBiography.setEnabled(false);
- profileBinding.profileView.mainProfileImage.setEnabled(false);
- profileBinding.profileView.mainLocationImage.setEnabled(false);
- profileBinding.profileView.mainHashtagImage.setEnabled(false);
- profileBinding.profileView.mainBiography.setMentionClickListener(null);
- profileBinding.profileView.locationBiography.setMentionClickListener(null);
- profileBinding.profileView.mainUrl.setVisibility(View.GONE);
- profileBinding.profileView.locationUrl.setVisibility(View.GONE);
- profileBinding.profileView.isVerified.setVisibility(View.GONE);
- profileBinding.profileView.btnFollow.setVisibility(View.GONE);
- profileBinding.profileView.btnRestrict.setVisibility(View.GONE);
- profileBinding.profileView.btnBlock.setVisibility(View.GONE);
- profileBinding.profileView.btnSaved.setVisibility(View.GONE);
- profileBinding.profileView.btnLiked.setVisibility(View.GONE);
- profileBinding.profileView.btnTagged.setVisibility(View.GONE);
- profileBinding.profileView.btnMap.setVisibility(View.GONE);
-
- profileBinding.profileView.btnFollow.setOnClickListener(profileActionListener);
- profileBinding.profileView.btnRestrict.setOnClickListener(profileActionListener);
- profileBinding.profileView.btnBlock.setOnClickListener(profileActionListener);
- profileBinding.profileView.btnSaved.setOnClickListener(profileActionListener);
- profileBinding.profileView.btnLiked.setOnClickListener(profileActionListener);
- profileBinding.profileView.btnTagged.setOnClickListener(profileActionListener);
- profileBinding.profileView.btnFollowTag.setOnClickListener(profileActionListener);
-
- profileBinding.profileView.infoContainer.setVisibility(View.GONE);
- profileBinding.profileView.tagInfoContainer.setVisibility(View.GONE);
- profileBinding.profileView.locInfoContainer.setVisibility(View.GONE);
-
- profileBinding.profileView.mainPosts.setNestedScrollingEnabled(false);
- profileBinding.profileView.highlightsList.setVisibility(View.GONE);
- collapsingToolbar.setVisibility(View.GONE);
- highlightsAdapter.setData(null);
-
- profileBinding.profileView.swipeRefreshLayout.setRefreshing(userQuery != null);
- if (userQuery == null) {
- profileBinding.toolbar.toolbar.setTitle(R.string.app_name);
- return;
- }
-
- isHashtag = userQuery.charAt(0) == '#';
- isUser = userQuery.charAt(0) == '@';
- isLocation = userQuery.contains("/");
- collapsingToolbar.setVisibility(isUser ? View.VISIBLE : View.GONE);
-
- if (isHashtag) {
- profileModel = null;
- locationModel = null;
- profileBinding.toolbar.toolbar.setTitle(userQuery);
- profileBinding.profileView.tagInfoContainer.setVisibility(View.VISIBLE);
- profileBinding.profileView.btnFollowTag.setVisibility(View.GONE);
-
- currentlyExecuting = new HashtagFetcher(userQuery.substring(1), result -> {
- hashtagModel = result;
-
- if (hashtagModel == null) {
- profileBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- Toast.makeText(ProfileViewer.this, R.string.error_loading_profile, Toast.LENGTH_SHORT).show();
- profileBinding.toolbar.toolbar.setTitle(R.string.app_name);
- return;
- }
-
- currentlyExecuting = new PostsFetcher(userQuery, postsFetchListener)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-
- profileBinding.profileView.btnFollowTag.setVisibility(View.VISIBLE);
-
- if (isLoggedIn) {
- new iStoryStatusFetcher(hashtagModel.getName(), null, false, true, false, false, stories -> {
- storyModels = stories;
- if (stories != null && stories.length > 0) profileBinding.profileView.mainHashtagImage.setStoriesBorder();
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-
- if (hashtagModel.getFollowing() == true) {
- profileBinding.profileView.btnFollowTag.setText(R.string.unfollow);
- profileBinding.profileView.btnFollowTag.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_purple_background)));
- }
- else {
- profileBinding.profileView.btnFollowTag.setText(R.string.follow);
- profileBinding.profileView.btnFollowTag.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_pink_background)));
- }
- } else {
- if (Utils.dataBox.getFavorite(userQuery) != null) {
- profileBinding.profileView.btnFollowTag.setText(R.string.unfavorite_short);
- profileBinding.profileView.btnFollowTag.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_purple_background)));
- }
- else {
- profileBinding.profileView.btnFollowTag.setText(R.string.favorite_short);
- profileBinding.profileView.btnFollowTag.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_pink_background)));
- }
- }
-
- profileBinding.profileView.mainHashtagImage.setEnabled(false);
- new MyTask().execute();
- profileBinding.profileView.mainHashtagImage.setEnabled(true);
-
- final String postCount = String.valueOf(hashtagModel.getPostCount());
-
- SpannableStringBuilder span = new SpannableStringBuilder(resources.getString(R.string.main_posts_count, postCount));
- span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
- span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
- profileBinding.profileView.mainTagPostCount.setText(span);
- profileBinding.profileView.mainTagPostCount.setVisibility(View.VISIBLE);
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- } else if (isUser) {
- hashtagModel = null;
- locationModel = null;
- profileBinding.toolbar.toolbar.setTitle(userQuery);
- profileBinding.profileView.infoContainer.setVisibility(View.VISIBLE);
- profileBinding.profileView.btnFollowTag.setVisibility(View.GONE);
-
- currentlyExecuting = new ProfileFetcher(userQuery.substring(1), result -> {
- profileModel = result;
-
- if (profileModel == null) {
- profileBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- Toast.makeText(ProfileViewer.this, R.string.error_loading_profile, Toast.LENGTH_SHORT).show();
- profileBinding.toolbar.toolbar.setTitle(R.string.app_name);
- return;
- }
-
- profileBinding.profileView.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE);
- final String profileId = profileModel.getId();
-
- if (isLoggedIn || Utils.settingsHelper.getBoolean(Constants.STORIESIG)) {
- new iStoryStatusFetcher(profileId, profileModel.getUsername(), false, false,
- (!isLoggedIn && Utils.settingsHelper.getBoolean(Constants.STORIESIG)), false,
- stories -> {
- storyModels = stories;
- if (stories != null && stories.length > 0) profileBinding.profileView.mainProfileImage.setStoriesBorder();
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-
- new HighlightsFetcher(profileId, (!isLoggedIn && Utils.settingsHelper.getBoolean(Constants.STORIESIG)), hls -> {
- if (hls != null && hls.length > 0) {
- profileBinding.profileView.highlightsList.setVisibility(View.VISIBLE);
- highlightsAdapter.setData(hls);
- }
- else profileBinding.profileView.highlightsList.setVisibility(View.GONE);
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- if (isLoggedIn) {
- final String myId = Utils.getUserIdFromCookie(cookie);
- if (!profileId.equals(myId)) {
- profileBinding.profileView.btnTagged.setVisibility(View.GONE);
- profileBinding.profileView.btnSaved.setVisibility(View.GONE);
- profileBinding.profileView.btnLiked.setVisibility(View.GONE);
- profileBinding.profileView.btnFollow.setVisibility(View.VISIBLE);
- if (profileModel.getFollowing() == true) {
- profileBinding.profileView.btnFollow.setText(R.string.unfollow);
- profileBinding.profileView.btnFollow.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_purple_background)));
- }
- else if (profileModel.getRequested() == true) {
- profileBinding.profileView.btnFollow.setText(R.string.cancel);
- profileBinding.profileView.btnFollow.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_purple_background)));
- }
- else {
- profileBinding.profileView.btnFollow.setText(R.string.follow);
- profileBinding.profileView.btnFollow.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_pink_background)));
- }
- profileBinding.profileView.btnRestrict.setVisibility(View.VISIBLE);
- if (profileModel.getRestricted() == true) {
- profileBinding.profileView.btnRestrict.setText(R.string.unrestrict);
- profileBinding.profileView.btnRestrict.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_green_background)));
- }
- else {
- profileBinding.profileView.btnRestrict.setText(R.string.restrict);
- profileBinding.profileView.btnRestrict.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_orange_background)));
- }
- if (profileModel.isReallyPrivate()) {
- profileBinding.profileView.btnBlock.setVisibility(View.VISIBLE);
- profileBinding.profileView.btnTagged.setVisibility(View.GONE);
- if (profileModel.getBlocked() == true) {
- profileBinding.profileView.btnBlock.setText(R.string.unblock);
- profileBinding.profileView.btnBlock.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_green_background)));
- } else {
- profileBinding.profileView.btnBlock.setText(R.string.block);
- profileBinding.profileView.btnBlock.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_red_background)));
- }
- } else {
- profileBinding.profileView.btnBlock.setVisibility(View.GONE);
- profileBinding.profileView.btnSaved.setVisibility(View.VISIBLE);
- profileBinding.profileView.btnTagged.setVisibility(View.VISIBLE);
- if (profileModel.getBlocked() == true) {
- profileBinding.profileView.btnSaved.setText(R.string.unblock);
- profileBinding.profileView.btnSaved.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_green_background)));
- } else {
- profileBinding.profileView.btnSaved.setText(R.string.block);
- profileBinding.profileView.btnSaved.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_red_background)));
- }
- }
- }
- else {
- profileBinding.profileView.btnTagged.setVisibility(View.VISIBLE);
- profileBinding.profileView.btnSaved.setVisibility(View.VISIBLE);
- profileBinding.profileView.btnLiked.setVisibility(View.VISIBLE);
- profileBinding.profileView.btnSaved.setText(R.string.saved);
- profileBinding.profileView.btnSaved.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_orange_background)));
- }
- } else {
- if (Utils.dataBox.getFavorite(userQuery) != null) {
- profileBinding.profileView.btnFollow.setText(R.string.unfavorite_short);
- profileBinding.profileView.btnFollow.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_purple_background)));
- }
- else {
- profileBinding.profileView.btnFollow.setText(R.string.favorite_short);
- profileBinding.profileView.btnFollow.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_pink_background)));
- }
- profileBinding.profileView.btnFollow.setVisibility(View.VISIBLE);
- if (!profileModel.isReallyPrivate()) {
- profileBinding.profileView.btnRestrict.setVisibility(View.VISIBLE);
- profileBinding.profileView.btnRestrict.setText(R.string.tagged);
- profileBinding.profileView.btnRestrict.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
- ProfileViewer.this, R.color.btn_blue_background)));
- }
- }
-
- profileBinding.profileView.mainProfileImage.setEnabled(false);
- new MyTask().execute();
- profileBinding.profileView.mainProfileImage.setEnabled(true);
-
- final long followersCount = profileModel.getFollowersCount();
- final long followingCount = profileModel.getFollowingCount();
-
- final String postCount = String.valueOf(profileModel.getPostCount());
-
- SpannableStringBuilder span = new SpannableStringBuilder(resources.getString(R.string.main_posts_count, postCount));
- span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
- span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
- profileBinding.profileView.mainPostCount.setText(span);
-
- final String followersCountStr = String.valueOf(followersCount);
- final int followersCountStrLen = followersCountStr.length();
- span = new SpannableStringBuilder(resources.getString(R.string.main_posts_followers, followersCountStr));
- span.setSpan(new RelativeSizeSpan(1.2f), 0, followersCountStrLen, 0);
- span.setSpan(new StyleSpan(Typeface.BOLD), 0, followersCountStrLen, 0);
- profileBinding.profileView.mainFollowers.setText(span);
-
- final String followingCountStr = String.valueOf(followingCount);
- final int followingCountStrLen = followingCountStr.length();
- span = new SpannableStringBuilder(resources.getString(R.string.main_posts_following, followingCountStr));
- span.setSpan(new RelativeSizeSpan(1.2f), 0, followingCountStrLen, 0);
- span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0);
- profileBinding.profileView.mainFollowing.setText(span);
-
- profileBinding.profileView.mainFullName.setText(Utils.isEmpty(profileModel.getName()) ? profileModel.getUsername() : profileModel.getName());
-
- CharSequence biography = profileModel.getBiography();
- profileBinding.profileView.mainBiography.setCaptionIsExpandable(true);
- profileBinding.profileView.mainBiography.setCaptionIsExpanded(true);
- if (Utils.hasMentions(biography)) {
- biography = Utils.getMentionText(biography);
- profileBinding.profileView.mainBiography.setText(biography, TextView.BufferType.SPANNABLE);
- profileBinding.profileView.mainBiography.setMentionClickListener(mentionClickListener);
- } else {
- profileBinding.profileView.mainBiography.setText(biography);
- profileBinding.profileView.mainBiography.setMentionClickListener(null);
- }
-
- final String url = profileModel.getUrl();
- if (Utils.isEmpty(url)) {
- profileBinding.profileView.mainUrl.setVisibility(View.GONE);
- } else {
- profileBinding.profileView.mainUrl.setVisibility(View.VISIBLE);
- profileBinding.profileView.mainUrl.setText(Utils.getSpannableUrl(url));
- }
-
- profileBinding.profileView.mainFullName.setSelected(true);
- profileBinding.profileView.mainBiography.setEnabled(true);
-
- if (!profileModel.isReallyPrivate()) {
- profileBinding.profileView.mainFollowing.setClickable(true);
- profileBinding.profileView.mainFollowers.setClickable(true);
-
- if (isLoggedIn) {
- final View.OnClickListener followClickListener = v -> startActivity(new Intent(ProfileViewer.this, FollowViewer.class)
- .putExtra(Constants.EXTRAS_FOLLOWERS, v == profileBinding.profileView.mainFollowers)
- .putExtra(Constants.EXTRAS_NAME, profileModel.getUsername())
- .putExtra(Constants.EXTRAS_ID, profileId));
-
- profileBinding.profileView.mainFollowers.setOnClickListener(followersCount > 0 ? followClickListener : null);
- profileBinding.profileView.mainFollowing.setOnClickListener(followingCount > 0 ? followClickListener : null);
- }
-
- if (profileModel.getPostCount() == 0) {
- profileBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- profileBinding.profileView.privatePage1.setImageResource(R.drawable.ic_cancel);
- profileBinding.profileView.privatePage2.setText(R.string.empty_acc);
- profileBinding.profileView.privatePage.setVisibility(View.VISIBLE);
- }
- else {
- profileBinding.profileView.swipeRefreshLayout.setRefreshing(true);
- profileBinding.profileView.mainPosts.setVisibility(View.VISIBLE);
- currentlyExecuting = new PostsFetcher(profileId, postsFetchListener).setUsername(profileModel.getUsername())
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- } else {
- profileBinding.profileView.mainFollowers.setClickable(false);
- profileBinding.profileView.mainFollowing.setClickable(false);
- profileBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- // error
- profileBinding.profileView.privatePage1.setImageResource(R.drawable.lock);
- profileBinding.profileView.privatePage2.setText(R.string.priv_acc);
- profileBinding.profileView.privatePage.setVisibility(View.VISIBLE);
- profileBinding.profileView.mainPosts.setVisibility(View.GONE);
- }
- }
- ).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- else if (isLocation) {
- profileModel = null;
- hashtagModel = null;
- profileBinding.toolbar.toolbar.setTitle(userQuery);
- profileBinding.profileView.locInfoContainer.setVisibility(View.VISIBLE);
-
- currentlyExecuting = new LocationFetcher(userQuery.split("/")[0], result -> {
- locationModel = result;
-
- if (locationModel == null) {
- profileBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- Toast.makeText(ProfileViewer.this, R.string.error_loading_profile, Toast.LENGTH_SHORT).show();
- profileBinding.toolbar.toolbar.setTitle(R.string.app_name);
- return;
- }
- profileBinding.toolbar.toolbar.setTitle(locationModel.getName());
-
- final String profileId = locationModel.getId();
-
- if (isLoggedIn) {
- new iStoryStatusFetcher(profileId.split("/")[0], null, true, false, false, false, stories -> {
- storyModels = stories;
- if (stories != null && stories.length > 0) profileBinding.profileView.mainLocationImage.setStoriesBorder();
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- profileBinding.profileView.mainLocationImage.setEnabled(false);
- new MyTask().execute();
- profileBinding.profileView.mainLocationImage.setEnabled(true);
-
- final String postCount = String.valueOf(locationModel.getPostCount());
-
- SpannableStringBuilder span = new SpannableStringBuilder(resources.getString(R.string.main_posts_count, postCount));
- span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
- span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
- profileBinding.profileView.mainLocPostCount.setText(span);
-
- profileBinding.profileView.locationFullName.setText(locationModel.getName());
-
- CharSequence biography = locationModel.getBio();
- profileBinding.profileView.locationBiography.setCaptionIsExpandable(true);
- profileBinding.profileView.locationBiography.setCaptionIsExpanded(true);
-
- if (Utils.isEmpty(biography)) {
- profileBinding.profileView.locationBiography.setVisibility(View.GONE);
- }
- else if (Utils.hasMentions(biography)) {
- profileBinding.profileView.locationBiography.setVisibility(View.VISIBLE);
- biography = Utils.getMentionText(biography);
- profileBinding.profileView.locationBiography.setText(biography, TextView.BufferType.SPANNABLE);
- profileBinding.profileView.locationBiography.setMentionClickListener(mentionClickListener);
- } else {
- profileBinding.profileView.locationBiography.setVisibility(View.VISIBLE);
- profileBinding.profileView.locationBiography.setText(biography);
- profileBinding.profileView.locationBiography.setMentionClickListener(null);
- }
-
- if (!locationModel.getGeo().startsWith("geo:0.0,0.0?z=17")) {
- profileBinding.profileView.btnMap.setVisibility(View.VISIBLE);
- profileBinding.profileView.btnMap.setOnClickListener(v -> {
- final Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(locationModel.getGeo()));
- startActivity(intent);
- });
- }
- else {
- profileBinding.profileView.btnMap.setVisibility(View.GONE);
- profileBinding.profileView.btnMap.setOnClickListener(null);
- }
-
- final String url = locationModel.getUrl();
- if (Utils.isEmpty(url)) {
- profileBinding.profileView.locationUrl.setVisibility(View.GONE);
- } else if (!url.startsWith("http")) {
- profileBinding.profileView.locationUrl.setVisibility(View.VISIBLE);
- profileBinding.profileView.locationUrl.setText(Utils.getSpannableUrl("http://"+url));
- } else {
- profileBinding.profileView.locationUrl.setVisibility(View.VISIBLE);
- profileBinding.profileView.locationUrl.setText(Utils.getSpannableUrl(url));
- }
-
- profileBinding.profileView.locationFullName.setSelected(true);
- profileBinding.profileView.locationBiography.setEnabled(true);
-
- if (locationModel.getPostCount() == 0) {
- profileBinding.profileView.swipeRefreshLayout.setRefreshing(false);
- profileBinding.profileView.privatePage1.setImageResource(R.drawable.ic_cancel);
- profileBinding.profileView.privatePage2.setText(R.string.empty_acc);
- profileBinding.profileView.privatePage.setVisibility(View.VISIBLE);
- }
- else {
- profileBinding.profileView.swipeRefreshLayout.setRefreshing(true);
- profileBinding.profileView.mainPosts.setVisibility(View.VISIBLE);
- currentlyExecuting = new PostsFetcher(profileId, postsFetchListener)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
- ).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
-
- public static void stopCurrentExecutor() {
- if (currentlyExecuting != null) {
- try {
- currentlyExecuting.cancel(true);
- } catch (final Exception e) {
- if (logCollector != null)
- logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
- }
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(final Menu menu) {
- getMenuInflater().inflate(R.menu.saved, menu);
-
- downloadAction = menu.findItem(R.id.downloadAction);
- downloadAction.setVisible(false);
-
- favouriteAction = menu.findItem(R.id.favouriteAction);
- favouriteAction.setVisible(!Utils.isEmpty(cookie));
- favouriteAction.setIcon(Utils.dataBox.getFavorite(userQuery) == null ? R.drawable.ic_not_liked : R.drawable.ic_like);
-
- downloadAction.setOnMenuItemClickListener(item -> {
- if (selectedItems.size() > 0) {
- Utils.batchDownload(this, userQuery, DownloadMethod.DOWNLOAD_MAIN, selectedItems);
- }
- return true;
- });
-
- favouriteAction.setOnMenuItemClickListener(item -> {
- if (Utils.dataBox.getFavorite(userQuery) == null) {
- Utils.dataBox.addFavorite(new DataBox.FavoriteModel(userQuery, System.currentTimeMillis(),
- locationModel != null ? locationModel.getName() : userQuery.replaceAll("^@", "")));
- favouriteAction.setIcon(R.drawable.ic_like);
- }
- else {
- Utils.dataBox.delFavorite(new DataBox.FavoriteModel(userQuery,
- Long.parseLong(Utils.dataBox.getFavorite(userQuery).split("/")[1]),
- locationModel != null ? locationModel.getName() : userQuery.replaceAll("^@", "")));
- favouriteAction.setIcon(R.drawable.ic_not_liked);
- }
- return true;
- });
-
- return true;
- }
-
- private void toggleSelection(final PostModel postModel) {
- if (postModel != null && postsAdapter != null) {
- if (postModel.isSelected()) selectedItems.remove(postModel);
- else if (selectedItems.size() >= 100) {
- Toast.makeText(ProfileViewer.this, R.string.downloader_too_many, Toast.LENGTH_SHORT);
- return;
- }
- else selectedItems.add(postModel);
- postModel.setSelected(!postModel.isSelected());
- notifyAdapter(postModel);
- }
- }
-
- private void notifyAdapter(final PostModel postModel) {
- if (selectedItems.size() < 1) postsAdapter.isSelecting = false;
- if (postModel.getPosition() < 0) postsAdapter.notifyDataSetChanged();
- else postsAdapter.notifyItemChanged(postModel.getPosition(), postModel);
-
- if (downloadAction != null) downloadAction.setVisible(postsAdapter.isSelecting);
- }
-
- @Override
- public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- if (requestCode == 8020 && grantResults[0] == PackageManager.PERMISSION_GRANTED && selectedItems.size() > 0)
- Utils.batchDownload(this, userQuery, DownloadMethod.DOWNLOAD_MAIN, selectedItems);
- }
-
- public void deselectSelection(final BasePostModel postModel) {
- if (postModel instanceof PostModel) {
- selectedItems.remove(postModel);
- postModel.setSelected(false);
- if (postsAdapter != null) notifyAdapter((PostModel) postModel);
- }
- }
-
- class MyTask extends AsyncTask {
- private Bitmap mIcon_val;
-
- protected Void doInBackground(Void... voids) {
- try {
- mIcon_val = BitmapFactory.decodeStream((InputStream) new URL(
- (hashtagModel != null) ? hashtagModel.getSdProfilePic() : (
- (locationModel != null) ? locationModel.getSdProfilePic() :
- profileModel.getSdProfilePic())
- ).getContent());
- } catch (Throwable ex) {
- Log.e("austin_debug", "bitmap: " + ex);
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- if (hashtagModel != null) profileBinding.profileView.mainHashtagImage.setImageBitmap(mIcon_val);
- else if (locationModel != null) profileBinding.profileView.mainLocationImage.setImageBitmap(mIcon_val);
- else profileBinding.profileView.mainProfileImage.setImageBitmap(mIcon_val);
- }
- }
-
- private final View.OnClickListener profileActionListener = new View.OnClickListener() {
- @Override
- public void onClick(final View v) {
- final boolean iamme = (isLoggedIn && profileModel != null) && Utils.getUserIdFromCookie(cookie).equals(profileModel.getId());
- if (!isLoggedIn && Utils.dataBox.getFavorite(userQuery) != null && v == profileBinding.profileView.btnFollow) {
- Utils.dataBox.delFavorite(new DataBox.FavoriteModel(userQuery,
- Long.parseLong(Utils.dataBox.getFavorite(userQuery).split("/")[1]),
- locationModel != null ? locationModel.getName() : userQuery.replaceAll("^@", "")));
- onRefresh();
- } else if (!isLoggedIn && (v == profileBinding.profileView.btnFollow || v == profileBinding.profileView.btnFollowTag)) {
- Utils.dataBox.addFavorite(new DataBox.FavoriteModel(userQuery, System.currentTimeMillis(),
- locationModel != null ? locationModel.getName() : userQuery.replaceAll("^@", "")));
- onRefresh();
- } else if (v == profileBinding.profileView.btnFollow) {
- new ProfileAction().execute("follow");
- } else if (v == profileBinding.profileView.btnRestrict && isLoggedIn) {
- new ProfileAction().execute("restrict");
- } else if (v == profileBinding.profileView.btnSaved && !iamme) {
- new ProfileAction().execute("block");
- } else if (v == profileBinding.profileView.btnFollowTag) {
- new ProfileAction().execute("followtag");
- } else if (v == profileBinding.profileView.btnTagged || (v == profileBinding.profileView.btnRestrict && !isLoggedIn)) {
- startActivity(new Intent(ProfileViewer.this, SavedViewer.class)
- .putExtra(Constants.EXTRAS_INDEX, "%"+profileModel.getId())
- .putExtra(Constants.EXTRAS_USER, "@"+profileModel.getUsername())
- );
- } else if (v == profileBinding.profileView.btnSaved) {
- startActivity(new Intent(ProfileViewer.this, SavedViewer.class)
- .putExtra(Constants.EXTRAS_INDEX, "$"+profileModel.getId())
- .putExtra(Constants.EXTRAS_USER, "@"+profileModel.getUsername())
- );
- } else if (v == profileBinding.profileView.btnLiked) {
- startActivity(new Intent(ProfileViewer.this, SavedViewer.class)
- .putExtra(Constants.EXTRAS_INDEX, "^"+profileModel.getId())
- .putExtra(Constants.EXTRAS_USER, "@"+profileModel.getUsername())
- );
- }
- }
- };
-
- class ProfileAction extends AsyncTask {
- boolean ok = false;
- String action;
-
- protected Void doInBackground(String... rawAction) {
- action = rawAction[0];
- final String url = "https://www.instagram.com/web/"+
- ((action == "followtag" && hashtagModel != null) ? ("tags/"+
- (hashtagModel.getFollowing() == true ? "unfollow/" : "follow/")+hashtagModel.getName()+"/") : (
- ((action == "restrict" && profileModel != null) ? "restrict_action" : ("friendships/"+profileModel.getId()))+"/"+
- ((action == "follow" && profileModel != null) ?
- ((profileModel.getFollowing() == true ||
- (profileModel.getFollowing() == false && profileModel.getRequested() == true))
- ? "unfollow/" : "follow/") :
- ((action == "restrict" && profileModel != null) ?
- (profileModel.getRestricted() == true ? "unrestrict/" : "restrict/") :
- (profileModel.getBlocked() == true ? "unblock/" : "block/")))));
- try {
- final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT);
- urlConnection.setRequestProperty("x-csrftoken", cookie.split("csrftoken=")[1].split(";")[0]);
- if (action == "restrict") {
- final String urlParameters = "target_user_id="+profileModel.getId();
- urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- urlConnection.setRequestProperty("Content-Length", "" +
- urlParameters.getBytes().length);
- urlConnection.setDoOutput(true);
- DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
- wr.writeBytes(urlParameters);
- wr.flush();
- wr.close();
- }
- else urlConnection.connect();
- if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
- ok = true;
- }
- else Toast.makeText(ProfileViewer.this, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- urlConnection.disconnect();
- } catch (Throwable ex) {
- Log.e("austin_debug", action+": " + ex);
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- if (ok == true) {
- onRefresh();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/activities/SavedViewer.java b/app/src/main/java/awais/instagrabber/activities/SavedViewer.java
deleted file mode 100755
index d49c2b94..00000000
--- a/app/src/main/java/awais/instagrabber/activities/SavedViewer.java
+++ /dev/null
@@ -1,250 +0,0 @@
-package awais.instagrabber.activities;
-
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import awais.instagrabber.BuildConfig;
-import awais.instagrabber.R;
-import awais.instagrabber.adapters.PostsAdapter;
-import awais.instagrabber.asyncs.PostsFetcher;
-import awais.instagrabber.asyncs.i.iLikedFetcher;
-import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager;
-import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
-import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
-import awais.instagrabber.databinding.ActivitySavedBinding;
-import awais.instagrabber.interfaces.FetchListener;
-import awais.instagrabber.interfaces.ItemGetter;
-import awais.instagrabber.models.BasePostModel;
-import awais.instagrabber.models.PostModel;
-import awais.instagrabber.models.enums.DownloadMethod;
-import awais.instagrabber.models.enums.ItemGetType;
-import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
-import awaisomereport.LogCollector;
-
-import static awais.instagrabber.utils.Constants.AUTOLOAD_POSTS;
-import static awais.instagrabber.utils.Utils.logCollector;
-
-public final class SavedViewer extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener {
- private static AsyncTask, ?, ?> currentlyExecuting;
- public static ItemGetter itemGetter;
- private PostsAdapter postsAdapter;
- private boolean hasNextPage, autoloadPosts;
- //private CommentModel commentModel;
- private ActivitySavedBinding savedBinding;
- private String action, username, endCursor;
- private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
- private RecyclerLazyLoader lazyLoader;
- private Resources resources;
- private ArrayList selectedItems = new ArrayList<>();
- private final ArrayList allItems = new ArrayList<>();
- private MenuItem downloadAction;
-
- private final FetchListener postsFetchListener = new FetchListener() {
- @Override
- public void onResult(final PostModel[] result) {
- final int oldSize = allItems.size();
- if (result != null && result.length > 0) {
- allItems.addAll(Arrays.asList(result));
-
- postsAdapter.notifyItemRangeInserted(oldSize, result.length);
-
- savedBinding.mainPosts.post(() -> {
- savedBinding.mainPosts.setNestedScrollingEnabled(true);
- savedBinding.mainPosts.setVisibility(View.VISIBLE);
- });
-
- final PostModel model = result[result.length - 1];
- if (model != null) {
- endCursor = model.getEndCursor();
-
- hasNextPage = model.hasNextPage();
- if (autoloadPosts && hasNextPage && action.charAt(0) == '^')
- currentlyExecuting = new iLikedFetcher(endCursor, postsFetchListener)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- else if (autoloadPosts && hasNextPage)
- currentlyExecuting = new PostsFetcher(action, endCursor, this)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- else {
- savedBinding.swipeRefreshLayout.setRefreshing(false);
- }
- model.setPageCursor(false, null);
- }
- }
- else {
- savedBinding.swipeRefreshLayout.setRefreshing(false);
- if (oldSize == 0) {
- Toast.makeText(getApplicationContext(), R.string.empty_list, Toast.LENGTH_SHORT).show();
- finish();
- }
- }
- }
- };
-
- @Override
- protected void onCreate(@Nullable final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- savedBinding = ActivitySavedBinding.inflate(getLayoutInflater());
- setContentView(savedBinding.getRoot());
- savedBinding.swipeRefreshLayout.setOnRefreshListener(this);
- autoloadPosts = Utils.settingsHelper.getBoolean(AUTOLOAD_POSTS);
- savedBinding.mainPosts.setNestedScrollingEnabled(false);
- final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(this, Utils.convertDpToPx(110));
- savedBinding.mainPosts.setLayoutManager(layoutManager);
- savedBinding.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4)));
-
- final Intent intent = getIntent();
- if (intent == null || !intent.hasExtra(Constants.EXTRAS_INDEX)
- || Utils.isEmpty((action = intent.getStringExtra(Constants.EXTRAS_INDEX)))
- || !intent.hasExtra(Constants.EXTRAS_USER)
- || Utils.isEmpty((username = intent.getStringExtra(Constants.EXTRAS_USER)))) {
- Utils.errorFinish(this);
- return;
- }
-
- savedBinding.mainPosts.setAdapter(postsAdapter = new PostsAdapter(allItems, v -> {
- final Object tag = v.getTag();
- if (tag instanceof PostModel) {
- final PostModel postModel = (PostModel) tag;
-
- if (postsAdapter.isSelecting) toggleSelection(postModel);
- else startActivity(new Intent(this, PostViewer.class)
- .putExtra(Constants.EXTRAS_INDEX, postModel.getPosition())
- .putExtra(Constants.EXTRAS_POST, postModel)
- .putExtra(Constants.EXTRAS_USER, username)
- .putExtra(Constants.EXTRAS_TYPE, ItemGetType.SAVED_ITEMS));
- }
- }, v -> {
- final Object tag = v.getTag();
- if (tag instanceof PostModel) {
- postsAdapter.isSelecting = true;
- toggleSelection((PostModel) tag);
- }
- return true;
- }));
- savedBinding.swipeRefreshLayout.setRefreshing(true);
- setSupportActionBar(savedBinding.toolbar.toolbar);
- savedBinding.toolbar.toolbar.setTitle((action.charAt(0) == '$' ? R.string.saved :
- (action.charAt(0) == '%' ? R.string.tagged : R.string.liked)));
- savedBinding.toolbar.toolbar.setSubtitle(username);
-
- lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
- if (!autoloadPosts && hasNextPage) {
- savedBinding.swipeRefreshLayout.setRefreshing(true);
- stopCurrentExecutor();
-
- currentlyExecuting = action.charAt(0) == '^'
- ? new iLikedFetcher(endCursor, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
- : new PostsFetcher(action, endCursor, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- endCursor = null;
- }
- });
- savedBinding.mainPosts.addOnScrollListener(lazyLoader);
-
- itemGetter = itemGetType -> {
- if (itemGetType == ItemGetType.SAVED_ITEMS) return allItems;
- return null;
- };
-
- if (action.charAt(0) == '^') new iLikedFetcher(postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- else new PostsFetcher(action, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- @Override
- public boolean onCreateOptionsMenu(final Menu menu) {
- getMenuInflater().inflate(R.menu.saved, menu);
-
- downloadAction = menu.findItem(R.id.downloadAction);
- downloadAction.setVisible(false);
-
- menu.findItem(R.id.favouriteAction).setVisible(false);
-
- downloadAction.setOnMenuItemClickListener(item -> {
- if (selectedItems.size() > 0) {
- Utils.batchDownload(this, null, DownloadMethod.DOWNLOAD_SAVED, selectedItems);
- }
- return true;
- });
- return true;
- }
-
- public void deselectSelection(final BasePostModel postModel) {
- if (postModel instanceof PostModel) {
- selectedItems.remove(postModel);
- postModel.setSelected(false);
- if (postsAdapter != null) notifyAdapter((PostModel) postModel);
- }
- }
-
- @Override
- public void onRefresh() {
- if (lazyLoader != null) lazyLoader.resetState();
- stopCurrentExecutor();
- allItems.clear();
- selectedItems.clear();
- if (postsAdapter != null) {
- postsAdapter.isSelecting = false;
- postsAdapter.notifyDataSetChanged();
- }
- savedBinding.swipeRefreshLayout.setRefreshing(true);
- if (action.charAt(0) == '^') new iLikedFetcher(postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- else new PostsFetcher(action, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- @Override
- public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- if (requestCode == 8020 && grantResults[0] == PackageManager.PERMISSION_GRANTED && selectedItems.size() > 0)
- Utils.batchDownload(this, null, DownloadMethod.DOWNLOAD_SAVED, selectedItems);
- }
-
- public static void stopCurrentExecutor() {
- if (currentlyExecuting != null) {
- try {
- currentlyExecuting.cancel(true);
- } catch (final Exception e) {
- if (logCollector != null)
- logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
- }
- }
- }
-
- private void toggleSelection(final PostModel postModel) {
- if (postModel != null && postsAdapter != null) {
- if (postModel.isSelected()) selectedItems.remove(postModel);
- else if (selectedItems.size() >= 100) {
- Toast.makeText(SavedViewer.this, R.string.downloader_too_many, Toast.LENGTH_SHORT);
- return;
- }
- else selectedItems.add(postModel);
- postModel.setSelected(!postModel.isSelected());
- notifyAdapter(postModel);
- }
- }
-
- private void notifyAdapter(final PostModel postModel) {
- if (selectedItems.size() < 1) postsAdapter.isSelecting = false;
- if (postModel.getPosition() < 0) postsAdapter.notifyDataSetChanged();
- else postsAdapter.notifyItemChanged(postModel.getPosition(), postModel);
-
- if (downloadAction != null) {
- downloadAction.setVisible(postsAdapter.isSelecting);
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/activities/StoryViewer.java b/app/src/main/java/awais/instagrabber/activities/StoryViewer.java
deleted file mode 100755
index 125b357e..00000000
--- a/app/src/main/java/awais/instagrabber/activities/StoryViewer.java
+++ /dev/null
@@ -1,781 +0,0 @@
-package awais.instagrabber.activities;
-
-import android.annotation.SuppressLint;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.util.Log;
-import android.util.Pair;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.EditText;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
-import androidx.core.app.ActivityCompat;
-import androidx.core.content.ContextCompat;
-import androidx.core.view.GestureDetectorCompat;
-import androidx.recyclerview.widget.LinearLayoutManager;
-
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.load.DataSource;
-import com.bumptech.glide.load.engine.GlideException;
-import com.bumptech.glide.request.RequestListener;
-import com.bumptech.glide.request.target.Target;
-import com.google.android.exoplayer2.Player;
-import com.google.android.exoplayer2.SimpleExoPlayer;
-import com.google.android.exoplayer2.source.MediaSource;
-import com.google.android.exoplayer2.source.MediaSourceEventListener;
-import com.google.android.exoplayer2.source.ProgressiveMediaSource;
-import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
-
-import org.json.JSONObject;
-
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Date;
-import java.util.UUID;
-
-import awais.instagrabber.BuildConfig;
-import awais.instagrabber.R;
-import awais.instagrabber.adapters.StoriesAdapter;
-import awais.instagrabber.asyncs.DownloadAsync;
-import awais.instagrabber.asyncs.direct_messages.DirectThreadBroadcaster;
-import awais.instagrabber.asyncs.i.iStoryStatusFetcher;
-import awais.instagrabber.customviews.helpers.SwipeGestureListener;
-import awais.instagrabber.databinding.ActivityStoryViewerBinding;
-import awais.instagrabber.interfaces.SwipeEvent;
-import awais.instagrabber.models.FeedStoryModel;
-import awais.instagrabber.models.PostModel;
-import awais.instagrabber.models.StoryModel;
-import awais.instagrabber.models.enums.MediaItemType;
-import awais.instagrabber.models.stickers.PollModel;
-import awais.instagrabber.models.stickers.QuestionModel;
-import awais.instagrabber.models.stickers.QuizModel;
-import awais.instagrabber.models.stickers.SwipeUpModel;
-import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
-import awaisomereport.LogCollector;
-
-import static awais.instagrabber.customviews.helpers.SwipeGestureListener.SWIPE_THRESHOLD;
-import static awais.instagrabber.customviews.helpers.SwipeGestureListener.SWIPE_VELOCITY_THRESHOLD;
-import static awais.instagrabber.utils.Constants.FOLDER_PATH;
-import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO;
-import static awais.instagrabber.utils.Constants.MARK_AS_SEEN;
-import static awais.instagrabber.utils.Utils.logCollector;
-import static awais.instagrabber.utils.Utils.settingsHelper;
-
-public final class StoryViewer extends BaseLanguageActivity {
- private final StoriesAdapter storiesAdapter = new StoriesAdapter(null, new View.OnClickListener() {
- @Override
- public void onClick(final View v) {
- final Object tag = v.getTag();
- if (tag instanceof StoryModel) {
- currentStory = (StoryModel) tag;
- slidePos = currentStory.getPosition();
- refreshStory();
- }
- }
- });
- private ActivityStoryViewerBinding storyViewerBinding;
- private StoryModel[] storyModels;
- private GestureDetectorCompat gestureDetector;
- private SimpleExoPlayer player;
- private SwipeEvent swipeEvent;
- private MenuItem menuDownload, menuDm;
- private PollModel poll;
- private QuestionModel question;
- private String[] mentions;
- private QuizModel quiz;
- private SwipeUpModel swipeUp;
- private StoryModel currentStory;
- private String url, username;
- private int slidePos = 0, lastSlidePos = 0;
- private final String cookie = settingsHelper.getString(Constants.COOKIE);
- private boolean fetching = false;
-
- @Override
- protected void onCreate(@Nullable final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- storyViewerBinding = ActivityStoryViewerBinding.inflate(getLayoutInflater());
- setContentView(storyViewerBinding.getRoot());
-
- setSupportActionBar(storyViewerBinding.toolbar.toolbar);
-
- final Intent intent = getIntent();
- if (intent == null || !intent.hasExtra(Constants.EXTRAS_STORIES)
- || (storyModels = (StoryModel[]) intent.getSerializableExtra(Constants.EXTRAS_STORIES)) == null) {
- Utils.errorFinish(this);
- return;
- }
-
- username = intent.getStringExtra(Constants.EXTRAS_USERNAME);
- final String highlight = intent.getStringExtra(Constants.EXTRAS_HIGHLIGHT);
- final boolean hasUsername = !Utils.isEmpty(username);
- final boolean hasHighlight = !Utils.isEmpty(highlight);
-
- if (hasUsername) {
- username = username.replace("@", "");
- storyViewerBinding.toolbar.toolbar.setTitle(username);
- storyViewerBinding.toolbar.toolbar.setOnClickListener(v -> {
- searchUsername(username);
- });
- if (hasHighlight) storyViewerBinding.toolbar.toolbar.setSubtitle(getString(R.string.title_highlight, highlight));
- else storyViewerBinding.toolbar.toolbar.setSubtitle(R.string.title_user_story);
- }
-
- storyViewerBinding.storiesList.setVisibility(View.GONE);
- storyViewerBinding.storiesList.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
- storyViewerBinding.storiesList.setAdapter(storiesAdapter);
-
- swipeEvent = new SwipeEvent() {
- private final int storiesLen = storyModels != null ? storyModels.length : 0;
-
- @Override
- public void onSwipe(final boolean isRightSwipe) {
- if (storyModels != null && storiesLen > 0) {
- if (((slidePos + 1 >= storiesLen && isRightSwipe == false) || (slidePos == 0 && isRightSwipe == true))
- && intent.hasExtra(Constants.FEED)) {
- final FeedStoryModel[] storyFeed = (FeedStoryModel[]) intent.getSerializableExtra(Constants.FEED);
- final int index = intent.getIntExtra(Constants.FEED_ORDER, 1738);
- if (settingsHelper.getBoolean(MARK_AS_SEEN)) new SeenAction().execute();
- if ((isRightSwipe == true && index == 0) || (isRightSwipe == false && index == storyFeed.length - 1))
- Toast.makeText(getApplicationContext(), R.string.no_more_stories, Toast.LENGTH_SHORT).show();
- else {
- final FeedStoryModel feedStoryModel = isRightSwipe ?
- (index == 0 ? null : storyFeed[index - 1]) :
- (storyFeed.length == index + 1 ? null : storyFeed[index + 1]);
- if (feedStoryModel != null) {
- if (fetching) {
- Toast.makeText(getApplicationContext(), R.string.be_patient, Toast.LENGTH_SHORT).show();
- } else {
- fetching = true;
- new iStoryStatusFetcher(feedStoryModel.getStoryMediaId(), null, false, false, false, false, result -> {
- if (result != null && result.length > 0) {
- final Intent newIntent = new Intent(getApplicationContext(), StoryViewer.class)
- .putExtra(Constants.EXTRAS_STORIES, result)
- .putExtra(Constants.EXTRAS_USERNAME, feedStoryModel.getProfileModel().getUsername())
- .putExtra(Constants.FEED, storyFeed)
- .putExtra(Constants.FEED_ORDER, isRightSwipe ? (index - 1) : (index + 1));
- newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(newIntent);
- } else
- Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
- }
- }
- else {
- if (isRightSwipe) {
- if (--slidePos <= 0) slidePos = 0;
- } else if (++slidePos >= storiesLen) slidePos = storiesLen - 1;
- currentStory = storyModels[slidePos];
- refreshStory();
- }
- }
- }
- };
- gestureDetector = new GestureDetectorCompat(this, new SwipeGestureListener(swipeEvent));
-
- viewPost();
- }
-
- @SuppressLint("ClickableViewAccessibility")
- private void viewPost() {
- lastSlidePos = 0;
- storyViewerBinding.storiesList.setVisibility(View.GONE);
- storiesAdapter.setData(null);
-
- if (menuDownload != null) menuDownload.setVisible(false);
- if (menuDm != null) menuDm.setVisible(false);
-
- storyViewerBinding.playerView.setOnTouchListener((v, event) -> gestureDetector.onTouchEvent(event));
- storyViewerBinding.imageViewer.setOnSingleFlingListener((e1, e2, velocityX, velocityY) -> {
- final float diffX = e2.getX() - e1.getX();
- try {
- if (Math.abs(diffX) > Math.abs(e2.getY() - e1.getY()) && Math.abs(diffX) > SWIPE_THRESHOLD
- && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
- swipeEvent.onSwipe(diffX > 0);
- return true;
- }
- } catch (final Exception e) {
- if (logCollector != null)
- logCollector.appendException(e, LogCollector.LogFile.ACTIVITY_STORY_VIEWER, "viewPost",
- new Pair<>("swipeEvent", swipeEvent),
- new Pair<>("diffX", diffX));
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
- }
- return false;
- });
-
- final View.OnClickListener linkActionListener = v -> {
- final Object tag = v.getTag();
- if (tag instanceof CharSequence) {
- final Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(tag.toString()));
- startActivity(intent);
- }
- };
-
- storyViewerBinding.spotify.setOnClickListener(linkActionListener);
- storyViewerBinding.swipeUp.setOnClickListener(linkActionListener);
-
- storyViewerBinding.viewStoryPost.setOnClickListener(v -> {
- final Object tag = v.getTag();
- if (tag instanceof CharSequence) startActivity(new Intent(this, PostViewer.class)
- .putExtra(Constants.EXTRAS_POST, new PostModel(tag.toString(), tag.toString().matches("^[\\d]+$"))));
- });
-
- final View.OnClickListener storyActionListener = v -> {
- final Object tag = v.getTag();
- if (tag instanceof PollModel) {
- poll = (PollModel) tag;
- if (poll.getMyChoice() > -1)
- new AlertDialog.Builder(this).setTitle(R.string.voted_story_poll)
- .setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new String[]{
- (poll.getMyChoice() == 0 ? "ā " : "") + poll.getLeftChoice() + " (" + poll.getLeftCount() + ")",
- (poll.getMyChoice() == 1 ? "ā " : "") + poll.getRightChoice() + " (" + poll.getRightCount() + ")"
- }), null)
- .setPositiveButton(R.string.ok, null)
- .show();
- else new AlertDialog.Builder(this).setTitle(poll.getQuestion())
- .setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new String[]{
- poll.getLeftChoice() + " (" + poll.getLeftCount() + ")",
- poll.getRightChoice() + " (" + poll.getRightCount() + ")"
- }), (d, w) -> {
- if (!Utils.isEmpty(cookie)) new VoteAction().execute(w);
- })
- .setPositiveButton(R.string.cancel, null)
- .show();
- }
- else if (tag instanceof QuestionModel) {
- question = (QuestionModel) tag;
- final EditText input = new EditText(this);
- input.setHint(R.string.answer_hint);
- new AlertDialog.Builder(this).setTitle(question.getQuestion())
- .setView(input)
- .setPositiveButton(R.string.ok, (d,w) -> {
- new RespondAction().execute(input.getText().toString());
- })
- .setNegativeButton(R.string.cancel, null)
- .show();
- }
- else if (tag instanceof String[]) {
- mentions = (String[]) tag;
- new AlertDialog.Builder(this).setTitle(R.string.story_mentions)
- .setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, mentions), (d,w) -> {
- searchUsername(mentions[w]);
- })
- .setPositiveButton(R.string.cancel, null)
- .show();
- }
- else if (tag instanceof QuizModel) {
- quiz = quiz;
- String[] choices = new String[quiz.getChoices().length];
- for (int q = 0; q < choices.length; ++q) {
- choices[q] = (quiz.getMyChoice() == q ? "ā " :"") + quiz.getChoices()[q]+ " (" + quiz.getCounts()[q] + ")";
- }
- new AlertDialog.Builder(this).setTitle(quiz.getMyChoice() > -1 ? getString(R.string.story_quizzed) : quiz.getQuestion())
- .setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, choices), (d,w) -> {
- if (quiz.getMyChoice() == -1 && !Utils.isEmpty(cookie)) new QuizAction().execute(w);
- })
- .setPositiveButton(R.string.cancel, null)
- .show();
- }
- };
-
- storyViewerBinding.poll.setOnClickListener(storyActionListener);
- storyViewerBinding.answer.setOnClickListener(storyActionListener);
- storyViewerBinding.mention.setOnClickListener(storyActionListener);
- storyViewerBinding.quiz.setOnClickListener(storyActionListener);
-
- storiesAdapter.setData(storyModels);
- if (storyModels.length > 1) storyViewerBinding.storiesList.setVisibility(View.VISIBLE);
-
- currentStory = storyModels[0];
- refreshStory();
- }
-
- private void setupVideo() {
- storyViewerBinding.playerView.setVisibility(View.VISIBLE);
- storyViewerBinding.progressView.setVisibility(View.GONE);
- storyViewerBinding.imageViewer.setVisibility(View.GONE);
- storyViewerBinding.imageViewer.setImageDrawable(null);
-
- player = new SimpleExoPlayer.Builder(this).build();
- storyViewerBinding.playerView.setPlayer(player);
- player.setPlayWhenReady(settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS));
-
- final ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(new DefaultDataSourceFactory(this, "instagram"))
- .createMediaSource(Uri.parse(url));
- mediaSource.addEventListener(new Handler(), new MediaSourceEventListener() {
- @Override
- public void onLoadCompleted(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
- if (menuDownload != null) menuDownload.setVisible(true);
- if (currentStory.canReply() && menuDm != null && !Utils.isEmpty(cookie)) menuDm.setVisible(true);
- storyViewerBinding.progressView.setVisibility(View.GONE);
- }
-
- @Override
- public void onLoadStarted(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
- if (menuDownload != null) menuDownload.setVisible(true);
- if (currentStory.canReply() && menuDm != null && !Utils.isEmpty(cookie)) menuDm.setVisible(true);
- storyViewerBinding.progressView.setVisibility(View.VISIBLE);
- }
-
- @Override
- public void onLoadCanceled(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
- storyViewerBinding.progressView.setVisibility(View.GONE);
- }
-
- @Override
- public void onLoadError(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData, final IOException error, final boolean wasCanceled) {
- if (menuDownload != null) menuDownload.setVisible(false);
- if (menuDm != null) menuDm.setVisible(false);
- storyViewerBinding.progressView.setVisibility(View.GONE);
- }
- });
- player.prepare(mediaSource);
-
- storyViewerBinding.playerView.setOnClickListener(v -> {
- if (player != null) {
- if (player.getPlaybackState() == Player.STATE_ENDED) player.seekTo(0);
- player.setPlayWhenReady(player.getPlaybackState() == Player.STATE_ENDED || !player.isPlaying());
- }
- });
- }
-
- private void setupImage() {
- storyViewerBinding.progressView.setVisibility(View.VISIBLE);
- storyViewerBinding.playerView.setVisibility(View.GONE);
-
- storyViewerBinding.imageViewer.setImageDrawable(null);
- storyViewerBinding.imageViewer.setVisibility(View.VISIBLE);
- storyViewerBinding.imageViewer.setZoomable(true);
- storyViewerBinding.imageViewer.setZoomTransitionDuration(420);
- storyViewerBinding.imageViewer.setMaximumScale(7.2f);
-
- Glide.with(this).load(url).listener(new RequestListener() {
- @Override
- public boolean onLoadFailed(@Nullable final GlideException e, final Object model, final Target target, final boolean isFirstResource) {
- storyViewerBinding.progressView.setVisibility(View.GONE);
- return false;
- }
-
- @Override
- public boolean onResourceReady(final Drawable resource, final Object model, final Target target, final DataSource dataSource, final boolean isFirstResource) {
- if (menuDownload != null) menuDownload.setVisible(true);
- if (currentStory.canReply() && menuDm != null && !Utils.isEmpty(cookie)) menuDm.setVisible(true);
- storyViewerBinding.progressView.setVisibility(View.GONE);
- return false;
- }
- }).into(storyViewerBinding.imageViewer);
- }
-
- @Override
- public boolean onCreateOptionsMenu(final Menu menu) {
- getMenuInflater().inflate(R.menu.menu, menu);
-
- menu.findItem(R.id.action_settings).setVisible(false);
- menu.findItem(R.id.action_search).setVisible(false);
-
- menuDownload = menu.findItem(R.id.action_download);
- menuDm = menu.findItem(R.id.action_dms);
- menuDownload.setVisible(true);
- menuDm.setVisible(false);
- menuDownload.setOnMenuItemClickListener(item -> {
- if (ContextCompat.checkSelfPermission(this, Utils.PERMS[0]) == PackageManager.PERMISSION_GRANTED)
- downloadStory();
- else
- ActivityCompat.requestPermissions(this, Utils.PERMS, 8020);
- return true;
- });
- menuDm.setOnMenuItemClickListener(item -> {
- final EditText input = new EditText(this);
- input.setHint(R.string.reply_hint);
- new AlertDialog.Builder(this).setTitle(R.string.reply_story)
- .setView(input)
- .setPositiveButton(R.string.ok, (d,w) -> {
- new CommentAction().execute(input.getText().toString());
- })
- .setNegativeButton(R.string.cancel, null)
- .show();
- return true;
- });
-
- return true;
- }
-
- @Override
- public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- if (requestCode == 8020 && grantResults[0] == PackageManager.PERMISSION_GRANTED) downloadStory();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- if (Build.VERSION.SDK_INT < 24) releasePlayer();
- }
-
- @Override
- public void onStop() {
- super.onStop();
- if (Build.VERSION.SDK_INT >= 24) releasePlayer();
- }
-
- private void downloadStory() {
- int error = 0;
- if (currentStory != null) {
- File dir = new File(Environment.getExternalStorageDirectory(), "Download");
-
- if (settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
- final String customPath = settingsHelper.getString(FOLDER_PATH);
- if (!Utils.isEmpty(customPath)) dir = new File(customPath);
- }
-
- if (settingsHelper.getBoolean(Constants.DOWNLOAD_USER_FOLDER) && !Utils.isEmpty(username))
- dir = new File(dir, username);
-
- if (dir.exists() || dir.mkdirs()) {
- final String storyUrl = currentStory.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO ? currentStory.getVideoUrl() : currentStory.getStoryUrl();
- final File saveFile = new File(dir, currentStory.getStoryMediaId() + "_" + currentStory.getTimestamp()
- + Utils.getExtensionFromModel(storyUrl, currentStory));
-
- new DownloadAsync(this, storyUrl, saveFile, result -> {
- final int toastRes = result != null && result.exists() ? R.string.downloader_complete
- : R.string.downloader_error_download_file;
- Toast.makeText(this, toastRes, Toast.LENGTH_SHORT).show();
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-
- } else error = 1;
- } else error = 2;
-
- if (error == 1) Toast.makeText(this, R.string.downloader_error_creating_folder, Toast.LENGTH_SHORT).show();
- else if (error == 2) Toast.makeText(this, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }
-
- private void refreshStory() {
- if (storyViewerBinding.storiesList.getVisibility() == View.VISIBLE) {
- StoryModel item = storiesAdapter.getItemAt(lastSlidePos);
- if (item != null) {
- item.setCurrentSlide(false);
- storiesAdapter.notifyItemChanged(lastSlidePos, item);
- }
-
- item = storiesAdapter.getItemAt(slidePos);
- if (item != null) {
- item.setCurrentSlide(true);
- storiesAdapter.notifyItemChanged(slidePos, item);
- }
- }
- lastSlidePos = slidePos;
-
- final MediaItemType itemType = currentStory.getItemType();
-
- if (menuDownload != null) menuDownload.setVisible(false);
- url = itemType == MediaItemType.MEDIA_TYPE_VIDEO ? currentStory.getVideoUrl() : currentStory.getStoryUrl();
-
- final String shortCode = currentStory.getTappableShortCode();
- storyViewerBinding.viewStoryPost.setVisibility(shortCode != null ? View.VISIBLE : View.GONE);
- storyViewerBinding.viewStoryPost.setTag(shortCode);
-
- final String spotify = currentStory.getSpotify();
- storyViewerBinding.spotify.setVisibility(spotify != null ? View.VISIBLE : View.GONE);
- storyViewerBinding.spotify.setTag(spotify);
-
- poll = currentStory.getPoll();
- storyViewerBinding.poll.setVisibility(poll != null ? View.VISIBLE : View.GONE);
- storyViewerBinding.poll.setTag(poll);
-
- question = currentStory.getQuestion();
- storyViewerBinding.answer.setVisibility((question != null && !Utils.isEmpty(cookie)) ? View.VISIBLE : View.GONE);
- storyViewerBinding.answer.setTag(question);
-
- mentions = currentStory.getMentions();
- storyViewerBinding.mention.setVisibility((mentions != null && mentions.length > 0) ? View.VISIBLE : View.GONE);
- storyViewerBinding.mention.setTag(mentions);
-
- quiz = currentStory.getQuiz();
- storyViewerBinding.quiz.setVisibility(quiz != null ? View.VISIBLE : View.GONE);
- storyViewerBinding.quiz.setTag(quiz);
-
- swipeUp = currentStory.getSwipeUp();
- storyViewerBinding.swipeUp.setVisibility(swipeUp != null ? View.VISIBLE : View.GONE);
- if (swipeUp != null) {
- storyViewerBinding.swipeUp.setText(swipeUp.getText());
- storyViewerBinding.swipeUp.setTag(swipeUp.getUrl());
- }
-
- releasePlayer();
- final Intent intent = getIntent();
- if (intent.getBooleanExtra(Constants.EXTRAS_HASHTAG, false)) {
- storyViewerBinding.toolbar.toolbar.setTitle(currentStory.getUsername() + " (" + intent.getStringExtra(Constants.EXTRAS_USERNAME) + ")");
- storyViewerBinding.toolbar.toolbar.setOnClickListener(v -> {
- searchUsername(currentStory.getUsername());
- });
- }
- if (itemType == MediaItemType.MEDIA_TYPE_VIDEO) setupVideo();
- else setupImage();
-
- if (!intent.hasExtra(Constants.EXTRAS_HIGHLIGHT))
- storyViewerBinding.toolbar.toolbar.setSubtitle(Utils.datetimeParser.format(new Date(currentStory.getTimestamp() * 1000L)));
-
- if (settingsHelper.getBoolean(MARK_AS_SEEN)) new SeenAction().execute();
- }
-
- private void searchUsername(final String text) {
- startActivity(
- new Intent(getApplicationContext(), ProfileViewer.class)
- .putExtra(Constants.EXTRAS_USERNAME, text)
- );
- }
-
- private void releasePlayer() {
- if (player != null) {
- try { player.stop(true); } catch (Exception ignored) { }
- try { player.release(); } catch (Exception ignored) { }
- player = null;
- }
- }
-
- public static int indexOfIntArray(Object[] array, Object key) {
- int returnvalue = -1;
- for (int i = 0; i < array.length; ++i) {
- if (key == array[i]) {
- returnvalue = i;
- break;
- }
- }
- return returnvalue;
- }
-
- class VoteAction extends AsyncTask {
- int ok = -1;
- String action;
-
- protected Void doInBackground(Integer... rawchoice) {
- int choice = rawchoice[0];
- final String url = "https://www.instagram.com/media/"+currentStory.getStoryMediaId().split("_")[0]+"/"+poll.getId()+"/story_poll_vote/";
- try {
- final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT);
- urlConnection.setRequestProperty("x-csrftoken", cookie.split("csrftoken=")[1].split(";")[0]);
- urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- urlConnection.setRequestProperty("Content-Length", "6");
- urlConnection.setDoOutput(true);
- DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
- wr.writeBytes("vote="+choice);
- wr.flush();
- wr.close();
- urlConnection.connect();
- if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
- ok = choice;
- }
- urlConnection.disconnect();
- } catch (Throwable ex) {
- Log.e("austin_debug", "vote: " + ex);
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- if (ok > -1) {
- poll.setMyChoice(ok);
- Toast.makeText(getApplicationContext(), R.string.votef_story_poll, Toast.LENGTH_SHORT).show();
- }
- else Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }
- }
-
- class QuizAction extends AsyncTask {
- int ok = -1;
- String action;
-
- protected Void doInBackground(Integer... rawchoice) {
- int choice = rawchoice[0];
-final String url = "https://i.instagram.com/api/v1/media/"+currentStory.getStoryMediaId().split("_")[0]+"/"+quiz.getId()+"/story_quiz_answer/";
- try {
- JSONObject ogbody = new JSONObject("{\"client_context\":\"" + UUID.randomUUID().toString()
- +"\",\"mutation_token\":\"" + UUID.randomUUID().toString()
- +"\",\"_csrftoken\":\"" + cookie.split("csrftoken=")[1].split(";")[0]
- +"\",\"_uid\":\"" + Utils.getUserIdFromCookie(cookie)
- +"\",\"__uuid\":\"" + settingsHelper.getString(Constants.DEVICE_UUID)
- +"\"}");
- ogbody.put("answer", String.valueOf(choice));
- String urlParameters = Utils.sign(ogbody.toString());
- final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("User-Agent", Constants.I_USER_AGENT);
- urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- urlConnection.setRequestProperty("Content-Length", Integer.toString(urlParameters.getBytes().length));
- urlConnection.setDoOutput(true);
- DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
- wr.writeBytes(urlParameters);
- wr.flush();
- wr.close();
- Log.d("austin_debug", "quiz: "+url+" "+cookie+" "+urlParameters);
- urlConnection.connect();
- if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
- ok = choice;
- }
- urlConnection.disconnect();
- } catch (Throwable ex) {
- Log.e("austin_debug", "quiz: " + ex);
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- if (ok > -1) {
- quiz.setMyChoice(ok);
- Toast.makeText(getApplicationContext(), R.string.answered_story, Toast.LENGTH_SHORT).show();
- }
- else Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }
- }
-
- class RespondAction extends AsyncTask {
- boolean ok = false;
- String action;
-
- protected Void doInBackground(String... rawchoice) {
- final String url = "https://i.instagram.com/api/v1/media/"
- +currentStory.getStoryMediaId().split("_")[0]+"/"+question.getId()+"/story_question_response/";
- try {
- JSONObject ogbody = new JSONObject("{\"client_context\":\"" + UUID.randomUUID().toString()
- +"\",\"mutation_token\":\"" + UUID.randomUUID().toString()
- +"\",\"_csrftoken\":\"" + cookie.split("csrftoken=")[1].split(";")[0]
- +"\",\"_uid\":\"" + Utils.getUserIdFromCookie(cookie)
- +"\",\"__uuid\":\"" + settingsHelper.getString(Constants.DEVICE_UUID)
- +"\"}");
- String choice = rawchoice[0].replaceAll("\"", ("\\\""));
- ogbody.put("response", choice);
- String urlParameters = Utils.sign(ogbody.toString());
- final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("User-Agent", Constants.I_USER_AGENT);
- urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- urlConnection.setRequestProperty("Content-Length", Integer.toString(urlParameters.getBytes().length));
- urlConnection.setDoOutput(true);
- DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
- wr.writeBytes(urlParameters);
- wr.flush();
- wr.close();
- urlConnection.connect();
- if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
- ok = true;
- }
- urlConnection.disconnect();
- } catch (Throwable ex) {
- Log.e("austin_debug", "respond: " + ex);
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- if (ok) {
- Toast.makeText(getApplicationContext(), R.string.answered_story, Toast.LENGTH_SHORT).show();
- }
- else Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }
- }
-
- class SeenAction extends AsyncTask {
- protected Void doInBackground(Void... lmao) {
- final String url = "https://www.instagram.com/stories/reel/seen";
- try {
- String urlParameters = "reelMediaId="+currentStory.getStoryMediaId().split("_")[0]
- +"&reelMediaOwnerId="+currentStory.getUserId()
- +"&reelId="+currentStory.getUserId()
- +"&reelMediaTakenAt="+ currentStory.getTimestamp()
- +"&viewSeenAt="+ currentStory.getTimestamp();
- final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("x-csrftoken", cookie.split("csrftoken=")[1].split(";")[0]);
- urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- urlConnection.setRequestProperty("Content-Length", Integer.toString(urlParameters.getBytes().length));
- urlConnection.setDoOutput(true);
- DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
- wr.writeBytes(urlParameters);
- wr.flush();
- wr.close();
- urlConnection.connect();
- Log.d("austin_debug", urlConnection.getResponseCode() + " " + Utils.readFromConnection(urlConnection));
- urlConnection.disconnect();
- } catch (Throwable ex) {
- Log.e("austin_debug", "seen: " + ex);
- }
- return null;
- }
- }
-
- class CommentAction extends AsyncTask {
- protected Void doInBackground(String... rawAction) {
- final String action = rawAction[0];
- final String url = "https://i.instagram.com/api/v1/direct_v2/create_group_thread/";
- try {
- final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setRequestProperty("User-Agent", Constants.I_USER_AGENT);
- urlConnection.setUseCaches(false);
- final String urlParameters = Utils.sign("{\"_csrftoken\":\"" + cookie.split("csrftoken=")[1].split(";")[0]
- +"\",\"_uid\":\"" + Utils.getUserIdFromCookie(cookie)
- +"\",\"__uuid\":\"" + settingsHelper.getString(Constants.DEVICE_UUID)
- +"\",\"recipient_users\":\"["+currentStory.getUserId() // <- string of array of number (not joking)
- +"]\"}");
- urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- urlConnection.setRequestProperty("Content-Length", "" + urlParameters.getBytes().length);
- urlConnection.setDoOutput(true);
- DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
- wr.writeBytes(urlParameters);
- wr.flush();
- wr.close();
- urlConnection.connect();
- if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
- final String threadid = new JSONObject(Utils.readFromConnection(urlConnection)).getString("thread_id");
- final DirectThreadBroadcaster.StoryReplyBroadcastOptions options =
- new DirectThreadBroadcaster.StoryReplyBroadcastOptions(
- action,
- currentStory.getStoryMediaId(),
- currentStory.getUserId()
- );
- final DirectThreadBroadcaster broadcast = new DirectThreadBroadcaster(threadid);
- broadcast.setOnTaskCompleteListener(result -> {
- Toast.makeText(getApplicationContext(),
- result != null ? R.string.answered_story : R.string.downloader_unknown_error,
- Toast.LENGTH_SHORT).show();
- });
- broadcast.execute(options);
- }
- urlConnection.disconnect();
- } catch (Throwable ex) {
- Log.e("austin_debug", "reply (CT): " + ex);
- Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- }
- return null;
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/AccountSwitcherAdapter.java b/app/src/main/java/awais/instagrabber/adapters/AccountSwitcherAdapter.java
new file mode 100644
index 00000000..8e984ddc
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/AccountSwitcherAdapter.java
@@ -0,0 +1,112 @@
+package awais.instagrabber.adapters;
+
+import android.annotation.SuppressLint;
+import android.graphics.Typeface;
+import android.text.TextUtils;
+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 awais.instagrabber.R;
+import awais.instagrabber.databinding.PrefAccountSwitcherBinding;
+import awais.instagrabber.utils.Constants;
+import awais.instagrabber.utils.DataBox;
+
+import static awais.instagrabber.utils.Utils.settingsHelper;
+
+public class AccountSwitcherAdapter extends ListAdapter {
+ private static final String TAG = "AccountSwitcherAdapter";
+ private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() {
+ @Override
+ public boolean areItemsTheSame(@NonNull final DataBox.CookieModel oldItem, @NonNull final DataBox.CookieModel newItem) {
+ return oldItem.getUid().equals(newItem.getUid());
+ }
+
+ @Override
+ public boolean areContentsTheSame(@NonNull final DataBox.CookieModel oldItem, @NonNull final DataBox.CookieModel newItem) {
+ return oldItem.getUid().equals(newItem.getUid());
+ }
+ };
+
+ private final OnAccountClickListener clickListener;
+ private final OnAccountLongClickListener longClickListener;
+
+ public AccountSwitcherAdapter(final OnAccountClickListener clickListener,
+ final OnAccountLongClickListener longClickListener) {
+ super(DIFF_CALLBACK);
+ this.clickListener = clickListener;
+ this.longClickListener = longClickListener;
+ }
+
+ @NonNull
+ @Override
+ public ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
+ final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
+ final PrefAccountSwitcherBinding binding = PrefAccountSwitcherBinding.inflate(layoutInflater, parent, false);
+ return new ViewHolder(binding);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
+ final DataBox.CookieModel model = getItem(position);
+ if (model == null) return;
+ final String cookie = settingsHelper.getString(Constants.COOKIE);
+ final boolean isCurrent = model.getCookie().equals(cookie);
+ holder.bind(model, isCurrent, clickListener, longClickListener);
+ }
+
+ public interface OnAccountClickListener {
+ void onAccountClick(final DataBox.CookieModel model, final boolean isCurrent);
+ }
+
+ public interface OnAccountLongClickListener {
+ boolean onAccountLongClick(final DataBox.CookieModel model, final boolean isCurrent);
+ }
+
+ public static class ViewHolder extends RecyclerView.ViewHolder {
+ private final PrefAccountSwitcherBinding binding;
+
+ public ViewHolder(final PrefAccountSwitcherBinding binding) {
+ super(binding.getRoot());
+ this.binding = binding;
+ binding.arrowDown.setImageResource(R.drawable.ic_check_24);
+ }
+
+ @SuppressLint("SetTextI18n")
+ public void bind(final DataBox.CookieModel model,
+ final boolean isCurrent,
+ final OnAccountClickListener clickListener,
+ final OnAccountLongClickListener longClickListener) {
+ // Log.d(TAG, model.getFullName());
+ itemView.setOnClickListener(v -> {
+ if (clickListener == null) return;
+ clickListener.onAccountClick(model, isCurrent);
+ });
+ itemView.setOnLongClickListener(v -> {
+ if (longClickListener == null) return false;
+ return longClickListener.onAccountLongClick(model, isCurrent);
+ });
+ binding.profilePic.setImageURI(model.getProfilePic());
+ binding.username.setText("@" + model.getUsername());
+ binding.fullName.setTypeface(null);
+ final String fullName = model.getFullName();
+ if (TextUtils.isEmpty(fullName)) {
+ binding.fullName.setVisibility(View.GONE);
+ } else {
+ binding.fullName.setVisibility(View.VISIBLE);
+ binding.fullName.setText(fullName);
+ }
+ if (!isCurrent) {
+ binding.arrowDown.setVisibility(View.GONE);
+ return;
+ }
+ binding.fullName.setTypeface(binding.fullName.getTypeface(), Typeface.BOLD);
+ binding.arrowDown.setVisibility(View.VISIBLE);
+ }
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java
index 3a456c21..6a00ff33 100755
--- a/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java
@@ -10,9 +10,6 @@ import android.widget.Filterable;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.request.RequestOptions;
-
import java.util.ArrayList;
import awais.instagrabber.R;
@@ -21,10 +18,18 @@ import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.CommentModel;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.utils.LocaleUtils;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.TextUtils;
public final class CommentsAdapter extends RecyclerView.Adapter implements Filterable {
+
+ private CommentModel[] filteredCommentModels;
+ private LayoutInflater layoutInflater;
+
private final boolean isParent;
+ private final View.OnClickListener onClickListener;
+ private final MentionClickListener mentionClickListener;
+ private final CommentModel[] commentModels;
+ private final String[] quantityStrings = new String[2];
private final Filter filter = new Filter() {
@NonNull
@Override
@@ -33,7 +38,7 @@ public final class CommentsAdapter extends RecyclerView.Adapter 0 && !Utils.isEmpty(filter)) {
+ if (commentModels != null && commentsLen > 0 && !TextUtils.isEmpty(filter)) {
final String query = filter.toString().toLowerCase();
final ArrayList filterList = new ArrayList<>(commentsLen);
@@ -66,15 +71,12 @@ public final class CommentsAdapter extends RecyclerView.Adapter 0)
diff --git a/app/src/main/java/awais/instagrabber/adapters/DirectMessageInboxAdapter.java b/app/src/main/java/awais/instagrabber/adapters/DirectMessageInboxAdapter.java
index dfe6af2c..c6701afc 100644
--- a/app/src/main/java/awais/instagrabber/adapters/DirectMessageInboxAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/DirectMessageInboxAdapter.java
@@ -8,7 +8,7 @@ import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import awais.instagrabber.adapters.viewholder.DirectMessageInboxItemViewHolder;
-import awais.instagrabber.databinding.LayoutIncludeSimpleItemBinding;
+import awais.instagrabber.databinding.LayoutDmInboxItemBinding;
import awais.instagrabber.models.direct_messages.InboxThreadModel;
public final class DirectMessageInboxAdapter extends ListAdapter {
@@ -35,7 +35,7 @@ public final class DirectMessageInboxAdapter extends ListAdapter {
+public final class DirectMessageMembersAdapter extends RecyclerView.Adapter {
private final ProfileModel[] profileModels;
private final List admins;
private final View.OnClickListener onClickListener;
- private final LayoutInflater layoutInflater;
- public DirectMessageMembersAdapter(final ProfileModel[] profileModels, final List admins,
- final Context context, final View.OnClickListener onClickListener) {
+ public DirectMessageMembersAdapter(final ProfileModel[] profileModels,
+ final List admins,
+ final View.OnClickListener onClickListener) {
this.profileModels = profileModels;
this.admins = admins;
- this.layoutInflater = LayoutInflater.from(context);
this.onClickListener = onClickListener;
}
@NonNull
@Override
- public RecyclerView.ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
- final View view = layoutInflater.inflate(R.layout.item_follow, parent, false);
- return new FollowsViewHolder(view);
+ public FollowsViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
+ final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
+ final ItemFollowBinding binding = ItemFollowBinding.inflate(layoutInflater, parent, false);
+ return new FollowsViewHolder(binding);
}
@Override
- public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
+ public void onBindViewHolder(@NonNull final FollowsViewHolder holder, final int position) {
final ProfileModel model = profileModels[position];
-
- final FollowsViewHolder followHolder = (FollowsViewHolder) holder;
- if (model != null) {
- followHolder.itemView.setTag(model);
- followHolder.itemView.setOnClickListener(onClickListener);
-
- followHolder.tvUsername.setText(model.getUsername());
- followHolder.tvFullName.setText(model.getName());
-
- if (admins != null && admins.contains(Long.parseLong(model.getId())))
- followHolder.isAdmin.setVisibility(View.VISIBLE);
-
- Glide.with(layoutInflater.getContext()).load(model.getSdProfilePic()).into(followHolder.profileImage);
- }
+ holder.bind(model, admins, onClickListener);
}
@Override
diff --git a/app/src/main/java/awais/instagrabber/adapters/DiscoverAdapter.java b/app/src/main/java/awais/instagrabber/adapters/DiscoverAdapter.java
index ebb0231c..5a1af57e 100755
--- a/app/src/main/java/awais/instagrabber/adapters/DiscoverAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/DiscoverAdapter.java
@@ -1,87 +1,57 @@
package awais.instagrabber.adapters;
-import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.load.DataSource;
-import com.bumptech.glide.load.engine.GlideException;
-import com.bumptech.glide.request.RequestListener;
-import com.bumptech.glide.request.target.Target;
-
-import java.util.ArrayList;
+import androidx.recyclerview.widget.DiffUtil;
import awais.instagrabber.R;
import awais.instagrabber.adapters.viewholder.DiscoverViewHolder;
import awais.instagrabber.models.DiscoverItemModel;
import awais.instagrabber.models.enums.MediaItemType;
-public final class DiscoverAdapter extends RecyclerView.Adapter {
- private final ArrayList discoverItemModels;
- private final View.OnClickListener clickListener;
- private final View.OnLongClickListener longClickListener;
- private LayoutInflater layoutInflater;
- public boolean isSelecting = false;
+public final class DiscoverAdapter extends MultiSelectListAdapter {
- public DiscoverAdapter(final ArrayList discoverItemModels, final View.OnClickListener clickListener,
- final View.OnLongClickListener longClickListener) {
- this.discoverItemModels = discoverItemModels;
- this.longClickListener = longClickListener;
- this.clickListener = clickListener;
+ private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() {
+ @Override
+ public boolean areItemsTheSame(@NonNull final DiscoverItemModel oldItem, @NonNull final DiscoverItemModel newItem) {
+ return oldItem.getPostId().equals(newItem.getPostId());
+ }
+
+ @Override
+ public boolean areContentsTheSame(@NonNull final DiscoverItemModel oldItem, @NonNull final DiscoverItemModel newItem) {
+ return oldItem.getPostId().equals(newItem.getPostId());
+ }
+ };
+
+ public DiscoverAdapter(final OnItemClickListener clickListener,
+ final OnItemLongClickListener longClickListener) {
+ super(diffCallback, clickListener, longClickListener);
}
@NonNull
@Override
public DiscoverViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
- if (layoutInflater == null) layoutInflater = LayoutInflater.from(parent.getContext());
+ final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
return new DiscoverViewHolder(layoutInflater.inflate(R.layout.item_post, parent, false));
}
@Override
public void onBindViewHolder(@NonNull final DiscoverViewHolder holder, final int position) {
- final DiscoverItemModel itemModel = discoverItemModels.get(position);
+ final DiscoverItemModel itemModel = getItem(position);
if (itemModel != null) {
itemModel.setPosition(position);
holder.itemView.setTag(itemModel);
-
- holder.itemView.setOnClickListener(clickListener);
- holder.itemView.setOnLongClickListener(longClickListener);
-
+ holder.itemView.setOnClickListener(v -> getInternalOnItemClickListener().onItemClick(itemModel, position));
+ holder.itemView.setOnLongClickListener(v -> getInternalOnLongItemClickListener().onItemLongClick(itemModel, position));
final MediaItemType mediaType = itemModel.getItemType();
-
- holder.typeIcon.setVisibility(mediaType == MediaItemType.MEDIA_TYPE_VIDEO || mediaType == MediaItemType.MEDIA_TYPE_SLIDER
- ? View.VISIBLE : View.GONE);
-
- holder.typeIcon.setImageResource(mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? R.drawable.slider : R.drawable.video);
-
+ holder.typeIcon.setVisibility(
+ mediaType == MediaItemType.MEDIA_TYPE_VIDEO || mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
+ holder.typeIcon.setImageResource(mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? R.drawable.ic_slider_24 : R.drawable.ic_video_24);
holder.selectedView.setVisibility(itemModel.isSelected() ? View.VISIBLE : View.GONE);
- holder.progressView.setVisibility(View.VISIBLE);
-
- Glide.with(layoutInflater.getContext()).load(itemModel.getDisplayUrl()).listener(new RequestListener() {
- @Override
- public boolean onLoadFailed(@Nullable final GlideException e, final Object model, final Target target, final boolean isFirstResource) {
- holder.progressView.setVisibility(View.GONE);
- return false;
- }
-
- @Override
- public boolean onResourceReady(final Drawable resource, final Object model, final Target target, final DataSource dataSource, final boolean isFirstResource) {
- holder.progressView.setVisibility(View.GONE);
- return false;
- }
- }).into(holder.postImage);
-
+ holder.postImage.setImageURI(itemModel.getDisplayUrl());
}
}
-
- @Override
- public int getItemCount() {
- return discoverItemModels == null ? 0 : discoverItemModels.size();
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/FeedAdapter.java b/app/src/main/java/awais/instagrabber/adapters/FeedAdapter.java
index acf8834a..09623f3f 100755
--- a/app/src/main/java/awais/instagrabber/adapters/FeedAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/FeedAdapter.java
@@ -1,496 +1,111 @@
package awais.instagrabber.adapters;
-import android.annotation.SuppressLint;
-import android.app.Activity;
import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.net.Uri;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.method.LinkMovementMethod;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
import androidx.annotation.NonNull;
-import androidx.appcompat.app.AlertDialog;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.viewpager.widget.PagerAdapter;
-import androidx.viewpager.widget.ViewPager;
+import androidx.recyclerview.widget.DiffUtil;
+import androidx.recyclerview.widget.ListAdapter;
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.RequestManager;
-import com.github.chrisbanes.photoview.PhotoView;
-import com.google.android.exoplayer2.Player;
-import com.google.android.exoplayer2.SimpleExoPlayer;
-import com.google.android.exoplayer2.source.ProgressiveMediaSource;
-import com.google.android.exoplayer2.ui.PlayerView;
-import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
-
-import org.json.JSONObject;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-import awais.instagrabber.BuildConfig;
-import awais.instagrabber.R;
-import awais.instagrabber.activities.CommentsViewer;
-import awais.instagrabber.activities.PostViewer;
-import awais.instagrabber.adapters.viewholder.FeedItemViewHolder;
-import awais.instagrabber.customviews.CommentMentionClickSpan;
+import awais.instagrabber.adapters.viewholder.feed.FeedItemViewHolder;
+import awais.instagrabber.adapters.viewholder.feed.FeedPhotoViewHolder;
+import awais.instagrabber.adapters.viewholder.feed.FeedSliderViewHolder;
+import awais.instagrabber.adapters.viewholder.feed.FeedVideoViewHolder;
import awais.instagrabber.customviews.RamboTextView;
+import awais.instagrabber.databinding.ItemFeedPhotoBinding;
+import awais.instagrabber.databinding.ItemFeedSliderBinding;
+import awais.instagrabber.databinding.ItemFeedVideoBinding;
import awais.instagrabber.interfaces.MentionClickListener;
-import awais.instagrabber.models.BasePostModel;
import awais.instagrabber.models.FeedModel;
-import awais.instagrabber.models.PostModel;
-import awais.instagrabber.models.ProfileModel;
-import awais.instagrabber.models.ViewerPostModel;
-import awais.instagrabber.models.enums.DownloadMethod;
-import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.models.enums.MediaItemType;
-import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
-import static awais.instagrabber.utils.Utils.settingsHelper;
-
-public final class FeedAdapter extends RecyclerView.Adapter {
- private final static String ellipsize = "ā¦ more";
- private final Activity activity;
- private final LayoutInflater layoutInflater;
- private final ArrayList feedModels;
+public final class FeedAdapter extends ListAdapter {
+ private static final String TAG = "FeedAdapter";
+ private final View.OnClickListener clickListener;
private final MentionClickListener mentionClickListener;
- private final View.OnClickListener clickListener = new View.OnClickListener() {
- @Override
- public void onClick(@NonNull final View v) {
- final Object tag = v.getTag();
-
- if (tag instanceof FeedModel) {
- final FeedModel feedModel = (FeedModel) tag;
-
- if (v instanceof RamboTextView) {
- if (feedModel.isMentionClicked())
- feedModel.toggleCaption();
- feedModel.setMentionClicked(false);
- if (!expandCollapseTextView((RamboTextView) v, feedModel))
- feedModel.toggleCaption();
-
- } else {
- final int id = v.getId();
- switch (id) {
- case R.id.btnComments:
- activity.startActivityForResult(new Intent(activity, CommentsViewer.class)
- .putExtra(Constants.EXTRAS_SHORTCODE, feedModel.getShortCode())
- .putExtra(Constants.EXTRAS_POST, feedModel.getPostId())
- .putExtra(Constants.EXTRAS_USER, feedModel.getProfileModel().getId()), 6969);
- break;
-
- case R.id.viewStoryPost:
- activity.startActivity(new Intent(activity, PostViewer.class)
- .putExtra(Constants.EXTRAS_INDEX, feedModel.getPosition())
- .putExtra(Constants.EXTRAS_POST, new PostModel(feedModel.getShortCode(), false))
- .putExtra(Constants.EXTRAS_TYPE, ItemGetType.FEED_ITEMS));
- break;
-
- case R.id.btnDownload:
- final Context context = v.getContext();
- ProfileModel profileModel = feedModel.getProfileModel();
- final String username = profileModel != null ? profileModel.getUsername() : null;
-
- final ViewerPostModel[] sliderItems = feedModel.getSliderItems();
-
- if (feedModel.getItemType() != MediaItemType.MEDIA_TYPE_SLIDER || sliderItems == null || sliderItems.length == 1)
- Utils.batchDownload(context, username, DownloadMethod.DOWNLOAD_FEED, Collections.singletonList(feedModel));
- else {
- final ArrayList postModels = new ArrayList<>();
- final DialogInterface.OnClickListener clickListener = (dialog, which) -> {
- postModels.clear();
-
- final boolean breakWhenFoundSelected = which == DialogInterface.BUTTON_POSITIVE;
-
- for (final ViewerPostModel sliderItem : sliderItems) {
- if (sliderItem != null) {
- if (!breakWhenFoundSelected) postModels.add(sliderItem);
- else if (sliderItem.isSelected()) {
- postModels.add(sliderItem);
- break;
- }
- }
- }
-
- // shows 0 items on first item of viewpager cause onPageSelected hasn't been called yet
- if (breakWhenFoundSelected && postModels.size() == 0)
- postModels.add(sliderItems[0]);
-
- if (postModels.size() > 0)
- Utils.batchDownload(context, username, DownloadMethod.DOWNLOAD_FEED, postModels);
- };
-
- new AlertDialog.Builder(context).setTitle(R.string.post_viewer_download_dialog_title)
- .setPositiveButton(R.string.post_viewer_download_current, clickListener)
- .setNegativeButton(R.string.post_viewer_download_album, clickListener).show();
- }
- break;
-
- case R.id.ivProfilePic:
- if (mentionClickListener != null) {
- profileModel = feedModel.getProfileModel();
- if (profileModel != null)
- mentionClickListener.onClick(null, profileModel.getUsername(), false);
- }
- break;
- }
- }
- }
- }
- };
private final View.OnLongClickListener longClickListener = v -> {
final Object tag;
if (v instanceof RamboTextView && (tag = v.getTag()) instanceof FeedModel)
Utils.copyText(v.getContext(), ((FeedModel) tag).getPostCaption());
return true;
};
- public SimpleExoPlayer pagerPlayer;
- private final PlayerChangeListener playerChangeListener = (childPos, player) -> {
- // todo
- pagerPlayer = player;
+
+ private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() {
+ @Override
+ public boolean areItemsTheSame(@NonNull final FeedModel oldItem, @NonNull final FeedModel newItem) {
+ return oldItem.getPostId().equals(newItem.getPostId());
+ }
+
+ @Override
+ public boolean areContentsTheSame(@NonNull final FeedModel oldItem, @NonNull final FeedModel newItem) {
+ return oldItem.getPostId().equals(newItem.getPostId());
+ }
};
- public FeedAdapter(final Activity activity, final ArrayList FeedModels, final MentionClickListener mentionClickListener) {
- this.activity = activity;
- this.feedModels = FeedModels;
+ public FeedAdapter(final View.OnClickListener clickListener,
+ final MentionClickListener mentionClickListener) {
+ super(diffCallback);
+ // private final static String ellipsize = "ā¦ more";
+ this.clickListener = clickListener;
this.mentionClickListener = mentionClickListener;
- this.layoutInflater = LayoutInflater.from(activity);
}
@NonNull
@Override
public FeedItemViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
- final View view;
- if (viewType == MediaItemType.MEDIA_TYPE_VIDEO.ordinal())
- view = layoutInflater.inflate(R.layout.item_feed_video, parent, false);
- else if (viewType == MediaItemType.MEDIA_TYPE_SLIDER.ordinal())
- view = layoutInflater.inflate(R.layout.item_feed_slider, parent, false);
- else
- view = layoutInflater.inflate(R.layout.item_feed, parent, false);
- return new FeedItemViewHolder(view);
- }
-
- @SuppressLint("SetTextI18n")
- @Override
- public void onBindViewHolder(@NonNull final FeedItemViewHolder viewHolder, final int position) {
- final FeedModel feedModel = feedModels.get(position);
- if (feedModel != null) {
- final RequestManager glideRequestManager = Glide.with(viewHolder.itemView);
-
- feedModel.setPosition(position);
-
- viewHolder.viewPost.setTag(feedModel);
- viewHolder.profilePic.setTag(feedModel);
- viewHolder.btnDownload.setTag(feedModel);
- viewHolder.viewerCaption.setTag(feedModel);
-
- final ProfileModel profileModel = feedModel.getProfileModel();
- if (profileModel != null) {
- glideRequestManager.load(profileModel.getSdProfilePic()).into(viewHolder.profilePic);
- final int titleLen = profileModel.getUsername().length() + 1;
- final SpannableString spannableString = new SpannableString("@"+profileModel.getUsername());
- spannableString.setSpan(new CommentMentionClickSpan(), 0, titleLen, 0);
- viewHolder.username.setText(spannableString);
- viewHolder.username.setMovementMethod(new LinkMovementMethod());
- viewHolder.username.setMentionClickListener((view, text, isHashtag) ->
- mentionClickListener.onClick(null, profileModel.getUsername(), false));
+ final Context context = parent.getContext();
+ final LayoutInflater layoutInflater = LayoutInflater.from(context);
+ final MediaItemType type = MediaItemType.valueOf(viewType);
+ switch (type) {
+ case MEDIA_TYPE_VIDEO: {
+ final ItemFeedVideoBinding binding = ItemFeedVideoBinding.inflate(layoutInflater, parent, false);
+ return new FeedVideoViewHolder(binding, mentionClickListener, clickListener, longClickListener);
}
-
- viewHolder.viewPost.setOnClickListener(clickListener);
- viewHolder.profilePic.setOnClickListener(clickListener);
- viewHolder.btnDownload.setOnClickListener(clickListener);
-
- viewHolder.tvPostDate.setText(feedModel.getPostDate());
-
- final long commentsCount = feedModel.getCommentsCount();
- viewHolder.commentsCount.setText(String.valueOf(commentsCount));
-
- viewHolder.btnComments.setTag(feedModel);
- viewHolder.btnComments.setOnClickListener(clickListener);
- viewHolder.btnComments.setEnabled(true);
-
- final JSONObject location = feedModel.getLocation();
-
- if (location == null) {
- viewHolder.location.setVisibility(View.GONE);
- viewHolder.username.setLayoutParams(new RelativeLayout.LayoutParams(
- RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT
- ));
+ case MEDIA_TYPE_SLIDER: {
+ final ItemFeedSliderBinding binding = ItemFeedSliderBinding.inflate(layoutInflater, parent, false);
+ return new FeedSliderViewHolder(binding, mentionClickListener, clickListener, longClickListener);
}
- else {
- viewHolder.location.setVisibility(View.VISIBLE);
- viewHolder.location.setText(location.optString("name"));
- viewHolder.username.setLayoutParams(new RelativeLayout.LayoutParams(
- RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT
- ));
- viewHolder.location.setOnClickListener(v ->
- new AlertDialog.Builder(v.getContext()).setTitle(location.optString("name"))
- .setMessage(R.string.comment_view_mention_location_search)
- .setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.ok,
- (dialog, which) -> mentionClickListener.onClick(null, location.optString("id")+"/"+location.optString("slug"), false)).show()
- );
- }
-
- final String thumbnailUrl = feedModel.getThumbnailUrl();
- final String displayUrl = feedModel.getDisplayUrl();
- CharSequence postCaption = feedModel.getPostCaption();
-
- final boolean captionEmpty = Utils.isEmpty(postCaption);
-
- viewHolder.viewerCaption.setOnClickListener(clickListener);
- viewHolder.viewerCaption.setOnLongClickListener(longClickListener);
- viewHolder.viewerCaption.setVisibility(captionEmpty ? View.GONE : View.VISIBLE);
-
- if (!captionEmpty && Utils.hasMentions(postCaption)) {
- postCaption = Utils.getMentionText(postCaption);
- feedModel.setPostCaption(postCaption);
- viewHolder.viewerCaption.setText(postCaption, TextView.BufferType.SPANNABLE);
- viewHolder.viewerCaption.setMentionClickListener(mentionClickListener);
- } else {
- viewHolder.viewerCaption.setText(postCaption);
- }
-
- expandCollapseTextView(viewHolder.viewerCaption, feedModel);
-
- final MediaItemType itemType = feedModel.getItemType();
- final View viewToChangeHeight;
-
- if (itemType == MediaItemType.MEDIA_TYPE_VIDEO) {
- viewToChangeHeight = viewHolder.playerView;
- final Player player = viewHolder.playerView.getPlayer();
- if (player != null) {
- final boolean shouldAutoplay = settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS);
- player.setPlayWhenReady(shouldAutoplay);
- }
- viewHolder.videoViewsParent.setVisibility(View.VISIBLE);
- viewHolder.videoViews.setText(String.valueOf(feedModel.getViewCount()));
- } else {
- viewHolder.videoViewsParent.setVisibility(View.GONE);
- viewHolder.btnMute.setVisibility(View.GONE);
-
- if (itemType == MediaItemType.MEDIA_TYPE_SLIDER) {
- viewToChangeHeight = viewHolder.mediaList;
-
- final ViewerPostModel[] sliderItems = feedModel.getSliderItems();
- final int sliderItemLen = sliderItems != null ? sliderItems.length : 0;
-
- if (sliderItemLen > 0) {
- viewHolder.mediaCounter.setText("1/" + sliderItemLen);
- viewHolder.mediaList.setOffscreenPageLimit(Math.min(5, sliderItemLen));
-
- final ViewPager.SimpleOnPageChangeListener simpleOnPageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
- private int prevPos = 0;
-
- @Override
- public void onPageSelected(final int position) {
- ViewerPostModel sliderItem = sliderItems[prevPos];
- if (sliderItem != null) sliderItem.setSelected(false);
- sliderItem = sliderItems[position];
- if (sliderItem != null) sliderItem.setSelected(true);
-
- View childAt = viewHolder.mediaList.getChildAt(prevPos);
- if (childAt instanceof PlayerView) {
- pagerPlayer = (SimpleExoPlayer) ((PlayerView) childAt).getPlayer();
- if (pagerPlayer != null) pagerPlayer.setPlayWhenReady(false);
- }
- childAt = viewHolder.mediaList.getChildAt(position);
- if (childAt instanceof PlayerView) {
- pagerPlayer = (SimpleExoPlayer) ((PlayerView) childAt).getPlayer();
- if (pagerPlayer != null) pagerPlayer.setPlayWhenReady(true);
- }
- prevPos = position;
- viewHolder.mediaCounter.setText((position + 1) + "/" + sliderItemLen);
- }
- };
-
- //noinspection deprecation
- viewHolder.mediaList.setOnPageChangeListener(simpleOnPageChangeListener); // cause add listeners might add to recycled holders
-
- final View.OnClickListener muteClickListener = v -> {
- Player player = null;
- if (v instanceof PlayerView) player = ((PlayerView) v).getPlayer();
- else if (v instanceof ImageView || v == viewHolder.btnMute) {
- final int currentItem = viewHolder.mediaList.getCurrentItem();
- if (currentItem < viewHolder.mediaList.getChildCount()) {
- final View childAt = viewHolder.mediaList.getChildAt(currentItem);
- if (childAt instanceof PlayerView) player = ((PlayerView) childAt).getPlayer();
- }
-
- } else {
- final Object tag = v.getTag();
- if (tag instanceof Player) player = (Player) tag;
- }
-
- if (player instanceof SimpleExoPlayer) {
- final SimpleExoPlayer exoPlayer = (SimpleExoPlayer) player;
- final float intVol = exoPlayer.getVolume() == 0f ? 1f : 0f;
- exoPlayer.setVolume(intVol);
- viewHolder.btnMute.setImageResource(intVol == 0f ? R.drawable.mute : R.drawable.vol);
- Utils.sessionVolumeFull = intVol == 1f;
- }
- };
-
- viewHolder.btnMute.setOnClickListener(muteClickListener);
- viewHolder.mediaList.setAdapter(new ChildMediaItemsAdapter(sliderItems, viewHolder.btnMute, playerChangeListener));
- }
- } else {
- viewToChangeHeight = viewHolder.imageView;
- String url = displayUrl;
- if (Utils.isEmpty(url)) url = thumbnailUrl;
- glideRequestManager.load(url).into(viewHolder.imageView);
- }
- }
-
- if (viewToChangeHeight != null) {
- final ViewGroup.LayoutParams layoutParams = viewToChangeHeight.getLayoutParams();
- layoutParams.height = Utils.displayMetrics.widthPixels + 1;
- viewToChangeHeight.setLayoutParams(layoutParams);
+ case MEDIA_TYPE_IMAGE:
+ default: {
+ final ItemFeedPhotoBinding binding = ItemFeedPhotoBinding.inflate(layoutInflater, parent, false);
+ return new FeedPhotoViewHolder(binding, mentionClickListener, clickListener, longClickListener);
}
}
}
@Override
- public int getItemCount() {
- return feedModels == null ? 0 : feedModels.size();
+ public void onBindViewHolder(@NonNull final FeedItemViewHolder viewHolder, final int position) {
+ final FeedModel feedModel = getItem(position);
+ if (feedModel == null) {
+ return;
+ }
+ feedModel.setPosition(position);
+ viewHolder.bind(feedModel);
}
@Override
public int getItemViewType(final int position) {
- if (feedModels != null) return feedModels.get(position).getItemType().ordinal();
- return MediaItemType.MEDIA_TYPE_IMAGE.ordinal();
+ return getItem(position).getItemType().getId();
}
- /**
- * expands or collapses {@link RamboTextView} [stg idek why i wrote this documentation]
- *
- * @param textView the {@link RamboTextView} view, to expand and collapse
- * @param feedModel the {@link FeedModel} model to check wether model is collapsed to expanded
- *
- * @return true if expanded/collapsed, false if empty or text size is <= 255 chars
- */
- public static boolean expandCollapseTextView(@NonNull final RamboTextView textView, @NonNull final FeedModel feedModel) {
- final CharSequence caption = feedModel.getPostCaption();
- if (Utils.isEmpty(caption)) return false;
-
- final TextView.BufferType bufferType = caption instanceof Spanned ? TextView.BufferType.SPANNABLE : TextView.BufferType.NORMAL;
-
- if (!feedModel.isCaptionExpanded()) {
- int i = Utils.indexOfChar(caption, '\r', 0);
- if (i == -1) i = Utils.indexOfChar(caption, '\n', 0);
- if (i == -1) i = 255;
-
- final int captionLen = caption.length();
- final int minTrim = Math.min(255, i);
- if (captionLen <= minTrim) return false;
-
- if (Utils.hasMentions(caption))
- textView.setText(Utils.getMentionText(caption), TextView.BufferType.SPANNABLE);
- textView.setCaptionIsExpandable(true);
- textView.setCaptionIsExpanded(true);
- } else {
- textView.setText(caption, bufferType);
- textView.setCaptionIsExpanded(false);
- }
- return true;
+ @Override
+ public void onViewAttachedToWindow(@NonNull final FeedItemViewHolder holder) {
+ super.onViewAttachedToWindow(holder);
+ // Log.d(TAG, "attached holder: " + holder);
+ if (!(holder instanceof FeedSliderViewHolder)) return;
+ final FeedSliderViewHolder feedSliderViewHolder = (FeedSliderViewHolder) holder;
+ feedSliderViewHolder.startPlayingVideo();
}
- private interface PlayerChangeListener {
- void playerChanged(final int childPos, final SimpleExoPlayer player);
- }
-
- private static final class ChildMediaItemsAdapter extends PagerAdapter {
- private final PlayerChangeListener playerChangeListener;
- private final ViewerPostModel[] sliderItems;
- private final View btnMute;
- private SimpleExoPlayer player;
-
- private ChildMediaItemsAdapter(final ViewerPostModel[] sliderItems, final View btnMute,
- final PlayerChangeListener playerChangeListener) {
- this.sliderItems = sliderItems;
- this.btnMute = btnMute;
- if (BuildConfig.DEBUG) this.playerChangeListener = playerChangeListener;
- else this.playerChangeListener = null;
- }
-
- @NonNull
- @Override
- public Object instantiateItem(@NonNull final ViewGroup container, final int position) {
- final Context context = container.getContext();
- final ViewerPostModel sliderItem = sliderItems[position];
-
- if (sliderItem.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO) {
- if (btnMute != null) btnMute.setVisibility(View.VISIBLE);
- final PlayerView playerView = new PlayerView(context);
-
- player = new SimpleExoPlayer.Builder(context).build();
- playerView.setPlayer(player);
-
- float vol = settingsHelper.getBoolean(Constants.MUTED_VIDEOS) ? 0f : 1f;
- if (vol == 0f && Utils.sessionVolumeFull) vol = 1f;
- player.setVolume(vol);
- player.setPlayWhenReady(Utils.settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS));
-
- final ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(new DefaultDataSourceFactory(context, "instagram"))
- .createMediaSource(Uri.parse(sliderItem.getDisplayUrl()));
-
- player.setRepeatMode(Player.REPEAT_MODE_ALL);
- player.prepare(mediaSource);
- player.setVolume(vol);
-
- playerView.setTag(player);
-
- if (playerChangeListener != null) {
- //todo
- // playerChangeListener.playerChanged(position, player);
- Log.d("AWAISKING_APP", "playerChangeListener: " + playerChangeListener);
- }
-
- container.addView(playerView);
- return playerView;
- } else {
- if (btnMute != null) btnMute.setVisibility(View.GONE);
-
- final PhotoView photoView = new PhotoView(context);
- photoView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
- Glide.with(context).load(sliderItem.getDisplayUrl()).into(photoView);
- container.addView(photoView);
- return photoView;
- }
- }
-
- @Override
- public void destroyItem(@NonNull final ViewGroup container, final int position, @NonNull final Object object) {
- final Player player = object instanceof PlayerView ? ((PlayerView) object).getPlayer() : this.player;
-
- if (player == this.player && this.player != null) {
- this.player.stop(true);
- this.player.release();
- } else if (player != null) {
- player.stop(true);
- player.release();
- }
-
- container.removeView((View) object);
- }
-
- @Override
- public int getCount() {
- return sliderItems != null ? sliderItems.length : 0;
- }
-
- @Override
- public boolean isViewFromObject(@NonNull final View view, @NonNull final Object object) {
- return view == object;
- }
+ @Override
+ public void onViewDetachedFromWindow(@NonNull final FeedItemViewHolder holder) {
+ super.onViewDetachedFromWindow(holder);
+ // Log.d(TAG, "detached holder: " + holder);
+ if (!(holder instanceof FeedSliderViewHolder)) return;
+ final FeedSliderViewHolder feedSliderViewHolder = (FeedSliderViewHolder) holder;
+ feedSliderViewHolder.stopPlayingVideo();
}
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/FeedStoriesAdapter.java b/app/src/main/java/awais/instagrabber/adapters/FeedStoriesAdapter.java
index 05769834..c1759893 100755
--- a/app/src/main/java/awais/instagrabber/adapters/FeedStoriesAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/FeedStoriesAdapter.java
@@ -1,59 +1,51 @@
package awais.instagrabber.adapters;
import android.view.LayoutInflater;
-import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.DiffUtil;
+import androidx.recyclerview.widget.ListAdapter;
-import com.bumptech.glide.Glide;
-
-import awais.instagrabber.R;
-import awais.instagrabber.adapters.viewholder.HighlightViewHolder;
+import awais.instagrabber.adapters.viewholder.FeedStoryViewHolder;
+import awais.instagrabber.databinding.ItemHighlightBinding;
import awais.instagrabber.models.FeedStoryModel;
-import awais.instagrabber.models.ProfileModel;
-public final class FeedStoriesAdapter extends RecyclerView.Adapter {
- private final View.OnClickListener clickListener;
- private LayoutInflater layoutInflater;
- private FeedStoryModel[] feedStoryModels;
+public final class FeedStoriesAdapter extends ListAdapter {
+ private final OnFeedStoryClickListener listener;
- public FeedStoriesAdapter(final FeedStoryModel[] feedStoryModels, final View.OnClickListener clickListener) {
- this.feedStoryModels = feedStoryModels;
- this.clickListener = clickListener;
+ 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());
+ }
+
+ @Override
+ public boolean areContentsTheSame(@NonNull final FeedStoryModel oldItem, @NonNull final FeedStoryModel newItem) {
+ return oldItem.getStoryMediaId().equals(newItem.getStoryMediaId());
+ }
+ };
+
+ public FeedStoriesAdapter(final OnFeedStoryClickListener listener) {
+ super(diffCallback);
+ this.listener = listener;
}
@NonNull
@Override
- public HighlightViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
- if (layoutInflater == null) layoutInflater = LayoutInflater.from(parent.getContext());
- return new HighlightViewHolder(layoutInflater.inflate(R.layout.item_highlight, parent, false));
+ public FeedStoryViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
+ final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
+ final ItemHighlightBinding binding = ItemHighlightBinding.inflate(layoutInflater, parent, false);
+ return new FeedStoryViewHolder(binding);
}
@Override
- public void onBindViewHolder(@NonNull final HighlightViewHolder holder, final int position) {
- final FeedStoryModel feedStoryModel = feedStoryModels[position];
- if (feedStoryModel != null) {
- holder.itemView.setTag(feedStoryModel);
- holder.itemView.setOnClickListener(clickListener);
-
- final ProfileModel profileModel = feedStoryModel.getProfileModel();
-
- holder.title.setText(profileModel.getUsername());
- Glide.with(layoutInflater.getContext()).load(profileModel.getSdProfilePic()).into(holder.icon);
- holder.icon.setAlpha(feedStoryModel.getFullyRead() ? 0.5F : 1.0F);
- holder.title.setAlpha(feedStoryModel.getFullyRead() ? 0.5F : 1.0F);
- }
+ public void onBindViewHolder(@NonNull final FeedStoryViewHolder holder, final int position) {
+ final FeedStoryModel model = getItem(position);
+ holder.bind(model, position, listener);
}
- public void setData(final FeedStoryModel[] feedStoryModels) {
- this.feedStoryModels = feedStoryModels;
- notifyDataSetChanged();
- }
-
- @Override
- public int getItemCount() {
- return feedStoryModels == null ? 0 : feedStoryModels.length;
+ public interface OnFeedStoryClickListener {
+ void onFeedStoryClick(FeedStoryModel model, int position);
}
}
diff --git a/app/src/main/java/awais/instagrabber/adapters/FollowAdapter.java b/app/src/main/java/awais/instagrabber/adapters/FollowAdapter.java
index 7466022b..b11e0411 100755
--- a/app/src/main/java/awais/instagrabber/adapters/FollowAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/FollowAdapter.java
@@ -1,6 +1,5 @@
package awais.instagrabber.adapters;
-import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -11,16 +10,15 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
-import com.bumptech.glide.Glide;
-
import java.util.ArrayList;
import java.util.List;
import awais.instagrabber.R;
import awais.instagrabber.adapters.viewholder.FollowsViewHolder;
+import awais.instagrabber.databinding.ItemFollowBinding;
import awais.instagrabber.interfaces.OnGroupClickListener;
import awais.instagrabber.models.FollowModel;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.TextUtils;
import thoughtbot.expandableadapter.ExpandableGroup;
import thoughtbot.expandableadapter.ExpandableList;
import thoughtbot.expandableadapter.ExpandableListPosition;
@@ -34,7 +32,7 @@ public final class FollowAdapter extends RecyclerView.Adapter groups) {
- this.layoutInflater = LayoutInflater.from(context);
+ public FollowAdapter(final View.OnClickListener onClickListener, @NonNull final ArrayList groups) {
this.expandableList = new ExpandableList(groups);
this.onClickListener = onClickListener;
this.hasManyGroups = groups.size() > 1;
@@ -79,10 +82,15 @@ public final class FollowAdapter extends RecyclerView.Adapter {
- private final View.OnClickListener clickListener;
- private LayoutInflater layoutInflater;
- private HighlightModel[] highlightModels;
+public final class HighlightsAdapter extends ListAdapter {
- public HighlightsAdapter(final HighlightModel[] highlightModels, final View.OnClickListener clickListener) {
- this.highlightModels = highlightModels;
+ private final OnHighlightClickListener clickListener;
+
+ private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() {
+ @Override
+ public boolean areItemsTheSame(@NonNull final HighlightModel oldItem, @NonNull final HighlightModel newItem) {
+ return oldItem.getId().equals(newItem.getId());
+ }
+
+ @Override
+ public boolean areContentsTheSame(@NonNull final HighlightModel oldItem, @NonNull final HighlightModel newItem) {
+ return oldItem.getId().equals(newItem.getId());
+ }
+ };
+
+ public HighlightsAdapter(final OnHighlightClickListener clickListener) {
+ super(diffCallback);
this.clickListener = clickListener;
}
@NonNull
@Override
public HighlightViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
- if (layoutInflater == null) layoutInflater = LayoutInflater.from(parent.getContext());
- return new HighlightViewHolder(layoutInflater.inflate(R.layout.item_highlight, parent, false));
+ final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
+ final ItemHighlightBinding binding = ItemHighlightBinding.inflate(layoutInflater, parent, false);
+ return new HighlightViewHolder(binding);
}
@Override
public void onBindViewHolder(@NonNull final HighlightViewHolder holder, final int position) {
- final HighlightModel highlightModel = highlightModels[position];
- if (highlightModel != null) {
- holder.itemView.setTag(highlightModel);
- holder.itemView.setOnClickListener(clickListener);
- holder.title.setText(highlightModel.getTitle());
- Glide.with(holder.itemView).load(highlightModel.getThumbnailUrl()).into(holder.icon);
+ final HighlightModel highlightModel = getItem(position);
+ if (clickListener != null) {
+ holder.itemView.setOnClickListener(v -> clickListener.onHighlightClick(highlightModel, position));
}
+ holder.bind(highlightModel);
}
- public void setData(final HighlightModel[] highlightModels) {
- this.highlightModels = highlightModels;
- notifyDataSetChanged();
- }
-
- @Override
- public int getItemCount() {
- return highlightModels == null ? 0 : highlightModels.length;
+ public interface OnHighlightClickListener {
+ void onHighlightClick(final HighlightModel model, final int position);
}
}
diff --git a/app/src/main/java/awais/instagrabber/adapters/MultiSelectListAdapter.java b/app/src/main/java/awais/instagrabber/adapters/MultiSelectListAdapter.java
new file mode 100644
index 00000000..d196b2c9
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/MultiSelectListAdapter.java
@@ -0,0 +1,104 @@
+package awais.instagrabber.adapters;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.DiffUtil;
+import androidx.recyclerview.widget.ListAdapter;
+import androidx.recyclerview.widget.RecyclerView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class MultiSelectListAdapter extends
+ ListAdapter {
+
+ private boolean isSelecting;
+ private final OnItemClickListener internalOnItemClickListener;
+ private final OnItemLongClickListener internalOnLongItemClickListener;
+
+ private final List selectedItems = new ArrayList<>();
+
+ protected MultiSelectListAdapter(@NonNull final DiffUtil.ItemCallback diffCallback,
+ final OnItemClickListener clickListener,
+ final OnItemLongClickListener longClickListener) {
+ super(diffCallback);
+ internalOnItemClickListener = (item, position) -> {
+ if (isSelecting) {
+ toggleSelection(item, position);
+ }
+ if (clickListener == null) {
+ return;
+ }
+ clickListener.onItemClick(item, position);
+ };
+ internalOnLongItemClickListener = (item, position) -> {
+ if (!isSelecting) {
+ isSelecting = true;
+ }
+ toggleSelection(item, position);
+ if (longClickListener == null) {
+ return true;
+ }
+ return longClickListener.onItemLongClick(item, position);
+ };
+ }
+
+ public OnItemClickListener getInternalOnItemClickListener() {
+ return internalOnItemClickListener;
+ }
+
+ public OnItemLongClickListener getInternalOnLongItemClickListener() {
+ return internalOnLongItemClickListener;
+ }
+
+ private void toggleSelection(final T item, final int position) {
+ if (item == null) {
+ return;
+ }
+ if (selectedItems.size() >= 100) {
+ // Toast.makeText(mainActivity, R.string.downloader_too_many, Toast.LENGTH_SHORT);
+ return;
+ }
+ if (item.isSelected()) {
+ item.setSelected(false);
+ selectedItems.remove(item);
+ } else {
+ item.setSelected(true);
+ selectedItems.add(item);
+ }
+ if (selectedItems.size() == 0) {
+ isSelecting = false;
+ }
+ notifyItemChanged(position);
+ }
+
+ public boolean isSelecting() {
+ return isSelecting;
+ }
+
+ public List getSelectedModels() {
+ return selectedItems;
+ }
+
+ public void clearSelection() {
+ for (final T item : selectedItems) {
+ item.setSelected(false);
+ }
+ selectedItems.clear();
+ isSelecting = false;
+ notifyDataSetChanged();
+ }
+
+ public interface Selectable {
+ boolean isSelected();
+
+ void setSelected(boolean selected);
+ }
+
+ public interface OnItemClickListener {
+ void onItemClick(T item, int position);
+ }
+
+ public interface OnItemLongClickListener {
+ boolean onItemLongClick(T item, int position);
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/adapters/NotificationsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/NotificationsAdapter.java
old mode 100755
new mode 100644
index b5d9606b..dac5f477
--- a/app/src/main/java/awais/instagrabber/adapters/NotificationsAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/NotificationsAdapter.java
@@ -1,91 +1,55 @@
package awais.instagrabber.adapters;
-import android.content.Context;
import android.view.LayoutInflater;
-import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.DiffUtil;
+import androidx.recyclerview.widget.ListAdapter;
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.RequestManager;
-import com.bumptech.glide.request.RequestOptions;
-
-import awais.instagrabber.R;
import awais.instagrabber.adapters.viewholder.NotificationViewHolder;
+import awais.instagrabber.databinding.ItemNotificationBinding;
import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.NotificationModel;
-import awais.instagrabber.models.enums.NotificationType;
-public final class NotificationsAdapter extends RecyclerView.Adapter {
- private final View.OnClickListener onClickListener;
+public final class NotificationsAdapter extends ListAdapter {
+ private final OnNotificationClickListener notificationClickListener;
private final MentionClickListener mentionClickListener;
- private final NotificationModel[] notificationModels;
- private LayoutInflater layoutInflater;
- public NotificationsAdapter(final NotificationModel[] notificationModels, final View.OnClickListener onClickListener,
+ private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() {
+ @Override
+ public boolean areItemsTheSame(@NonNull final NotificationModel oldItem, @NonNull final NotificationModel newItem) {
+ return oldItem.getId().equals(newItem.getId());
+ }
+
+ @Override
+ public boolean areContentsTheSame(@NonNull final NotificationModel oldItem, @NonNull final NotificationModel newItem) {
+ return oldItem.getId().equals(newItem.getId());
+ }
+ };
+
+ public NotificationsAdapter(final OnNotificationClickListener notificationClickListener,
final MentionClickListener mentionClickListener) {
- this.notificationModels = notificationModels;
- this.onClickListener = onClickListener;
+ super(DIFF_CALLBACK);
+ this.notificationClickListener = notificationClickListener;
this.mentionClickListener = mentionClickListener;
}
@NonNull
@Override
public NotificationViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int type) {
- final Context context = parent.getContext();
- if (layoutInflater == null) layoutInflater = LayoutInflater.from(context);
- return new NotificationViewHolder(layoutInflater.inflate(R.layout.item_notification,
- parent, false), onClickListener, mentionClickListener);
+ final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
+ final ItemNotificationBinding binding = ItemNotificationBinding.inflate(layoutInflater, parent, false);
+ return new NotificationViewHolder(binding);
}
@Override
public void onBindViewHolder(@NonNull final NotificationViewHolder holder, final int position) {
- final NotificationModel notificationModel = notificationModels[position];
- if (notificationModel != null) {
- holder.setNotificationModel(notificationModel);
-
- int text = -1;
- CharSequence subtext = null;
- switch (notificationModel.getType()) {
- case LIKE:
- text = R.string.liked_notif;
- break;
- case COMMENT:
- text = R.string.comment_notif;
- subtext = notificationModel.getText();
- break;
- case MENTION:
- text = R.string.mention_notif;
- subtext = notificationModel.getText();
- break;
- case FOLLOW:
- text = R.string.follow_notif;
- break;
- case REQUEST:
- text = R.string.request_notif;
- subtext = notificationModel.getText();
- break;
- }
-
- holder.setCommment(text);
- holder.setSubCommment(subtext);
- if (notificationModel.getType() != NotificationType.REQUEST)
- holder.setDate(notificationModel.getDateTime());
-
- holder.setUsername(notificationModel.getUsername());
-
- final RequestManager rm = Glide.with(layoutInflater.getContext())
- .applyDefaultRequestOptions(new RequestOptions().skipMemoryCache(true));
-
- rm.load(notificationModel.getProfilePic()).into(holder.getProfilePicView());
- rm.load(notificationModel.getPreviewPic()).into(holder.getPreviewPicView());
- }
+ final NotificationModel notificationModel = getItem(position);
+ holder.bind(notificationModel, notificationClickListener);
}
- @Override
- public int getItemCount() {
- return notificationModels == null ? 0 : notificationModels.length;
+ public interface OnNotificationClickListener {
+ void onNotificationClick(final NotificationModel model);
}
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/PostViewAdapter.java b/app/src/main/java/awais/instagrabber/adapters/PostViewAdapter.java
new file mode 100644
index 00000000..305f04cd
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/PostViewAdapter.java
@@ -0,0 +1,77 @@
+package awais.instagrabber.adapters;
+
+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 java.util.Arrays;
+
+import awais.instagrabber.adapters.viewholder.PostViewerViewHolder;
+import awais.instagrabber.databinding.ItemFullPostViewBinding;
+import awais.instagrabber.interfaces.MentionClickListener;
+import awais.instagrabber.models.ViewerPostModelWrapper;
+
+public class PostViewAdapter extends ListAdapter {
+ private final OnPostViewChildViewClickListener clickListener;
+ private final OnPostCaptionLongClickListener longClickListener;
+ private final MentionClickListener mentionClickListener;
+
+ private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() {
+ @Override
+ public boolean areItemsTheSame(@NonNull final ViewerPostModelWrapper oldItem,
+ @NonNull final ViewerPostModelWrapper newItem) {
+ return oldItem.getPosition() == newItem.getPosition();
+ }
+
+ @Override
+ public boolean areContentsTheSame(@NonNull final ViewerPostModelWrapper oldItem,
+ @NonNull final ViewerPostModelWrapper newItem) {
+ return Arrays.equals(oldItem.getViewerPostModels(), newItem.getViewerPostModels());
+ }
+ };
+
+ public PostViewAdapter(final OnPostViewChildViewClickListener clickListener,
+ final OnPostCaptionLongClickListener longClickListener,
+ final MentionClickListener mentionClickListener) {
+ super(diffCallback);
+ this.clickListener = clickListener;
+ this.longClickListener = longClickListener;
+ this.mentionClickListener = mentionClickListener;
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(@NonNull final PostViewerViewHolder holder) {
+ holder.stopPlayingVideo();
+ }
+
+ @NonNull
+ @Override
+ public PostViewerViewHolder onCreateViewHolder(@NonNull final ViewGroup parent,
+ final int viewType) {
+ final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
+ final ItemFullPostViewBinding binding = ItemFullPostViewBinding
+ .inflate(layoutInflater, parent, false);
+ return new PostViewerViewHolder(binding);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull final PostViewerViewHolder holder, final int position) {
+ final ViewerPostModelWrapper item = getItem(position);
+ holder.bind(item, position, clickListener, longClickListener, mentionClickListener);
+ }
+
+ public interface OnPostViewChildViewClickListener {
+ void onClick(View v,
+ ViewerPostModelWrapper viewerPostModelWrapper,
+ int postPosition,
+ int childPosition);
+ }
+
+ public interface OnPostCaptionLongClickListener {
+ void onLongClick(String text);
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/adapters/PostViewerChildAdapter.java b/app/src/main/java/awais/instagrabber/adapters/PostViewerChildAdapter.java
new file mode 100644
index 00000000..ca3e59e0
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/PostViewerChildAdapter.java
@@ -0,0 +1,203 @@
+package awais.instagrabber.adapters;
+
+import android.net.Uri;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.widget.AppCompatTextView;
+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.interfaces.DraweeController;
+import com.facebook.imagepipeline.request.ImageRequest;
+import com.facebook.imagepipeline.request.ImageRequestBuilder;
+import com.google.android.exoplayer2.Player;
+import com.google.android.exoplayer2.SimpleExoPlayer;
+import com.google.android.exoplayer2.source.ProgressiveMediaSource;
+import com.google.android.exoplayer2.ui.PlayerView;
+import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
+
+import awais.instagrabber.customviews.drawee.ZoomableDraweeView;
+import awais.instagrabber.models.ViewerPostModel;
+import awais.instagrabber.models.enums.MediaItemType;
+import awais.instagrabber.utils.Constants;
+import awais.instagrabber.utils.Utils;
+
+public class PostViewerChildAdapter extends ListAdapter {
+
+ private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() {
+ @Override
+ public boolean areItemsTheSame(@NonNull final ViewerPostModel oldItem, @NonNull final ViewerPostModel newItem) {
+ return oldItem.getPostId().equals(newItem.getPostId()) && oldItem.getShortCode().equals(newItem.getShortCode());
+ }
+
+ @Override
+ public boolean areContentsTheSame(@NonNull final ViewerPostModel oldItem, @NonNull final ViewerPostModel newItem) {
+ return oldItem.getPostId().equals(newItem.getPostId()) && oldItem.getShortCode().equals(newItem.getShortCode());
+ }
+ };
+
+ public PostViewerChildAdapter() {
+ super(diffCallback);
+ }
+
+ @NonNull
+ @Override
+ public ChildViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
+ // final AppCompatTextView textView = new AppCompatTextView(parent.getContext());
+ // textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ // return new ChildViewHolder(textView);
+ final MediaItemType mediaItemType = MediaItemType.valueOf(viewType);
+ if (mediaItemType == null) return getPlaceholder(parent);
+ switch (mediaItemType) {
+ case MEDIA_TYPE_IMAGE:
+ return getImageViewHolder(parent);
+ case MEDIA_TYPE_VIDEO:
+ return getVideoViewHolder(parent);
+ default:
+ return getPlaceholder(parent);
+ }
+ }
+
+ private ChildViewHolder getImageViewHolder(final ViewGroup parent) {
+ final ZoomableDraweeView view = new ZoomableDraweeView(parent.getContext());
+ view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ return new ChildViewHolder(view);
+ }
+
+ private ChildViewHolder getVideoViewHolder(final ViewGroup parent) {
+ final PlayerView view = new PlayerView(parent.getContext());
+ view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ return new ChildViewHolder(view);
+ }
+
+ private ChildViewHolder getPlaceholder(final ViewGroup parent) {
+ final AppCompatTextView textView = new AppCompatTextView(parent.getContext());
+ textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ textView.setGravity(Gravity.CENTER);
+ textView.setText("Placeholder");
+ return new ChildViewHolder(textView);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull final ChildViewHolder holder, final int position) {
+ holder.bind(getItem(position));
+ }
+
+ @Override
+ public int getItemViewType(final int position) {
+ final ViewerPostModel item = getItem(position);
+ return item.getItemType().getId();
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(@NonNull final ChildViewHolder holder) {
+ if (holder.itemView instanceof PlayerView) {
+ final Player player = ((PlayerView) holder.itemView).getPlayer();
+ if (player != null) {
+ player.setPlayWhenReady(false);
+ }
+ }
+ }
+
+ @Override
+ public void onViewRecycled(@NonNull final ChildViewHolder holder) {
+ if (holder.itemView instanceof PlayerView) {
+ final Player player = ((PlayerView) holder.itemView).getPlayer();
+ if (player != null) {
+ player.release();
+ }
+ return;
+ }
+ if (holder.itemView instanceof ZoomableDraweeView) {
+ ((ZoomableDraweeView) holder.itemView).setController(null);
+ }
+ }
+
+ public static class ChildViewHolder extends RecyclerView.ViewHolder {
+
+ public ChildViewHolder(@NonNull final View itemView) {
+ super(itemView);
+ }
+
+ public void bind(final ViewerPostModel item) {
+ final MediaItemType mediaItemType = item.getItemType();
+ switch (mediaItemType) {
+ case MEDIA_TYPE_IMAGE:
+ bindImage(item);
+ break;
+ case MEDIA_TYPE_VIDEO:
+ bindVideo(item);
+ break;
+ default:
+ }
+ }
+
+ private void bindImage(final ViewerPostModel item) {
+ final ZoomableDraweeView imageView = (ZoomableDraweeView) itemView;
+ imageView.setController(null);
+ final ImageRequest requestBuilder = ImageRequestBuilder.newBuilderWithSource(Uri.parse(item.getDisplayUrl()))
+ .setLocalThumbnailPreviewsEnabled(true)
+ .setProgressiveRenderingEnabled(true)
+ .build();
+ final DraweeController controller = Fresco.newDraweeControllerBuilder()
+ .setImageRequest(requestBuilder)
+ .setOldController(imageView.getController())
+ // .setControllerListener(new BaseControllerListener() {
+ //
+ // @Override
+ // public void onFailure(final String id, final Throwable throwable) {
+ // // viewerBinding.progressView.setVisibility(View.GONE);
+ // }
+ //
+ // @Override
+ // public void onFinalImageSet(final String id, final ImageInfo imageInfo, final Animatable animatable) {
+ // // viewerBinding.progressView.setVisibility(View.GONE);
+ // }
+ // })
+ .build();
+ imageView.setController(controller);
+ }
+
+ private void bindVideo(final ViewerPostModel item) {
+ final SimpleExoPlayer player = new SimpleExoPlayer.Builder(itemView.getContext()).build();
+ final PlayerView playerView = (PlayerView) itemView;
+ playerView.setPlayer(player);
+ float vol = Utils.settingsHelper.getBoolean(Constants.MUTED_VIDEOS) ? 0f : 1f;
+ if (vol == 0f && Utils.sessionVolumeFull) vol = 1f;
+ player.setVolume(vol);
+ player.setPlayWhenReady(Utils.settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS));
+ final ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(new DefaultDataSourceFactory(itemView.getContext(), "instagram"))
+ .createMediaSource(Uri.parse(item.getDisplayUrl()));
+ // mediaSource.addEventListener(new Handler(), new MediaSourceEventListener() {
+ // @Override
+ // public void onLoadCompleted(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
+ // viewerBinding.progressView.setVisibility(View.GONE);
+ // }
+ //
+ // @Override
+ // public void onLoadStarted(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
+ // viewerBinding.progressView.setVisibility(View.VISIBLE);
+ // }
+ //
+ // @Override
+ // public void onLoadCanceled(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
+ // viewerBinding.progressView.setVisibility(View.GONE);
+ // }
+ //
+ // @Override
+ // public void onLoadError(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData, final IOException error, final boolean wasCanceled) {
+ // viewerBinding.progressView.setVisibility(View.GONE);
+ // }
+ // });
+ player.prepare(mediaSource);
+ player.setVolume(vol);
+ // viewerBinding.bottomPanel.btnMute.setImageResource(vol == 0f ? R.drawable.ic_volume_up_24 : R.drawable.ic_volume_off_24);
+ // viewerBinding.bottomPanel.btnMute.setOnClickListener(onClickListener);
+ }
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/adapters/PostsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/PostsAdapter.java
index 7a528f65..521f261a 100755
--- a/app/src/main/java/awais/instagrabber/adapters/PostsAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/PostsAdapter.java
@@ -1,92 +1,45 @@
package awais.instagrabber.adapters;
-import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
-import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.DiffUtil;
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.RequestManager;
-import com.bumptech.glide.load.DataSource;
-import com.bumptech.glide.load.engine.GlideException;
-import com.bumptech.glide.request.RequestListener;
-import com.bumptech.glide.request.target.Target;
-
-import java.util.ArrayList;
-
-import awais.instagrabber.R;
import awais.instagrabber.adapters.viewholder.PostViewHolder;
+import awais.instagrabber.databinding.ItemPostBinding;
import awais.instagrabber.models.PostModel;
-import awais.instagrabber.models.enums.MediaItemType;
-public final class PostsAdapter extends RecyclerView.Adapter {
- private final ArrayList postModels;
- private final View.OnClickListener clickListener;
- private final View.OnLongClickListener longClickListener;
- private LayoutInflater layoutInflater;
- public boolean isSelecting = false;
+public final class PostsAdapter extends MultiSelectListAdapter {
- public PostsAdapter(final ArrayList postModels, final View.OnClickListener clickListener,
- final View.OnLongClickListener longClickListener) {
- this.postModels = postModels;
- this.clickListener = clickListener;
- this.longClickListener = longClickListener;
+ private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() {
+ @Override
+ public boolean areItemsTheSame(@NonNull final PostModel oldItem, @NonNull final PostModel newItem) {
+ return oldItem.getPostId().equals(newItem.getPostId());
+ }
+
+ @Override
+ public boolean areContentsTheSame(@NonNull final PostModel oldItem, @NonNull final PostModel newItem) {
+ return oldItem.getPostId().equals(newItem.getPostId());
+ }
+ };
+
+ public PostsAdapter(final OnItemClickListener clickListener,
+ final OnItemLongClickListener longClickListener) {
+ super(DIFF_CALLBACK, clickListener, longClickListener);
}
@NonNull
@Override
public PostViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
- if (layoutInflater == null) layoutInflater = LayoutInflater.from(parent.getContext());
- return new PostViewHolder(layoutInflater.inflate(R.layout.item_post, parent, false));
+ final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
+ final ItemPostBinding binding = ItemPostBinding.inflate(layoutInflater, parent, false);
+ return new PostViewHolder(binding);
}
@Override
public void onBindViewHolder(@NonNull final PostViewHolder holder, final int position) {
- final PostModel postModel = postModels.get(position);
- if (postModel != null) {
- postModel.setPosition(position);
-
- holder.itemView.setTag(postModel);
-
- holder.itemView.setOnClickListener(clickListener);
- holder.itemView.setOnLongClickListener(longClickListener);
-
- final MediaItemType itemType = postModel.getItemType();
- final boolean isSlider = itemType == MediaItemType.MEDIA_TYPE_SLIDER;
-
- holder.isDownloaded.setVisibility(postModel.isDownloaded() ? View.VISIBLE : View.GONE);
-
- holder.typeIcon.setVisibility(itemType == MediaItemType.MEDIA_TYPE_VIDEO || isSlider ? View.VISIBLE : View.GONE);
- holder.typeIcon.setImageResource(isSlider ? R.drawable.slider : R.drawable.video);
-
- holder.selectedView.setVisibility(postModel.isSelected() ? View.VISIBLE : View.GONE);
- holder.progressView.setVisibility(View.VISIBLE);
-
- final RequestManager glideRequestManager = Glide.with(holder.postImage);
-
- glideRequestManager.load(postModel.getThumbnailUrl()).listener(new RequestListener() {
- @Override
- public boolean onResourceReady(final Drawable resource, final Object model, final Target target, final DataSource dataSource, final boolean isFirstResource) {
- holder.progressView.setVisibility(View.GONE);
- return false;
- }
-
- @Override
- public boolean onLoadFailed(@Nullable final GlideException e, final Object model, final Target target, final boolean isFirstResource) {
- holder.progressView.setVisibility(View.GONE);
- // glideRequestManager.load(postModel.getDisplayUrl()).into(holder.postImage);
- return false;
- }
- }).into(holder.postImage);
- }
- }
-
- @Override
- public int getItemCount() {
- return postModels == null ? 0 : postModels.size();
+ final PostModel postModel = getItem(position);
+ holder.bind(postModel, position, getInternalOnItemClickListener(), getInternalOnLongItemClickListener());
}
}
diff --git a/app/src/main/java/awais/instagrabber/adapters/PostsMediaAdapter.java b/app/src/main/java/awais/instagrabber/adapters/PostsMediaAdapter.java
index f2786b6b..828a111d 100755
--- a/app/src/main/java/awais/instagrabber/adapters/PostsMediaAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/PostsMediaAdapter.java
@@ -7,16 +7,14 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
-import com.bumptech.glide.Glide;
-
import awais.instagrabber.R;
import awais.instagrabber.adapters.viewholder.PostMediaViewHolder;
+import awais.instagrabber.databinding.ItemChildPostBinding;
import awais.instagrabber.models.BasePostModel;
import awais.instagrabber.models.ViewerPostModel;
public final class PostsMediaAdapter extends RecyclerView.Adapter {
private final View.OnClickListener clickListener;
- private LayoutInflater layoutInflater;
private ViewerPostModel[] postModels;
public PostsMediaAdapter(final ViewerPostModel[] postModels, final View.OnClickListener clickListener) {
@@ -27,25 +25,16 @@ public final class PostsMediaAdapter extends RecyclerView.Adapter {
- private final View.OnClickListener clickListener;
- private LayoutInflater layoutInflater;
- private StoryModel[] storyModels;
- private Resources resources;
- private int width, height;
+public final class StoriesAdapter extends ListAdapter {
+ private final OnItemClickListener onItemClickListener;
- public StoriesAdapter(final StoryModel[] storyModels, final View.OnClickListener clickListener) {
- this.storyModels = storyModels;
- this.clickListener = clickListener;
+ private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() {
+ @Override
+ public boolean areItemsTheSame(@NonNull final StoryModel oldItem, @NonNull final StoryModel newItem) {
+ return oldItem.getStoryMediaId().equals(newItem.getStoryMediaId());
+ }
+
+ @Override
+ public boolean areContentsTheSame(@NonNull final StoryModel oldItem, @NonNull final StoryModel newItem) {
+ return oldItem.getStoryMediaId().equals(newItem.getStoryMediaId());
+ }
+ };
+
+ public StoriesAdapter(final OnItemClickListener onItemClickListener) {
+ super(diffCallback);
+ this.onItemClickListener = onItemClickListener;
}
@NonNull
@Override
public StoryViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
- final Context context = parent.getContext();
- if (layoutInflater == null) layoutInflater = LayoutInflater.from(context);
- if (resources == null) resources = context.getResources();
-
- height = Math.round(resources.getDimension(R.dimen.story_item_height));
- width = Math.round(resources.getDimension(R.dimen.story_item_width));
-
- return new StoryViewHolder(layoutInflater.inflate(R.layout.item_story, parent, false));
+ final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
+ final ItemStoryBinding binding = ItemStoryBinding.inflate(layoutInflater, parent, false);
+ return new StoryViewHolder(binding);
}
@Override
public void onBindViewHolder(@NonNull final StoryViewHolder holder, final int position) {
- final StoryModel storyModel = storyModels[position];
- if (storyModel != null) {
- storyModel.setPosition(position);
-
- holder.itemView.setTag(storyModel);
- holder.itemView.setOnClickListener(clickListener);
-
- holder.selectedView.setVisibility(storyModel.isCurrentSlide() ? View.VISIBLE : View.GONE);
-
- Glide.with(holder.itemView).load(storyModel.getStoryUrl())
- .apply(new RequestOptions().override(width, height))
- .into(holder.icon);
- }
- }
-
- public void setData(final StoryModel[] storyModels) {
- this.storyModels = storyModels;
- notifyDataSetChanged();
- }
-
- public StoryModel getItemAt(final int position) {
- return storyModels == null ? null : storyModels[position];
- }
-
- @Override
- public int getItemCount() {
- return storyModels == null ? 0 : storyModels.length;
+ final StoryModel storyModel = getItem(position);
+ holder.bind(storyModel, position, onItemClickListener);
}
public final static class StoryViewHolder extends RecyclerView.ViewHolder {
- public final ImageView icon, selectedView;
+ private final ItemStoryBinding binding;
- public StoryViewHolder(@NonNull final View itemView) {
- super(itemView);
- selectedView = itemView.findViewById(R.id.selectedView);
- icon = itemView.findViewById(R.id.icon);
+ public StoryViewHolder(final ItemStoryBinding binding) {
+ super(binding.getRoot());
+ this.binding = binding;
+ }
+
+ public void bind(final StoryModel model,
+ final int position,
+ final OnItemClickListener clickListener) {
+ if (model == null) return;
+ model.setPosition(position);
+
+ itemView.setTag(model);
+ itemView.setOnClickListener(v -> {
+ if (clickListener == null) return;
+ clickListener.onItemClick(model, position);
+ });
+
+ binding.selectedView.setVisibility(model.isCurrentSlide() ? View.VISIBLE : View.GONE);
+ binding.icon.setImageURI(model.getStoryUrl());
+ // Glide.with(itemView).load(model.getStoryUrl())
+ // .apply(new RequestOptions().override(width, height))
+ // .into(holder.icon);
}
}
+
+ public interface OnItemClickListener {
+ void onItemClick(StoryModel storyModel, int position);
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/SuggestionsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/SuggestionsAdapter.java
index 826b8767..19412e37 100755
--- a/app/src/main/java/awais/instagrabber/adapters/SuggestionsAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/SuggestionsAdapter.java
@@ -2,60 +2,87 @@ package awais.instagrabber.adapters;
import android.content.Context;
import android.database.Cursor;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cursoradapter.widget.CursorAdapter;
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.RequestManager;
-import com.bumptech.glide.request.RequestOptions;
-
-import awais.instagrabber.R;
+import awais.instagrabber.databinding.ItemSuggestionBinding;
+import awais.instagrabber.models.enums.SuggestionType;
public final class SuggestionsAdapter extends CursorAdapter {
- private final LayoutInflater layoutInflater;
- private final View.OnClickListener onClickListener;
- private final RequestManager glideRequestManager;
+ private static final String TAG = "SuggestionsAdapter";
- public SuggestionsAdapter(final Context context, final View.OnClickListener onClickListener) {
+ private final OnSuggestionClickListener onSuggestionClickListener;
+
+ public SuggestionsAdapter(final Context context,
+ final OnSuggestionClickListener onSuggestionClickListener) {
super(context, null, FLAG_REGISTER_CONTENT_OBSERVER);
- this.glideRequestManager = Glide.with(context);
- this.layoutInflater = LayoutInflater.from(context);
- this.onClickListener = onClickListener;
+ this.onSuggestionClickListener = onSuggestionClickListener;
}
@Override
public View newView(final Context context, final Cursor cursor, final ViewGroup parent) {
- return layoutInflater.inflate(R.layout.item_suggestion, parent, false);
+ final LayoutInflater layoutInflater = LayoutInflater.from(context);
+ final ItemSuggestionBinding binding = ItemSuggestionBinding.inflate(layoutInflater, parent, false);
+ return binding.getRoot();
+ // return layoutInflater.inflate(R.layout.item_suggestion, parent, false);
}
@Override
public void bindView(@NonNull final View view, final Context context, @NonNull final Cursor cursor) {
// i, username, fullname, type, picUrl, verified
// 0, 1 , 2 , 3 , 4 , 5
-
- final String fullname = cursor.getString(2);
+ final String fullName = cursor.getString(2);
String username = cursor.getString(1);
final String picUrl = cursor.getString(4);
final boolean verified = cursor.getString(5).charAt(0) == 't';
- if ("TYPE_HASHTAG".equals(cursor.getString(3))) username = '#' + username;
- else if ("TYPE_USER".equals(cursor.getString(3))) username = '@' + username;
+ final String type = cursor.getString(3);
+ SuggestionType suggestionType = null;
+ try {
+ suggestionType = SuggestionType.valueOf(type);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Unknown suggestion type: " + type, e);
+ }
+ if (suggestionType == null) return;
+ final String query;
+ switch (suggestionType) {
+ case TYPE_USER:
+ username = '@' + username;
+ query = username;
+ break;
+ case TYPE_HASHTAG:
+ username = '#' + username;
+ query = username;
+ break;
+ case TYPE_LOCATION:
+ query = fullName;
+ break;
+ default:
+ return; // will never come here
+ }
- view.setOnClickListener(onClickListener);
- view.setTag("TYPE_LOCATION".equals(cursor.getString(3)) ? fullname : username);
+ if (onSuggestionClickListener != null) {
+ final SuggestionType finalSuggestionType = suggestionType;
+ view.setOnClickListener(v -> onSuggestionClickListener.onSuggestionClick(finalSuggestionType, query));
+ }
+ final ItemSuggestionBinding binding = ItemSuggestionBinding.bind(view);
+ binding.isVerified.setVisibility(verified ? View.VISIBLE : View.GONE);
+ binding.tvUsername.setText(username);
+ if (suggestionType.equals(SuggestionType.TYPE_LOCATION)) {
+ binding.tvFullName.setVisibility(View.GONE);
+ } else {
+ binding.tvFullName.setVisibility(View.VISIBLE);
+ binding.tvFullName.setText(fullName);
+ }
+ binding.ivProfilePic.setImageURI(picUrl);
+ }
- view.findViewById(R.id.isVerified).setVisibility(verified ? View.VISIBLE : View.GONE);
-
- ((TextView) view.findViewById(R.id.tvUsername)).setText(username);
- ((TextView) view.findViewById(R.id.tvFullName)).setText(fullname);
-
- glideRequestManager.applyDefaultRequestOptions(new RequestOptions().skipMemoryCache(true))
- .load(picUrl == null ? R.drawable.ic_location : picUrl).into((ImageView) view.findViewById(R.id.ivProfilePic));
+ public interface OnSuggestionClickListener {
+ void onSuggestionClick(final SuggestionType type, final String query);
}
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/CommentViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/CommentViewHolder.java
index d34b0597..0a2e7687 100755
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/CommentViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/CommentViewHolder.java
@@ -2,12 +2,13 @@ package awais.instagrabber.adapters.viewholder;
import android.text.Spannable;
import android.view.View;
-import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
+import com.facebook.drawee.view.SimpleDraweeView;
+
import awais.instagrabber.R;
import awais.instagrabber.adapters.CommentsAdapter;
import awais.instagrabber.customviews.RamboTextView;
@@ -17,11 +18,16 @@ import awais.instagrabber.models.CommentModel;
public final class CommentViewHolder extends RecyclerView.ViewHolder {
private final MentionClickListener mentionClickListener;
private final RecyclerView rvChildComments;
- private final ImageView ivProfilePic;
- private final TextView tvUsername, tvDate, tvComment, tvLikes;
+ private final SimpleDraweeView ivProfilePic;
+ private final TextView tvUsername;
+ private final TextView tvDate;
+ private final TextView tvComment;
+ private final TextView tvLikes;
private final View container;
- public CommentViewHolder(@NonNull final View itemView, final View.OnClickListener onClickListener, final MentionClickListener mentionClickListener) {
+ public CommentViewHolder(@NonNull final View itemView,
+ final View.OnClickListener onClickListener,
+ final MentionClickListener mentionClickListener) {
super(itemView);
container = itemView.findViewById(R.id.container);
@@ -41,7 +47,7 @@ public final class CommentViewHolder extends RecyclerView.ViewHolder {
rvChildComments = itemView.findViewById(R.id.rvChildComments);
}
- public final ImageView getProfilePicView() {
+ public final SimpleDraweeView getProfilePicView() {
return ivProfilePic;
}
@@ -69,9 +75,9 @@ public final class CommentViewHolder extends RecyclerView.ViewHolder {
if (liked) container.setBackgroundColor(0x40FF69B4);
}
- public final void setCommment(final CharSequence commment) {
+ public final void setComment(final CharSequence comment) {
if (tvComment != null) {
- tvComment.setText(commment, commment instanceof Spannable ? TextView.BufferType.SPANNABLE : TextView.BufferType.NORMAL);
+ tvComment.setText(comment, comment instanceof Spannable ? TextView.BufferType.SPANNABLE : TextView.BufferType.NORMAL);
((RamboTextView) tvComment).setMentionClickListener(mentionClickListener);
}
}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/DirectMessageInboxItemViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/DirectMessageInboxItemViewHolder.java
index f01ff706..cd975fa7 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/DirectMessageInboxItemViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/DirectMessageInboxItemViewHolder.java
@@ -1,19 +1,22 @@
package awais.instagrabber.adapters.viewholder;
import android.content.Context;
+import android.net.Uri;
import android.view.View;
-import android.widget.ImageView;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.core.text.HtmlCompat;
import androidx.recyclerview.widget.RecyclerView;
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.RequestManager;
+import com.facebook.drawee.backends.pipeline.Fresco;
+import com.facebook.drawee.view.SimpleDraweeView;
+import com.facebook.imagepipeline.common.ResizeOptions;
+import com.facebook.imagepipeline.request.ImageRequest;
+import com.facebook.imagepipeline.request.ImageRequestBuilder;
import awais.instagrabber.R;
-import awais.instagrabber.databinding.LayoutIncludeSimpleItemBinding;
+import awais.instagrabber.databinding.LayoutDmInboxItemBinding;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.direct_messages.DirectItemModel;
import awais.instagrabber.models.direct_messages.InboxThreadModel;
@@ -21,19 +24,18 @@ import awais.instagrabber.models.enums.DirectItemType;
public final class DirectMessageInboxItemViewHolder extends RecyclerView.ViewHolder {
private final LinearLayout multipleProfilePicsContainer;
- private final ImageView[] multipleProfilePics;
- private final LayoutIncludeSimpleItemBinding binding;
+ private final SimpleDraweeView[] multipleProfilePics;
+ private final LayoutDmInboxItemBinding binding;
- public DirectMessageInboxItemViewHolder(@NonNull final LayoutIncludeSimpleItemBinding binding) {
+ public DirectMessageInboxItemViewHolder(@NonNull final LayoutDmInboxItemBinding binding) {
super(binding.getRoot());
this.binding = binding;
- binding.tvLikes.setVisibility(View.GONE);
- multipleProfilePicsContainer = binding.container;
+ multipleProfilePicsContainer = binding.multiPicContainer;
final LinearLayout containerChild = (LinearLayout) multipleProfilePicsContainer.getChildAt(1);
- multipleProfilePics = new ImageView[]{
- (ImageView) multipleProfilePicsContainer.getChildAt(0),
- (ImageView) containerChild.getChildAt(0),
- (ImageView) containerChild.getChildAt(1)
+ multipleProfilePics = new SimpleDraweeView[]{
+ (SimpleDraweeView) multipleProfilePicsContainer.getChildAt(0),
+ (SimpleDraweeView) containerChild.getChildAt(0),
+ (SimpleDraweeView) containerChild.getChildAt(1)
};
binding.tvDate.setSelected(true);
binding.tvUsername.setSelected(true);
@@ -45,22 +47,35 @@ public final class DirectMessageInboxItemViewHolder extends RecyclerView.ViewHol
return;
}
itemView.setTag(model);
- final RequestManager glideRequestManager = Glide.with(itemView);
final ProfileModel[] users = model.getUsers();
if (users.length > 1) {
binding.ivProfilePic.setVisibility(View.GONE);
multipleProfilePicsContainer.setVisibility(View.VISIBLE);
- for (int i = 0; i < Math.min(3, users.length); ++i)
- glideRequestManager.load(users[i].getSdProfilePic()).into(multipleProfilePics[i]);
+ for (int i = 0; i < Math.min(3, users.length); ++i) {
+ multipleProfilePics[i].setImageURI(users[i].getSdProfilePic());
+ }
} else {
- binding.ivProfilePic.setVisibility(View.VISIBLE);
- multipleProfilePicsContainer.setVisibility(View.GONE);
- glideRequestManager.load(users.length == 1 ? users[0].getSdProfilePic() : null).into(binding.ivProfilePic);
+ final String uriString = users.length == 1 ? users[0].getSdProfilePic() : null;
+ if (uriString == null) {
+ binding.ivProfilePic.setVisibility(View.GONE);
+ } else {
+ binding.ivProfilePic.setVisibility(View.VISIBLE);
+ multipleProfilePicsContainer.setVisibility(View.GONE);
+ final ImageRequest request = ImageRequestBuilder.newBuilderWithSource(Uri.parse(uriString))
+ .setResizeOptions(new ResizeOptions(50, 50))
+ .build();
+ binding.ivProfilePic.setController(
+ Fresco.newDraweeControllerBuilder()
+ .setOldController(binding.ivProfilePic.getController())
+ .setImageRequest(request)
+ .build()
+ );
+ }
}
binding.tvUsername.setText(model.getThreadTitle());
final DirectItemModel lastItemModel = itemModels[itemModels.length - 1];
final DirectItemType itemType = lastItemModel.getItemType();
- binding.notTextType.setVisibility(itemType != DirectItemType.TEXT ? View.VISIBLE : View.GONE);
+ // binding.notTextType.setVisibility(itemType != DirectItemType.TEXT ? View.VISIBLE : View.GONE);
final Context context = itemView.getContext();
final CharSequence messageText;
switch (itemType) {
@@ -104,6 +119,6 @@ public final class DirectMessageInboxItemViewHolder extends RecyclerView.ViewHol
}
binding.tvComment.setText(HtmlCompat.fromHtml(messageText.toString(), HtmlCompat.FROM_HTML_MODE_COMPACT));
binding.tvDate.setText(lastItemModel.getDateTime());
- binding.unread.setVisibility(model.getUnreadCount() > 0L ? View.VISIBLE : View.GONE);
+ binding.unread.setVisibility(model.getUnreadCount() > 0L ? View.VISIBLE : View.INVISIBLE);
}
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/DiscoverViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/DiscoverViewHolder.java
index 6795ceb6..1dbd28a0 100755
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/DiscoverViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/DiscoverViewHolder.java
@@ -6,17 +6,21 @@ import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
+import com.facebook.drawee.view.SimpleDraweeView;
+
import awais.instagrabber.R;
public final class DiscoverViewHolder extends RecyclerView.ViewHolder {
- public final ImageView postImage, typeIcon;
- public final View selectedView, progressView;
+ public final SimpleDraweeView postImage;
+ public final ImageView typeIcon;
+ public final View selectedView;
+ // public final View progressView;
public DiscoverViewHolder(@NonNull final View itemView) {
super(itemView);
typeIcon = itemView.findViewById(R.id.typeIcon);
postImage = itemView.findViewById(R.id.postImage);
selectedView = itemView.findViewById(R.id.selectedView);
- progressView = itemView.findViewById(R.id.progressView);
+ // progressView = itemView.findViewById(R.id.progressView);
}
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/FeedItemViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/FeedItemViewHolder.java
deleted file mode 100755
index b1ac0ffd..00000000
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/FeedItemViewHolder.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package awais.instagrabber.adapters.viewholder;
-
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.viewpager.widget.ViewPager;
-
-import com.github.chrisbanes.photoview.PhotoView;
-import com.google.android.exoplayer2.ui.PlayerView;
-
-import awais.instagrabber.R;
-import awais.instagrabber.customviews.RamboTextView;
-
-public final class FeedItemViewHolder extends RecyclerView.ViewHolder {
- public final ImageView profilePic, btnMute, btnDownload;
- public final TextView commentsCount, videoViews, mediaCounter, tvPostDate, location;
- public final RamboTextView username, viewerCaption;
- public final View btnComments, videoViewsParent, viewPost;
- public final ViewPager mediaList;
- public final PhotoView imageView;
- public final PlayerView playerView;
-
- public FeedItemViewHolder(@NonNull final View itemView) {
- super(itemView);
-
- // common
- viewerCaption = itemView.findViewById(R.id.viewerCaption);
- btnDownload = itemView.findViewById(R.id.btnDownload);
- btnComments = itemView.findViewById(R.id.btnComments);
- profilePic = itemView.findViewById(R.id.ivProfilePic);
- tvPostDate = itemView.findViewById(R.id.tvPostDate);
- viewPost = itemView.findViewById(R.id.viewStoryPost);
- username = itemView.findViewById(R.id.title);
- location = itemView.findViewById(R.id.location);
-
- // video view
- btnMute = itemView.findViewById(R.id.btnMute);
- videoViews = itemView.findViewById(R.id.tvVideoViews);
- commentsCount = btnComments.findViewById(R.id.commentsCount);
- videoViewsParent = videoViews != null ? (View) videoViews.getParent() : null;
-
- // slider view
- mediaCounter = itemView.findViewById(R.id.mediaCounter);
-
- // different types
- mediaList = itemView.findViewById(R.id.media_list);
- imageView = itemView.findViewById(R.id.imageViewer);
- playerView = itemView.findViewById(R.id.playerView);
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/FeedStoryViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/FeedStoryViewHolder.java
new file mode 100644
index 00000000..10c00e69
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/FeedStoryViewHolder.java
@@ -0,0 +1,33 @@
+package awais.instagrabber.adapters.viewholder;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import awais.instagrabber.adapters.FeedStoriesAdapter;
+import awais.instagrabber.databinding.ItemHighlightBinding;
+import awais.instagrabber.models.FeedStoryModel;
+import awais.instagrabber.models.ProfileModel;
+
+public final class FeedStoryViewHolder extends RecyclerView.ViewHolder {
+
+ private final ItemHighlightBinding binding;
+
+ public FeedStoryViewHolder(final ItemHighlightBinding binding) {
+ super(binding.getRoot());
+ this.binding = binding;
+ }
+
+ public void bind(final FeedStoryModel model,
+ final int position,
+ final FeedStoriesAdapter.OnFeedStoryClickListener listener) {
+ if (model == null) return;
+ binding.getRoot().setOnClickListener(v -> {
+ if (listener == null) return;
+ listener.onFeedStoryClick(model, position);
+ });
+ final ProfileModel profileModel = model.getProfileModel();
+ binding.title.setText(profileModel.getUsername());
+ binding.title.setAlpha(model.getFullyRead() ? 0.5F : 1.0F);
+ binding.icon.setImageURI(profileModel.getSdProfilePic());
+ binding.icon.setAlpha(model.getFullyRead() ? 0.5F : 1.0F);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/FollowsViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/FollowsViewHolder.java
index 4f3b9b58..a9b09de0 100755
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/FollowsViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/FollowsViewHolder.java
@@ -1,23 +1,45 @@
package awais.instagrabber.adapters.viewholder;
import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
-import awais.instagrabber.R;
+import java.util.List;
+
+import awais.instagrabber.databinding.ItemFollowBinding;
+import awais.instagrabber.models.FollowModel;
+import awais.instagrabber.models.ProfileModel;
public final class FollowsViewHolder extends RecyclerView.ViewHolder {
- public final ImageView profileImage, isAdmin;
- public final TextView tvFullName, tvUsername;
- public FollowsViewHolder(@NonNull final View itemView) {
- super(itemView);
- profileImage = itemView.findViewById(R.id.ivProfilePic);
- tvFullName = itemView.findViewById(R.id.tvFullName);
- tvUsername = itemView.findViewById(R.id.tvUsername);
- isAdmin = itemView.findViewById(R.id.isAdmin);
+ private final ItemFollowBinding binding;
+
+ public FollowsViewHolder(final ItemFollowBinding binding) {
+ super(binding.getRoot());
+ this.binding = binding;
+ }
+
+ public void bind(final ProfileModel model,
+ final List admins,
+ final View.OnClickListener onClickListener) {
+ if (model == null) return;
+ itemView.setTag(model);
+ itemView.setOnClickListener(onClickListener);
+ binding.tvUsername.setText(model.getUsername());
+ binding.tvFullName.setText(model.getName());
+ if (admins != null && admins.contains(Long.parseLong(model.getId()))) {
+ binding.isAdmin.setVisibility(View.VISIBLE);
+ }
+ binding.ivProfilePic.setImageURI(model.getSdProfilePic());
+ }
+
+ public void bind(final FollowModel model,
+ final View.OnClickListener onClickListener) {
+ if (model == null) return;
+ itemView.setTag(model);
+ itemView.setOnClickListener(onClickListener);
+ binding.tvUsername.setText(model.getUsername());
+ binding.tvFullName.setText(model.getFullName());
+ binding.ivProfilePic.setImageURI(model.getProfilePicUrl());
}
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/HighlightViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/HighlightViewHolder.java
index 1d1654ff..d9956e92 100755
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/HighlightViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/HighlightViewHolder.java
@@ -1,21 +1,31 @@
package awais.instagrabber.adapters.viewholder;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
-import awais.instagrabber.R;
+import awais.instagrabber.databinding.ItemHighlightBinding;
+import awais.instagrabber.models.HighlightModel;
public final class HighlightViewHolder extends RecyclerView.ViewHolder {
- public final ImageView icon;
- public final TextView title;
- public HighlightViewHolder(@NonNull final View itemView) {
- super(itemView);
- icon = itemView.findViewById(R.id.icon);
- title = itemView.findViewById(R.id.title);
+ private final ItemHighlightBinding binding;
+
+ public HighlightViewHolder(final ItemHighlightBinding binding) {
+ super(binding.getRoot());
+ this.binding = binding;
+ }
+
+ public void bind(final HighlightModel model) {
+ if (model == null) return;
+ binding.title.setText(model.getTitle());
+ binding.icon.setImageURI(model.getThumbnailUrl());
+ // binding.getRoot().setOnClickListener(v -> {
+ // if (listener == null) return;
+ // listener.onFeedStoryClick(model, position);
+ // });
+ // final ProfileModel profileModel = model.getProfileModel();
+ // binding.title.setText(profileModel.getUsername());
+ // binding.title.setAlpha(model.getFullyRead() ? 0.5F : 1.0F);
+ // binding.icon.setImageURI(profileModel.getSdProfilePic());
+ // binding.icon.setAlpha(model.getFullyRead() ? 0.5F : 1.0F);
}
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/NotificationViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/NotificationViewHolder.java
old mode 100755
new mode 100644
index e660c5e2..fbd527c0
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/NotificationViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/NotificationViewHolder.java
@@ -1,75 +1,68 @@
package awais.instagrabber.adapters.viewholder;
import android.text.Spannable;
+import android.text.TextUtils;
import android.view.View;
-import android.widget.ImageView;
import android.widget.TextView;
-import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import awais.instagrabber.R;
-import awais.instagrabber.customviews.RamboTextView;
-import awais.instagrabber.interfaces.MentionClickListener;
+import awais.instagrabber.adapters.NotificationsAdapter.OnNotificationClickListener;
+import awais.instagrabber.databinding.ItemNotificationBinding;
import awais.instagrabber.models.NotificationModel;
+import awais.instagrabber.models.enums.NotificationType;
public final class NotificationViewHolder extends RecyclerView.ViewHolder {
- private final MentionClickListener mentionClickListener;
- private final ImageView ivProfilePic, ivPreviewPic;
- private final TextView tvUsername, tvDate, tvComment, tvSubComment;
- private final View container, rightContainer;
+ private final ItemNotificationBinding binding;
- public NotificationViewHolder(@NonNull final View itemView, final View.OnClickListener onClickListener, final MentionClickListener mentionClickListener) {
- super(itemView);
-
- container = itemView.findViewById(R.id.container);
- rightContainer = itemView.findViewById(R.id.rightContainer);
- if (onClickListener != null) container.setOnClickListener(onClickListener);
-
- this.mentionClickListener = mentionClickListener;
-
- ivProfilePic = itemView.findViewById(R.id.ivProfilePic);
- ivPreviewPic = itemView.findViewById(R.id.ivPreviewPic);
- tvUsername = itemView.findViewById(R.id.tvUsername);
- tvDate = itemView.findViewById(R.id.tvDate);
- tvComment = itemView.findViewById(R.id.tvComment);
- tvSubComment = itemView.findViewById(R.id.tvSubComment);
-
- tvUsername.setSelected(true);
- tvDate.setSelected(true);
+ public NotificationViewHolder(final ItemNotificationBinding binding) {
+ super(binding.getRoot());
+ this.binding = binding;
}
- public final ImageView getProfilePicView() {
- return ivProfilePic;
- }
-
- public final ImageView getPreviewPicView() {
- return ivPreviewPic;
- }
-
- public final void setNotificationModel(final NotificationModel notificationModel) {
- if (container != null) container.setTag(notificationModel);
- if (rightContainer != null) rightContainer.setTag(notificationModel);
- }
-
- public final void setUsername(final String username) {
- if (tvUsername != null) tvUsername.setText(username);
- }
-
- public final void setDate(final String date) {
- if (tvDate != null) tvDate.setText(date);
- }
-
- public final void setCommment(final int commment) {
- if (tvComment != null) {
- tvComment.setText(commment);
+ public void bind(final NotificationModel model,
+ final OnNotificationClickListener notificationClickListener) {
+ if (model == null) return;
+ itemView.setOnClickListener(v -> {
+ if (notificationClickListener == null) return;
+ notificationClickListener.onNotificationClick(model);
+ });
+ int text = -1;
+ CharSequence subtext = null;
+ switch (model.getType()) {
+ case LIKE:
+ text = R.string.liked_notif;
+ break;
+ case COMMENT:
+ text = R.string.comment_notif;
+ subtext = model.getText();
+ break;
+ case MENTION:
+ text = R.string.mention_notif;
+ subtext = model.getText();
+ break;
+ case FOLLOW:
+ text = R.string.follow_notif;
+ break;
+ case REQUEST:
+ text = R.string.request_notif;
+ subtext = model.getText();
+ break;
}
- }
-
- public final void setSubCommment(final CharSequence commment) {
- if (tvSubComment != null) {
- tvSubComment.setText(commment, commment instanceof Spannable ? TextView.BufferType.SPANNABLE : TextView.BufferType.NORMAL);
- ((RamboTextView) tvSubComment).setMentionClickListener(mentionClickListener);
+ binding.tvUsername.setText(model.getUsername());
+ binding.tvComment.setText(text);
+ binding.tvSubComment.setText(subtext, subtext instanceof Spannable ? TextView.BufferType.SPANNABLE : TextView.BufferType.NORMAL);
+ // binding.tvSubComment.setMentionClickListener(mentionClickListener);
+ if (model.getType() != NotificationType.REQUEST) {
+ binding.tvDate.setText(model.getDateTime());
+ }
+ binding.ivProfilePic.setImageURI(model.getProfilePic());
+ if (TextUtils.isEmpty(model.getPreviewPic())) {
+ binding.ivPreviewPic.setVisibility(View.GONE);
+ } else {
+ binding.ivPreviewPic.setVisibility(View.VISIBLE);
+ binding.ivPreviewPic.setImageURI(model.getPreviewPic());
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/PostMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/PostMediaViewHolder.java
index 65d115bd..2c81475a 100755
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/PostMediaViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/PostMediaViewHolder.java
@@ -1,20 +1,29 @@
package awais.instagrabber.adapters.viewholder;
import android.view.View;
-import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
-import awais.instagrabber.R;
+import awais.instagrabber.databinding.ItemChildPostBinding;
+import awais.instagrabber.models.ViewerPostModel;
public final class PostMediaViewHolder extends RecyclerView.ViewHolder {
- public final ImageView icon, isDownloaded, selectedView;
- public PostMediaViewHolder(@NonNull final View itemView) {
- super(itemView);
- selectedView = itemView.findViewById(R.id.selectedView);
- isDownloaded = itemView.findViewById(R.id.isDownloaded);
- icon = itemView.findViewById(R.id.icon);
+ private final ItemChildPostBinding binding;
+
+ public PostMediaViewHolder(@NonNull final ItemChildPostBinding binding) {
+ super(binding.getRoot());
+ this.binding = binding;
+ }
+
+ public void bind(final ViewerPostModel model, final int position, final View.OnClickListener clickListener) {
+ if (model == null) return;
+ model.setPosition(position);
+ itemView.setTag(model);
+ itemView.setOnClickListener(clickListener);
+ binding.selectedView.setVisibility(model.isCurrentSlide() ? View.VISIBLE : View.GONE);
+ binding.isDownloaded.setVisibility(model.isDownloaded() ? View.VISIBLE : View.GONE);
+ binding.icon.setImageURI(model.getSliderDisplayUrl());
}
}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/PostViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/PostViewHolder.java
index f76778b8..39c1d61a 100755
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/PostViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/PostViewHolder.java
@@ -1,23 +1,43 @@
package awais.instagrabber.adapters.viewholder;
import android.view.View;
-import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import awais.instagrabber.R;
+import awais.instagrabber.adapters.MultiSelectListAdapter.OnItemClickListener;
+import awais.instagrabber.adapters.MultiSelectListAdapter.OnItemLongClickListener;
+import awais.instagrabber.databinding.ItemPostBinding;
+import awais.instagrabber.models.PostModel;
+import awais.instagrabber.models.enums.MediaItemType;
public final class PostViewHolder extends RecyclerView.ViewHolder {
- public final ImageView postImage, typeIcon;
- public final View selectedView, progressView, isDownloaded;
+ private final ItemPostBinding binding;
- public PostViewHolder(@NonNull final View itemView) {
- super(itemView);
- typeIcon = itemView.findViewById(R.id.typeIcon);
- postImage = itemView.findViewById(R.id.postImage);
- isDownloaded = itemView.findViewById(R.id.isDownloaded);
- selectedView = itemView.findViewById(R.id.selectedView);
- progressView = itemView.findViewById(R.id.progressView);
+ public PostViewHolder(@NonNull final ItemPostBinding binding) {
+ super(binding.getRoot());
+ this.binding = binding;
+ }
+
+ public void bind(final PostModel postModel,
+ final int position,
+ final OnItemClickListener clickListener,
+ final OnItemLongClickListener longClickListener) {
+ if (postModel == null) return;
+ postModel.setPosition(position);
+ itemView.setOnClickListener(v -> clickListener.onItemClick(postModel, position));
+ itemView.setOnLongClickListener(v -> longClickListener.onItemLongClick(postModel, position));
+
+ final MediaItemType itemType = postModel.getItemType();
+ final boolean isSlider = itemType == MediaItemType.MEDIA_TYPE_SLIDER;
+
+ binding.isDownloaded.setVisibility(postModel.isDownloaded() ? View.VISIBLE : View.GONE);
+
+ binding.typeIcon.setVisibility(itemType == MediaItemType.MEDIA_TYPE_VIDEO || isSlider ? View.VISIBLE : View.GONE);
+ binding.typeIcon.setImageResource(isSlider ? R.drawable.ic_slider_24 : R.drawable.ic_video_24);
+
+ binding.selectedView.setVisibility(postModel.isSelected() ? View.VISIBLE : View.GONE);
+ binding.postImage.setImageURI(postModel.getThumbnailUrl());
}
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/PostViewerViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/PostViewerViewHolder.java
new file mode 100644
index 00000000..7bc44b71
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/PostViewerViewHolder.java
@@ -0,0 +1,239 @@
+package awais.instagrabber.adapters.viewholder;
+
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
+import androidx.core.view.ViewCompat;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.viewpager2.widget.ViewPager2;
+
+import com.google.android.exoplayer2.Player;
+import com.google.android.exoplayer2.SimpleExoPlayer;
+import com.google.android.exoplayer2.ui.PlayerView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import awais.instagrabber.R;
+import awais.instagrabber.adapters.PostViewAdapter.OnPostCaptionLongClickListener;
+import awais.instagrabber.adapters.PostViewAdapter.OnPostViewChildViewClickListener;
+import awais.instagrabber.adapters.PostViewerChildAdapter;
+import awais.instagrabber.databinding.ItemFullPostViewBinding;
+import awais.instagrabber.interfaces.MentionClickListener;
+import awais.instagrabber.models.ProfileModel;
+import awais.instagrabber.models.ViewerPostModel;
+import awais.instagrabber.models.ViewerPostModelWrapper;
+import awais.instagrabber.models.enums.MediaItemType;
+import awais.instagrabber.utils.TextUtils;
+import awais.instagrabber.utils.Utils;
+
+public class PostViewerViewHolder extends RecyclerView.ViewHolder {
+ private static final String TAG = "PostViewerViewHolder";
+
+ private final ItemFullPostViewBinding binding;
+ private int currentChildPosition;
+
+ public PostViewerViewHolder(@NonNull final ItemFullPostViewBinding binding) {
+ super(binding.getRoot());
+ this.binding = binding;
+ binding.topPanel.viewStoryPost.setVisibility(View.GONE);
+ }
+
+ public void bind(final ViewerPostModelWrapper wrapper,
+ final int position,
+ final OnPostViewChildViewClickListener clickListener,
+ final OnPostCaptionLongClickListener longClickListener,
+ final MentionClickListener mentionClickListener) {
+ if (wrapper == null) return;
+ final ViewerPostModel[] items = wrapper.getViewerPostModels();
+ if (items == null || items.length <= 0) return;
+ if (items[0] == null) return;
+ final PostViewerChildAdapter adapter = new PostViewerChildAdapter();
+ binding.mediaViewPager.setAdapter(adapter);
+ final ViewerPostModel firstPost = items[0];
+ setPostInfo(firstPost, mentionClickListener);
+ setMediaItems(items, adapter);
+ setupListeners(wrapper,
+ position,
+ clickListener,
+ longClickListener,
+ mentionClickListener,
+ firstPost.getLocation());
+ }
+
+ private void setPostInfo(final ViewerPostModel firstPost,
+ final MentionClickListener mentionClickListener) {
+ final ProfileModel profileModel = firstPost.getProfileModel();
+ if (profileModel == null) return;
+ binding.topPanel.title.setText(profileModel.getUsername());
+ final String locationName = firstPost.getLocationName();
+ if (!TextUtils.isEmpty(locationName)) {
+ binding.topPanel.location.setVisibility(View.VISIBLE);
+ binding.topPanel.location.setText(locationName);
+ } else binding.topPanel.location.setVisibility(View.GONE);
+ binding.topPanel.ivProfilePic.setImageURI(profileModel.getSdProfilePic());
+ binding.bottomPanel.commentsCount.setText(String.valueOf(firstPost.getCommentsCount()));
+ final CharSequence postCaption = firstPost.getPostCaption();
+ if (TextUtils.hasMentions(postCaption)) {
+ binding.bottomPanel.viewerCaption.setMentionClickListener(mentionClickListener);
+ binding.bottomPanel.viewerCaption
+ .setText(TextUtils.getMentionText(postCaption), TextView.BufferType.SPANNABLE);
+ } else {
+ binding.bottomPanel.viewerCaption.setMentionClickListener(null);
+ binding.bottomPanel.viewerCaption.setText(postCaption);
+ }
+ binding.bottomPanel.tvPostDate.setText(firstPost.getPostDate());
+ setupLikes(firstPost);
+ setupSave(firstPost);
+ }
+
+ private void setupLikes(final ViewerPostModel firstPost) {
+ final boolean liked = firstPost.getLike();
+ final long likeCount = firstPost.getLikes();
+ final Resources resources = itemView.getContext().getResources();
+ if (liked) {
+ final String unlikeString = resources.getString(R.string.unlike, String.valueOf(likeCount));
+ binding.btnLike.setText(unlikeString);
+ ViewCompat.setBackgroundTintList(binding.btnLike,
+ ColorStateList.valueOf(ContextCompat.getColor(itemView.getContext(), R.color.btn_pink_background)));
+ } else {
+ final String likeString = resources.getString(R.string.like, String.valueOf(likeCount));
+ binding.btnLike.setText(likeString);
+ ViewCompat.setBackgroundTintList(binding.btnLike,
+ ColorStateList.valueOf(ContextCompat.getColor(itemView.getContext(), R.color.btn_lightpink_background)));
+ }
+ }
+
+ private void setupSave(final ViewerPostModel firstPost) {
+ final boolean saved = firstPost.getBookmark();
+ if (saved) {
+ binding.btnBookmark.setText(R.string.unbookmark);
+ ViewCompat.setBackgroundTintList(binding.btnBookmark,
+ ColorStateList.valueOf(ContextCompat.getColor(itemView.getContext(), R.color.btn_orange_background)));
+ } else {
+ binding.btnBookmark.setText(R.string.bookmark);
+ ViewCompat.setBackgroundTintList(
+ binding.btnBookmark,
+ ColorStateList.valueOf(ContextCompat.getColor(itemView.getContext(), R.color.btn_lightorange_background)));
+ }
+ }
+
+ private void setupListeners(final ViewerPostModelWrapper wrapper,
+ final int position,
+ final OnPostViewChildViewClickListener clickListener,
+ final OnPostCaptionLongClickListener longClickListener,
+ final MentionClickListener mentionClickListener,
+ final String location) {
+ final View.OnClickListener onClickListener = v -> clickListener
+ .onClick(v, wrapper, position, currentChildPosition);
+ binding.bottomPanel.btnComments.setOnClickListener(onClickListener);
+ binding.topPanel.title.setOnClickListener(onClickListener);
+ binding.topPanel.ivProfilePic.setOnClickListener(onClickListener);
+ binding.bottomPanel.btnDownload.setOnClickListener(onClickListener);
+ binding.bottomPanel.viewerCaption.setOnClickListener(onClickListener);
+ binding.btnLike.setOnClickListener(onClickListener);
+ binding.btnBookmark.setOnClickListener(onClickListener);
+ binding.bottomPanel.viewerCaption.setOnLongClickListener(v -> {
+ longClickListener.onLongClick(binding.bottomPanel.viewerCaption.getText().toString());
+ return true;
+ });
+ if (!TextUtils.isEmpty(location)) {
+ binding.topPanel.location.setOnClickListener(v -> mentionClickListener
+ .onClick(binding.topPanel.location, location, false, true));
+ }
+ }
+
+ private void setMediaItems(final ViewerPostModel[] items,
+ final PostViewerChildAdapter adapter) {
+ final List filteredList = new ArrayList<>();
+ for (final ViewerPostModel model : items) {
+ final MediaItemType itemType = model.getItemType();
+ if (itemType == MediaItemType.MEDIA_TYPE_VIDEO || itemType == MediaItemType.MEDIA_TYPE_IMAGE) {
+ filteredList.add(model);
+ }
+ }
+ binding.mediaCounter.setVisibility(filteredList.size() > 1 ? View.VISIBLE : View.GONE);
+ final String counter = "1/" + filteredList.size();
+ binding.mediaCounter.setText(counter);
+ adapter.submitList(filteredList);
+ binding.mediaViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
+ @Override
+ public void onPageSelected(final int position) {
+ if (filteredList.size() <= 0 || position >= filteredList.size()) return;
+ currentChildPosition = position;
+ final String counter = (position + 1) + "/" + filteredList.size();
+ binding.mediaCounter.setText(counter);
+ final ViewerPostModel viewerPostModel = filteredList.get(position);
+ if (viewerPostModel.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO) {
+ setVideoDetails(viewerPostModel);
+ setVolumeListener(position);
+ return;
+ }
+ setImageDetails();
+ }
+ });
+ }
+
+ private void setVolumeListener(final int position) {
+ binding.bottomPanel.btnMute.setOnClickListener(v -> {
+ try {
+ final RecyclerView.ViewHolder viewHolder = ((RecyclerView) binding.mediaViewPager
+ .getChildAt(0)).findViewHolderForAdapterPosition(position);
+ if (viewHolder != null) {
+ final View itemView = viewHolder.itemView;
+ if (itemView instanceof PlayerView) {
+ final SimpleExoPlayer player = (SimpleExoPlayer) ((PlayerView) itemView)
+ .getPlayer();
+ if (player == null) return;
+ final float vol = player.getVolume() == 0f ? 1f : 0f;
+ player.setVolume(vol);
+ binding.bottomPanel.btnMute.setImageResource(vol == 0f ? R.drawable.ic_volume_up_24
+ : R.drawable.ic_volume_off_24);
+ Utils.sessionVolumeFull = vol == 1f;
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Error", e);
+ }
+ });
+ }
+
+ private void setImageDetails() {
+ binding.bottomPanel.btnMute.setVisibility(View.GONE);
+ binding.bottomPanel.videoViewsContainer.setVisibility(View.GONE);
+ }
+
+ private void setVideoDetails(final ViewerPostModel viewerPostModel) {
+ binding.bottomPanel.btnMute.setVisibility(View.VISIBLE);
+ final long videoViews = viewerPostModel.getVideoViews();
+ if (videoViews < 0) {
+ binding.bottomPanel.videoViewsContainer.setVisibility(View.GONE);
+ return;
+ }
+ binding.bottomPanel.tvVideoViews.setText(String.valueOf(videoViews));
+ binding.bottomPanel.videoViewsContainer.setVisibility(View.VISIBLE);
+ }
+
+ public void stopPlayingVideo() {
+ try {
+ final RecyclerView.ViewHolder viewHolder = ((RecyclerView) binding.mediaViewPager
+ .getChildAt(0)).findViewHolderForAdapterPosition(currentChildPosition);
+ if (viewHolder != null) {
+ final View itemView = viewHolder.itemView;
+ if (itemView instanceof PlayerView) {
+ final Player player = ((PlayerView) itemView).getPlayer();
+ if (player != null) {
+ player.setPlayWhenReady(false);
+ }
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Error", e);
+ }
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageAnimatedMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageAnimatedMediaViewHolder.java
index ed96398c..8f9f3f4e 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageAnimatedMediaViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageAnimatedMediaViewHolder.java
@@ -4,6 +4,8 @@ import android.view.View;
import androidx.annotation.NonNull;
+import com.facebook.drawee.backends.pipeline.Fresco;
+
import awais.instagrabber.databinding.LayoutDmAnimatedMediaBinding;
import awais.instagrabber.databinding.LayoutDmBaseBinding;
import awais.instagrabber.models.direct_messages.DirectItemModel;
@@ -22,8 +24,10 @@ public class DirectMessageAnimatedMediaViewHolder extends DirectMessageItemViewH
@Override
public void bindItem(final DirectItemModel directItemModel) {
- getGlideRequestManager().asGif().load(directItemModel.getAnimatedMediaModel().getGifUrl())
- .into(binding.ivAnimatedMessage);
+ binding.ivAnimatedMessage.setController(Fresco.newDraweeControllerBuilder()
+ .setUri(directItemModel.getAnimatedMediaModel().getGifUrl())
+ .setAutoPlayAnimations(true)
+ .build());
binding.ivAnimatedMessage.setVisibility(View.VISIBLE);
}
}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageItemViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageItemViewHolder.java
index 4564144f..747fd8ef 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageItemViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageItemViewHolder.java
@@ -8,37 +8,32 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.RequestManager;
-
import java.util.List;
-import awais.instagrabber.R;
import awais.instagrabber.databinding.LayoutDmBaseBinding;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.direct_messages.DirectItemModel;
import awais.instagrabber.utils.Constants;
+import awais.instagrabber.utils.CookieUtils;
+import awais.instagrabber.utils.TextUtils;
import awais.instagrabber.utils.Utils;
public abstract class DirectMessageItemViewHolder extends RecyclerView.ViewHolder {
private static final int MESSAGE_INCOMING = 69;
private static final int MESSAGE_OUTGOING = 420;
- private final ProfileModel myProfileHolder = ProfileModel.getDefaultProfileModel(Utils.getUserIdFromCookie(Utils.settingsHelper.getString(Constants.COOKIE)));
+ private final ProfileModel myProfileHolder = ProfileModel.getDefaultProfileModel(
+ CookieUtils.getUserIdFromCookie(Utils.settingsHelper.getString(Constants.COOKIE)));
private final LayoutDmBaseBinding binding;
- private final String strDmYou;
private final int itemMargin;
- private final RequestManager glideRequestManager;
-
public DirectMessageItemViewHolder(@NonNull final LayoutDmBaseBinding binding, @NonNull final View.OnClickListener onClickListener) {
super(binding.getRoot());
this.binding = binding;
binding.ivProfilePic.setOnClickListener(onClickListener);
binding.messageCard.setOnClickListener(onClickListener);
- strDmYou = binding.getRoot().getContext().getString(R.string.direct_messages_you);
+ // final String strDmYou = binding.getRoot().getContext().getString(R.string.direct_messages_you);
itemMargin = Utils.displayMetrics.widthPixels / 5;
- glideRequestManager = Glide.with(itemView);
}
public void bind(final DirectItemModel directItemModel, final List users, final List leftUsers) {
@@ -47,7 +42,7 @@ public abstract class DirectMessageItemViewHolder extends RecyclerView.ViewHolde
final RecyclerView.LayoutParams itemViewLayoutParams = (RecyclerView.LayoutParams) itemView.getLayoutParams();
itemViewLayoutParams.setMargins(type == MESSAGE_OUTGOING ? itemMargin : 0, 0,
- type == MESSAGE_INCOMING ? itemMargin : 0, 0);
+ type == MESSAGE_INCOMING ? itemMargin : 0, 0);
final ViewGroup messageCardParent = (ViewGroup) binding.messageCard.getParent();
binding.contentContainer.setGravity(type == MESSAGE_INCOMING ? Gravity.START : Gravity.END);
@@ -56,7 +51,7 @@ public abstract class DirectMessageItemViewHolder extends RecyclerView.ViewHolde
if (user != null && user != myProfileHolder) {
text = user.getUsername();
} else if (user == myProfileHolder) text = "";
- text = (Utils.isEmpty(text) ? "" : text + " - ") + directItemModel.getDateTime();
+ text = (TextUtils.isEmpty(text) ? "" : text + " - ") + directItemModel.getDateTime();
binding.tvUsername.setText(text);
binding.tvUsername.setGravity(type == MESSAGE_INCOMING ? Gravity.START : Gravity.END);
binding.ivProfilePic.setVisibility(type == MESSAGE_INCOMING ? View.VISIBLE : View.GONE);
@@ -66,7 +61,7 @@ public abstract class DirectMessageItemViewHolder extends RecyclerView.ViewHolde
binding.messageCard.setTag(directItemModel);
if (type == MESSAGE_INCOMING && user != null) {
- glideRequestManager.load(user.getSdProfilePic()).into(binding.ivProfilePic);
+ binding.ivProfilePic.setImageURI(user.getSdProfilePic());
}
bindItem(directItemModel);
@@ -76,10 +71,6 @@ public abstract class DirectMessageItemViewHolder extends RecyclerView.ViewHolde
this.binding.messageCard.addView(view);
}
- public RequestManager getGlideRequestManager() {
- return glideRequestManager;
- }
-
public abstract void bindItem(final DirectItemModel directItemModel);
@Nullable
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageLinkViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageLinkViewHolder.java
index 2c277d75..776c9355 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageLinkViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageLinkViewHolder.java
@@ -7,7 +7,7 @@ import androidx.annotation.NonNull;
import awais.instagrabber.databinding.LayoutDmBaseBinding;
import awais.instagrabber.databinding.LayoutDmLinkBinding;
import awais.instagrabber.models.direct_messages.DirectItemModel;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.TextUtils;
public class DirectMessageLinkViewHolder extends DirectMessageItemViewHolder {
@@ -26,21 +26,21 @@ public class DirectMessageLinkViewHolder extends DirectMessageItemViewHolder {
final DirectItemModel.DirectItemLinkModel link = directItemModel.getLinkModel();
final DirectItemModel.DirectItemLinkContext linkContext = link.getLinkContext();
final String linkImageUrl = linkContext.getLinkImageUrl();
- if (Utils.isEmpty(linkImageUrl)) {
+ if (TextUtils.isEmpty(linkImageUrl)) {
binding.ivLinkPreview.setVisibility(View.GONE);
} else {
- getGlideRequestManager().load(linkImageUrl).into(binding.ivLinkPreview);
+ binding.ivLinkPreview.setImageURI(linkImageUrl);
}
- if (Utils.isEmpty(linkContext.getLinkTitle())) {
+ if (TextUtils.isEmpty(linkContext.getLinkTitle())) {
binding.tvLinkTitle.setVisibility(View.GONE);
} else {
binding.tvLinkTitle.setText(linkContext.getLinkTitle());
}
- if (Utils.isEmpty(linkContext.getLinkSummary())) {
+ if (TextUtils.isEmpty(linkContext.getLinkSummary())) {
binding.tvLinkSummary.setVisibility(View.GONE);
} else {
binding.tvLinkSummary.setText(linkContext.getLinkSummary());
}
- binding.tvMessage.setText(Utils.getSpannableUrl(link.getText()));
+ binding.tvMessage.setText(TextUtils.getSpannableUrl(link.getText()));
}
}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageMediaShareViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageMediaShareViewHolder.java
index e8840096..d788074d 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageMediaShareViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageMediaShareViewHolder.java
@@ -34,11 +34,13 @@ public class DirectMessageMediaShareViewHolder extends DirectMessageItemViewHold
final DirectItemMediaModel mediaModel = directItemModel.getMediaModel();
final ProfileModel modelUser = mediaModel.getUser();
if (modelUser != null) {
- binding.tvMessage.setText(HtmlCompat.fromHtml("" + context.getString(R.string.dms_inbox_media_shared_from, modelUser.getUsername()) + "", FROM_HTML_MODE_COMPACT));
+ binding.tvMessage.setText(HtmlCompat.fromHtml(
+ "" + context.getString(R.string.dms_inbox_media_shared_from, modelUser.getUsername()) + "",
+ FROM_HTML_MODE_COMPACT));
}
- getGlideRequestManager().load(mediaModel.getThumbUrl()).into(binding.ivMediaPreview);
+ binding.ivMediaPreview.setImageURI(mediaModel.getThumbUrl());
final MediaItemType modelMediaType = mediaModel.getMediaType();
binding.typeIcon.setVisibility(modelMediaType == MediaItemType.MEDIA_TYPE_VIDEO
- || modelMediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
+ || modelMediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
}
}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageMediaViewHolder.java
index 3bbe8a87..8c6e0da6 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageMediaViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageMediaViewHolder.java
@@ -24,9 +24,9 @@ public class DirectMessageMediaViewHolder extends DirectMessageItemViewHolder {
@Override
public void bindItem(final DirectItemModel directItemModel) {
final DirectItemModel.DirectItemMediaModel mediaModel = directItemModel.getMediaModel();
- getGlideRequestManager().load(mediaModel.getThumbUrl()).into(binding.ivMediaPreview);
+ binding.ivMediaPreview.setImageURI(mediaModel.getThumbUrl());
final MediaItemType modelMediaType = mediaModel.getMediaType();
binding.typeIcon.setVisibility(modelMediaType == MediaItemType.MEDIA_TYPE_VIDEO
- || modelMediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
+ || modelMediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
}
}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageProfileViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageProfileViewHolder.java
index 1ebfae22..64f4d70b 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageProfileViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageProfileViewHolder.java
@@ -4,8 +4,6 @@ import android.view.View;
import androidx.annotation.NonNull;
-import com.bumptech.glide.Glide;
-
import awais.instagrabber.databinding.LayoutDmBaseBinding;
import awais.instagrabber.databinding.LayoutDmProfileBinding;
import awais.instagrabber.models.ProfileModel;
@@ -27,9 +25,8 @@ public class DirectMessageProfileViewHolder extends DirectMessageItemViewHolder
@Override
public void bindItem(final DirectItemModel directItemModel) {
final ProfileModel profileModel = directItemModel.getProfileModel();
- Glide.with(binding.profileInfo)
- .load(profileModel.getSdProfilePic())
- .into(binding.profileInfo);
+ if (profileModel == null) return;
+ binding.profileInfo.setImageURI(profileModel.getSdProfilePic());
binding.btnOpenProfile.setTag(profileModel);
binding.tvFullName.setText(profileModel.getName());
binding.profileInfoText.setText(profileModel.getUsername());
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageRavenMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageRavenMediaViewHolder.java
index 473778ac..fc7e404f 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageRavenMediaViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageRavenMediaViewHolder.java
@@ -12,7 +12,7 @@ import awais.instagrabber.models.direct_messages.DirectItemModel;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.models.enums.RavenExpiringMediaType;
import awais.instagrabber.models.enums.RavenMediaViewType;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.TextUtils;
public class DirectMessageRavenMediaViewHolder extends DirectMessageItemViewHolder {
@@ -33,7 +33,7 @@ public class DirectMessageRavenMediaViewHolder extends DirectMessageItemViewHold
final DirectItemModel.DirectItemRavenMediaModel ravenMediaModel = directItemModel.getRavenMediaModel();
DirectItemModel.DirectItemMediaModel mediaModel = directItemModel.getMediaModel();
final boolean isExpired = ravenMediaModel == null || (mediaModel = ravenMediaModel.getMedia()) == null ||
- Utils.isEmpty(mediaModel.getThumbUrl()) && mediaModel.getPk() < 1;
+ TextUtils.isEmpty(mediaModel.getThumbUrl()) && mediaModel.getPk() < 1;
DirectItemModel.RavenExpiringMediaActionSummaryModel mediaActionSummary = null;
if (ravenMediaModel != null) {
@@ -73,8 +73,8 @@ public class DirectMessageRavenMediaViewHolder extends DirectMessageItemViewHold
final MediaItemType mediaType = mediaModel.getMediaType();
textRes = -1;
binding.typeIcon.setVisibility(mediaType == MediaItemType.MEDIA_TYPE_VIDEO ||
- mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
- getGlideRequestManager().load(mediaModel.getThumbUrl()).into(binding.ivMediaPreview);
+ mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
+ binding.ivMediaPreview.setImageURI(mediaModel.getThumbUrl());
}
}
if (textRes != -1) {
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageReelShareViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageReelShareViewHolder.java
index 31b50ea4..ce027fc3 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageReelShareViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageReelShareViewHolder.java
@@ -9,7 +9,7 @@ import awais.instagrabber.databinding.LayoutDmRavenMediaBinding;
import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.direct_messages.DirectItemModel;
import awais.instagrabber.models.enums.MediaItemType;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.TextUtils;
public class DirectMessageReelShareViewHolder extends DirectMessageItemViewHolder {
@@ -29,10 +29,10 @@ public class DirectMessageReelShareViewHolder extends DirectMessageItemViewHolde
public void bindItem(final DirectItemModel directItemModel) {
final DirectItemModel.DirectItemReelShareModel reelShare = directItemModel.getReelShare();
CharSequence text = reelShare.getText();
- if (Utils.isEmpty(text)) {
+ if (TextUtils.isEmpty(text)) {
binding.tvMessage.setVisibility(View.GONE);
} else {
- if (Utils.hasMentions(text)) text = Utils.getMentionText(text); // for mentions
+ if (TextUtils.hasMentions(text)) text = TextUtils.getMentionText(text); // for mentions
binding.tvMessage.setText(text);
}
final DirectItemModel.DirectItemMediaModel reelShareMedia = reelShare.getMedia();
@@ -41,8 +41,8 @@ public class DirectMessageReelShareViewHolder extends DirectMessageItemViewHolde
binding.mediaExpiredIcon.setVisibility(View.VISIBLE);
} else {
binding.typeIcon.setVisibility(mediaType == MediaItemType.MEDIA_TYPE_VIDEO ||
- mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
- getGlideRequestManager().load(reelShareMedia.getThumbUrl()).into(binding.ivMediaPreview);
+ mediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE : View.GONE);
+ binding.ivMediaPreview.setImageURI(reelShareMedia.getThumbUrl());
}
}
}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageStoryShareViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageStoryShareViewHolder.java
index 155cd86f..e588bc3c 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageStoryShareViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageStoryShareViewHolder.java
@@ -9,7 +9,7 @@ import awais.instagrabber.databinding.LayoutDmBaseBinding;
import awais.instagrabber.databinding.LayoutDmStoryShareBinding;
import awais.instagrabber.models.direct_messages.DirectItemModel;
import awais.instagrabber.models.enums.MediaItemType;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.TextUtils;
import static androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT;
@@ -34,15 +34,14 @@ public class DirectMessageStoryShareViewHolder extends DirectMessageItemViewHold
binding.tvMessage.setVisibility(View.VISIBLE);
} else {
final String text = reelShare.getText();
- if (!Utils.isEmpty(text)) {
+ if (!TextUtils.isEmpty(text)) {
binding.tvMessage.setText(text);
binding.tvMessage.setVisibility(View.VISIBLE);
- }
- else {
+ } else {
final DirectItemModel.DirectItemMediaModel reelShareMedia = reelShare.getMedia();
final MediaItemType mediaType = reelShareMedia.getMediaType();
binding.typeIcon.setVisibility(mediaType == MediaItemType.MEDIA_TYPE_VIDEO ? View.VISIBLE : View.GONE);
- getGlideRequestManager().load(reelShareMedia.getThumbUrl()).into(binding.ivMediaPreview);
+ binding.ivMediaPreview.setImageURI(reelShareMedia.getThumbUrl());
}
}
}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageTextViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageTextViewHolder.java
index 12fe1b38..e8d0bb72 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageTextViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageTextViewHolder.java
@@ -12,7 +12,7 @@ import awais.instagrabber.databinding.LayoutDmBaseBinding;
import awais.instagrabber.databinding.LayoutDmTextBinding;
import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.direct_messages.DirectItemModel;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.TextUtils;
public class DirectMessageTextViewHolder extends DirectMessageItemViewHolder {
@@ -32,8 +32,8 @@ public class DirectMessageTextViewHolder extends DirectMessageItemViewHolder {
public void bindItem(final DirectItemModel directItemModel) {
final Context context = itemView.getContext();
CharSequence text = directItemModel.getText();
- text = Utils.getSpannableUrl(text.toString()); // for urls
- if (Utils.hasMentions(text)) text = Utils.getMentionText(text); // for mentions
+ text = TextUtils.getSpannableUrl(text.toString()); // for urls
+ if (TextUtils.hasMentions(text)) text = TextUtils.getMentionText(text); // for mentions
if (text instanceof Spanned)
binding.tvMessage.setText(text, TextView.BufferType.SPANNABLE);
else if (text == "") {
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageVoiceMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageVoiceMediaViewHolder.java
index f6790e54..bbee55fa 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageVoiceMediaViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageVoiceMediaViewHolder.java
@@ -9,7 +9,7 @@ import androidx.annotation.NonNull;
import awais.instagrabber.databinding.LayoutDmBaseBinding;
import awais.instagrabber.databinding.LayoutDmVoiceMediaBinding;
import awais.instagrabber.models.direct_messages.DirectItemModel;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.NumberUtils;
public class DirectMessageVoiceMediaViewHolder extends DirectMessageItemViewHolder {
@@ -61,13 +61,13 @@ public class DirectMessageVoiceMediaViewHolder extends DirectMessageItemViewHold
if (waveformData != null) binding.waveformSeekBar.setSample(waveformData);
final long durationMs = voiceMediaModel.getDurationMs();
- binding.tvVoiceDuration.setText(Utils.millisToString(durationMs));
+ binding.tvVoiceDuration.setText(NumberUtils.millisToString(durationMs));
binding.waveformSeekBar.setProgress(voiceMediaModel.getProgress());
binding.waveformSeekBar.setProgressChangeListener((waveformSeekBar, progress, fromUser) -> {
// todo progress audio player
voiceMediaModel.setProgress(progress);
if (fromUser)
- binding.tvVoiceDuration.setText(Utils.millisToString(durationMs * progress / 100));
+ binding.tvVoiceDuration.setText(NumberUtils.millisToString(durationMs * progress / 100));
});
binding.btnPlayVoice.setTag(voiceMediaModel);
} else {
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java
new file mode 100644
index 00000000..ce28419f
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java
@@ -0,0 +1,138 @@
+package awais.instagrabber.adapters.viewholder.feed;
+
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.view.View;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import awais.instagrabber.customviews.CommentMentionClickSpan;
+import awais.instagrabber.customviews.RamboTextView;
+import awais.instagrabber.databinding.ItemFeedBottomBinding;
+import awais.instagrabber.databinding.ItemFeedTopBinding;
+import awais.instagrabber.interfaces.MentionClickListener;
+import awais.instagrabber.models.FeedModel;
+import awais.instagrabber.models.ProfileModel;
+import awais.instagrabber.utils.TextUtils;
+
+public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder {
+ public static final int MAX_CHARS = 255;
+ private final ItemFeedTopBinding topBinding;
+ private final ItemFeedBottomBinding bottomBinding;
+ private final MentionClickListener mentionClickListener;
+
+ public FeedItemViewHolder(@NonNull final View root,
+ final ItemFeedTopBinding topBinding,
+ final ItemFeedBottomBinding bottomBinding,
+ final MentionClickListener mentionClickListener,
+ final View.OnClickListener clickListener,
+ final View.OnLongClickListener longClickListener) {
+ super(root);
+ this.topBinding = topBinding;
+ this.bottomBinding = bottomBinding;
+ this.mentionClickListener = mentionClickListener;
+ // topBinding.title.setMovementMethod(new LinkMovementMethod());
+ bottomBinding.btnComments.setOnClickListener(clickListener);
+ topBinding.viewStoryPost.setOnClickListener(clickListener);
+ topBinding.ivProfilePic.setOnClickListener(clickListener);
+ bottomBinding.btnDownload.setOnClickListener(clickListener);
+ bottomBinding.viewerCaption.setOnClickListener(clickListener);
+ bottomBinding.viewerCaption.setOnLongClickListener(longClickListener);
+ bottomBinding.viewerCaption.setMentionClickListener(mentionClickListener);
+ }
+
+ public void bind(final FeedModel feedModel) {
+ if (feedModel == null) {
+ return;
+ }
+ topBinding.viewStoryPost.setTag(feedModel);
+ topBinding.ivProfilePic.setTag(feedModel);
+ bottomBinding.btnDownload.setTag(feedModel);
+ bottomBinding.viewerCaption.setTag(feedModel);
+ bottomBinding.btnComments.setTag(feedModel);
+ final ProfileModel profileModel = feedModel.getProfileModel();
+ if (profileModel != null) {
+ topBinding.ivProfilePic.setImageURI(profileModel.getSdProfilePic());
+ final int titleLen = profileModel.getUsername().length() + 1;
+ final SpannableString spannableString = new SpannableString("@" + profileModel.getUsername());
+ spannableString.setSpan(new CommentMentionClickSpan(), 0, titleLen, 0);
+ topBinding.title.setText(spannableString);
+ topBinding.title.setMentionClickListener(
+ (view, text, isHashtag, isLocation) -> mentionClickListener.onClick(null, profileModel.getUsername(), false, false));
+ }
+ bottomBinding.tvPostDate.setText(feedModel.getPostDate());
+ final long commentsCount = feedModel.getCommentsCount();
+ bottomBinding.commentsCount.setText(String.valueOf(commentsCount));
+
+ final String locationName = feedModel.getLocationName();
+ final String locationId = feedModel.getLocationId();
+ setLocation(locationName, locationId);
+ CharSequence postCaption = feedModel.getPostCaption();
+ final boolean captionEmpty = TextUtils.isEmpty(postCaption);
+ bottomBinding.viewerCaption.setVisibility(captionEmpty ? View.GONE : View.VISIBLE);
+ if (!captionEmpty) {
+ if (TextUtils.hasMentions(postCaption)) {
+ postCaption = TextUtils.getMentionText(postCaption);
+ feedModel.setPostCaption(postCaption);
+ bottomBinding.viewerCaption.setText(postCaption, TextView.BufferType.SPANNABLE);
+ } else {
+ bottomBinding.viewerCaption.setText(postCaption);
+ }
+ }
+ expandCollapseTextView(bottomBinding.viewerCaption, feedModel.getPostCaption());
+ bindItem(feedModel);
+ }
+
+ private void setLocation(final String locationName, final String locationId) {
+ if (TextUtils.isEmpty(locationName)) {
+ topBinding.location.setVisibility(View.GONE);
+ topBinding.title.setLayoutParams(new RelativeLayout.LayoutParams(
+ RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT
+ ));
+ } else {
+ topBinding.location.setVisibility(View.VISIBLE);
+ topBinding.location.setText(locationName);
+ topBinding.title.setLayoutParams(new RelativeLayout.LayoutParams(
+ RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT
+ ));
+ topBinding.location.setOnClickListener(v -> mentionClickListener.onClick(topBinding.location, locationId, false, true));
+ }
+ }
+
+ /**
+ * expands or collapses {@link RamboTextView} [stg idek why i wrote this documentation]
+ *
+ * @param textView the {@link RamboTextView} view, to expand and collapse
+ * @param caption caption
+ * @return isExpanded
+ */
+ public static boolean expandCollapseTextView(@NonNull final RamboTextView textView, final CharSequence caption) {
+ if (TextUtils.isEmpty(caption)) return false;
+
+ final TextView.BufferType bufferType = caption instanceof Spanned ? TextView.BufferType.SPANNABLE : TextView.BufferType.NORMAL;
+
+ if (textView.isCaptionExpanded()) {
+ textView.setText(caption, bufferType);
+ textView.setCaptionIsExpanded(false);
+ return true;
+ }
+ int i = TextUtils.indexOfChar(caption, '\r', 0);
+ if (i == -1) i = TextUtils.indexOfChar(caption, '\n', 0);
+ if (i == -1) i = MAX_CHARS;
+
+ final int captionLen = caption.length();
+ final int minTrim = Math.min(MAX_CHARS, i);
+ if (captionLen <= minTrim) return false;
+
+ if (TextUtils.hasMentions(caption))
+ textView.setText(TextUtils.getMentionText(caption), TextView.BufferType.SPANNABLE);
+ textView.setCaptionIsExpandable(true);
+ textView.setCaptionIsExpanded(true);
+ return true;
+ }
+
+ public abstract void bindItem(final FeedModel feedModel);
+}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedPhotoViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedPhotoViewHolder.java
new file mode 100644
index 00000000..f89a2624
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedPhotoViewHolder.java
@@ -0,0 +1,76 @@
+package awais.instagrabber.adapters.viewholder.feed;
+
+import android.net.Uri;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+
+import com.facebook.drawee.backends.pipeline.Fresco;
+import com.facebook.drawee.drawable.ScalingUtils;
+import com.facebook.drawee.generic.GenericDraweeHierarchy;
+import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
+import com.facebook.imagepipeline.request.ImageRequest;
+import com.facebook.imagepipeline.request.ImageRequestBuilder;
+
+import awais.instagrabber.databinding.ItemFeedPhotoBinding;
+import awais.instagrabber.interfaces.MentionClickListener;
+import awais.instagrabber.models.FeedModel;
+import awais.instagrabber.utils.TextUtils;
+import awais.instagrabber.utils.Utils;
+
+public class FeedPhotoViewHolder extends FeedItemViewHolder {
+ private static final String TAG = "FeedPhotoViewHolder";
+
+ private final ItemFeedPhotoBinding binding;
+
+ public FeedPhotoViewHolder(@NonNull final ItemFeedPhotoBinding binding,
+ final MentionClickListener mentionClickListener,
+ final View.OnClickListener clickListener,
+ final View.OnLongClickListener longClickListener) {
+ super(binding.getRoot(), binding.itemFeedTop, binding.itemFeedBottom, mentionClickListener, clickListener, longClickListener);
+ this.binding = binding;
+ binding.itemFeedBottom.videoViewsContainer.setVisibility(View.GONE);
+ binding.itemFeedBottom.btnMute.setVisibility(View.GONE);
+ binding.imageViewer.setAllowTouchInterceptionWhileZoomed(false);
+ final GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(itemView.getContext().getResources())
+ .setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER)
+ .build();
+ binding.imageViewer.setHierarchy(hierarchy);
+ }
+
+ @Override
+ public void bindItem(final FeedModel feedModel) {
+ if (feedModel == null) {
+ return;
+ }
+ final ViewGroup.LayoutParams layoutParams = binding.imageViewer.getLayoutParams();
+ final int requiredWidth = Utils.displayMetrics.widthPixels;
+ layoutParams.width = feedModel.getImageWidth() == 0 ? requiredWidth : feedModel.getImageWidth();
+ layoutParams.height = feedModel.getImageHeight() == 0 ? requiredWidth + 1 : feedModel.getImageHeight();
+ binding.imageViewer.requestLayout();
+ final String thumbnailUrl = feedModel.getThumbnailUrl();
+ String url = feedModel.getDisplayUrl();
+ if (TextUtils.isEmpty(url)) url = thumbnailUrl;
+ final ImageRequest requestBuilder = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
+ .setLocalThumbnailPreviewsEnabled(true)
+ .setProgressiveRenderingEnabled(true)
+ .build();
+ binding.imageViewer.setController(Fresco.newDraweeControllerBuilder()
+ .setImageRequest(requestBuilder)
+ .setOldController(binding.imageViewer.getController())
+ .setLowResImageRequest(ImageRequest.fromUri(thumbnailUrl))
+ .build());
+ // binding.imageViewer.setImageURI(url);
+ // final RequestBuilder thumbnailRequestBuilder = glide
+ // .asBitmap()
+ // .load(thumbnailUrl)
+ // .diskCacheStrategy(DiskCacheStrategy.ALL);
+ // glide.asBitmap()
+ // .load(url)
+ // .thumbnail(thumbnailRequestBuilder)
+ // .diskCacheStrategy(DiskCacheStrategy.ALL)
+ // .into(customTarget);
+
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedSliderViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedSliderViewHolder.java
new file mode 100644
index 00000000..9fa5fcf5
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedSliderViewHolder.java
@@ -0,0 +1,341 @@
+package awais.instagrabber.adapters.viewholder.feed;
+
+import android.content.Context;
+import android.net.Uri;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ViewSwitcher;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.widget.AppCompatImageView;
+import androidx.viewpager.widget.PagerAdapter;
+import androidx.viewpager.widget.ViewPager;
+
+import com.facebook.drawee.drawable.ScalingUtils;
+import com.facebook.drawee.generic.GenericDraweeHierarchy;
+import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
+import com.facebook.drawee.view.SimpleDraweeView;
+import com.facebook.imagepipeline.request.ImageRequest;
+import com.facebook.imagepipeline.request.ImageRequestBuilder;
+import com.google.android.exoplayer2.Player;
+import com.google.android.exoplayer2.SimpleExoPlayer;
+import com.google.android.exoplayer2.source.ProgressiveMediaSource;
+import com.google.android.exoplayer2.ui.PlayerView;
+import com.google.android.exoplayer2.upstream.DataSource;
+import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
+import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory;
+import com.google.android.exoplayer2.upstream.cache.SimpleCache;
+
+import awais.instagrabber.R;
+import awais.instagrabber.databinding.ItemFeedSliderBinding;
+import awais.instagrabber.interfaces.MentionClickListener;
+import awais.instagrabber.models.FeedModel;
+import awais.instagrabber.models.ViewerPostModel;
+import awais.instagrabber.models.enums.MediaItemType;
+import awais.instagrabber.utils.Constants;
+import awais.instagrabber.utils.Utils;
+
+import static awais.instagrabber.utils.Utils.settingsHelper;
+
+public class FeedSliderViewHolder extends FeedItemViewHolder {
+ private static final String TAG = "FeedSliderViewHolder";
+ private static final boolean shouldAutoPlay = settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS);
+
+ private final ItemFeedSliderBinding binding;
+ private final DefaultDataSourceFactory dataSourceFactory;
+
+ private final PlayerChangeListener playerChangeListener = (position, player) -> {
+ pagerPlayer = player;
+ playerPosition = position;
+ };
+
+ private CacheDataSourceFactory cacheDataSourceFactory;
+ private SimpleExoPlayer pagerPlayer;
+ private int playerPosition = 0;
+
+ public FeedSliderViewHolder(@NonNull final ItemFeedSliderBinding binding,
+ final MentionClickListener mentionClickListener,
+ final View.OnClickListener clickListener,
+ final View.OnLongClickListener longClickListener) {
+ super(binding.getRoot(), binding.itemFeedTop, binding.itemFeedBottom, mentionClickListener, clickListener, longClickListener);
+ this.binding = binding;
+ binding.itemFeedBottom.videoViewsContainer.setVisibility(View.GONE);
+ binding.itemFeedBottom.btnMute.setVisibility(View.GONE);
+ final ViewGroup.LayoutParams layoutParams = binding.mediaList.getLayoutParams();
+ layoutParams.height = Utils.displayMetrics.widthPixels + 1;
+ binding.mediaList.setLayoutParams(layoutParams);
+ final Context context = binding.getRoot().getContext();
+ dataSourceFactory = new DefaultDataSourceFactory(context, "instagram");
+ final SimpleCache simpleCache = Utils.getSimpleCacheInstance(context);
+ if (simpleCache != null) {
+ cacheDataSourceFactory = new CacheDataSourceFactory(simpleCache, dataSourceFactory);
+ }
+ }
+
+ @Override
+ public void bindItem(final FeedModel feedModel) {
+ final ViewerPostModel[] sliderItems = feedModel.getSliderItems();
+ final int sliderItemLen = sliderItems != null ? sliderItems.length : 0;
+ if (sliderItemLen <= 0) {
+ return;
+ }
+ final String text = "1/" + sliderItemLen;
+ binding.mediaCounter.setText(text);
+ binding.mediaList.setOffscreenPageLimit(Math.min(5, sliderItemLen));
+
+ final PagerAdapter adapter = binding.mediaList.getAdapter();
+ if (adapter != null) {
+ final int count = adapter.getCount();
+ for (int i = 0; i < count; i++) {
+ adapter.destroyItem(binding.mediaList, i, binding.mediaList.getChildAt(i));
+ }
+ }
+ final ChildMediaItemsAdapter itemsAdapter = new ChildMediaItemsAdapter(sliderItems,
+ cacheDataSourceFactory != null
+ ? cacheDataSourceFactory
+ : dataSourceFactory,
+ playerChangeListener);
+ binding.mediaList.setAdapter(itemsAdapter);
+
+ //noinspection deprecation
+ binding.mediaList.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
+ private int prevPos = 0;
+
+ @Override
+ public void onPageSelected(final int position) {
+ ViewerPostModel sliderItem = sliderItems[prevPos];
+ if (sliderItem != null) {
+ sliderItem.setSelected(false);
+ if (sliderItem.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO) {
+ // stop playing prev video
+ final ViewSwitcher prevChild = (ViewSwitcher) binding.mediaList.getChildAt(prevPos);
+ if (prevChild == null || prevChild.getTag() == null || !(prevChild.getTag() instanceof SimpleExoPlayer)) {
+ return;
+ }
+ ((SimpleExoPlayer) prevChild.getTag()).setPlayWhenReady(false);
+ }
+ }
+ sliderItem = sliderItems[position];
+ if (sliderItem == null) return;
+ sliderItem.setSelected(true);
+ final String text = (position + 1) + "/" + sliderItemLen;
+ binding.mediaCounter.setText(text);
+ prevPos = position;
+ if (sliderItem.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO) {
+ binding.itemFeedBottom.btnMute.setVisibility(View.VISIBLE);
+ if (shouldAutoPlay) {
+ autoPlay(position);
+ }
+ } else binding.itemFeedBottom.btnMute.setVisibility(View.GONE);
+ }
+ });
+
+ final View.OnClickListener muteClickListener = v -> {
+ final int currentItem = binding.mediaList.getCurrentItem();
+ if (currentItem < 0 || currentItem >= binding.mediaList.getChildCount()) {
+ return;
+ }
+ final ViewerPostModel sliderItem = sliderItems[currentItem];
+ if (sliderItem.getItemType() != MediaItemType.MEDIA_TYPE_VIDEO) {
+ return;
+ }
+ final View currentView = binding.mediaList.getChildAt(currentItem);
+ if (!(currentView instanceof ViewSwitcher)) {
+ return;
+ }
+ final ViewSwitcher viewSwitcher = (ViewSwitcher) currentView;
+ final Object tag = viewSwitcher.getTag();
+ if (!(tag instanceof SimpleExoPlayer)) {
+ return;
+ }
+ final SimpleExoPlayer player = (SimpleExoPlayer) tag;
+ final float intVol = player.getVolume() == 0f ? 1f : 0f;
+ player.setVolume(intVol);
+ binding.itemFeedBottom.btnMute.setImageResource(intVol == 0f ? R.drawable.ic_volume_up_24 : R.drawable.ic_volume_off_24);
+ Utils.sessionVolumeFull = intVol == 1f;
+ };
+ final ViewerPostModel firstItem = sliderItems[0];
+ if (firstItem.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO) {
+ binding.itemFeedBottom.btnMute.setVisibility(View.VISIBLE);
+ }
+ binding.itemFeedBottom.btnMute.setImageResource(Utils.sessionVolumeFull ? R.drawable.ic_volume_off_24 : R.drawable.ic_volume_up_24);
+ binding.itemFeedBottom.btnMute.setOnClickListener(muteClickListener);
+ }
+
+ private void autoPlay(final int position) {
+ if (!shouldAutoPlay) {
+ return;
+ }
+ final ChildMediaItemsAdapter adapter = (ChildMediaItemsAdapter) binding.mediaList.getAdapter();
+ if (adapter == null) {
+ return;
+ }
+ final ViewerPostModel sliderItem = adapter.getItemAtPosition(position);
+ if (sliderItem.getItemType() != MediaItemType.MEDIA_TYPE_VIDEO) {
+ return;
+ }
+ final ViewSwitcher viewSwitcher = (ViewSwitcher) binding.mediaList.getChildAt(position);
+ loadPlayer(binding.getRoot().getContext(),
+ position, sliderItem.getDisplayUrl(),
+ viewSwitcher,
+ cacheDataSourceFactory != null ? cacheDataSourceFactory : dataSourceFactory,
+ playerChangeListener);
+ }
+
+ public void startPlayingVideo() {
+ autoPlay(playerPosition);
+ }
+
+ public void stopPlayingVideo() {
+ if (pagerPlayer == null) {
+ return;
+ }
+ pagerPlayer.setPlayWhenReady(false);
+ }
+
+ private interface PlayerChangeListener {
+ void playerChanged(final int position, final SimpleExoPlayer player);
+ }
+
+ private static void loadPlayer(final Context context,
+ final int position, final String displayUrl,
+ final ViewSwitcher viewSwitcher,
+ final DataSource.Factory factory,
+ final PlayerChangeListener playerChangeListener) {
+ if (viewSwitcher == null) {
+ return;
+ }
+ SimpleExoPlayer player = (SimpleExoPlayer) viewSwitcher.getTag();
+ if (player != null) {
+ player.setPlayWhenReady(true);
+ return;
+ }
+ player = new SimpleExoPlayer.Builder(context).build();
+ final PlayerView playerView = (PlayerView) viewSwitcher.getChildAt(1);
+ playerView.setPlayer(player);
+ if (viewSwitcher.getDisplayedChild() == 0) {
+ viewSwitcher.showNext();
+ }
+ playerView.setControllerShowTimeoutMs(1000);
+ float vol = settingsHelper.getBoolean(Constants.MUTED_VIDEOS) ? 0f : 1f;
+ if (vol == 0f && Utils.sessionVolumeFull) vol = 1f;
+ player.setVolume(vol);
+ player.setPlayWhenReady(Utils.settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS));
+ final ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(factory).createMediaSource(Uri.parse(displayUrl));
+ player.setRepeatMode(Player.REPEAT_MODE_ALL);
+ player.prepare(mediaSource);
+ player.setVolume(vol);
+ playerChangeListener.playerChanged(position, player);
+ viewSwitcher.setTag(player);
+ }
+
+ private static final class ChildMediaItemsAdapter extends PagerAdapter {
+ // private static final String TAG = "ChildMediaItemsAdapter";
+
+ private final ViewerPostModel[] sliderItems;
+ private final DataSource.Factory factory;
+ private final PlayerChangeListener playerChangeListener;
+ private final ViewGroup.LayoutParams layoutParams;
+
+ private ChildMediaItemsAdapter(final ViewerPostModel[] sliderItems,
+ final DataSource.Factory factory,
+ final PlayerChangeListener playerChangeListener) {
+ this.sliderItems = sliderItems;
+ this.factory = factory;
+ this.playerChangeListener = playerChangeListener;
+ layoutParams = new ViewGroup.LayoutParams(Utils.displayMetrics.widthPixels, Utils.displayMetrics.widthPixels + 1);
+ }
+
+ @NonNull
+ @Override
+ public Object instantiateItem(@NonNull final ViewGroup container, final int position) {
+ final Context context = container.getContext();
+ final ViewerPostModel sliderItem = sliderItems[position];
+
+ final String displayUrl = sliderItem.getDisplayUrl();
+ if (sliderItem.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO) {
+ final ViewSwitcher viewSwitcher = createViewSwitcher(context, position, sliderItem.getSliderDisplayUrl(), displayUrl);
+ container.addView(viewSwitcher);
+ return viewSwitcher;
+ }
+ final GenericDraweeHierarchy hierarchy = GenericDraweeHierarchyBuilder.newInstance(container.getResources())
+ .setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER)
+ .build();
+ final SimpleDraweeView photoView = new SimpleDraweeView(context, hierarchy);
+ photoView.setLayoutParams(layoutParams);
+ final ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(displayUrl))
+ .setLocalThumbnailPreviewsEnabled(true)
+ .setProgressiveRenderingEnabled(true)
+ .build();
+ photoView.setImageRequest(imageRequest);
+ container.addView(photoView);
+ return photoView;
+ }
+
+ @NonNull
+ private ViewSwitcher createViewSwitcher(final Context context, final int position, final String sliderDisplayUrl, final String displayUrl) {
+
+ final ViewSwitcher viewSwitcher = new ViewSwitcher(context);
+ viewSwitcher.setLayoutParams(layoutParams);
+
+ final FrameLayout frameLayout = new FrameLayout(context);
+ frameLayout.setLayoutParams(layoutParams);
+
+ final GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(context.getResources())
+ .setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER)
+ .build();
+ final SimpleDraweeView simpleDraweeView = new SimpleDraweeView(context, hierarchy);
+ simpleDraweeView.setLayoutParams(layoutParams);
+ simpleDraweeView.setImageURI(sliderDisplayUrl);
+ frameLayout.addView(simpleDraweeView);
+
+ final AppCompatImageView imageView = new AppCompatImageView(context);
+ final int px = Utils.convertDpToPx(50);
+ final FrameLayout.LayoutParams playButtonLayoutParams = new FrameLayout.LayoutParams(px, px);
+ playButtonLayoutParams.gravity = Gravity.CENTER;
+ imageView.setLayoutParams(playButtonLayoutParams);
+ imageView.setImageResource(R.drawable.exo_icon_play);
+ frameLayout.addView(imageView);
+
+ viewSwitcher.addView(frameLayout);
+
+ final PlayerView playerView = new PlayerView(context);
+ viewSwitcher.addView(playerView);
+ if (shouldAutoPlay && position == 0) {
+ loadPlayer(context, position, displayUrl, viewSwitcher, factory, playerChangeListener);
+ } else
+ frameLayout.setOnClickListener(v -> loadPlayer(context, position, displayUrl, viewSwitcher, factory, playerChangeListener));
+ return viewSwitcher;
+ }
+
+ @Override
+ public void destroyItem(@NonNull final ViewGroup container, final int position, @NonNull final Object object) {
+ final View view = container.getChildAt(position);
+ // Log.d(TAG, "destroy position: " + position + ", view: " + view);
+ if (view instanceof ViewSwitcher) {
+ final Object tag = view.getTag();
+ if (tag instanceof SimpleExoPlayer) {
+ final SimpleExoPlayer player = (SimpleExoPlayer) tag;
+ player.release();
+ }
+ }
+ container.removeView((View) object);
+ }
+
+ @Override
+ public int getCount() {
+ return sliderItems != null ? sliderItems.length : 0;
+ }
+
+ @Override
+ public boolean isViewFromObject(@NonNull final View view, @NonNull final Object object) {
+ return view.equals(object);
+ }
+
+ public ViewerPostModel getItemAtPosition(final int position) {
+ return sliderItems[0];
+ }
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java
new file mode 100644
index 00000000..2887cbd4
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java
@@ -0,0 +1,158 @@
+package awais.instagrabber.adapters.viewholder.feed;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+
+import com.facebook.drawee.backends.pipeline.Fresco;
+import com.facebook.drawee.interfaces.DraweeController;
+import com.facebook.imagepipeline.request.ImageRequest;
+import com.facebook.imagepipeline.request.ImageRequestBuilder;
+import com.google.android.exoplayer2.Player;
+import com.google.android.exoplayer2.SimpleExoPlayer;
+import com.google.android.exoplayer2.source.ProgressiveMediaSource;
+import com.google.android.exoplayer2.upstream.DataSource;
+import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
+import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory;
+import com.google.android.exoplayer2.upstream.cache.SimpleCache;
+
+import awais.instagrabber.R;
+import awais.instagrabber.databinding.ItemFeedVideoBinding;
+import awais.instagrabber.interfaces.MentionClickListener;
+import awais.instagrabber.models.FeedModel;
+import awais.instagrabber.utils.Constants;
+import awais.instagrabber.utils.NumberUtils;
+import awais.instagrabber.utils.Utils;
+
+import static awais.instagrabber.utils.Utils.settingsHelper;
+
+public class FeedVideoViewHolder extends FeedItemViewHolder {
+ private static final String TAG = "FeedVideoViewHolder";
+
+ private final ItemFeedVideoBinding binding;
+ private final Handler handler;
+ private final DefaultDataSourceFactory dataSourceFactory;
+
+ private CacheDataSourceFactory cacheDataSourceFactory;
+ private FeedModel feedModel;
+ private SimpleExoPlayer player;
+
+ private final Runnable loadRunnable = new Runnable() {
+ @Override
+ public void run() {
+ loadPlayer(feedModel);
+ }
+ };
+
+ public FeedVideoViewHolder(@NonNull final ItemFeedVideoBinding binding,
+ final MentionClickListener mentionClickListener,
+ final View.OnClickListener clickListener,
+ final View.OnLongClickListener longClickListener) {
+ super(binding.getRoot(), binding.itemFeedTop, binding.itemFeedBottom, mentionClickListener, clickListener, longClickListener);
+ this.binding = binding;
+ binding.itemFeedBottom.videoViewsContainer.setVisibility(View.VISIBLE);
+ handler = new Handler(Looper.getMainLooper());
+ final Context context = binding.getRoot().getContext();
+ dataSourceFactory = new DefaultDataSourceFactory(context, "instagram");
+ final SimpleCache simpleCache = Utils.getSimpleCacheInstance(context);
+ if (simpleCache != null) {
+ cacheDataSourceFactory = new CacheDataSourceFactory(simpleCache, dataSourceFactory);
+ }
+ }
+
+ @Override
+ public void bindItem(final FeedModel feedModel) {
+ // Log.d(TAG, "Binding post: " + feedModel.getPostId());
+ this.feedModel = feedModel;
+ setThumbnail(feedModel);
+ binding.itemFeedBottom.tvVideoViews.setText(String.valueOf(feedModel.getViewCount()));
+ }
+
+ private void setThumbnail(final FeedModel feedModel) {
+ final ViewGroup.LayoutParams layoutParams = binding.thumbnailParent.getLayoutParams();
+ final int requiredWidth = Utils.displayMetrics.widthPixels;
+ layoutParams.width = feedModel.getImageWidth() == 0 ? requiredWidth : feedModel.getImageWidth();
+ layoutParams.height = feedModel.getImageHeight() == 0 ? requiredWidth + 1 : feedModel.getImageHeight();
+ binding.thumbnailParent.requestLayout();
+ final ImageRequest thumbnailRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(feedModel.getThumbnailUrl()))
+ .setProgressiveRenderingEnabled(true)
+ .build();
+ final DraweeController controller = Fresco.newDraweeControllerBuilder()
+ .setImageRequest(thumbnailRequest)
+ .build();
+ binding.thumbnail.setController(controller);
+ binding.thumbnailParent.setOnClickListener(v -> loadPlayer(feedModel));
+ }
+
+ private void loadPlayer(final FeedModel feedModel) {
+ if (feedModel == null) {
+ return;
+ }
+ // Log.d(TAG, "playing post:" + feedModel.getPostId());
+ if (binding.viewSwitcher.getDisplayedChild() == 0) {
+ binding.viewSwitcher.showNext();
+ }
+ binding.itemFeedBottom.btnMute.setVisibility(View.VISIBLE);
+ final ViewGroup.LayoutParams layoutParams = binding.playerView.getLayoutParams();
+ final int requiredWidth = Utils.displayMetrics.widthPixels;
+ final int resultingHeight = NumberUtils.getResultingHeight(requiredWidth, feedModel.getImageHeight(), feedModel.getImageWidth());
+ layoutParams.width = requiredWidth;
+ layoutParams.height = resultingHeight;
+ binding.playerView.requestLayout();
+ float vol = settingsHelper.getBoolean(Constants.MUTED_VIDEOS) ? 0f : 1f;
+ if (vol == 0f && Utils.sessionVolumeFull) vol = 1f;
+ setMuteIcon(vol);
+ player = (SimpleExoPlayer) binding.playerView.getPlayer();
+ if (player != null) {
+ player.release();
+ }
+ player = new SimpleExoPlayer.Builder(itemView.getContext())
+ .setLooper(Looper.getMainLooper())
+ .build();
+ player.setVolume(vol);
+ player.setPlayWhenReady(true);
+ final DataSource.Factory factory = cacheDataSourceFactory != null ? cacheDataSourceFactory : dataSourceFactory;
+ final ProgressiveMediaSource.Factory sourceFactory = new ProgressiveMediaSource.Factory(factory);
+ final ProgressiveMediaSource mediaSource = sourceFactory.createMediaSource(Uri.parse(feedModel.getDisplayUrl()));
+ player.setRepeatMode(Player.REPEAT_MODE_ALL);
+ player.prepare(mediaSource);
+ binding.playerView.setPlayer(player);
+ final SimpleExoPlayer finalPlayer = player;
+ binding.itemFeedBottom.btnMute.setOnClickListener(v -> {
+ final float intVol = finalPlayer.getVolume() == 0f ? 1f : 0f;
+ finalPlayer.setVolume(intVol);
+ setMuteIcon(intVol);
+ Utils.sessionVolumeFull = intVol == 1f;
+ });
+ binding.playerView.setOnClickListener(v -> finalPlayer.setPlayWhenReady(!finalPlayer.getPlayWhenReady()));
+ }
+
+ private void setMuteIcon(final float vol) {
+ binding.itemFeedBottom.btnMute.setImageResource(vol == 0f ? R.drawable.ic_volume_up_24 : R.drawable.ic_volume_off_24);
+ }
+
+ public FeedModel getCurrentFeedModel() {
+ return feedModel;
+ }
+
+ public void stopPlaying() {
+ // Log.d(TAG, "Stopping post: " + feedModel.getPostId() + ", player: " + player + ", player.isPlaying: " + (player != null && player.isPlaying()));
+ handler.removeCallbacks(loadRunnable);
+ if (player != null) {
+ player.release();
+ }
+ if (binding.viewSwitcher.getDisplayedChild() == 1) {
+ binding.viewSwitcher.showPrevious();
+ }
+ }
+
+ public void startPlaying() {
+ handler.removeCallbacks(loadRunnable);
+ handler.postDelayed(loadRunnable, 800);
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/asyncs/CommentAction.java b/app/src/main/java/awais/instagrabber/asyncs/CommentAction.java
new file mode 100644
index 00000000..2a5dcaf5
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/asyncs/CommentAction.java
@@ -0,0 +1,83 @@
+package awais.instagrabber.asyncs;
+
+import android.os.AsyncTask;
+import android.util.Log;
+
+import org.json.JSONObject;
+
+import java.io.DataOutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import awais.instagrabber.models.StoryModel;
+import awais.instagrabber.utils.Constants;
+import awais.instagrabber.utils.CookieUtils;
+import awais.instagrabber.utils.NetworkUtils;
+import awais.instagrabber.utils.Utils;
+
+import static awais.instagrabber.utils.Utils.settingsHelper;
+
+public class CommentAction extends AsyncTask {
+ private static final String TAG = "CommentAction";
+
+ private final String cookie;
+ private final StoryModel storyModel;
+ private final OnTaskCompleteListener onTaskCompleteListener;
+
+ public CommentAction(final String cookie, final StoryModel storyModel, final OnTaskCompleteListener onTaskCompleteListener) {
+ this.cookie = cookie;
+ this.storyModel = storyModel;
+ this.onTaskCompleteListener = onTaskCompleteListener;
+ }
+
+ protected String doInBackground(String... rawAction) {
+ final String action = rawAction[0];
+ final String url = "https://i.instagram.com/api/v1/direct_v2/create_group_thread/";
+ HttpURLConnection urlConnection = null;
+ try {
+ urlConnection = (HttpURLConnection) new URL(url).openConnection();
+ urlConnection.setRequestMethod("POST");
+ urlConnection.setRequestProperty("User-Agent", Constants.I_USER_AGENT);
+ urlConnection.setUseCaches(false);
+ final String urlParameters = Utils.sign("{\"_csrftoken\":\"" + cookie.split("csrftoken=")[1].split(";")[0]
+ + "\",\"_uid\":\"" + CookieUtils.getUserIdFromCookie(cookie)
+ + "\",\"__uuid\":\"" + settingsHelper.getString(Constants.DEVICE_UUID)
+ + "\",\"recipient_users\":\"[" + storyModel.getUserId() // <- string of array of number (not joking)
+ + "]\"}");
+ urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+ if (urlParameters != null) {
+ urlConnection.setRequestProperty("Content-Length", "" + urlParameters.getBytes().length);
+ }
+ urlConnection.setDoOutput(true);
+ DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
+ wr.writeBytes(urlParameters);
+ wr.flush();
+ wr.close();
+ urlConnection.connect();
+ if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
+ return new JSONObject(NetworkUtils.readFromConnection(urlConnection)).getString("thread_id");
+ }
+
+ } catch (Throwable ex) {
+ Log.e(TAG, "reply (CT): " + ex);
+ // Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
+ } finally {
+ if (urlConnection != null) {
+ urlConnection.disconnect();
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(final String threadId) {
+ if (threadId == null || onTaskCompleteListener == null) {
+ return;
+ }
+ onTaskCompleteListener.onTaskComplete(threadId);
+ }
+
+ public interface OnTaskCompleteListener {
+ void onTaskComplete(final String threadId);
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java
index cf043962..6107a038 100755
--- a/app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java
+++ b/app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java
@@ -19,7 +19,8 @@ import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.CommentModel;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.NetworkUtils;
+import awais.instagrabber.utils.TextUtils;
import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Utils.logCollector;
@@ -57,7 +58,7 @@ public final class CommentsFetcher extends AsyncTask
final int childCommentsLen = childCommentModels.length;
final CommentModel lastChild = childCommentModels[childCommentsLen - 1];
- if (lastChild != null && lastChild.hasNextPage() && !Utils.isEmpty(lastChild.getEndCursor())) {
+ if (lastChild != null && lastChild.hasNextPage() && !TextUtils.isEmpty(lastChild.getEndCursor())) {
final CommentModel[] remoteChildComments = getChildComments(commentModel.getId());
commentModel.setChildCommentModels(remoteChildComments);
lastChild.setPageCursor(false, null);
@@ -94,12 +95,12 @@ public final class CommentsFetcher extends AsyncTask
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) break;
else {
- final JSONObject data = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("data")
- .getJSONObject("comment").getJSONObject("edge_threaded_comments");
+ final JSONObject data = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("data")
+ .getJSONObject("comment").getJSONObject("edge_threaded_comments");
final JSONObject pageInfo = data.getJSONObject("page_info");
endCursor = pageInfo.getString("end_cursor");
- if (Utils.isEmpty(endCursor)) endCursor = null;
+ if (TextUtils.isEmpty(endCursor)) endCursor = null;
final JSONArray childComments = data.optJSONArray("edges");
if (childComments != null) {
@@ -158,12 +159,12 @@ public final class CommentsFetcher extends AsyncTask
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) break;
else {
- final JSONObject parentComments = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("data")
- .getJSONObject("shortcode_media").getJSONObject("edge_media_to_parent_comment");
+ final JSONObject parentComments = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("data")
+ .getJSONObject("shortcode_media").getJSONObject("edge_media_to_parent_comment");
final JSONObject pageInfo = parentComments.getJSONObject("page_info");
endCursor = pageInfo.optString("end_cursor");
- if (Utils.isEmpty(endCursor)) endCursor = null;
+ if (TextUtils.isEmpty(endCursor)) endCursor = null;
// final boolean containsToken = endCursor.contains("bifilter_token");
// if (!Utils.isEmpty(endCursor) && (containsToken || endCursor.contains("cached_comments_cursor"))) {
@@ -216,7 +217,7 @@ public final class CommentsFetcher extends AsyncTask
final boolean hasNextPage;
if ((tempJsonObject = tempJsonObject.optJSONObject("page_info")) != null) {
childEndCursor = tempJsonObject.optString("end_cursor");
- hasNextPage = tempJsonObject.optBoolean("has_next_page", !Utils.isEmpty(childEndCursor));
+ hasNextPage = tempJsonObject.optBoolean("has_next_page", !TextUtils.isEmpty(childEndCursor));
} else {
childEndCursor = null;
hasNextPage = false;
diff --git a/app/src/main/java/awais/instagrabber/asyncs/DiscoverFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/DiscoverFetcher.java
index 4c7c3821..c83f2cb0 100755
--- a/app/src/main/java/awais/instagrabber/asyncs/DiscoverFetcher.java
+++ b/app/src/main/java/awais/instagrabber/asyncs/DiscoverFetcher.java
@@ -21,6 +21,10 @@ import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.DiscoverItemModel;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.utils.Constants;
+import awais.instagrabber.utils.DownloadUtils;
+import awais.instagrabber.utils.NetworkUtils;
+import awais.instagrabber.utils.ResponseBodyUtils;
+import awais.instagrabber.utils.TextUtils;
import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector;
@@ -67,7 +71,7 @@ public final class DiscoverFetcher extends AsyncTask fetchItems(ArrayList discoverItemModels, final String maxId) {
try {
final String url = "https://www.instagram.com/explore/grid/?is_prefetch=false&omit_cover_media=true&module=explore_popular" +
- "&use_sectional_payload=false&cluster_id="+cluster+"&include_fixed_destinations=true&session_id="+rankToken+maxId;
+ "&use_sectional_payload=false&cluster_id=" + cluster + "&include_fixed_destinations=true&session_id=" + rankToken + maxId;
final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
@@ -75,7 +79,7 @@ public final class DiscoverFetcher extends AsyncTask("maxId", maxId),
- new Pair<>("lastId", lastId),
- new Pair<>("isFirst", isFirst),
- new Pair<>("nextMaxId", nextMaxId));
+ new Pair<>("maxId", maxId),
+ new Pair<>("lastId", lastId),
+ new Pair<>("isFirst", isFirst),
+ new Pair<>("nextMaxId", nextMaxId));
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
}
@@ -160,25 +164,27 @@ public final class DiscoverFetcher extends AsyncTask {
+ private static final String TAG = "DownloadAsync";
+
private static int lastNotifId = 1;
private final int currentNotifId;
private final AtomicReference context;
@@ -56,8 +53,12 @@ public final class DownloadAsync extends AsyncTask {
private final Resources resources;
private final NotificationCompat.Builder downloadNotif;
private String shortCode, username;
+ private final NotificationManagerCompat notificationManager;
- public DownloadAsync(final Context context, final String url, final File outFile, final FetchListener fetchListener) {
+ public DownloadAsync(@NonNull final Context context,
+ final String url,
+ final File outFile,
+ final FetchListener fetchListener) {
this.context = new AtomicReference<>(context);
this.resources = context.getResources();
this.url = url;
@@ -67,22 +68,18 @@ public final class DownloadAsync extends AsyncTask {
this.currentNotifId = ++lastNotifId;
if (++lastNotifId + 1 == Integer.MAX_VALUE) lastNotifId = 1;
- if (notificationManager == null)
- notificationManager = NotificationManagerCompat.from(context.getApplicationContext());
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !isChannelCreated) {
- notificationManager.createNotificationChannel(new NotificationChannel(CHANNEL_ID,
- CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH));
- isChannelCreated = true;
- }
-
- @StringRes final int titleRes = context instanceof ProfilePicViewer ? R.string.downloader_downloading_pfp : R.string.downloader_downloading_post;
-
- downloadNotif = new NotificationCompat.Builder(context, CHANNEL_ID).setCategory(NotificationCompat.CATEGORY_STATUS)
- .setSmallIcon(R.mipmap.ic_launcher).setContentText(shortCode == null ? username : shortCode).setOngoing(true)
- .setProgress(100, 0, false).setAutoCancel(false).setOnlyAlertOnce(true)
+ @StringRes final int titleRes = R.string.downloader_downloading_post;
+ downloadNotif = new NotificationCompat.Builder(context, Constants.DOWNLOAD_CHANNEL_ID)
+ .setCategory(NotificationCompat.CATEGORY_STATUS)
+ .setSmallIcon(R.mipmap.ic_launcher)
+ .setContentText(shortCode == null ? username : shortCode)
+ .setOngoing(true)
+ .setProgress(100, 0, false)
+ .setAutoCancel(false)
+ .setOnlyAlertOnce(true)
.setContentTitle(resources.getString(titleRes));
+ notificationManager = NotificationManagerCompat.from(context.getApplicationContext());
notificationManager.notify(currentNotifId, downloadNotif.build());
}
@@ -99,7 +96,7 @@ public final class DownloadAsync extends AsyncTask {
try {
final URLConnection urlConnection = new URL(url).openConnection();
final long fileSize = Build.VERSION.SDK_INT >= 24 ? urlConnection.getContentLengthLong() :
- urlConnection.getContentLength();
+ urlConnection.getContentLength();
float totalRead = 0;
try (final BufferedInputStream bis = new BufferedInputStream(urlConnection.getInputStream());
@@ -152,13 +149,13 @@ public final class DownloadAsync extends AsyncTask {
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogFile.ASYNC_DOWNLOADER, "doInBackground",
- new Pair<>("context", context.get()),
- new Pair<>("resources", resources),
- new Pair<>("lastNotifId", lastNotifId),
- new Pair<>("downloadNotif", downloadNotif),
- new Pair<>("currentNotifId", currentNotifId),
- new Pair<>("notificationManager", notificationManager));
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
+ new Pair<>("context", context.get()),
+ new Pair<>("resources", resources),
+ new Pair<>("lastNotifId", lastNotifId),
+ new Pair<>("downloadNotif", downloadNotif),
+ new Pair<>("currentNotifId", currentNotifId),
+ new Pair<>("notificationManager", notificationManager));
+ if (BuildConfig.DEBUG) Log.e(TAG, "", e);
}
return null;
}
@@ -182,23 +179,23 @@ public final class DownloadAsync extends AsyncTask {
final Context context = this.context.get();
context.sendBroadcast(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT ?
- new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.fromFile(Environment.getExternalStorageDirectory())) :
- new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(result.getAbsoluteFile()))
+ new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.fromFile(Environment.getExternalStorageDirectory())) :
+ new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(result.getAbsoluteFile()))
);
MediaScannerConnection.scanFile(context, new String[]{result.getAbsolutePath()}, null, null);
if (notificationManager != null) {
- final Uri uri = FileProvider.getUriForFile(context, "me.austinhuang.instagrabber.provider", result);
+ final Uri uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", result);
final ContentResolver contentResolver = context.getContentResolver();
Bitmap bitmap = null;
if (Utils.isImage(uri, contentResolver)) {
- try {
- bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(uri));
+ try (final InputStream inputStream = contentResolver.openInputStream(uri)) {
+ bitmap = BitmapFactory.decodeStream(inputStream);
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogFile.ASYNC_DOWNLOADER, "onPostExecute::bitmap_1");
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
+ if (BuildConfig.DEBUG) Log.e(TAG, "", e);
}
}
@@ -228,15 +225,16 @@ public final class DownloadAsync extends AsyncTask {
final String downloadComplete = resources.getString(R.string.downloader_complete);
downloadNotif.setContentText(null).setContentTitle(downloadComplete).setProgress(0, 0, false)
- .setWhen(System.currentTimeMillis()).setOngoing(false).setOnlyAlertOnce(false).setAutoCancel(true)
- .setGroup(NOTIF_GROUP_NAME).setGroupSummary(true).setContentIntent(
+ .setWhen(System.currentTimeMillis()).setOngoing(false).setOnlyAlertOnce(false).setAutoCancel(true)
+ .setGroup(NOTIF_GROUP_NAME).setGroupSummary(true).setContentIntent(
PendingIntent.getActivity(context, 2020, new Intent(Intent.ACTION_VIEW, uri)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_FROM_BACKGROUND | Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
+ .addFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_FROM_BACKGROUND | Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
.putExtra(Intent.EXTRA_STREAM, uri), PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT));
if (bitmap != null)
downloadNotif.setStyle(new NotificationCompat.BigPictureStyle().setBigContentTitle(downloadComplete).bigPicture(bitmap))
- .setLargeIcon(bitmap).setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL);
+ .setLargeIcon(bitmap).setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL);
notificationManager.cancel(currentNotifId);
notificationManager.notify(currentNotifId + 1, downloadNotif.build());
diff --git a/app/src/main/java/awais/instagrabber/asyncs/FeedFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/FeedFetcher.java
index b70fccea..8f139ff7 100755
--- a/app/src/main/java/awais/instagrabber/asyncs/FeedFetcher.java
+++ b/app/src/main/java/awais/instagrabber/asyncs/FeedFetcher.java
@@ -19,12 +19,16 @@ import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.ViewerPostModel;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.NetworkUtils;
+import awais.instagrabber.utils.ResponseBodyUtils;
+import awais.instagrabber.utils.TextUtils;
import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Utils.logCollector;
public final class FeedFetcher extends AsyncTask {
+ private static final String TAG = "FeedFetcher";
+
private static final int maxItemsToLoad = 25; // max is 50, but that's too many posts, setting more than 30 is gay
private final String endCursor;
private final FetchListener fetchListener;
@@ -61,8 +65,10 @@ public final class FeedFetcher extends AsyncTask {
final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
- final JSONObject timelineFeed = new JSONObject(Utils.readFromConnection(urlConnection)).getJSONObject("data")
- .getJSONObject(Constants.EXTRAS_USER).getJSONObject("edge_web_feed_timeline");
+ final String json = NetworkUtils.readFromConnection(urlConnection);
+ // Log.d(TAG, json);
+ final JSONObject timelineFeed = new JSONObject(json).getJSONObject("data")
+ .getJSONObject(Constants.EXTRAS_USER).getJSONObject("edge_web_feed_timeline");
final String endCursor;
final boolean hasNextPage;
@@ -83,30 +89,41 @@ public final class FeedFetcher extends AsyncTask {
for (int i = 0; i < feedLen; ++i) {
final JSONObject feedItem = feedItems.getJSONObject(i).getJSONObject("node");
final String mediaType = feedItem.optString("__typename");
- if (mediaType.isEmpty() || "GraphSuggestedUserFeedUnit".equals(mediaType)) continue;
+ if (mediaType.isEmpty() || "GraphSuggestedUserFeedUnit".equals(mediaType))
+ continue;
final boolean isVideo = feedItem.optBoolean("is_video");
final long videoViews = feedItem.optLong("video_view_count", 0);
final String displayUrl = feedItem.optString("display_url");
- if (Utils.isEmpty(displayUrl)) continue;
+ if (TextUtils.isEmpty(displayUrl)) continue;
final String resourceUrl;
if (isVideo) resourceUrl = feedItem.getString("video_url");
- else resourceUrl = feedItem.has("display_resources") ? Utils.getHighQualityImage(feedItem) : displayUrl;
+ else
+ resourceUrl = feedItem.has("display_resources") ? ResponseBodyUtils.getHighQualityImage(feedItem) : displayUrl;
ProfileModel profileModel = null;
if (feedItem.has("owner")) {
final JSONObject owner = feedItem.getJSONObject("owner");
- profileModel = new ProfileModel(owner.optBoolean("is_private"),
+ profileModel = new ProfileModel(
+ owner.optBoolean("is_private"),
false, // if you can see it then you def follow
owner.optBoolean("is_verified"),
owner.getString(Constants.EXTRAS_ID),
owner.getString(Constants.EXTRAS_USERNAME),
owner.optString("full_name"),
- null, null,
+ null,
+ null,
owner.getString("profile_pic_url"),
- null, 0, 0, 0, false, false, false, false);
+ null,
+ 0,
+ 0,
+ 0,
+ false,
+ false,
+ false,
+ false);
}
JSONObject tempJsonObject = feedItem.optJSONObject("edge_media_preview_comment");
@@ -122,7 +139,21 @@ public final class FeedFetcher extends AsyncTask {
captionText = tempJsonObject.getString("text");
}
- final FeedModel feedModel = new FeedModel(profileModel,
+ final JSONObject location = feedItem.optJSONObject("location");
+ // Log.d(TAG, "location: " + (location == null ? null : location.toString()));
+ String locationId = null;
+ String locationName = null;
+ if (location != null) {
+ locationName = location.optString("name");
+ if (location.has("id")) {
+ locationId = location.getString("id");
+ } else if (location.has("pk")) {
+ locationId = location.getString("pk");
+ }
+ // Log.d(TAG, "locationId: " + locationId);
+ }
+ final FeedModel feedModel = new FeedModel(
+ profileModel,
isVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
videoViews,
feedItem.getString(Constants.EXTRAS_ID),
@@ -135,7 +166,8 @@ public final class FeedFetcher extends AsyncTask {
feedItem.getBoolean("viewer_has_liked"),
feedItem.getBoolean("viewer_has_saved"),
feedItem.getJSONObject("edge_media_preview_like").getLong("count"),
- feedItem.optJSONObject("location"));
+ locationName,
+ locationId);
final boolean isSlider = "GraphSidecar".equals(mediaType) && feedItem.has("edge_sidecar_to_children");
@@ -154,14 +186,17 @@ public final class FeedFetcher extends AsyncTask {
sliderItems[j] = new ViewerPostModel(
isChildVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
node.getString(Constants.EXTRAS_ID),
- isChildVideo ? node.getString("video_url") : Utils.getHighQualityImage(node),
- null, null, null,
- node.optLong("video_view_count", -1), -1, false, false,
+ isChildVideo ? node.getString("video_url") : ResponseBodyUtils.getHighQualityImage(node),
+ null,
+ null,
+ null,
+ node.optLong("video_view_count", -1),
+ -1,
+ false,
+ false,
feedItem.getJSONObject("edge_media_preview_like").getLong("count"),
- feedItem.isNull("location") ? null : feedItem.getJSONObject("location").optString("name"),
- feedItem.isNull("location") ? null :
- (feedItem.getJSONObject("location").optString("id") + "/" +
- feedItem.getJSONObject("location").optString("slug")));
+ locationName,
+ locationId);
sliderItems[j].setSliderDisplayUrl(node.getString("display_url"));
}
@@ -187,7 +222,9 @@ public final class FeedFetcher extends AsyncTask {
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_FEED_FETCHER, "doInBackground");
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
+ if (BuildConfig.DEBUG) {
+ Log.e(TAG, "", e);
+ }
}
return result;
diff --git a/app/src/main/java/awais/instagrabber/asyncs/FeedStoriesFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/FeedStoriesFetcher.java
index 903486d5..c975dc5d 100755
--- a/app/src/main/java/awais/instagrabber/asyncs/FeedStoriesFetcher.java
+++ b/app/src/main/java/awais/instagrabber/asyncs/FeedStoriesFetcher.java
@@ -14,7 +14,7 @@ import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.FeedStoryModel;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.NetworkUtils;
import awaisomereport.LogCollector.LogFile;
import static awais.instagrabber.utils.Utils.logCollector;
@@ -39,7 +39,7 @@ public final class FeedStoriesFetcher extends AsyncTask {
conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
- final JSONObject data = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("data")
- .getJSONObject(Constants.EXTRAS_USER).getJSONObject(isFollowers ? "edge_followed_by" : "edge_follow");
+ final JSONObject data = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("data")
+ .getJSONObject(Constants.EXTRAS_USER).getJSONObject(isFollowers ? "edge_followed_by" : "edge_follow");
final String endCursor;
final boolean hasNextPage;
diff --git a/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java b/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java
index 860015fd..ff65a56b 100644
--- a/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java
+++ b/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java
@@ -9,24 +9,24 @@ import java.net.HttpURLConnection;
import java.net.URL;
import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.CookieUtils;
+import awais.instagrabber.utils.NetworkUtils;
+import awais.instagrabber.utils.TextUtils;
-public class GetActivityAsyncTask extends AsyncTask {
+public class GetActivityAsyncTask extends AsyncTask {
private static final String TAG = "GetActivityAsyncTask";
- private String uid;
- private String cookie;
+
private OnTaskCompleteListener onTaskCompleteListener;
- public GetActivityAsyncTask(final String uid, final String cookie, final OnTaskCompleteListener onTaskCompleteListener) {
- this.uid = uid;
- this.cookie = cookie;
+ public GetActivityAsyncTask(final OnTaskCompleteListener onTaskCompleteListener) {
this.onTaskCompleteListener = onTaskCompleteListener;
}
- protected NotificationCounts doInBackground(Void... voids) {
- if (Utils.isEmpty(cookie)) {
- return null;
- }
+ protected NotificationCounts doInBackground(final String... cookiesArray) {
+ if (cookiesArray == null) return null;
+ final String cookie = cookiesArray[0];
+ if (TextUtils.isEmpty(cookie)) return null;
+ final String uid = CookieUtils.getUserIdFromCookie(cookie);
final String url = "https://www.instagram.com/graphql/query/?query_hash=0f318e8cfff9cc9ef09f88479ff571fb"
+ "&variables={\"id\":\"" + uid + "\"}";
HttpURLConnection urlConnection = null;
@@ -39,8 +39,12 @@ public class GetActivityAsyncTask extends AsyncTask {
+public final class HighlightsFetcher extends AsyncTask> {
private final String id;
private final boolean storiesig;
- private final FetchListener fetchListener;
+ private final FetchListener> fetchListener;
- public HighlightsFetcher(final String id, final boolean storiesig, final FetchListener fetchListener) {
+ public HighlightsFetcher(final String id, final boolean storiesig, final FetchListener> fetchListener) {
this.id = id;
this.storiesig = storiesig;
this.fetchListener = fetchListener;
}
@Override
- protected HighlightModel[] doInBackground(final Void... voids) {
- HighlightModel[] result = null;
+ protected List doInBackground(final Void... voids) {
+ List result = null;
String url = "https://" + (storiesig ? "storiesig" : "i.instagram") + ".com/api/v1/highlights/" + id + "/highlights_tray/";
try {
@@ -39,20 +41,21 @@ public final class HighlightsFetcher extends AsyncTask highlightModels = new ArrayList<>();
+ // final String[] highlightIds = new String[length];
for (int i = 0; i < length; ++i) {
final JSONObject highlightNode = highlightsReel.getJSONObject(i);
- highlightModels[i] = new HighlightModel(
+ highlightModels.add(new HighlightModel(
highlightNode.getString("title"),
highlightNode.getString(Constants.EXTRAS_ID),
- highlightNode.getJSONObject("cover_media").getJSONObject("cropped_image_version").getString("url")
- );
+ highlightNode.getJSONObject("cover_media")
+ .getJSONObject("cropped_image_version")
+ .getString("url")
+ ));
}
-
conn.disconnect();
result = highlightModels;
}
@@ -66,7 +69,7 @@ public final class HighlightsFetcher extends AsyncTask result) {
if (fetchListener != null) fetchListener.onResult(result);
}
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/asyncs/ImageUploader.java b/app/src/main/java/awais/instagrabber/asyncs/ImageUploader.java
index e4cdaa6e..386cb4de 100644
--- a/app/src/main/java/awais/instagrabber/asyncs/ImageUploader.java
+++ b/app/src/main/java/awais/instagrabber/asyncs/ImageUploader.java
@@ -18,11 +18,11 @@ import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
-import java.util.Random;
import java.util.UUID;
import awais.instagrabber.models.ImageUploadOptions;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.NetworkUtils;
+import awais.instagrabber.utils.NumberUtils;
public class ImageUploader extends AsyncTask {
private static final String TAG = "ImageUploader";
@@ -52,7 +52,7 @@ public class ImageUploader extends AsyncTask headers = new HashMap<>();
final String uploadId = String.valueOf(new Date().getTime());
- final long random = LOWER + new Random().nextLong() * (UPPER - LOWER + 1);
+ final long random = NumberUtils.random(LOWER, UPPER + 1);
final String name = String.format("%s_0_%s", uploadId, random);
final String waterfallId = options.getWaterfallId() != null ? options.getWaterfallId() : UUID.randomUUID().toString();
headers.put("X-Entity-Type", "image/jpeg");
@@ -69,7 +69,7 @@ public class ImageUploader extends AsyncTask {
- private final FetchListener fetchListener;
- private final String idSlug;
+ private static final String TAG = "LocationFetcher";
- public LocationFetcher(String idSlug, FetchListener fetchListener) {
+ private final FetchListener fetchListener;
+ private final String id;
+
+ public LocationFetcher(final String id, final FetchListener fetchListener) {
// idSlug = id + "/" + slug UPDATE: slug can be ignored tbh
- this.idSlug = idSlug;
+ this.id = id;
this.fetchListener = fetchListener;
}
@@ -37,27 +38,29 @@ public final class LocationFetcher extends AsyncTask
LocationModel result = null;
try {
- final HttpURLConnection conn = (HttpURLConnection) new URL("https://www.instagram.com/explore/locations/" + idSlug + "/?__a=1").openConnection();
+ final HttpURLConnection conn = (HttpURLConnection) new URL("https://www.instagram.com/explore/locations/" + id + "/?__a=1")
+ .openConnection();
conn.setUseCaches(true);
conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
- final JSONObject user = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("graphql").getJSONObject(Constants.EXTRAS_LOCATION);
-
- final JSONObject timelineMedia = user.getJSONObject("edge_location_to_media");
- if (timelineMedia.has("edges")) {
- final JSONArray edges = timelineMedia.getJSONArray("edges");
- }
+ final JSONObject location = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("graphql")
+ .getJSONObject(Constants.EXTRAS_LOCATION);
+ final JSONObject timelineMedia = location.getJSONObject("edge_location_to_media");
+ // if (timelineMedia.has("edges")) {
+ // final JSONArray edges = timelineMedia.getJSONArray("edges");
+ // }
result = new LocationModel(
- user.getString(Constants.EXTRAS_ID) + "/" + user.getString("slug"),
- user.getString("name"),
- user.getString("blurb"),
- user.getString("website"),
- user.getString("profile_pic_url"),
+ location.getString(Constants.EXTRAS_ID),
+ location.getString("slug"),
+ location.getString("name"),
+ location.getString("blurb"),
+ location.getString("website"),
+ location.getString("profile_pic_url"),
timelineMedia.getLong("count"),
- BigDecimal.valueOf(user.optDouble("lat", 0d)).toString(),
- BigDecimal.valueOf(user.optDouble("lng", 0d)).toString()
+ BigDecimal.valueOf(location.optDouble("lat", 0d)).toString(),
+ BigDecimal.valueOf(location.optDouble("lng", 0d)).toString()
);
}
@@ -65,9 +68,10 @@ public final class LocationFetcher extends AsyncTask
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_LOCATION_FETCHER, "doInBackground");
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
+ if (BuildConfig.DEBUG) {
+ Log.e(TAG, "", e);
+ }
}
-
return result;
}
diff --git a/app/src/main/java/awais/instagrabber/asyncs/NotificationsFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/NotificationsFetcher.java
old mode 100755
new mode 100644
index d1bdbd22..50284647
--- a/app/src/main/java/awais/instagrabber/asyncs/NotificationsFetcher.java
+++ b/app/src/main/java/awais/instagrabber/asyncs/NotificationsFetcher.java
@@ -8,31 +8,36 @@ import org.json.JSONObject;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.NotificationModel;
import awais.instagrabber.models.enums.NotificationType;
import awais.instagrabber.utils.Constants;
+import awais.instagrabber.utils.CookieUtils;
import awais.instagrabber.utils.LocaleUtils;
-import awais.instagrabber.utils.Utils;
+import awais.instagrabber.utils.NetworkUtils;
import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Utils.logCollector;
import static awais.instagrabber.utils.Utils.settingsHelper;
-public final class NotificationsFetcher extends AsyncTask {
- private final FetchListener fetchListener;
+public final class NotificationsFetcher extends AsyncTask> {
+ private static final String TAG = "NotificationsFetcher";
- public NotificationsFetcher(final FetchListener fetchListener) {
+ private final FetchListener> fetchListener;
+
+ public NotificationsFetcher(final FetchListener> fetchListener) {
this.fetchListener = fetchListener;
}
@Override
- protected NotificationModel[] doInBackground(final Void... voids) {
- NotificationModel[] result = null;
+ protected List doInBackground(final Void... voids) {
+ List result = new ArrayList<>();
final String url = "https://www.instagram.com/accounts/activity/?__a=1";
- Utils.setupCookies(settingsHelper.getString(Constants.COOKIE));
+ CookieUtils.setupCookies(settingsHelper.getString(Constants.COOKIE));
try {
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
@@ -42,56 +47,62 @@ public final class NotificationsFetcher extends AsyncTask 0 &&
- (data = media.optJSONObject(0).optJSONObject("node")) != null) {
- mediaLen = media.length();
- models = new NotificationModel[mediaLen];
- for (int i = 0; i < mediaLen; ++i) {
+ if (ewaf != null
+ && (media = ewaf.optJSONArray("edges")) != null
+ && media.length() > 0
+ && media.optJSONObject(0).optJSONObject("node") != null) {
+ for (int i = 0; i < media.length(); ++i) {
data = media.optJSONObject(i).optJSONObject("node");
- if (Utils.getNotifType(data.getString("__typename")) == null) continue;
- models[i] = new NotificationModel(data.getString(Constants.EXTRAS_ID),
+ if (data == null) continue;
+ final String type = data.getString("__typename");
+ final NotificationType notificationType = NotificationType.valueOfType(type);
+ if (notificationType == null) continue;
+ final JSONObject user = data.getJSONObject("user");
+ result.add(new NotificationModel(
+ data.getString(Constants.EXTRAS_ID),
data.optString("text"), // comments or mentions
data.getLong("timestamp"),
- data.getJSONObject("user").getString("username"),
- data.getJSONObject("user").getString("profile_pic_url"),
+ user.getString("id"),
+ user.getString("username"),
+ user.getString("profile_pic_url"),
!data.isNull("media") ? data.getJSONObject("media").getString("shortcode") : null,
- !data.isNull("media") ? data.getJSONObject("media").getString("thumbnail_src") : null,
- Utils.getNotifType(data.getString("__typename")));
+ !data.isNull("media") ? data.getJSONObject("media").getString("thumbnail_src") : null, notificationType));
}
}
- if (efr != null && (media = efr.optJSONArray("edges")) != null && media.length() > 0 &&
- (data = media.optJSONObject(0).optJSONObject("node")) != null) {
- reqLen = media.length();
- req = new NotificationModel[reqLen];
- for (int i = 0; i < reqLen; ++i) {
+ if (efr != null
+ && (media = efr.optJSONArray("edges")) != null
+ && media.length() > 0
+ && media.optJSONObject(0).optJSONObject("node") != null) {
+ for (int i = 0; i < media.length(); ++i) {
data = media.optJSONObject(i).optJSONObject("node");
- req[i] = new NotificationModel(data.getString(Constants.EXTRAS_ID),
- data.optString("full_name"), 0L, data.getString("username"),
- data.getString("profile_pic_url"), null, null, NotificationType.REQUEST);
+ if (data == null) continue;
+ result.add(new NotificationModel(
+ data.getString(Constants.EXTRAS_ID),
+ data.optString("full_name"),
+ 0L,
+ data.getString(Constants.EXTRAS_ID),
+ data.getString("username"),
+ data.getString("profile_pic_url"),
+ null,
+ null, NotificationType.REQUEST));
}
}
-
- result = new NotificationModel[mediaLen + reqLen];
- if (req != null) System.arraycopy(req, 0, result, 0, reqLen);
- if (models != null) System.arraycopy(models, 0, result, reqLen, mediaLen);
}
-
conn.disconnect();
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_NOTIFICATION_FETCHER, "doInBackground");
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
+ if (BuildConfig.DEBUG) Log.e(TAG, "", e);
}
-
return result;
}
@@ -101,7 +112,7 @@ public final class NotificationsFetcher extends AsyncTask result) {
if (fetchListener != null) fetchListener.onResult(result);
}
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/asyncs/PostFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/PostFetcher.java
index 38a6e0b0..71b69c54 100755
--- a/app/src/main/java/awais/instagrabber/asyncs/PostFetcher.java
+++ b/app/src/main/java/awais/instagrabber/asyncs/PostFetcher.java
@@ -11,11 +11,16 @@ import java.io.File;
import java.net.HttpURLConnection;
import java.net.URL;
-import awais.instagrabber.BuildConfig;
import awais.instagrabber.interfaces.FetchListener;
+import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.ViewerPostModel;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.utils.Constants;
+import awais.instagrabber.utils.CookieUtils;
+import awais.instagrabber.utils.DownloadUtils;
+import awais.instagrabber.utils.NetworkUtils;
+import awais.instagrabber.utils.ResponseBodyUtils;
+import awais.instagrabber.utils.TextUtils;
import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector;
@@ -25,6 +30,8 @@ import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO;
import static awais.instagrabber.utils.Utils.logCollector;
public final class PostFetcher extends AsyncTask {
+ private static final String TAG = "PostFetcher";
+
private final String shortCode;
private final FetchListener fetchListener;
@@ -36,7 +43,7 @@ public final class PostFetcher extends AsyncTask
@Override
protected ViewerPostModel[] doInBackground(final Void... voids) {
ViewerPostModel[] result = null;
- Utils.setupCookies(Utils.settingsHelper.getString(Constants.COOKIE)); // <- direct download
+ CookieUtils.setupCookies(Utils.settingsHelper.getString(Constants.COOKIE)); // <- direct download
try {
final HttpURLConnection conn = (HttpURLConnection) new URL("https://www.instagram.com/p/" + shortCode + "/?__a=1").openConnection();
conn.setUseCaches(false);
@@ -44,19 +51,43 @@ public final class PostFetcher extends AsyncTask
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
- final JSONObject media = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("graphql")
- .getJSONObject("shortcode_media");
-
- final String username = media.has("owner") ? media.getJSONObject("owner").getString(Constants.EXTRAS_USERNAME) : null;
+ final JSONObject media = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("graphql")
+ .getJSONObject("shortcode_media");
+ ProfileModel profileModel = null;
+ if (media.has("owner")) {
+ final JSONObject owner = media.getJSONObject("owner");
+ profileModel = new ProfileModel(
+ owner.optBoolean("is_private"),
+ owner.optBoolean("is_private"),
+ owner.optBoolean("is_verified"),
+ owner.optString("id"),
+ owner.optString("username"),
+ owner.optString("full_name"),
+ null,
+ null,
+ owner.optString("profile_pic_url"),
+ owner.optString("profile_pic_url"),
+ owner.optInt("edge_owner_to_timeline_media"),
+ owner.optInt("edge_followed_by"),
+ -1,
+ owner.optBoolean("followed_by_viewer"),
+ owner.optBoolean("restricted_by_viewer"),
+ owner.optBoolean("blocked_by_viewer"),
+ owner.optBoolean("requested_by_viewer")
+ );
+ }
+ final String username = profileModel == null ? "" : profileModel.getUsername();
// to check if file exists
final File downloadDir = new File(Environment.getExternalStorageDirectory(), "Download" +
- (Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/"+username) : ""));
+ (Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/" + username) : ""));
File customDir = null;
if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
final String customPath = Utils.settingsHelper.getString(FOLDER_PATH +
- (Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/"+username) : ""));
- if (!Utils.isEmpty(customPath)) customDir = new File(customPath);
+ (Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER)
+ ? ("/" + username)
+ : ""));
+ if (!TextUtils.isEmpty(customPath)) customDir = new File(customPath);
}
final long timestamp = media.getLong("taken_at_timestamp");
@@ -75,34 +106,36 @@ public final class PostFetcher extends AsyncTask
else {
final JSONArray captions = mediaToCaption.optJSONArray("edges");
postCaption = captions != null && captions.length() > 0 ?
- captions.getJSONObject(0).getJSONObject("node").optString("text") : null;
+ captions.getJSONObject(0).getJSONObject("node").optString("text") : null;
}
JSONObject commentObject = media.optJSONObject("edge_media_to_parent_comment");
final long commentsCount = commentObject != null ? commentObject.optLong("count") : 0;
String endCursor = null;
- if (commentObject != null && (commentObject = commentObject.optJSONObject("page_info")) != null)
+ if (commentObject != null && (commentObject = commentObject.optJSONObject("page_info")) != null) {
endCursor = commentObject.optString("end_cursor");
+ }
if (mediaItemType != MediaItemType.MEDIA_TYPE_SLIDER) {
- final ViewerPostModel postModel = new ViewerPostModel(mediaItemType,
+ final ViewerPostModel postModel = new ViewerPostModel(
+ mediaItemType,
media.getString(Constants.EXTRAS_ID),
- isVideo ? media.getString("video_url") : Utils.getHighQualityImage(media),
+ isVideo ? media.getString("video_url") : ResponseBodyUtils.getHighQualityImage(media),
shortCode,
- Utils.isEmpty(postCaption) ? null : postCaption,
- username,
+ TextUtils.isEmpty(postCaption) ? null : postCaption,
+ profileModel,
isVideo && media.has("video_view_count") ? media.getLong("video_view_count") : -1,
timestamp, media.getBoolean("viewer_has_liked"), media.getBoolean("viewer_has_saved"),
media.getJSONObject("edge_media_preview_like").getLong("count"),
media.isNull("location") ? null : media.getJSONObject("location").optString("name"),
media.isNull("location") ? null :
- (media.getJSONObject("location").optString("id") + "/" +
+ (media.getJSONObject("location").optString("id") + "/" +
media.getJSONObject("location").optString("slug")));
postModel.setCommentsCount(commentsCount);
- Utils.checkExistence(downloadDir, customDir, false, postModel);
+ DownloadUtils.checkExistence(downloadDir, customDir, false, postModel);
result = new ViewerPostModel[]{postModel};
@@ -114,22 +147,23 @@ public final class PostFetcher extends AsyncTask
final JSONObject node = children.getJSONObject(i).getJSONObject("node");
final boolean isChildVideo = node.getBoolean("is_video");
- postModels[i] = new ViewerPostModel(isChildVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
+ postModels[i] = new ViewerPostModel(
+ isChildVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
media.getString(Constants.EXTRAS_ID),
- isChildVideo ? node.getString("video_url") : Utils.getHighQualityImage(node),
+ isChildVideo ? node.getString("video_url") : ResponseBodyUtils.getHighQualityImage(node),
node.getString(Constants.EXTRAS_SHORTCODE),
postCaption,
- username,
+ profileModel,
isChildVideo && node.has("video_view_count") ? node.getLong("video_view_count") : -1,
timestamp, media.getBoolean("viewer_has_liked"), media.getBoolean("viewer_has_saved"),
media.getJSONObject("edge_media_preview_like").getLong("count"),
media.isNull("location") ? null : media.getJSONObject("location").optString("name"),
media.isNull("location") ? null :
- (media.getJSONObject("location").optString("id") + "/" +
- media.getJSONObject("location").optString("slug")));
+ (media.getJSONObject("location").optString("id") + "/" +
+ media.getJSONObject("location").optString("slug")));
postModels[i].setSliderDisplayUrl(node.getString("display_url"));
- Utils.checkExistence(downloadDir, customDir, true, postModels[i]);
+ DownloadUtils.checkExistence(downloadDir, customDir, true, postModels[i]);
}
postModels[0].setCommentsCount(commentsCount);
@@ -140,9 +174,10 @@ public final class PostFetcher extends AsyncTask
conn.disconnect();
} catch (Exception e) {
- if (logCollector != null)
+ if (logCollector != null) {
logCollector.appendException(e, LogCollector.LogFile.ASYNC_POST_FETCHER, "doInBackground");
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
+ }
+ Log.e(TAG, "Error fetching post", e);
}
return result;
}
diff --git a/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java
index 6dbd4c88..0ac8ed24 100755
--- a/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java
+++ b/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java
@@ -15,7 +15,11 @@ import awais.instagrabber.BuildConfig;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.enums.MediaItemType;
+import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.utils.Constants;
+import awais.instagrabber.utils.DownloadUtils;
+import awais.instagrabber.utils.NetworkUtils;
+import awais.instagrabber.utils.TextUtils;
import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector;
@@ -25,19 +29,19 @@ import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO;
import static awais.instagrabber.utils.Utils.logCollector;
public final class PostsFetcher extends AsyncTask {
+ private static final String TAG = "PostsFetcher";
+ private final PostItemType type;
private final String endCursor;
private final String id;
private final FetchListener fetchListener;
private String username = null;
- public PostsFetcher(final String id, final FetchListener