1
0
mirror of https://github.com/KokaKiwi/BarInsta synced 2024-11-24 15:47:30 +00:00

Convert Post view to a regular fragment instead of dialog.

Added global fragment animations too
This commit is contained in:
Ammar Githam 2021-05-07 20:34:31 +09:00
parent 3bbafc654c
commit 96da16ff84
48 changed files with 1401 additions and 1324 deletions

View File

@ -651,7 +651,11 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage
if (navController == null) return;
final Bundle bundle = new Bundle();
bundle.putString("username", "@" + username);
try {
navController.navigate(R.id.action_global_profileFragment, bundle);
} catch (Exception e) {
Log.e(TAG, "showProfileView: ", e);
}
}
private void showPostView(@NonNull final IntentModel intentModel) {
@ -664,11 +668,16 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage
alertDialog.show();
new PostFetcher(shortCode, feedModel -> {
if (feedModel != null) {
final PostViewV2Fragment fragment = PostViewV2Fragment
.builder(feedModel)
.build();
fragment.setOnShowListener(dialog -> alertDialog.dismiss());
fragment.show(getSupportFragmentManager(), "post_view");
if (currentNavControllerLiveData == null) return;
final NavController navController = currentNavControllerLiveData.getValue();
if (navController == null) return;
final Bundle bundle = new Bundle();
bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel);
try {
navController.navigate(R.id.action_global_post_view, bundle);
} catch (Exception e) {
Log.e(TAG, "showPostView: ", e);
}
return;
}
Toast.makeText(getApplicationContext(), R.string.post_not_found, Toast.LENGTH_SHORT).show();
@ -724,11 +733,19 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage
}
public void setCollapsingView(@NonNull final View view) {
try {
binding.collapsingToolbarLayout.addView(view, 0);
} catch (Exception e) {
Log.e(TAG, "setCollapsingView: ", e);
}
}
public void removeCollapsingView(@NonNull final View view) {
try {
binding.collapsingToolbarLayout.removeView(view);
} catch (Exception e) {
Log.e(TAG, "removeCollapsingView: ", e);
}
}
public void setToolbar(final Toolbar toolbar) {

View File

@ -0,0 +1,75 @@
package awais.instagrabber.customviews;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentManager;
import androidx.navigation.NavDestination;
import androidx.navigation.NavOptions;
import androidx.navigation.Navigator;
import androidx.navigation.fragment.FragmentNavigator;
import awais.instagrabber.R;
@Navigator.Name("fragment")
public class FragmentNavigatorWithDefaultAnimations extends FragmentNavigator {
private final NavOptions emptyNavOptions = new NavOptions.Builder().build();
// private final NavOptions defaultNavOptions = new NavOptions.Builder()
// .setEnterAnim(R.animator.nav_default_enter_anim)
// .setExitAnim(R.animator.nav_default_exit_anim)
// .setPopEnterAnim(R.animator.nav_default_pop_enter_anim)
// .setPopExitAnim(R.animator.nav_default_pop_exit_anim)
// .build();
private final NavOptions defaultNavOptions = new NavOptions.Builder()
.setEnterAnim(R.anim.slide_in_right)
.setExitAnim(R.anim.slide_out_left)
.setPopEnterAnim(android.R.anim.slide_in_left)
.setPopExitAnim(android.R.anim.slide_out_right)
.build();
public FragmentNavigatorWithDefaultAnimations(@NonNull final Context context,
@NonNull final FragmentManager manager,
final int containerId) {
super(context, manager, containerId);
}
@Nullable
@Override
public NavDestination navigate(@NonNull final Destination destination,
@Nullable final Bundle args,
@Nullable final NavOptions navOptions,
@Nullable final Navigator.Extras navigatorExtras) {
// this will try to fill in empty animations with defaults when no shared element transitions are set
// https://developer.android.com/guide/navigation/navigation-animate-transitions#shared-element
final boolean shouldUseTransitionsInstead = navigatorExtras != null;
final NavOptions navOptions1 = shouldUseTransitionsInstead ? navOptions : fillEmptyAnimationsWithDefaults(navOptions);
return super.navigate(destination, args, navOptions1, navigatorExtras);
}
private NavOptions fillEmptyAnimationsWithDefaults(@Nullable final NavOptions navOptions) {
if (navOptions == null) {
return defaultNavOptions;
}
return copyNavOptionsWithDefaultAnimations(navOptions);
}
@NonNull
private NavOptions copyNavOptionsWithDefaultAnimations(@NonNull final NavOptions navOptions) {
return new NavOptions.Builder()
.setLaunchSingleTop(navOptions.shouldLaunchSingleTop())
.setPopUpTo(navOptions.getPopUpTo(), navOptions.isPopUpToInclusive())
.setEnterAnim(navOptions.getEnterAnim() == emptyNavOptions.getEnterAnim()
? defaultNavOptions.getEnterAnim() : navOptions.getEnterAnim())
.setExitAnim(navOptions.getExitAnim() == emptyNavOptions.getExitAnim()
? defaultNavOptions.getExitAnim() : navOptions.getExitAnim())
.setPopEnterAnim(navOptions.getPopEnterAnim() == emptyNavOptions.getPopEnterAnim()
? defaultNavOptions.getPopEnterAnim() : navOptions.getPopEnterAnim())
.setPopExitAnim(navOptions.getPopExitAnim() == emptyNavOptions.getPopExitAnim()
? defaultNavOptions.getPopExitAnim() : navOptions.getPopExitAnim())
.build();
}
}

View File

@ -0,0 +1,60 @@
package awais.instagrabber.customviews;
import android.os.Bundle;
import androidx.annotation.NavigationRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.navigation.NavController;
import androidx.navigation.Navigator;
import androidx.navigation.fragment.FragmentNavigator;
import androidx.navigation.fragment.NavHostFragment;
public class NavHostFragmentWithDefaultAnimations extends NavHostFragment {
private static final String KEY_GRAPH_ID = "android-support-nav:fragment:graphId";
private static final String KEY_START_DESTINATION_ARGS =
"android-support-nav:fragment:startDestinationArgs";
private static final String KEY_NAV_CONTROLLER_STATE =
"android-support-nav:fragment:navControllerState";
private static final String KEY_DEFAULT_NAV_HOST = "android-support-nav:fragment:defaultHost";
@NonNull
public static NavHostFragment create(@NavigationRes int graphResId) {
return create(graphResId, null);
}
@NonNull
public static NavHostFragment create(@NavigationRes int graphResId,
@Nullable Bundle startDestinationArgs) {
Bundle b = null;
if (graphResId != 0) {
b = new Bundle();
b.putInt(KEY_GRAPH_ID, graphResId);
}
if (startDestinationArgs != null) {
if (b == null) {
b = new Bundle();
}
b.putBundle(KEY_START_DESTINATION_ARGS, startDestinationArgs);
}
final NavHostFragmentWithDefaultAnimations result = new NavHostFragmentWithDefaultAnimations();
if (b != null) {
result.setArguments(b);
}
return result;
}
@NonNull
@Override
protected Navigator<? extends FragmentNavigator.Destination> createFragmentNavigator() {
return new FragmentNavigatorWithDefaultAnimations(requireContext(), getChildFragmentManager(), getId());
}
@Override
protected void onCreateNavController(@NonNull final NavController navController) {
super.onCreateNavController(navController);
navController.getNavigatorProvider()
.addNavigator(new FragmentNavigatorWithDefaultAnimations(requireContext(), getChildFragmentManager(), getId()));
}
}

View File

@ -3,6 +3,8 @@ package awais.instagrabber.customviews;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -25,6 +27,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import awais.instagrabber.adapters.FeedAdapterV2;
import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
@ -60,14 +63,17 @@ public class PostsRecyclerView extends RecyclerView {
private FeedAdapterV2.FeedItemCallback feedItemCallback;
private boolean shouldScrollToTop;
private FeedAdapterV2.SelectionModeCallback selectionModeCallback;
private Function<ViewGroup, View> headerViewCreator;
private Function<View, Void> headerBinder;
private boolean refresh = true;
private final List<FetchStatusChangeListener> fetchStatusChangeListeners = new ArrayList<>();
private final FetchListener<List<Media>> fetchListener = new FetchListener<List<Media>>() {
@Override
public void onResult(final List<Media> result) {
final int currentPage = lazyLoader.getCurrentPage();
if (currentPage == 0) {
if (refresh) {
refresh = false;
mediaViewModel.getList().postValue(result);
shouldScrollToTop = true;
dispatchFetchStatus();
@ -198,21 +204,19 @@ public class PostsRecyclerView extends RecyclerView {
Log.e(TAG, "initSelf: ", e);
}
if (mediaViewModel == null) return;
mediaViewModel.getList().observe(lifeCycleOwner, list -> {
if (list.size() <= 0) return;
feedAdapter.submitList(list, () -> {
mediaViewModel.getList().observe(lifeCycleOwner, list -> feedAdapter.submitList(list, () -> {
// postDelayed(this::fetchMoreIfPossible, 1000);
if (!shouldScrollToTop) return;
smoothScrollToPosition(0);
shouldScrollToTop = false;
});
});
post(() -> smoothScrollToPosition(0));
}));
postFetcher = new PostFetcher(postFetchService, fetchListener);
if (layoutPreferences.getHasGap()) {
addItemDecoration(gridSpacingItemDecoration);
}
setHasFixedSize(true);
setNestedScrollingEnabled(true);
setItemAnimator(null);
lazyLoader = new RecyclerLazyLoaderAtEdge(layoutManager, (page) -> {
if (postFetcher.hasMore()) {
postFetcher.fetch();
@ -316,11 +320,12 @@ public class PostsRecyclerView extends RecyclerView {
}
public void refresh() {
refresh = true;
if (lazyLoader != null) {
lazyLoader.resetState();
}
if (postFetcher != null) {
mediaViewModel.getList().postValue(Collections.emptyList());
// mediaViewModel.getList().postValue(Collections.emptyList());
postFetcher.reset();
postFetcher.fetch();
}

View File

@ -228,7 +228,7 @@ public class ZoomableDraweeView extends DraweeView<GenericDraweeHierarchy>
public void setZoomingEnabled(boolean zoomingEnabled) {
mZoomingEnabled = zoomingEnabled;
mZoomableController.setEnabled(false);
mZoomableController.setEnabled(zoomingEnabled);
}
/**

View File

@ -7,17 +7,24 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
private final int spacing;
private final int halfSpace;
private boolean hasHeader;
public GridSpacingItemDecoration(int spacing) {
this.spacing = spacing;
halfSpace = spacing / 2;
}
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
final int halfSpace = spacing / 2;
if (hasHeader && parent.getChildAdapterPosition(view) == 0) {
outRect.bottom = halfSpace;
outRect.left = -halfSpace;
outRect.right = -halfSpace;
return;
}
if (parent.getPaddingLeft() != halfSpace) {
parent.setPadding(halfSpace, halfSpace, halfSpace, halfSpace);
parent.setPadding(halfSpace, hasHeader ? 0 : halfSpace, halfSpace, halfSpace);
parent.setClipToPadding(false);
}
outRect.top = halfSpace;
@ -25,4 +32,8 @@ public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
outRect.left = halfSpace;
outRect.right = halfSpace;
}
public void setHasHeader(final boolean hasHeader) {
this.hasHeader = hasHeader;
}
}

View File

@ -190,16 +190,15 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay
final View profilePicView,
final View mainPostImage,
final int position) {
final PostViewV2Fragment.Builder builder = PostViewV2Fragment
.builder(feedModel);
if (position >= 0) {
builder.setPosition(position);
final NavController navController = NavHostFragment.findNavController(CollectionPostsFragment.this);
final Bundle bundle = new Bundle();
bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel);
bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, position);
try {
navController.navigate(R.id.action_global_post_view, bundle);
} catch (Exception e) {
Log.e(TAG, "openPostDialog: ", e);
}
if (!layoutPreferences.isAnimationDisabled()) {
builder.setSharedProfilePicElement(profilePicView)
.setSharedMainPostElement(mainPostImage);
}
builder.build().show(getChildFragmentManager(), "post_view");
}
};
private final FeedAdapterV2.SelectionModeCallback selectionModeCallback = new FeedAdapterV2.SelectionModeCallback() {
@ -243,8 +242,10 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay
super.onCreate(savedInstanceState);
fragmentActivity = (MainActivity) requireActivity();
final TransitionSet transitionSet = new TransitionSet();
final Context context = getContext();
if (context == null) return;
transitionSet.addTransition(new ChangeBounds())
.addTransition(TransitionInflater.from(getContext()).inflateTransition(android.R.transition.move))
.addTransition(TransitionInflater.from(context).inflateTransition(android.R.transition.move))
.setDuration(200);
setSharedElementEnterTransition(transitionSet);
postponeEnterTransition();
@ -280,7 +281,8 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay
@Override
public void onCreateOptionsMenu(@NonNull final Menu menu, @NonNull final MenuInflater inflater) {
inflater.inflate(R.menu.collection_posts_menu, menu);
// delaying to make toolbar resume animation smooth, otherwise lags
binding.getRoot().postDelayed(() -> inflater.inflate(R.menu.collection_posts_menu, menu), 500);
}
@Override
@ -288,14 +290,13 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay
if (item.getItemId() == R.id.layout) {
showPostsLayoutPreferences();
return true;
}
else if (item.getItemId() == R.id.delete) {
} else if (item.getItemId() == R.id.delete) {
final Context context = getContext();
if (context == null) return false;
new AlertDialog.Builder(context)
.setTitle(R.string.delete_collection)
.setMessage(R.string.delete_collection_note)
.setPositiveButton(R.string.confirm, (d, w) -> {
collectionService.deleteCollection(
.setPositiveButton(R.string.confirm, (d, w) -> collectionService.deleteCollection(
savedCollection.getId(),
new ServiceCallback<String>() {
@Override
@ -308,23 +309,22 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay
public void onFailure(final Throwable t) {
Log.e(TAG, "Error deleting collection", t);
try {
final Context context = getContext();
if (context == null) return;
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
} catch (final Throwable ignored) {}
}
catch(final Throwable e) {}
}
});
})
}))
.setNegativeButton(R.string.cancel, null)
.show();
}
else if (item.getItemId() == R.id.edit) {
} else if (item.getItemId() == R.id.edit) {
final Context context = getContext();
if (context == null) return false;
final EditText input = new EditText(context);
new AlertDialog.Builder(context)
.setTitle(R.string.edit_collection)
.setView(input)
.setPositiveButton(R.string.confirm, (d, w) -> {
collectionService.editCollectionName(
.setPositiveButton(R.string.confirm, (d, w) -> collectionService.editCollectionName(
savedCollection.getId(),
input.getText().toString(),
new ServiceCallback<String>() {
@ -338,12 +338,12 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay
public void onFailure(final Throwable t) {
Log.e(TAG, "Error editing collection", t);
try {
final Context context = getContext();
if (context == null) return;
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
} catch (final Throwable ignored) {}
}
catch(final Throwable e) {}
}
});
})
}))
.setNegativeButton(R.string.cancel, null)
.show();
}

View File

@ -1,5 +1,6 @@
package awais.instagrabber.fragments;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Typeface;
@ -23,13 +24,14 @@ import androidx.activity.OnBackPressedDispatcher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.constraintlayout.motion.widget.MotionLayout;
import androidx.constraintlayout.motion.widget.MotionScene;
import androidx.core.content.PermissionChecker;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.navigation.NavController;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.snackbar.BaseTransientBottomBar;
@ -76,9 +78,6 @@ import static androidx.core.content.PermissionChecker.checkSelfPermission;
import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
import static awais.instagrabber.utils.Utils.settingsHelper;
//import awaisomereport.LogCollector;
//import static awais.instagrabber.utils.Utils.logCollector;
public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private static final String TAG = "HashTagFragment";
private static final int STORAGE_PERM_REQUEST_CODE = 8020;
@ -88,7 +87,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
private MainActivity fragmentActivity;
private FragmentHashtagBinding binding;
private CoordinatorLayout root;
private MotionLayout root;
private boolean shouldRefresh = true;
private boolean hasStories = false;
private boolean opening = false;
@ -227,17 +226,15 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
return;
}
opening = true;
final PostViewV2Fragment.Builder builder = PostViewV2Fragment.builder(feedModel);
if (position >= 0) {
builder.setPosition(position);
final NavController navController = NavHostFragment.findNavController(HashTagFragment.this);
final Bundle bundle = new Bundle();
bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel);
bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, position);
try {
navController.navigate(R.id.action_global_post_view, bundle);
} catch (Exception e) {
Log.e(TAG, "openPostDialog: ", e);
}
if (!layoutPreferences.isAnimationDisabled()) {
builder.setSharedProfilePicElement(profilePicView)
.setSharedMainPostElement(mainPostImage);
}
final FragmentManager fragmentManager = getChildFragmentManager();
if (fragmentManager.isDestroyed()) return;
builder.build().show(fragmentManager, "post_view");
opening = false;
}
};
@ -307,13 +304,11 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
if (root != null) {
shouldRefresh = false;
fragmentActivity.setCollapsingView(hashtagDetailsBinding.getRoot());
return root;
}
binding = FragmentHashtagBinding.inflate(inflater, container, false);
root = binding.getRoot();
hashtagDetailsBinding = LayoutHashtagDetailsBinding.inflate(inflater, fragmentActivity.getCollapsingToolbarView(), false);
fragmentActivity.setCollapsingView(hashtagDetailsBinding.getRoot());
hashtagDetailsBinding = binding.header;
return root;
}
@ -370,14 +365,6 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (hashtagDetailsBinding != null) {
fragmentActivity.removeCollapsingView(hashtagDetailsBinding.getRoot());
}
}
private void init() {
if (getArguments() == null) return;
final HashTagFragmentArgs fragmentArgs = HashTagFragmentArgs.fromBundle(getArguments());
@ -402,6 +389,17 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
.setSelectionModeCallback(selectionModeCallback)
.init();
binding.swipeRefreshLayout.setRefreshing(true);
binding.posts.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
super.onScrolled(recyclerView, dx, dy);
final boolean canScrollVertically = recyclerView.canScrollVertically(-1);
final MotionScene.Transition transition = root.getTransition(R.id.transition);
if (transition != null) {
transition.setEnable(!canScrollVertically);
}
}
});
}
private void setHashtagDetails() {
@ -428,9 +426,10 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
final long userId = CookieUtils.getUserIdFromCookie(cookie);
final String deviceUuid = Utils.settingsHelper.getString(Constants.DEVICE_UUID);
if (csrfToken != null && userId != 0 && deviceUuid != null) {
if (csrfToken != null && userId != 0) {
hashtagDetailsBinding.btnFollowTag.setClickable(false);
tagsService.changeFollow(hashtagModel.getFollowing() == FollowingType.FOLLOWING ? "unfollow" : "follow",
tagsService.changeFollow(
hashtagModel.getFollowing() == FollowingType.FOLLOWING ? "unfollow" : "follow",
hashtag,
csrfToken,
userId,
@ -454,21 +453,22 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
hashtagDetailsBinding.btnFollowTag.setClickable(true);
Log.e(TAG, "onFailure: ", t);
final String message = t.getMessage();
Snackbar.make(root,
message != null ? message
: getString(R.string.downloader_unknown_error),
Snackbar.make(
root,
message != null ? message : getString(R.string.downloader_unknown_error),
BaseTransientBottomBar.LENGTH_LONG)
.show();
}
});
return;
}
});
} else {
hashtagDetailsBinding.btnFollowTag.setVisibility(View.GONE);
}
hashtagDetailsBinding.favChip.setVisibility(View.VISIBLE);
final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(getContext()));
final Context context = getContext();
if (context == null) return;
final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(context));
favoriteRepository.getFavorite(hashtag, FavoriteType.HASHTAG, new RepositoryCallback<Favorite>() {
@Override
public void onSuccess(final Favorite result) {
@ -557,7 +557,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
private void showSnackbar(final String message) {
final Snackbar snackbar = Snackbar.make(root, message, BaseTransientBottomBar.LENGTH_LONG);
@SuppressLint("ShowToast") final Snackbar snackbar = Snackbar.make(root, message, BaseTransientBottomBar.LENGTH_LONG);
snackbar.setAction(R.string.ok, v1 -> snackbar.dismiss())
.setAnimationMode(BaseTransientBottomBar.ANIMATION_MODE_SLIDE)
.setAnchorView(fragmentActivity.getBottomNavView())

View File

@ -22,13 +22,14 @@ import androidx.activity.OnBackPressedDispatcher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.constraintlayout.motion.widget.MotionLayout;
import androidx.constraintlayout.motion.widget.MotionScene;
import androidx.core.content.PermissionChecker;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.navigation.NavController;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.snackbar.BaseTransientBottomBar;
@ -73,9 +74,6 @@ import static androidx.core.content.PermissionChecker.checkSelfPermission;
import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
import static awais.instagrabber.utils.Utils.settingsHelper;
//import awaisomereport.LogCollector;
//import static awais.instagrabber.utils.Utils.logCollector;
public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private static final String TAG = "LocationFragment";
private static final int STORAGE_PERM_REQUEST_CODE = 8020;
@ -83,7 +81,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
private MainActivity fragmentActivity;
private FragmentLocationBinding binding;
private CoordinatorLayout root;
private MotionLayout root;
private boolean shouldRefresh = true;
private boolean hasStories = false;
private boolean opening = false;
@ -219,18 +217,15 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
return;
}
opening = true;
final PostViewV2Fragment.Builder builder = PostViewV2Fragment
.builder(feedModel);
if (position >= 0) {
builder.setPosition(position);
final NavController navController = NavHostFragment.findNavController(LocationFragment.this);
final Bundle bundle = new Bundle();
bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel);
bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, position);
try {
navController.navigate(R.id.action_global_post_view, bundle);
} catch (Exception e) {
Log.e(TAG, "openPostDialog: ", e);
}
if (!layoutPreferences.isAnimationDisabled()) {
builder.setSharedProfilePicElement(profilePicView)
.setSharedMainPostElement(mainPostImage);
}
final FragmentManager fragmentManager = getChildFragmentManager();
if (fragmentManager.isDestroyed()) return;
builder.build().show(fragmentManager, "post_view");
opening = false;
}
};
@ -302,13 +297,11 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
@Nullable final Bundle savedInstanceState) {
if (root != null) {
shouldRefresh = false;
fragmentActivity.setCollapsingView(locationDetailsBinding.getRoot());
return root;
}
binding = FragmentLocationBinding.inflate(inflater, container, false);
root = binding.getRoot();
locationDetailsBinding = LayoutLocationDetailsBinding.inflate(inflater, fragmentActivity.getCollapsingToolbarView(), false);
fragmentActivity.setCollapsingView(locationDetailsBinding.getRoot());
locationDetailsBinding = binding.header;
return root;
}
@ -365,14 +358,6 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (locationDetailsBinding != null) {
fragmentActivity.removeCollapsingView(locationDetailsBinding.getRoot());
}
}
private void init() {
if (getArguments() == null) return;
final LocationFragmentArgs fragmentArgs = LocationFragmentArgs.fromBundle(getArguments());
@ -393,6 +378,17 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
.setSelectionModeCallback(selectionModeCallback)
.init();
binding.swipeRefreshLayout.setRefreshing(true);
binding.posts.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
super.onScrolled(recyclerView, dx, dy);
final boolean canScrollVertically = recyclerView.canScrollVertically(-1);
final MotionScene.Transition transition = root.getTransition(R.id.transition);
if (transition != null) {
transition.setEnable(!canScrollVertically);
}
}
});
}
private void fetchLocationModel() {

View File

@ -20,6 +20,7 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationManagerCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
@ -108,11 +109,14 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
mediaService.fetch(mediaId, new ServiceCallback<Media>() {
@Override
public void onSuccess(final Media feedModel) {
final PostViewV2Fragment fragment = PostViewV2Fragment
.builder(feedModel)
.build();
fragment.setOnShowListener(dialog -> alertDialog.dismiss());
fragment.show(getChildFragmentManager(), "post_view");
final NavController navController = NavHostFragment.findNavController(NotificationsViewerFragment.this);
final Bundle bundle = new Bundle();
bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel);
try {
navController.navigate(R.id.action_global_post_view, bundle);
} catch (Exception e) {
Log.e(TAG, "onSuccess: ", e);
}
}
@Override

View File

@ -1,50 +1,34 @@
package awais.instagrabber.fragments;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.ColorDrawable;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.util.Log;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ScrollView;
import android.widget.Toast;
import android.widget.ViewSwitcher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.PermissionChecker;
import androidx.core.util.Pair;
import androidx.core.widget.NestedScrollView;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
@ -58,11 +42,7 @@ import androidx.transition.TransitionManager;
import androidx.viewpager2.widget.ViewPager2;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.controller.BaseControllerListener;
import com.facebook.drawee.drawable.ScalingUtils;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.imagepipeline.image.ImageInfo;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
@ -76,7 +56,6 @@ import awais.instagrabber.R;
import awais.instagrabber.adapters.SliderCallbackAdapter;
import awais.instagrabber.adapters.SliderItemsAdapter;
import awais.instagrabber.adapters.viewholder.SliderVideoViewHolder;
import awais.instagrabber.customviews.SharedElementTransitionDialogFragment;
import awais.instagrabber.customviews.VerticalImageSpan;
import awais.instagrabber.customviews.VideoPlayerCallbackAdapter;
import awais.instagrabber.customviews.VideoPlayerViewHelper;
@ -101,31 +80,28 @@ import awais.instagrabber.viewmodels.PostViewV2ViewModel;
import static androidx.core.content.PermissionChecker.checkSelfPermission;
import static awais.instagrabber.fragments.HashTagFragment.ARG_HASHTAG;
import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
import static awais.instagrabber.utils.Utils.getAttrValue;
import static awais.instagrabber.utils.Utils.settingsHelper;
public class PostViewV2Fragment extends SharedElementTransitionDialogFragment implements EditTextDialogFragment.EditTextDialogFragmentCallback {
public class PostViewV2Fragment extends Fragment implements EditTextDialogFragment.EditTextDialogFragmentCallback {
private static final String TAG = "PostViewV2Fragment";
private static final int DETAILS_HIDE_DELAY_MILLIS = 2000;
private static final String ARG_MEDIA = "media";
private static final String ARG_SLIDER_POSITION = "position";
public static final String ARG_MEDIA = "media";
public static final String ARG_SLIDER_POSITION = "position";
private static final int STORAGE_PERM_REQUEST_CODE = 8020;
// private Media media;
private View sharedProfilePicElement;
private View sharedMainPostElement;
private DialogPostViewBinding binding;
// private MediaService mediaService;
private Context context;
// private Context context;
private BottomSheetBehavior<NestedScrollView> bottomSheetBehavior;
private boolean detailsVisible = true;
private boolean video;
private VideoPlayerViewHelper videoPlayerViewHelper;
private SliderItemsAdapter sliderItemsAdapter;
// private boolean wasControlsVisible;
private boolean wasPaused;
private int captionState = BottomSheetBehavior.STATE_HIDDEN;
private int sliderPosition = -1;
private DialogInterface.OnShowListener onShowListener;
private boolean hasBeenToggled = false;
private PostViewV2ViewModel viewModel;
private PopupMenu optionsPopup;
@ -151,51 +127,6 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
}
};
// private final VerticalDragHelper.OnVerticalDragListener onVerticalDragListener = new VerticalDragHelper.OnVerticalDragListener() {
//
// @Override
// public void onDrag(final float dY) {
// // allow the view to be draggable
// final ConstraintLayout v = binding.getRoot();
// final float finalY = v.getY() + dY;
// animateY(v, finalY, 0, null);
// }
//
// @Override
// public void onDragEnd() {
// // animate and dismiss if user drags the view more that 30% of the view
// if (Math.abs(binding.getRoot().getY()) > Utils.displayMetrics.heightPixels * 0.25) {
// animateAndDismiss(binding.getRoot().getY() < 0 ? 1 : -1);
// return;
// }
// // animate back the view to proper position
// animateY(binding.getRoot(), 0, 200, null);
// }
//
// @Override
// public void onFling(final double flingVelocity) {
// // animate and dismiss if user flings up/down
// animateAndDismiss(flingVelocity > 0 ? 1 : -1);
// }
//
// private void animateAndDismiss(final int direction) {
// final int height = binding.getRoot().getHeight();
// final int finalYDist = height + Utils.getStatusBarHeight(context);
// // less than 0 means up direction, else down
// final int finalY = direction > 0 ? -finalYDist : finalYDist;
// animateY(binding.getRoot(), finalY, 200, new AnimatorListenerAdapter() {
// @Override
// public void onAnimationEnd(final Animator animation) {
// dismiss();
// }
// });
// }
// };
public void setOnShowListener(final DialogInterface.OnShowListener onShowListener) {
this.onShowListener = onShowListener;
}
public void setOnDeleteListener(final OnDeleteListener onDeleteListener) {
if (onDeleteListener == null) return;
this.onDeleteListener = onDeleteListener;
@ -205,68 +136,12 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
void onDelete();
}
public static class Builder {
private final Media feedModel;
private View profilePicElement;
private View mainPostElement;
private int position;
public Builder setSharedProfilePicElement(final View profilePicElement) {
this.profilePicElement = profilePicElement;
return this;
}
@SuppressWarnings("UnusedReturnValue")
public Builder setSharedMainPostElement(final View mainPostElement) {
this.mainPostElement = mainPostElement;
return this;
}
public Builder setPosition(final int position) {
this.position = position;
return this;
}
public PostViewV2Fragment build() {
return PostViewV2Fragment.newInstance(feedModel, profilePicElement, mainPostElement, position);
}
public Builder(final Media feedModel) {
this.feedModel = feedModel;
}
}
private static PostViewV2Fragment newInstance(final Media feedModel,
final View profilePicElement,
final View mainPostElement,
final int position) {
final PostViewV2Fragment f = new PostViewV2Fragment(profilePicElement, mainPostElement);
final Bundle args = new Bundle();
args.putSerializable(ARG_MEDIA, feedModel);
if (position >= 0) {
args.putInt(ARG_SLIDER_POSITION, position);
}
f.setArguments(args);
return f;
}
public static Builder builder(final Media feedModel) {
return new Builder(feedModel);
}
// default constructor for fragment manager
public PostViewV2Fragment() {}
private PostViewV2Fragment(final View sharedProfilePicElement,
final View sharedMainPostElement) {
this.sharedProfilePicElement = sharedProfilePicElement;
this.sharedMainPostElement = sharedMainPostElement;
}
@Override
public void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_FRAME, R.style.PostViewV2Style);
viewModel = new ViewModelProvider(this).get(PostViewV2ViewModel.class);
captionState = settingsHelper.getBoolean(Constants.SHOW_CAPTIONS) ?
BottomSheetBehavior.STATE_COLLAPSED : BottomSheetBehavior.STATE_HIDDEN;
@ -278,58 +153,19 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
@Nullable final ViewGroup container,
@Nullable final Bundle savedInstanceState) {
binding = DialogPostViewBinding.inflate(inflater, container, false);
final ConstraintLayout root = binding.getRoot();
final ViewTreeObserver.OnPreDrawListener preDrawListener = new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
root.getViewTreeObserver().removeOnPreDrawListener(this);
return false;
}
};
root.getViewTreeObserver().addOnPreDrawListener(preDrawListener);
return root;
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
// postponeEnterTransition();
init();
}
@Override
public void onAttach(@NonNull final Context context) {
super.onAttach(context);
this.context = context;
}
@Override
public void onStart() {
super.onStart();
final Dialog dialog = getDialog();
if (dialog == null) return;
final Window window = dialog.getWindow();
if (window == null) return;
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
window.setDimAmount(0);
int width = ViewGroup.LayoutParams.MATCH_PARENT;
int height = ViewGroup.LayoutParams.MATCH_PARENT;
window.setLayout(width, height);
if (!wasPaused && (sharedProfilePicElement != null || sharedMainPostElement != null)) {
final ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(
binding.getRoot().getBackground().mutate(),
PropertyValuesHolder.ofInt("alpha", 0, 255)
);
addAnimator(animator);
}
if (onShowListener != null) {
onShowListener.onShow(dialog);
}
}
@Override
public void onPause() {
super.onPause();
wasPaused = true;
// wasPaused = true;
if (bottomSheetBehavior != null) {
captionState = bottomSheetBehavior.getState();
}
@ -390,85 +226,12 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
}
}
@Override
protected void onBeforeSharedElementAnimation(@NonNull final View startView,
@NonNull final View destView,
@NonNull final SharedElementTransitionDialogFragment.ViewBounds viewBounds) {
GenericDraweeHierarchy hierarchy = null;
if (destView == binding.postImage) {
hierarchy = binding.postImage.getHierarchy();
} else if (destView == binding.videoPost.thumbnailParent) {
hierarchy = binding.videoPost.thumbnail.getHierarchy();
}
if (hierarchy != null) {
final ScalingUtils.ScaleType scaleTypeTo = ScalingUtils.ScaleType.FIT_CENTER;
final ScalingUtils.InterpolatingScaleType scaleType = new ScalingUtils.InterpolatingScaleType(
ScalingUtils.ScaleType.CENTER_CROP,
scaleTypeTo,
viewBounds.getStartBounds(),
viewBounds.getDestBounds()
);
hierarchy.setActualImageScaleType(scaleType);
final ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
animator.setDuration(getAnimationDuration());
animator.addUpdateListener(animation -> {
float fraction = (float) animation.getAnimatedValue();
scaleType.setValue(fraction);
});
final GenericDraweeHierarchy finalHierarchy = hierarchy;
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
finalHierarchy.setActualImageScaleType(scaleTypeTo);
destView.requestLayout();
}
});
addAnimator(animator);
}
}
@Override
protected void onEndSharedElementAnimation(@NonNull final View startView,
@NonNull final View destView,
@NonNull final ViewBounds viewBounds) {
if (destView == binding.postImage) {
binding.postImage.setTranslationX(0);
binding.postImage.setTranslationY(0);
binding.postImage.setX(0);
binding.postImage.setY(0);
binding.postImage.setLayoutParams(new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
binding.postImage.requestLayout();
if (bottomSheetBehavior != null) {
bottomSheetBehavior.setState(captionState);
}
return;
}
if (destView == binding.sliderParent) {
binding.sliderParent.setLayoutParams(new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
binding.sliderParent.requestLayout();
if (bottomSheetBehavior != null) {
bottomSheetBehavior.setState(captionState);
}
return;
}
if (destView == binding.videoPost.thumbnailParent) {
final FrameLayout.LayoutParams params = new ViewSwitcher.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER;
binding.videoPost.thumbnailParent.setLayoutParams(params);
binding.videoPost.thumbnailParent.requestLayout();
if (bottomSheetBehavior != null) {
bottomSheetBehavior.setState(captionState);
}
}
}
@Override
public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == STORAGE_PERM_REQUEST_CODE && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
final Context context = getContext();
if (context == null) return;
DownloadUtils.showDownloadDialog(context, viewModel.getMedia(), sliderPosition);
}
}
@ -476,17 +239,17 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
private void init() {
final Bundle arguments = getArguments();
if (arguments == null) {
dismiss();
// dismiss();
return;
}
final Serializable feedModelSerializable = arguments.getSerializable(ARG_MEDIA);
if (feedModelSerializable == null) {
Log.e(TAG, "onCreate: feedModelSerializable is null");
dismiss();
// dismiss();
return;
}
if (!(feedModelSerializable instanceof Media)) {
dismiss();
// dismiss();
return;
}
final Media media = (Media) feedModelSerializable;
@ -494,11 +257,11 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
sliderPosition = arguments.getInt(ARG_SLIDER_POSITION, 0);
}
viewModel.setMedia(media);
if (!wasPaused && (sharedProfilePicElement != null || sharedMainPostElement != null)) {
binding.getRoot().getBackground().mutate().setAlpha(0);
}
setProfilePicSharedElement();
setupCaptionBottomSheet();
// if (!wasPaused && (sharedProfilePicElement != null || sharedMainPostElement != null)) {
// binding.getRoot().getBackground().mutate().setAlpha(0);
// }
// setProfilePicSharedElement();
// setupCaptionBottomSheet();
setupCommonActions();
setObservers();
}
@ -506,10 +269,14 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
private void setObservers() {
viewModel.getUser().observe(getViewLifecycleOwner(), user -> {
if (user == null) {
binding.userDetailsGroup.setVisibility(View.GONE);
binding.profilePic.setVisibility(View.GONE);
binding.title.setVisibility(View.GONE);
binding.subtitle.setVisibility(View.GONE);
return;
}
binding.userDetailsGroup.setVisibility(View.VISIBLE);
binding.profilePic.setVisibility(View.VISIBLE);
binding.title.setVisibility(View.VISIBLE);
binding.subtitle.setVisibility(View.VISIBLE);
binding.getRoot().post(() -> setupProfilePic(user));
binding.getRoot().post(() -> setupTitles(user));
});
@ -563,30 +330,6 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
return safeCount;
}
private void setupCaptionBottomSheet() {
bottomSheetBehavior = BottomSheetBehavior.from(binding.captionParent);
bottomSheetBehavior.setState(captionState);
bottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull final View bottomSheet, final int newState) {}
@Override
public void onSlide(@NonNull final View bottomSheet, final float slideOffset) {
binding.captionParent.getBackground().mutate().setAlpha((int) (128 + (128 * (slideOffset < 0 ? 0 : slideOffset))));
}
});
if (sharedProfilePicElement == null || sharedMainPostElement == null) {
binding.getRoot().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
binding.getRoot().getViewTreeObserver().removeOnGlobalLayoutListener(this);
if (bottomSheetBehavior == null) return;
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
});
}
}
private void setupCommonActions() {
setupLike();
setupSave();
@ -619,6 +362,8 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
}
});
binding.comment.setOnLongClickListener(v -> {
final Context context = getContext();
if (context == null) return false;
Utils.displayToastAboveView(context, v, getString(R.string.comment));
return true;
});
@ -626,6 +371,8 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
private void setupDownload() {
binding.download.setOnClickListener(v -> {
final Context context = getContext();
if (context == null) return;
if (checkSelfPermission(context, WRITE_PERMISSION) == PermissionChecker.PERMISSION_GRANTED) {
DownloadUtils.showDownloadDialog(context, viewModel.getMedia(), sliderPosition);
return;
@ -633,6 +380,8 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
requestPermissions(DownloadUtils.PERMS, STORAGE_PERM_REQUEST_CODE);
});
binding.download.setOnLongClickListener(v -> {
final Context context = getContext();
if (context == null) return false;
Utils.displayToastAboveView(context, v, getString(R.string.action_download));
return true;
});
@ -702,17 +451,21 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
private void setLikedResources(final boolean liked) {
final int iconResource;
final int tintResource;
final Context context = getContext();
if (context == null) return;
final Resources resources = context.getResources();
if (resources == null) return;
if (liked) {
iconResource = R.drawable.ic_like;
tintResource = R.color.red_600;
tintResource = resources.getColor(R.color.red_600);
// textResId = R.string.unlike_without_count;
} else {
iconResource = R.drawable.ic_not_liked;
tintResource = R.color.white;
tintResource = getAttrValue(context, R.attr.colorPrimary);
// textResId = R.string.like_without_count;
}
binding.like.setIconResource(iconResource);
binding.like.setIconTintResource(tintResource);
binding.like.setIconTint(ColorStateList.valueOf(tintResource));
}
private void setupSave() {
@ -769,23 +522,21 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
private void setSavedResources(final boolean saved) {
final int iconResource;
final int tintResource;
final Context context = getContext();
if (context == null) return;
final Resources resources = context.getResources();
if (resources == null) return;
if (saved) {
iconResource = R.drawable.ic_class_24;
tintResource = R.color.blue_700;
tintResource = resources.getColor(R.color.blue_700);
// textResId = R.string.saved;
} else {
iconResource = R.drawable.ic_outline_class_24;
tintResource = R.color.white;
tintResource = getAttrValue(context, R.attr.colorPrimary);
// textResId = R.string.save;
}
binding.save.setIconResource(iconResource);
binding.save.setIconTintResource(tintResource);
}
private void setProfilePicSharedElement() {
if (!wasPaused && sharedProfilePicElement != null) {
addSharedElement(sharedProfilePicElement, binding.profilePic);
}
binding.save.setIconTint(ColorStateList.valueOf(tintResource));
}
private void setupProfilePic(final User user) {
@ -797,19 +548,6 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
final DraweeController controller = Fresco
.newDraweeControllerBuilder()
.setUri(uri)
.setControllerListener(new BaseControllerListener<ImageInfo>() {
@Override
public void onFailure(final String id, final Throwable throwable) {
startPostponedEnterTransition();
}
@Override
public void onFinalImageSet(final String id,
final ImageInfo imageInfo,
final Animatable animatable) {
startPostponedEnterTransition();
}
})
.build();
binding.profilePic.setController(controller);
binding.profilePic.setOnClickListener(v -> navigateToProfile("@" + user.getUsername()));
@ -821,7 +559,13 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
binding.subtitle.setVisibility(View.GONE);
return;
}
binding.subtitle.setText(user.getFullName());
final String fullName = user.getFullName();
if (TextUtils.isEmpty(fullName)) {
binding.subtitle.setVisibility(View.GONE);
} else {
binding.subtitle.setVisibility(View.VISIBLE);
binding.subtitle.setText(fullName);
}
setUsername(user);
binding.title.setOnClickListener(v -> navigateToProfile("@" + user.getUsername()));
binding.subtitle.setOnClickListener(v -> navigateToProfile("@" + user.getUsername()));
@ -831,6 +575,8 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
final SpannableStringBuilder sb = new SpannableStringBuilder(user.getUsername());
final int drawableSize = Utils.convertDpToPx(24);
if (user.isVerified()) {
final Context context = getContext();
if (context == null) return;
final Drawable verifiedDrawable = AppCompatResources.getDrawable(context, R.drawable.verified);
VerticalImageSpan verifiedSpan = null;
if (verifiedDrawable != null) {
@ -854,7 +600,6 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
if (caption == null || TextUtils.isEmpty(caption.getText())) {
binding.caption.setVisibility(View.GONE);
binding.translate.setVisibility(View.GONE);
binding.captionToggle.setVisibility(View.GONE);
return;
}
final String postCaption = caption.getText();
@ -872,35 +617,13 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
binding.caption.addOnEmailClickListener(autoLinkItem -> Utils.openEmailAddress(getContext(), autoLinkItem.getOriginalText().trim()));
binding.caption.addOnURLClickListener(autoLinkItem -> Utils.openURL(getContext(), autoLinkItem.getOriginalText().trim()));
binding.caption.setOnLongClickListener(v -> {
final Context context = getContext();
if (context == null) return false;
Utils.copyText(context, postCaption);
return true;
});
binding.caption.setText(postCaption);
binding.translate.setOnClickListener(v -> handleTranslateCaptionResource(viewModel.translateCaption()));
binding.captionToggle.setOnClickListener(v -> {
if (bottomSheetBehavior == null) return;
switch (bottomSheetBehavior.getState()) {
case BottomSheetBehavior.STATE_HIDDEN:
binding.captionParent.fullScroll(ScrollView.FOCUS_UP); // reset scroll position
// if (binding.playerControls.getRoot().getVisibility() == View.VISIBLE) {
// hidePlayerControls();
// }
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
return;
case BottomSheetBehavior.STATE_COLLAPSED:
case BottomSheetBehavior.STATE_EXPANDED:
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
return;
case BottomSheetBehavior.STATE_DRAGGING:
case BottomSheetBehavior.STATE_HALF_EXPANDED:
case BottomSheetBehavior.STATE_SETTLING:
default:
}
});
binding.captionToggle.setOnLongClickListener(v -> {
Utils.displayToastAboveView(context, v, getString(R.string.caption));
return true;
});
}
private void handleTranslateCaptionResource(@NonNull final LiveData<Resource<String>> data) {
@ -953,6 +676,8 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
}
binding.share.setVisibility(View.VISIBLE);
binding.share.setOnLongClickListener(v -> {
final Context context = getContext();
if (context == null) return false;
Utils.displayToastAboveView(context, v, getString(R.string.share));
return true;
});
@ -962,6 +687,8 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
if (profileModel == null) return;
final boolean isPrivate = profileModel.isPrivate();
if (isPrivate) {
final Context context = getContext();
if (context == null) return;
// is this necessary?
Toast.makeText(context, R.string.share_private_post, Toast.LENGTH_LONG).show();
}
@ -996,15 +723,15 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
// binding.playerControls.getRoot().setVisibility(View.GONE);
binding.mediaCounter.setVisibility(View.GONE);
binding.postImage.setVisibility(View.VISIBLE);
if (!wasPaused && sharedMainPostElement != null) {
binding.postImage.getHierarchy().setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP);
addSharedElement(sharedMainPostElement, binding.postImage);
}
final Media media = viewModel.getMedia();
final String imageUrl = ResponseBodyUtils.getImageUrl(media);
if (TextUtils.isEmpty(imageUrl)) {
return;
}
if (TextUtils.isEmpty(imageUrl)) return;
final ViewGroup.LayoutParams layoutParams = binding.postImage.getLayoutParams();
final Pair<Integer, Integer> widthHeight = NumberUtils.calculateWidthHeight(media.getOriginalHeight(),
media.getOriginalWidth(),
(int) (Utils.displayMetrics.heightPixels * 0.8),
Utils.displayMetrics.widthPixels);
layoutParams.height = widthHeight.second;
final ImageRequest requestBuilder = ImageRequestBuilder.newBuilderWithSource(Uri.parse(imageUrl))
.setLocalThumbnailPreviewsEnabled(true)
.build();
@ -1012,35 +739,22 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
.newDraweeControllerBuilder()
.setLowResImageRequest(ImageRequest.fromUri(ResponseBodyUtils.getThumbUrl(media)))
.setImageRequest(requestBuilder)
.setControllerListener(new BaseControllerListener<ImageInfo>() {
@Override
public void onFailure(final String id, final Throwable throwable) {
startPostponedEnterTransition();
}
@Override
public void onFinalImageSet(final String id,
final ImageInfo imageInfo,
final Animatable animatable) {
startPostponedEnterTransition();
}
})
.build();
binding.postImage.setController(controller);
// binding.postImage.setOnClickListener(v -> toggleDetails());
final AnimatedZoomableController zoomableController = AnimatedZoomableController.newInstance();
final AnimatedZoomableController zoomableController = (AnimatedZoomableController) binding.postImage.getZoomableController();
zoomableController.setMaxScaleFactor(3f);
zoomableController.setGestureZoomEnabled(true);
zoomableController.setEnabled(true);
binding.postImage.setZoomableController(zoomableController);
binding.postImage.setZoomingEnabled(true);
binding.postImage.setTapListener(new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(final MotionEvent e) {
toggleDetails();
// toggleDetails();
return true;
}
});
binding.postImage.setAllowTouchInterceptionWhileZoomed(true);
// binding.postImage.setAllowTouchInterceptionWhileZoomed(true);
// binding.postImage.setOnVerticalDragListener(onVerticalDragListener);
}
@ -1052,9 +766,26 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
// binding.playerControls.getRoot().setVisibility(View.GONE);
binding.sliderParent.setVisibility(View.VISIBLE);
binding.mediaCounter.setVisibility(View.VISIBLE);
if (!wasPaused && sharedMainPostElement != null) {
addSharedElement(sharedMainPostElement, binding.sliderParent);
}
final Pair<Integer, Integer> maxHW = media
.getCarouselMedia()
.stream()
.reduce(new Pair<>(0, 0),
(prev, m) -> {
final int height = m.getOriginalHeight() > prev.first ? m.getOriginalHeight() : prev.first;
final int width = m.getOriginalWidth() > prev.second ? m.getOriginalWidth() : prev.second;
return new Pair<>(height, width);
},
(p1, p2) -> {
final int height = p1.first > p2.first ? p1.first : p2.first;
final int width = p1.second > p2.second ? p1.second : p2.second;
return new Pair<>(height, width);
});
final ViewGroup.LayoutParams layoutParams = binding.sliderParent.getLayoutParams();
final Pair<Integer, Integer> widthHeight = NumberUtils.calculateWidthHeight(maxHW.first,
maxHW.second,
(int) (Utils.displayMetrics.heightPixels * 0.8),
Utils.displayMetrics.widthPixels);
layoutParams.height = widthHeight.second;
final boolean hasVideo = media.getCarouselMedia()
.stream()
.anyMatch(postChild -> postChild.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO);
@ -1078,7 +809,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
@Override
public void onItemClicked(final int position) {
toggleDetails();
// toggleDetails();
}
@Override
@ -1095,8 +826,8 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
final FragmentActivity activity = getActivity();
if (activity == null) return;
Utils.disableKeepScreenOn(activity);
if (detailsVisible || hasBeenToggled) return;
toggleDetails();
// if (detailsVisible || hasBeenToggled) return;
// toggleDetails();
}
@Override
@ -1135,7 +866,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
final String text = (position + 1) + "/" + size;
binding.mediaCounter.setText(text);
final Media childMedia = media.getCarouselMedia().get(position);
final View view = binding.sliderParent.getChildAt(0);
// final View view = binding.sliderParent.getChildAt(0);
// if (prevPosition != -1) {
// if (view instanceof RecyclerView) {
// final RecyclerView.ViewHolder viewHolder = ((RecyclerView) view).findViewHolderForAdapterPosition(prevPosition);
@ -1203,32 +934,17 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
binding.sliderParent.setVisibility(View.GONE);
binding.mediaCounter.setVisibility(View.GONE);
// binding.playerControls.getRoot().setVisibility(View.VISIBLE);
if (!wasPaused && sharedMainPostElement != null) {
final GenericDraweeHierarchy hierarchy = binding.videoPost.thumbnail.getHierarchy();
hierarchy.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP);
addSharedElement(sharedMainPostElement, binding.videoPost.thumbnailParent);
}
final ViewGroup.LayoutParams layoutParams = binding.videoPost.root.getLayoutParams();
final Pair<Integer, Integer> widthHeight = NumberUtils.calculateWidthHeight(media.getOriginalHeight(),
media.getOriginalWidth(),
(int) (Utils.displayMetrics.heightPixels * 0.8),
Utils.displayMetrics.widthPixels);
layoutParams.height = widthHeight.second;
binding.videoPost.root.setVisibility(View.VISIBLE);
// final VerticalDragHelper thumbnailVerticalDragHelper = new VerticalDragHelper(binding.videoPost.thumbnailParent);
// final VerticalDragHelper playerVerticalDragHelper = new VerticalDragHelper(binding.videoPost.playerView);
// thumbnailVerticalDragHelper.setOnVerticalDragListener(onVerticalDragListener);
// playerVerticalDragHelper.setOnVerticalDragListener(onVerticalDragListener);
// enablePlayerControls(true);
// binding.videoPost.thumbnailParent.setOnTouchListener((v, event) -> {
// final boolean onDragTouch = thumbnailVerticalDragHelper.onDragTouch(event);
// if (onDragTouch) {
// return true;
// }
// return thumbnailVerticalDragHelper.onGestureTouchEvent(event);
// });
// binding.videoPost.playerView.setOnTouchListener((v, event) -> {
// final boolean onDragTouch = playerVerticalDragHelper.onDragTouch(event);
// if (onDragTouch) {
// return true;
// }
// return playerVerticalDragHelper.onGestureTouchEvent(event);
// });
binding.videoPost.playerView.setOnClickListener(v -> toggleDetails());
// binding.videoPost.playerView.setOnClickListener(v -> toggleDetails());
final Context context = getContext();
if (context == null) return;
final GestureDetector gestureDetector = new GestureDetector(context, videoPlayerViewGestureListener);
binding.videoPost.playerView.setOnTouchListener((v, event) -> {
gestureDetector.onTouchEvent(event);
@ -1258,9 +974,9 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
final FragmentActivity activity = getActivity();
if (activity == null) return;
Utils.enabledKeepScreenOn(activity);
if (detailsVisible) {
new Handler().postDelayed(() -> toggleDetails(), DETAILS_HIDE_DELAY_MILLIS);
}
// if (detailsVisible) {
// new Handler().postDelayed(() -> toggleDetails(), DETAILS_HIDE_DELAY_MILLIS);
// }
}
@Override
@ -1318,10 +1034,10 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
// hidePlayerControls();
// }
private void hideCaption() {
if (bottomSheetBehavior == null) return;
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
}
// private void hideCaption() {
// if (bottomSheetBehavior == null) return;
// bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
// }
// private void showPlayerControls() {
// hideCaption();
@ -1400,6 +1116,8 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
private void createOptionsPopupMenu() {
if (optionsPopup == null) {
final Context context = getContext();
if (context == null) return;
final ContextThemeWrapper themeWrapper = new ContextThemeWrapper(context, R.style.popupMenuStyle);
optionsPopup = new PopupMenu(themeWrapper, binding.options);
} else {
@ -1526,18 +1244,18 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
binding.profilePic.setVisibility(View.GONE);
binding.title.setVisibility(View.GONE);
binding.subtitle.setVisibility(View.GONE);
binding.topBg.setVisibility(View.GONE);
// binding.topBg.setVisibility(View.GONE);
}
if (media.getLocation() != null) {
binding.location.setVisibility(View.GONE);
}
binding.captionParent.setVisibility(View.GONE);
// binding.captionParent.setVisibility(View.GONE);
binding.bottomBg.setVisibility(View.GONE);
binding.likesCount.setVisibility(View.GONE);
binding.commentsCount.setVisibility(View.GONE);
binding.date.setVisibility(View.GONE);
binding.comment.setVisibility(View.GONE);
binding.captionToggle.setVisibility(View.GONE);
// binding.captionToggle.setVisibility(View.GONE);
// binding.playerControlsToggle.setVisibility(View.GONE);
binding.like.setVisibility(View.GONE);
binding.save.setVisibility(View.GONE);
@ -1559,7 +1277,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
binding.profilePic.setVisibility(View.VISIBLE);
binding.title.setVisibility(View.VISIBLE);
binding.subtitle.setVisibility(View.VISIBLE);
binding.topBg.setVisibility(View.VISIBLE);
// binding.topBg.setVisibility(View.VISIBLE);
}
if (media.getLocation() != null) {
binding.location.setVisibility(View.VISIBLE);
@ -1568,8 +1286,8 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
if (viewModel.hasPk()) {
binding.likesCount.setVisibility(View.VISIBLE);
binding.date.setVisibility(View.VISIBLE);
binding.captionParent.setVisibility(View.VISIBLE);
binding.captionToggle.setVisibility(View.VISIBLE);
// binding.captionParent.setVisibility(View.VISIBLE);
// binding.captionToggle.setVisibility(View.VISIBLE);
binding.share.setVisibility(View.VISIBLE);
}
if (viewModel.hasPk() && !viewModel.getMedia().isCommentsDisabled()) {
@ -1599,16 +1317,6 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
});
}
// private void animateY(final View v,
// final float finalY,
// final int duration,
// final AnimatorListenerAdapter listener) {
// v.animate()
// .y(finalY)
// .setDuration(duration)
// .setListener(listener).start();
// }
private void navigateToProfile(final String username) {
final NavController navController = getNavController();
if (navController == null) return;

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
@ -50,6 +51,7 @@ import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
import static awais.instagrabber.utils.Utils.settingsHelper;
public final class SavedViewerFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private static final String TAG = SavedViewerFragment.class.getSimpleName();
private static final int STORAGE_PERM_REQUEST_CODE = 8020;
private static final int STORAGE_PERM_REQUEST_CODE_FOR_SELECTION = 8030;
@ -171,16 +173,15 @@ public final class SavedViewerFragment extends Fragment implements SwipeRefreshL
final View profilePicView,
final View mainPostImage,
final int position) {
final PostViewV2Fragment.Builder builder = PostViewV2Fragment
.builder(feedModel);
if (position >= 0) {
builder.setPosition(position);
final NavController navController = NavHostFragment.findNavController(SavedViewerFragment.this);
final Bundle bundle = new Bundle();
bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel);
bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, position);
try {
navController.navigate(R.id.action_global_post_view, bundle);
} catch (Exception e) {
Log.e(TAG, "openPostDialog: ", e);
}
if (!layoutPreferences.isAnimationDisabled()) {
builder.setSharedProfilePicElement(profilePicView)
.setSharedMainPostElement(mainPostImage);
}
builder.build().show(getChildFragmentManager(), "post_view");
}
};
private final FeedAdapterV2.SelectionModeCallback selectionModeCallback = new FeedAdapterV2.SelectionModeCallback() {

View File

@ -35,6 +35,7 @@ import androidx.core.view.GestureDetectorCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
@ -459,11 +460,14 @@ public class StoryViewerFragment extends Fragment {
mediaService.fetch(Long.parseLong(mediaId), new ServiceCallback<Media>() {
@Override
public void onSuccess(final Media feedModel) {
final PostViewV2Fragment fragment = PostViewV2Fragment
.builder(feedModel)
.build();
fragment.setOnShowListener(dialog -> alertDialog.dismiss());
fragment.show(getChildFragmentManager(), "post_view");
final NavController navController = NavHostFragment.findNavController(StoryViewerFragment.this);
final Bundle bundle = new Bundle();
bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel);
try {
navController.navigate(R.id.action_global_post_view, bundle);
} catch (Exception e) {
Log.e(TAG, "openPostDialog: ", e);
}
}
@Override
@ -478,16 +482,16 @@ public class StoryViewerFragment extends Fragment {
if (tag instanceof PollModel) {
poll = (PollModel) tag;
if (poll.getMyChoice() > -1) {
new AlertDialog.Builder(context).setTitle(R.string.voted_story_poll)
.setAdapter(new ArrayAdapter<>(context, android.R.layout.simple_list_item_1,
new AlertDialog.Builder(context)
.setTitle(R.string.voted_story_poll)
.setAdapter(new ArrayAdapter<>(
context,
android.R.layout.simple_list_item_1,
new String[]{
(poll.getMyChoice() == 0 ? "" : "") + poll
.getLeftChoice() + " (" + poll
.getLeftCount() + ")",
(poll.getMyChoice() == 1 ? "" : "") + poll
.getRightChoice() + " (" + poll
.getRightCount() + ")"
}), null)
(poll.getMyChoice() == 0 ? "" : "") + poll.getLeftChoice() + " (" + poll.getLeftCount() + ")",
(poll.getMyChoice() == 1 ? "" : "") + poll.getRightChoice() + " (" + poll.getRightCount() + ")"
}),
null)
.setPositiveButton(R.string.ok, null)
.show();
} else {

View File

@ -10,6 +10,7 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
@ -51,8 +52,8 @@ import awais.instagrabber.databinding.FragmentTopicPostsBinding;
import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment;
import awais.instagrabber.fragments.main.DiscoverFragmentDirections;
import awais.instagrabber.models.PostsLayoutPreferences;
import awais.instagrabber.repositories.responses.discover.TopicCluster;
import awais.instagrabber.repositories.responses.Media;
import awais.instagrabber.repositories.responses.discover.TopicCluster;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.DownloadUtils;
import awais.instagrabber.utils.ResponseBodyUtils;
@ -63,6 +64,7 @@ import static androidx.core.content.PermissionChecker.checkSelfPermission;
import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
public class TopicPostsFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private static final String TAG = TopicPostsFragment.class.getSimpleName();
private static final int STORAGE_PERM_REQUEST_CODE = 8020;
private static final int STORAGE_PERM_REQUEST_CODE_FOR_SELECTION = 8030;
@ -182,16 +184,15 @@ public class TopicPostsFragment extends Fragment implements SwipeRefreshLayout.O
final View profilePicView,
final View mainPostImage,
final int position) {
final PostViewV2Fragment.Builder builder = PostViewV2Fragment
.builder(feedModel);
if (position >= 0) {
builder.setPosition(position);
final NavController navController = NavHostFragment.findNavController(TopicPostsFragment.this);
final Bundle bundle = new Bundle();
bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel);
bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, position);
try {
navController.navigate(R.id.action_global_post_view, bundle);
} catch (Exception e) {
Log.e(TAG, "openPostDialog: ", e);
}
if (!layoutPreferences.isAnimationDisabled()) {
builder.setSharedProfilePicElement(profilePicView)
.setSharedMainPostElement(mainPostImage);
}
builder.build().show(getChildFragmentManager(), "post_view");
}
};
private final FeedAdapterV2.SelectionModeCallback selectionModeCallback = new FeedAdapterV2.SelectionModeCallback() {

View File

@ -224,8 +224,14 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
}
return;
}
final PostViewV2Fragment.Builder builder = PostViewV2Fragment.builder(media);
builder.build().show(getChildFragmentManager(), "post_view");
final NavController navController = NavHostFragment.findNavController(DirectMessageThreadFragment.this);
final Bundle bundle = new Bundle();
bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, media);
try {
navController.navigate(R.id.action_global_post_view, bundle);
} catch (Exception e) {
Log.e(TAG, "openPostDialog: ", e);
}
}
@Override
@ -327,11 +333,13 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
final Bundle arguments = getArguments();
if (arguments == null) return;
final DirectMessageThreadFragmentArgs fragmentArgs = DirectMessageThreadFragmentArgs.fromBundle(arguments);
final User currentUser = appStateViewModel.getCurrentUser();
if (currentUser == null) return;
final DirectThreadViewModelFactory viewModelFactory = new DirectThreadViewModelFactory(
fragmentActivity.getApplication(),
fragmentArgs.getThreadId(),
fragmentArgs.getPending(),
appStateViewModel.getCurrentUser()
currentUser
);
viewModel = new ViewModelProvider(this, viewModelFactory).get(DirectThreadViewModel.class);
setHasOptionsMenu(true);
@ -386,7 +394,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
final DirectMessageThreadFragmentDirections.ActionThreadToSettings directions = DirectMessageThreadFragmentDirections
.actionThreadToSettings(viewModel.getThreadId(), null);
final Boolean pending = viewModel.isPending().getValue();
directions.setPending(pending == null ? false : pending);
directions.setPending(pending != null && pending);
NavHostFragment.findNavController(this).navigate(directions);
return true;
}
@ -414,14 +422,10 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
case SUCCESS:
Toast.makeText(context, R.string.marked_as_seen, Toast.LENGTH_SHORT).show();
case LOADING:
if (item != null) {
item.setEnabled(false);
}
break;
case ERROR:
if (item != null) {
item.setEnabled(true);
}
if (resource.message != null) {
Snackbar.make(context, binding.getRoot(), resource.message, Snackbar.LENGTH_LONG).show();
return;
@ -1352,7 +1356,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
requestPermissions(DownloadUtils.PERMS, STORAGE_PERM_REQUEST_CODE);
}
@NonNull
@Nullable
private User getUser(final long userId) {
for (final User user : users) {
if (userId != user.getPk()) continue;

View File

@ -18,7 +18,8 @@ import androidx.activity.OnBackPressedCallback;
import androidx.activity.OnBackPressedDispatcher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.constraintlayout.motion.widget.MotionLayout;
import androidx.constraintlayout.motion.widget.MotionScene;
import androidx.core.content.PermissionChecker;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
@ -29,7 +30,6 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.common.collect.ImmutableList;
import java.util.List;
@ -64,7 +64,7 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
private static final int STORAGE_PERM_REQUEST_CODE_FOR_SELECTION = 8030;
private MainActivity fragmentActivity;
private CoordinatorLayout root;
private MotionLayout root;
private FragmentFeedBinding binding;
private StoriesService storiesService;
private boolean shouldRefresh = true;
@ -179,15 +179,21 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
final View profilePicView,
final View mainPostImage,
final int position) {
final PostViewV2Fragment.Builder builder = PostViewV2Fragment.builder(feedModel);
if (position >= 0) {
builder.setPosition(position);
// ViewCompat.setTransitionName(profilePicView, "profile_pic");
// ViewCompat.setTransitionName(mainPostImage, "post_image");
// final FragmentNavigator.Extras extras = new FragmentNavigator.Extras.Builder()
// .addSharedElement(profilePicView, "profile_pic")
// .addSharedElement(mainPostImage, "post_image")
// .build();
final NavController navController = NavHostFragment.findNavController(FeedFragment.this);
final Bundle bundle = new Bundle();
bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel);
bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, position);
try {
navController.navigate(R.id.action_global_post_view, bundle);
} catch (Exception e) {
Log.e(TAG, "openPostDialog: ", e);
}
if (!layoutPreferences.isAnimationDisabled()) {
builder.setSharedProfilePicElement(profilePicView)
.setSharedMainPostElement(mainPostImage);
}
builder.build().show(getChildFragmentManager(), "post_view");
}
};
private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(false) {
@ -278,9 +284,6 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
final Bundle savedInstanceState) {
if (root != null) {
shouldRefresh = false;
if (storiesRecyclerView != null) {
fragmentActivity.setCollapsingView(storiesRecyclerView);
}
return root;
}
binding = FragmentFeedBinding.inflate(inflater, container, false);
@ -381,6 +384,17 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
.setSelectionModeCallback(selectionModeCallback)
.init();
binding.feedSwipeRefreshLayout.setRefreshing(true);
binding.feedRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
super.onScrolled(recyclerView, dx, dy);
final boolean canScrollVertically = recyclerView.canScrollVertically(-1);
final MotionScene.Transition transition = root.getTransition(R.id.transition);
if (transition != null) {
transition.setEnable(!canScrollVertically);
}
}
});
// if (shouldAutoPlay) {
// videoAwareRecyclerScroller = new VideoAwareRecyclerScroller();
// binding.feedRecyclerView.addOnScrollListener(videoAwareRecyclerScroller);
@ -396,15 +410,9 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
feedStoriesViewModel = new ViewModelProvider(fragmentActivity).get(FeedStoriesViewModel.class);
final Context context = getContext();
if (context == null) return;
storiesRecyclerView = new RecyclerView(context);
final CollapsingToolbarLayout.LayoutParams params = new CollapsingToolbarLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(0, Utils.getActionBarHeight(context), 0, 0);
storiesRecyclerView.setLayoutParams(params);
storiesRecyclerView.setClipToPadding(false);
storiesRecyclerView = binding.header;
storiesRecyclerView.setLayoutManager(new LinearLayoutManager(context, RecyclerView.HORIZONTAL, false));
storiesRecyclerView.setAdapter(feedStoriesAdapter);
fragmentActivity.setCollapsingView(storiesRecyclerView);
feedStoriesViewModel.getList().observe(getViewLifecycleOwner(), feedStoriesAdapter::submitList);
fetchStories();
}

View File

@ -27,7 +27,8 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.constraintlayout.motion.widget.MotionLayout;
import androidx.constraintlayout.motion.widget.MotionScene;
import androidx.core.content.PermissionChecker;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
@ -108,7 +109,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
private static final int STORAGE_PERM_REQUEST_CODE_FOR_SELECTION = 8030;
private MainActivity fragmentActivity;
private CoordinatorLayout root;
private MotionLayout root;
private FragmentProfileBinding binding;
private boolean isLoggedIn;
private String cookie;
@ -250,23 +251,15 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
final View profilePicView,
final View mainPostImage,
final int position) {
final PostViewV2Fragment.Builder builder = PostViewV2Fragment
.builder(feedModel);
if (position >= 0) {
builder.setPosition(position);
final NavController navController = NavHostFragment.findNavController(ProfileFragment.this);
final Bundle bundle = new Bundle();
bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel);
bundle.putInt(PostViewV2Fragment.ARG_SLIDER_POSITION, position);
try {
navController.navigate(R.id.action_global_post_view, bundle);
} catch (Exception e) {
Log.e(TAG, "openPostDialog: ", e);
}
if (!layoutPreferences.isAnimationDisabled()) {
builder.setSharedProfilePicElement(profilePicView)
.setSharedMainPostElement(mainPostImage);
}
final PostViewV2Fragment postViewV2Fragment = builder.build();
postViewV2Fragment.setOnDeleteListener(() -> {
postViewV2Fragment.dismiss();
binding.postsRecyclerView.refresh();
});
final FragmentManager fragmentManager = getChildFragmentManager();
if (fragmentManager.isDestroyed() || fragmentManager.isStateSaved()) return;
postViewV2Fragment.show(fragmentManager, "post_view");
}
};
private final FeedAdapterV2.SelectionModeCallback selectionModeCallback = new FeedAdapterV2.SelectionModeCallback() {
@ -345,7 +338,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
final boolean isSame = ("@" + profileModelUsername).equals(this.username);
if (isSame) {
setUsernameDelayed();
fragmentActivity.setCollapsingView(profileDetailsBinding.getRoot());
shouldRefresh = false;
return root;
}
@ -357,14 +349,12 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
}
setUsernameDelayed();
fragmentActivity.setCollapsingView(profileDetailsBinding.getRoot());
shouldRefresh = false;
return root;
}
binding = FragmentProfileBinding.inflate(inflater, container, false);
root = binding.getRoot();
profileDetailsBinding = LayoutProfileDetailsBinding.inflate(inflater, fragmentActivity.getCollapsingToolbarView(), false);
fragmentActivity.setCollapsingView(profileDetailsBinding.getRoot());
profileDetailsBinding = binding.header;
return root;
}
@ -554,14 +544,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (profileDetailsBinding != null) {
fragmentActivity.removeCollapsingView(profileDetailsBinding.getRoot());
}
}
@Override
public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
@ -589,7 +571,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
setUsernameDelayed();
}
if (TextUtils.isEmpty(username) && !isLoggedIn) {
profileDetailsBinding.infoContainer.setVisibility(View.GONE);
binding.header.getRoot().setVisibility(View.GONE);
binding.swipeRefreshLayout.setEnabled(false);
binding.privatePage1.setImageResource(R.drawable.ic_outline_info_24);
binding.privatePage2.setText(R.string.no_acc);
@ -1209,6 +1191,17 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
.setFeedItemCallback(feedItemCallback)
.setSelectionModeCallback(selectionModeCallback)
.init();
binding.postsRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
super.onScrolled(recyclerView, dx, dy);
final boolean canScrollVertically = recyclerView.canScrollVertically(-1);
final MotionScene.Transition transition = root.getTransition(R.id.transition);
if (transition != null) {
transition.setEnable(!canScrollVertically);
}
}
});
binding.swipeRefreshLayout.setRefreshing(true);
postsSetupDone = true;
}

View File

@ -21,6 +21,7 @@ import com.google.android.material.bottomnavigation.BottomNavigationView;
import java.util.List;
import awais.instagrabber.R;
import awais.instagrabber.customviews.NavHostFragmentWithDefaultAnimations;
import awais.instagrabber.fragments.main.FeedFragment;
/**
@ -139,7 +140,7 @@ public class NavigationExtensions {
if (existingFragment != null) {
return existingFragment;
}
final NavHostFragment navHostFragment = NavHostFragment.create(navGraphId);
final NavHostFragment navHostFragment = NavHostFragmentWithDefaultAnimations.create(navGraphId);
fragmentManager.beginTransaction()
.setReorderingAllowed(true)
.add(containerId, navHostFragment, fragmentTag)

View File

@ -288,6 +288,12 @@ public final class Utils {
return outValue.data;
}
public static int getAttrValue(@NonNull final Context context, final int attr) {
final TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(attr, outValue, true);
return outValue.data;
}
public static void transparentStatusBar(final Activity activity,
final boolean enable,
final boolean fullscreen) {

View File

@ -65,6 +65,7 @@ public class IgErrorsInterceptor implements Interceptor {
if (body == null) return;
try {
final String bodyString = body.string();
Log.d(TAG, "checkError: " + bodyString);
final JSONObject jsonObject = new JSONObject(bodyString);
String message = jsonObject.optString("message");
if (!TextUtils.isEmpty(message)) {

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@android:integer/config_mediumAnimTime"
android:fromXDelta="50%p"
android:toXDelta="0" />
<alpha
android:duration="@android:integer/config_mediumAnimTime"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>

View File

@ -1,10 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:fromXDelta="100%"
android:fromYDelta="0%"
android:toXDelta="0%"
android:toYDelta="0%" />
</set>
android:toXDelta="0%" />

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@android:integer/config_mediumAnimTime"
android:fromXDelta="0"
android:toXDelta="-50%p" />
<alpha
android:duration="@android:integer/config_mediumAnimTime"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>

View File

@ -1,10 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:fromXDelta="0%"
android:fromYDelta="0%"
android:toXDelta="100%"
android:toYDelta="0%" />
</set>
android:toXDelta="100%" />

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M3,17.46v3.04c0,0.28 0.22,0.5 0.5,0.5h3.04c0.13,0 0.26,-0.05 0.35,-0.15L17.81,9.94l-3.75,-3.75L3.15,17.1c-0.1,0.1 -0.15,0.22 -0.15,0.36zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
</vector>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/black" />
<solid android:color="@android:color/transparent" />
</shape>

View File

@ -1,48 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black_a80">
android:layout_height="match_parent">
<awais.instagrabber.customviews.drawee.DraggableZoomableDraweeView
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<awais.instagrabber.customviews.drawee.ZoomableDraweeView
android:id="@+id/post_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:clickable="true"
android:focusable="true"
android:transitionName="post_image"
app:actualImageScaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_bg_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_barrier"
tools:background="@mipmap/ic_launcher"
tools:visibility="visible" />
tools:layout_height="400dp"
tools:visibility="gone" />
<include
android:id="@+id/video_post"
layout="@layout/layout_video_player_with_thumbnail"
android:visibility="gone" />
android:layout_width="match_parent"
android:layout_height="0dp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/bottom_bg_barrier"
app:layout_constraintTop_toBottomOf="@id/top_barrier"
tools:layout_height="400dp"
tools:visibility="visible" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/slider_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
tools:visibility="visible" />
<View
android:id="@+id/top_bg"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/black_a80"
app:layout_constraintBottom_toBottomOf="@id/profile_pic"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/bottom_bg_barrier"
app:layout_constraintTop_toBottomOf="@id/top_barrier"
tools:layout_height="400dp"
tools:visibility="gone" />
<!--<View-->
<!-- android:id="@+id/top_bg"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="0dp"-->
<!-- app:layout_constraintBottom_toBottomOf="@id/profile_pic"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent" />-->
<awais.instagrabber.customviews.ProfilePicView
android:id="@+id/profile_pic"
@ -50,12 +62,12 @@
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:transitionName="profile_pic"
app:layout_constraintBottom_toBottomOf="@id/top_bg"
app:layout_constraintBottom_toTopOf="@id/top_barrier"
app:layout_constraintEnd_toStartOf="@id/title"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bg"
app:layout_constraintTop_toTopOf="parent"
app:size="regular" />
<androidx.appcompat.widget.AppCompatTextView
@ -65,7 +77,6 @@
android:ellipsize="marquee"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
android:textColor="@color/white"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toTopOf="@id/subtitle"
app:layout_constraintEnd_toStartOf="@id/options"
@ -80,12 +91,12 @@
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
android:textColor="@color/white"
app:layout_constraintBottom_toBottomOf="@id/profile_pic"
app:layout_constraintEnd_toStartOf="@id/options"
app:layout_constraintStart_toStartOf="@id/title"
app:layout_constraintTop_toBottomOf="@id/title"
tools:text="Full name Full name Full name Full name Full name Full name Full name " />
tools:text="Full name Full name Full name Full name Full name Full name Full name "
tools:visibility="gone" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/options"
@ -94,19 +105,24 @@
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/top_bg"
app:layout_constraintBottom_toBottomOf="@id/profile_pic"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bg"
app:layout_constraintTop_toTopOf="@id/profile_pic"
app:srcCompat="@drawable/ic_more_vert_24"
app:tint="@color/white"
tools:visibility="visible" />
<androidx.constraintlayout.widget.Group
android:id="@+id/user_details_group"
<androidx.constraintlayout.widget.Barrier
android:id="@+id/top_barrier"
android:layout_width="0dp"
android:layout_height="0dp"
app:constraint_referenced_ids="top_bg, profile_pic,title,subtitle,options"
tools:visibility="visible" />
app:barrierAllowsGoneWidgets="true"
app:barrierDirection="bottom" />
<!--<androidx.constraintlayout.widget.Group-->
<!-- android:id="@+id/user_details_group"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="0dp"-->
<!-- app:constraint_referenced_ids="profile_pic,title,subtitle,options" />-->
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/media_counter"
@ -121,7 +137,7 @@
android:textColor="@android:color/white"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_bg"
app:layout_constraintTop_toBottomOf="@id/profile_pic"
tools:text="1/5"
tools:visibility="visible" />
@ -151,87 +167,43 @@
app:iconSize="16dp"
app:iconTint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_bg"
app:layout_constraintTop_toBottomOf="@id/profile_pic"
app:rippleColor="@color/grey_600"
tools:text="Location, Location, Location, Location, "
tools:visibility="visible" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@null"
app:layout_constraintBottom_toBottomOf="@id/bottom_bg_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible">
<!--<androidx.coordinatorlayout.widget.CoordinatorLayout-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="0dp"-->
<!-- android:background="@null"-->
<!-- app:layout_constraintBottom_toBottomOf="@id/bottom_bg_barrier"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- tools:visibility="gone">-->
<androidx.core.widget.NestedScrollView
android:id="@+id/caption_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/black_a80"
app:behavior_hideable="true"
app:behavior_peekHeight="100dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<ScrollView
android:id="@+id/bottom_scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<awais.instagrabber.customviews.RamboTextViewV2
android:id="@+id/caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@null"
android:clickable="true"
android:focusable="true"
android:padding="16dp"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
android:textColor="@color/white"
tools:text="Text text text" />
<!--<androidx.appcompat.widget.AppCompatTextView-->
<!-- android:id="@+id/editCaption"-->
<!-- <androidx.core.widget.NestedScrollView-->
<!-- android:id="@+id/caption_parent"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginStart="16dp"-->
<!-- android:layout_marginTop="8dp"-->
<!-- android:background="@null"-->
<!-- android:gravity="center_vertical"-->
<!-- android:text="@string/edit_caption"-->
<!-- android:textColor="?android:textColorSecondary"-->
<!-- android:textSize="16sp"-->
<!-- android:visibility="gone"-->
<!-- app:layout_constraintBottom_toTopOf="@id/translatedCaption"-->
<!-- app:layout_constraintTop_toBottomOf="@id/caption"-->
<!-- tools:visibility="visible" />-->
<!-- android:background="@color/black_a80"-->
<!-- app:behavior_hideable="true"-->
<!-- app:behavior_peekHeight="100dp"-->
<!-- app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">-->
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/translate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp"
android:text="@string/translate_caption"
android:textColor="@color/blue_600"
android:textSize="16sp"
android:visibility="visible" />
<!-- <ScrollView-->
<!-- android:id="@+id/bottom_scroll_view"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:background="@null">-->
<!--<awais.instagrabber.customviews.RamboTextViewV2-->
<!-- android:id="@+id/translatedCaption"-->
<!-- <LinearLayout-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:orientation="vertical">-->
<!-- <awais.instagrabber.customviews.RamboTextViewV2-->
<!-- android:id="@+id/caption"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_gravity="bottom"-->
@ -241,15 +213,59 @@
<!-- android:padding="16dp"-->
<!-- android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"-->
<!-- android:textColor="@color/white"-->
<!-- android:visibility="gone"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/translateTitle"-->
<!-- tools:text="Text text text"-->
<!-- tools:visibility="visible" />-->
</LinearLayout>
</ScrollView>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<!-- tools:text="Text text text" />-->
<!-- &lt;!&ndash;<androidx.appcompat.widget.AppCompatTextView&ndash;&gt;-->
<!-- &lt;!&ndash; android:id="@+id/editCaption"&ndash;&gt;-->
<!-- &lt;!&ndash; android:layout_width="match_parent"&ndash;&gt;-->
<!-- &lt;!&ndash; android:layout_height="wrap_content"&ndash;&gt;-->
<!-- &lt;!&ndash; android:layout_marginStart="16dp"&ndash;&gt;-->
<!-- &lt;!&ndash; android:layout_marginTop="8dp"&ndash;&gt;-->
<!-- &lt;!&ndash; android:background="@null"&ndash;&gt;-->
<!-- &lt;!&ndash; android:gravity="center_vertical"&ndash;&gt;-->
<!-- &lt;!&ndash; android:text="@string/edit_caption"&ndash;&gt;-->
<!-- &lt;!&ndash; android:textColor="?android:textColorSecondary"&ndash;&gt;-->
<!-- &lt;!&ndash; android:textSize="16sp"&ndash;&gt;-->
<!-- &lt;!&ndash; android:visibility="gone"&ndash;&gt;-->
<!-- &lt;!&ndash; app:layout_constraintBottom_toTopOf="@id/translatedCaption"&ndash;&gt;-->
<!-- &lt;!&ndash; app:layout_constraintTop_toBottomOf="@id/caption"&ndash;&gt;-->
<!-- &lt;!&ndash; tools:visibility="visible" />&ndash;&gt;-->
<!-- <androidx.appcompat.widget.AppCompatTextView-->
<!-- android:id="@+id/translate"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:background="@null"-->
<!-- android:gravity="center_vertical"-->
<!-- android:paddingStart="16dp"-->
<!-- android:paddingTop="8dp"-->
<!-- android:paddingEnd="16dp"-->
<!-- android:paddingBottom="8dp"-->
<!-- android:text="@string/translate_caption"-->
<!-- android:textColor="@color/blue_600"-->
<!-- android:textSize="16sp"-->
<!-- android:visibility="visible" />-->
<!-- &lt;!&ndash;<awais.instagrabber.customviews.RamboTextViewV2&ndash;&gt;-->
<!-- &lt;!&ndash; android:id="@+id/translatedCaption"&ndash;&gt;-->
<!-- &lt;!&ndash; android:layout_width="match_parent"&ndash;&gt;-->
<!-- &lt;!&ndash; android:layout_height="wrap_content"&ndash;&gt;-->
<!-- &lt;!&ndash; android:layout_gravity="bottom"&ndash;&gt;-->
<!-- &lt;!&ndash; android:background="@null"&ndash;&gt;-->
<!-- &lt;!&ndash; android:clickable="true"&ndash;&gt;-->
<!-- &lt;!&ndash; android:focusable="true"&ndash;&gt;-->
<!-- &lt;!&ndash; android:padding="16dp"&ndash;&gt;-->
<!-- &lt;!&ndash; android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"&ndash;&gt;-->
<!-- &lt;!&ndash; android:textColor="@color/white"&ndash;&gt;-->
<!-- &lt;!&ndash; android:visibility="gone"&ndash;&gt;-->
<!-- &lt;!&ndash; app:layout_constraintBottom_toBottomOf="parent"&ndash;&gt;-->
<!-- &lt;!&ndash; app:layout_constraintTop_toBottomOf="@id/translateTitle"&ndash;&gt;-->
<!-- &lt;!&ndash; tools:text="Text text text"&ndash;&gt;-->
<!-- &lt;!&ndash; tools:visibility="visible" />&ndash;&gt;-->
<!-- </LinearLayout>-->
<!-- </ScrollView>-->
<!-- </androidx.core.widget.NestedScrollView>-->
<!--</androidx.coordinatorlayout.widget.CoordinatorLayout>-->
<!--<include-->
<!-- android:id="@+id/player_controls"-->
@ -266,7 +282,6 @@
android:id="@+id/bottom_bg"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/black_a80"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@ -285,7 +300,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:textColor="@color/white"
app:layout_constraintBottom_toTopOf="@id/counts_barrier"
app:layout_constraintEnd_toStartOf="@id/comments_count"
app:layout_constraintHorizontal_bias="0"
@ -299,7 +313,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:textColor="@color/white"
app:layout_constraintBottom_toTopOf="@id/counts_barrier"
app:layout_constraintEnd_toStartOf="@id/views_count"
app:layout_constraintHorizontal_bias="0"
@ -313,7 +326,6 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="8dp"
android:textColor="@color/white"
app:layout_constraintBottom_toTopOf="@id/counts_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/comments_count"
@ -334,7 +346,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:textColor="@color/white"
app:layout_constraintBottom_toBottomOf="@id/buttons_barrier"
app:layout_constraintTop_toBottomOf="@id/counts_barrier"
tools:text="2020-11-07 11:18:55"
@ -348,23 +359,21 @@
app:barrierDirection="bottom"
app:constraint_referenced_ids="date" />
<com.google.android.material.button.MaterialButton
android:id="@+id/caption_toggle"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="0dp"
android:layout_height="48dp"
android:visibility="visible"
app:icon="@drawable/ic_notes_24"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:iconSize="24dp"
app:iconTint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/like"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/buttons_barrier"
app:rippleColor="@color/grey_300"
tools:visibility="visible" />
<!--<com.google.android.material.button.MaterialButton-->
<!-- android:id="@+id/caption_toggle"-->
<!-- style="@style/Widget.MaterialComponents.Button.TextButton"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="48dp"-->
<!-- android:visibility="visible"-->
<!-- app:icon="@drawable/ic_notes_24"-->
<!-- app:iconGravity="textStart"-->
<!-- app:iconPadding="0dp"-->
<!-- app:iconSize="24dp"-->
<!-- app:layout_constraintBottom_toTopOf="@id/caption_barrier"-->
<!-- app:layout_constraintEnd_toStartOf="@id/like"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/buttons_barrier"-->
<!-- tools:visibility="visible" />-->
<com.google.android.material.button.MaterialButton
android:id="@+id/like"
@ -376,12 +385,10 @@
app:iconGravity="textStart"
app:iconPadding="0dp"
app:iconSize="24dp"
app:iconTint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@id/caption_barrier"
app:layout_constraintEnd_toStartOf="@id/comment"
app:layout_constraintStart_toEndOf="@id/caption_toggle"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/buttons_barrier"
app:rippleColor="@color/grey_300"
tools:visibility="visible" />
<com.google.android.material.button.MaterialButton
@ -394,12 +401,10 @@
app:iconGravity="textStart"
app:iconPadding="0dp"
app:iconSize="24dp"
app:iconTint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@id/caption_barrier"
app:layout_constraintEnd_toStartOf="@id/save"
app:layout_constraintStart_toEndOf="@id/like"
app:layout_constraintTop_toBottomOf="@id/buttons_barrier"
app:rippleColor="@color/grey_300"
tools:visibility="visible" />
<!--<com.google.android.material.button.MaterialButton-->
@ -430,12 +435,10 @@
app:iconGravity="textStart"
app:iconPadding="0dp"
app:iconSize="24dp"
app:iconTint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@id/caption_barrier"
app:layout_constraintEnd_toStartOf="@id/share"
app:layout_constraintStart_toEndOf="@id/comment"
app:layout_constraintTop_toBottomOf="@id/buttons_barrier"
app:rippleColor="@color/grey_300"
tools:visibility="visible" />
<com.google.android.material.button.MaterialButton
@ -448,12 +451,10 @@
app:iconGravity="textStart"
app:iconPadding="0dp"
app:iconSize="24dp"
app:iconTint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@id/caption_barrier"
app:layout_constraintEnd_toStartOf="@id/download"
app:layout_constraintStart_toEndOf="@id/save"
app:layout_constraintTop_toBottomOf="@id/buttons_barrier"
app:rippleColor="@color/grey_300"
tools:visibility="visible" />
<com.google.android.material.button.MaterialButton
@ -466,12 +467,48 @@
app:iconGravity="textStart"
app:iconPadding="0dp"
app:iconSize="24dp"
app:iconTint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@id/caption_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/share"
app:layout_constraintTop_toBottomOf="@id/buttons_barrier"
app:rippleColor="@color/grey_300"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.Barrier
android:id="@+id/caption_barrier"
android:layout_width="0dp"
android:layout_height="0dp"
app:barrierAllowsGoneWidgets="true"
app:barrierDirection="bottom"
app:constraint_referenced_ids="like,comment,save,share,download" />
<awais.instagrabber.customviews.RamboTextViewV2
android:id="@+id/caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@null"
android:clickable="true"
android:focusable="true"
android:padding="8dp"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
app:layout_constraintBottom_toTopOf="@id/translate"
app:layout_constraintTop_toBottomOf="@id/caption_barrier"
tools:text="Text text text Text text text Text text text Text text text Text text text"
tools:visibility="gone" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/translate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:gravity="center_vertical"
android:padding="8dp"
android:text="@string/translate_caption"
android:textColor="@color/blue_600"
android:textSize="16sp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/caption" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

View File

@ -1,40 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface">
android:background="?attr/colorSurface"
app:layoutDescription="@xml/header_list_scene">
<!--<com.google.android.material.appbar.AppBarLayout-->
<!-- android:id="@+id/stories_container"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content">-->
<!-- <com.google.android.material.appbar.CollapsingToolbarLayout-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- app:layout_scrollFlags="scroll|snap">-->
<!--<androidx.recyclerview.widget.RecyclerView-->
<!-- android:id="@+id/feed_stories_recycler_view"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:clipToPadding="false" />-->
<!-- </com.google.android.material.appbar.CollapsingToolbarLayout>-->
<!--</com.google.android.material.appbar.AppBarLayout>-->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/toolbarColor"
android:clipToPadding="false"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="@id/feed_swipe_refresh_layout"
app:layout_constraintTop_toTopOf="parent"
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_highlight" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/feed_swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:layout_height="0dp"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/header">
<awais.instagrabber.customviews.PostsRecyclerView
android:id="@+id/feed_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
tools:listitem="@layout/item_feed_photo" />
android:paddingBottom="?attr/actionBarSize"
tools:listitem="@layout/item_feed_grid" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>

View File

@ -1,20 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface">
android:background="?attr/colorSurface"
app:layoutDescription="@xml/header_list_scene">
<include
android:id="@+id/header"
layout="@layout/layout_hashtag_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/swipe_refresh_layout"
app:layout_constraintTop_toTopOf="parent" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:layout_height="0dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/header">
<awais.instagrabber.customviews.PostsRecyclerView
android:id="@+id/posts"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false" />
android:clipToPadding="false"
android:paddingBottom="?attr/actionBarSize" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>

View File

@ -1,20 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface">
android:background="?attr/colorSurface"
app:layoutDescription="@xml/header_list_scene">
<include
android:id="@+id/header"
layout="@layout/layout_location_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/swipe_refresh_layout"
app:layout_constraintTop_toTopOf="parent" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:layout_height="0dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/header">
<awais.instagrabber.customviews.PostsRecyclerView
android:id="@+id/posts"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false" />
android:clipToPadding="false"
android:paddingBottom="?attr/actionBarSize" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>

View File

@ -1,39 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface">
android:background="?attr/colorSurface"
app:layoutDescription="@xml/header_list_scene">
<!--<com.google.android.material.appbar.AppBarLayout-->
<!-- android:id="@+id/appBarLayout"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:background="?attr/colorSurface"-->
<!-- app:elevation="0dp"-->
<!-- app:layout_scrollFlags="scroll">-->
<!-- <com.google.android.material.appbar.CollapsingToolbarLayout-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- app:layout_scrollFlags="scroll">-->
<!-- <include layout="@layout/layout_profile_details" />-->
<!-- </com.google.android.material.appbar.CollapsingToolbarLayout>-->
<!--</com.google.android.material.appbar.AppBarLayout>-->
<include
android:id="@+id/header"
layout="@layout/layout_profile_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/swipe_refresh_layout"
app:layout_constraintTop_toTopOf="parent" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:layout_height="0dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/header">
<awais.instagrabber.customviews.PostsRecyclerView
android:id="@+id/posts_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="?attr/actionBarSize"
tools:listitem="@layout/item_feed_photo" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
@ -62,4 +57,4 @@
android:text="@string/priv_acc"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>

View File

@ -20,6 +20,7 @@
android:gravity="center"
android:maxLines="1"
android:padding="2dp"
android:scrollbars="none"
android:singleLine="true"
android:textColor="?attr/colorOnPrimarySurface"
android:textStyle="bold"

View File

@ -4,8 +4,6 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- android:padding="8dp"
android:background="@color/black_a80"-->
<View
android:layout_width="0dp"
@ -14,18 +12,13 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!--<androidx.constraintlayout.widget.Barrier-->
<!-- android:id="@+id/top_barrier"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="0dp"-->
<!-- app:barrierDirection="top" />-->
app:layout_constraintTop_toTopOf="@id/exo_position" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/exo_position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:textColor="@color/white"
app:layout_constraintBottom_toBottomOf="@id/exo_progress"
app:layout_constraintEnd_toStartOf="@id/exo_progress"
@ -33,24 +26,6 @@
app:layout_constraintTop_toTopOf="@id/exo_progress"
tools:text="0:00" />
<!--<com.google.android.material.slider.Slider-->
<!-- android:id="@+id/timeline"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:contentDescription="@string/player_timeline_desc"-->
<!-- android:enabled="false"-->
<!-- android:value="0"-->
<!-- android:valueFrom="0.0"-->
<!-- android:valueTo="1.0"-->
<!-- app:labelStyle="@style/Widget.MaterialComponents.Tooltip.ExoPlayer"-->
<!-- app:layout_constraintBottom_toTopOf="@id/play_pause"-->
<!-- app:layout_constraintEnd_toStartOf="@id/to_time"-->
<!-- app:layout_constraintStart_toEndOf="@id/from_time"-->
<!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- app:thumbColor="@color/white"-->
<!-- app:trackColorActive="@color/white"-->
<!-- app:trackColorInactive="@color/grey_800" />-->
<com.google.android.exoplayer2.ui.DefaultTimeBar
android:id="@+id/exo_progress"
android:layout_width="0dp"
@ -65,6 +40,7 @@
android:id="@+id/exo_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:textColor="@color/white"
app:layout_constraintBottom_toBottomOf="@id/exo_progress"
app:layout_constraintEnd_toEndOf="parent"
@ -87,28 +63,23 @@
app:icon="@drawable/ic_replay_5_24_states"
app:iconSize="24dp"
app:iconTint="@color/white"
app:layout_constraintBottom_toTopOf="@id/bottom_barrier"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/exo_play_pause"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/progress_barrier"
tools:enabled="false"
tools:visibility="visible" />
<!--
style="@style/Widget.App.MaterialButton.IconOnly.BorderlessRipple"
app:icon="@drawable/ic_play_states"
app:iconSize="24dp"
app:iconTint="@color/white"
-->
<androidx.appcompat.widget.AppCompatImageView
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/exo_play_pause"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:background="@drawable/background_grey_ripple"
android:contentDescription="@string/exo_controls_play_description"
android:padding="@dimen/exo_icon_padding"
android:padding="8dp"
android:scaleType="fitCenter"
android:src="@drawable/exo_styled_controls_play"
app:layout_constraintBottom_toTopOf="@id/bottom_barrier"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/exo_ffwd_with_amount"
app:layout_constraintStart_toEndOf="@id/exo_rew_with_amount"
app:layout_constraintTop_toBottomOf="@id/progress_barrier"
@ -123,7 +94,7 @@
app:icon="@drawable/ic_forward_5_24_states"
app:iconSize="24dp"
app:iconTint="@color/white"
app:layout_constraintBottom_toTopOf="@id/bottom_barrier"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/mute"
app:layout_constraintStart_toEndOf="@id/exo_play_pause"
app:layout_constraintTop_toBottomOf="@id/progress_barrier"
@ -138,7 +109,7 @@
app:icon="@drawable/ic_volume_off_24_states"
app:iconSize="24dp"
app:iconTint="@color/white"
app:layout_constraintBottom_toTopOf="@id/bottom_barrier"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/exo_settings"
app:layout_constraintStart_toEndOf="@id/exo_ffwd_with_amount"
app:layout_constraintTop_toBottomOf="@id/progress_barrier"
@ -153,32 +124,10 @@
app:icon="@drawable/exo_ic_settings"
app:iconSize="24dp"
app:iconTint="@color/white"
app:layout_constraintBottom_toTopOf="@id/bottom_barrier"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/mute"
app:layout_constraintTop_toBottomOf="@id/progress_barrier"
tools:enabled="false"
tools:visibility="visible" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/bottom_barrier"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="horizontal"
app:layout_constraintGuide_end="200dp" />
<!--<com.google.android.material.button.MaterialButton-->
<!-- android:id="@+id/speed"-->
<!-- style="@style/Widget.App.MaterialButton.IconOnly.BorderlessRipple"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/one_x"-->
<!-- android:textAllCaps="false"-->
<!-- android:textColor="@drawable/speed_text_color_states"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toEndOf="@id/mute"-->
<!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- tools:enabled="false"-->
<!-- tools:visibility="visible" />-->
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -2,10 +2,9 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tagInfoContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize"
android:background="?toolbarColor"
android:padding="@dimen/profile_info_container_bottom_space">
<awais.instagrabber.customviews.CircularImageView

View File

@ -2,11 +2,10 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/locInfoContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize"
android:animateLayoutChanges="true"
android:background="?toolbarColor"
android:padding="8dp">
<awais.instagrabber.customviews.CircularImageView
@ -20,20 +19,20 @@
app:layout_constraintTop_toTopOf="parent"
tools:background="@mipmap/ic_launcher" />
<!-- <androidx.appcompat.widget.AppCompatTextView-->
<!-- android:id="@+id/mainLocPostCount"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="0dp"-->
<!-- android:gravity="center_vertical"-->
<!-- android:maxLines="1"-->
<!-- android:paddingStart="12dp"-->
<!-- android:paddingEnd="12dp"-->
<!-- android:textAppearance="@style/TextAppearance.AppCompat"-->
<!-- app:layout_constraintBottom_toTopOf="@id/btnMap"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toEndOf="@id/mainLocationImage"-->
<!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- tools:text="35 Posts" />-->
<!-- <androidx.appcompat.widget.AppCompatTextView-->
<!-- android:id="@+id/mainLocPostCount"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="0dp"-->
<!-- android:gravity="center_vertical"-->
<!-- android:maxLines="1"-->
<!-- android:paddingStart="12dp"-->
<!-- android:paddingEnd="12dp"-->
<!-- android:textAppearance="@style/TextAppearance.AppCompat"-->
<!-- app:layout_constraintBottom_toTopOf="@id/btnMap"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toEndOf="@id/mainLocationImage"-->
<!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- tools:text="35 Posts" />-->
<com.google.android.material.chip.Chip
android:id="@+id/btnMap"
@ -44,8 +43,8 @@
app:chipBackgroundColor="@null"
app:chipIcon="@drawable/ic_outline_map_24"
app:chipIconTint="@color/green_500"
app:layout_constraintTop_toTopOf="@id/mainLocationImage"
app:layout_constraintStart_toEndOf="@id/mainLocationImage"
app:layout_constraintTop_toTopOf="@id/mainLocationImage"
app:rippleColor="@color/grey_500"
tools:visibility="visible" />
@ -86,8 +85,8 @@
android:id="@+id/locationBiography"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="8dp"
android:background="?android:selectableItemBackground"
android:padding="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -2,10 +2,9 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/infoContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize">
android:background="?toolbarColor">
<awais.instagrabber.customviews.CircularImageView
android:id="@+id/mainProfileImage"
@ -326,9 +325,9 @@
<androidx.constraintlayout.widget.Barrier
android:id="@+id/highlights_barrier"
android:layout_width="wrap_content"
app:constraint_referenced_ids="mainPostCount, mainFollowers, mainFollowing"
android:layout_height="wrap_content"
app:barrierDirection="bottom" />
app:barrierDirection="bottom"
app:constraint_referenced_ids="mainPostCount, mainFollowers, mainFollowing" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/highlightsList"

View File

@ -25,10 +25,6 @@
app:srcCompat="@drawable/ic_video_24" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.exoplayer2.ui.StyledPlayerView
android:id="@+id/playerView"
android:layout_width="match_parent"
@ -37,16 +33,6 @@
app:animation_enabled="false"
app:controller_layout_id="@layout/layout_exo_custom_controls"
app:resize_mode="fit"
app:show_timeout="1500"
app:show_timeout="2000"
app:use_controller="true" />
<!--<com.google.android.exoplayer2.ui.StyledPlayerControlView-->
<!-- android:id="@+id/controls"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- app:controller_layout_id="@layout/layout_exo_custom_controls"-->
<!-- app:show_fastforward_button="false"-->
<!-- app:show_rewind_button="false"-->
<!-- app:show_timeout="3000" />-->
</FrameLayout>
</ViewSwitcher>

View File

@ -4,15 +4,15 @@
<item
android:id="@+id/edit"
android:icon="@android:drawable/ic_menu_edit"
android:icon="@drawable/ic_round_edit_24"
android:title="@string/edit_collection"
app:showAsAction="always" />
app:showAsAction="ifRoom" />
<item
android:id="@+id/delete"
android:icon="@android:drawable/ic_menu_delete"
android:icon="@drawable/ic_delete"
android:title="@string/delete_collection"
app:showAsAction="always" />
app:showAsAction="ifRoom" />
<item
android:id="@+id/layout"

View File

@ -100,6 +100,18 @@
android:id="@+id/action_global_search"
app:destination="@id/searchFragment" />
<action
android:id="@+id/action_global_post_view"
app:destination="@id/postViewFragment">
<argument
android:name="media"
app:argType="awais.instagrabber.repositories.responses.Media"
app:nullable="false" />
<argument
android:name="position"
app:argType="integer" />
</action>
<fragment
android:id="@+id/directMessagesInboxFragment"
android:name="awais.instagrabber.fragments.directmessages.DirectMessageInboxFragment"
@ -191,10 +203,14 @@
android:id="@+id/action_pending_inbox_to_thread"
app:destination="@id/directMessagesThreadFragment" />
</fragment>
<fragment
android:id="@+id/searchFragment"
android:name="awais.instagrabber.fragments.search.SearchFragment"
android:label="@string/search"
tools:layout="@layout/fragment_search" />
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment"
android:label="Post"
tools:layout="@layout/dialog_post_view" />
</navigation>

View File

@ -99,6 +99,18 @@
android:id="@+id/action_global_search"
app:destination="@id/searchFragment" />
<action
android:id="@+id/action_global_post_view"
app:destination="@id/postViewFragment">
<argument
android:name="media"
app:argType="awais.instagrabber.repositories.responses.Media"
app:nullable="false" />
<argument
android:name="position"
app:argType="integer" />
</action>
<fragment
android:id="@+id/discoverFragment"
android:name="awais.instagrabber.fragments.main.DiscoverFragment"
@ -129,4 +141,9 @@
android:name="awais.instagrabber.fragments.search.SearchFragment"
android:label="@string/search"
tools:layout="@layout/fragment_search" />
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment"
android:label="Post"
tools:layout="@layout/dialog_post_view" />
</navigation>

View File

@ -110,6 +110,18 @@
android:id="@+id/action_global_search"
app:destination="@id/searchFragment" />
<action
android:id="@+id/action_global_post_view"
app:destination="@id/postViewFragment">
<argument
android:name="media"
app:argType="awais.instagrabber.repositories.responses.Media"
app:nullable="false" />
<argument
android:name="position"
app:argType="integer" />
</action>
<fragment
android:id="@+id/feedFragment"
android:name="awais.instagrabber.fragments.main.FeedFragment"
@ -133,4 +145,9 @@
android:name="awais.instagrabber.fragments.search.SearchFragment"
android:label="@string/search"
tools:layout="@layout/fragment_search" />
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment"
android:label="Post"
tools:layout="@layout/dialog_post_view" />
</navigation>

View File

@ -69,6 +69,18 @@
android:id="@+id/action_global_search"
app:destination="@id/searchFragment" />
<action
android:id="@+id/action_global_post_view"
app:destination="@id/postViewFragment">
<argument
android:name="media"
app:argType="awais.instagrabber.repositories.responses.Media"
app:nullable="false" />
<argument
android:name="position"
app:argType="integer" />
</action>
<fragment
android:id="@+id/hashTagFragment"
android:name="awais.instagrabber.fragments.HashTagFragment"
@ -104,4 +116,9 @@
app:argType="string"
app:nullable="false" />
</action>
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment"
android:label="Post"
tools:layout="@layout/dialog_post_view" />
</navigation>

View File

@ -70,6 +70,18 @@
android:id="@+id/action_global_search"
app:destination="@id/searchFragment" />
<action
android:id="@+id/action_global_post_view"
app:destination="@id/postViewFragment">
<argument
android:name="media"
app:argType="awais.instagrabber.repositories.responses.Media"
app:nullable="false" />
<argument
android:name="position"
app:argType="integer" />
</action>
<fragment
android:id="@+id/locationFragment"
android:name="awais.instagrabber.fragments.LocationFragment"
@ -103,4 +115,9 @@
android:name="awais.instagrabber.fragments.search.SearchFragment"
android:label="@string/search"
tools:layout="@layout/fragment_search" />
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment"
android:label="Post"
tools:layout="@layout/dialog_post_view" />
</navigation>

View File

@ -72,6 +72,18 @@
app:argType="boolean" />
</action>
<action
android:id="@+id/action_global_post_view"
app:destination="@id/postViewFragment">
<argument
android:name="media"
app:argType="awais.instagrabber.repositories.responses.Media"
app:nullable="false" />
<argument
android:name="position"
app:argType="integer" />
</action>
<fragment
android:id="@+id/storyViewerFragment"
android:name="awais.instagrabber.fragments.StoryViewerFragment"
@ -100,4 +112,9 @@
android:id="@+id/action_notifications_to_story"
app:destination="@id/storyViewerFragment" />
</fragment>
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment"
android:label="Post"
tools:layout="@layout/dialog_post_view" />
</navigation>

View File

@ -86,6 +86,18 @@
app:destination="@id/storyViewerFragment" />
</action>
<action
android:id="@+id/action_global_post_view"
app:destination="@id/postViewFragment">
<argument
android:name="media"
app:argType="awais.instagrabber.repositories.responses.Media"
app:nullable="false" />
<argument
android:name="position"
app:argType="integer" />
</action>
<fragment
android:id="@+id/notificationsViewer"
android:name="awais.instagrabber.fragments.NotificationsViewerFragment"
@ -93,9 +105,9 @@
tools:layout="@layout/fragment_notifications_viewer">
<argument
android:name="type"
android:defaultValue="notif"
app:argType="string"
app:nullable="false"
android:defaultValue="notif"/>
app:nullable="false" />
<argument
android:name="targetId"
android:defaultValue="0L"
@ -197,4 +209,9 @@
android:name="awais.instagrabber.fragments.search.SearchFragment"
android:label="@string/search"
tools:layout="@layout/fragment_search" />
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment"
android:label="Post"
tools:layout="@layout/dialog_post_view" />
</navigation>

View File

@ -64,15 +64,27 @@
app:nullable="false" />
</action>
<action
android:id="@+id/action_global_post_view"
app:destination="@id/postViewFragment">
<argument
android:name="media"
app:argType="awais.instagrabber.repositories.responses.Media"
app:nullable="false" />
<argument
android:name="position"
app:argType="integer" />
</action>
<fragment
android:id="@+id/savedCollectionsFragment"
android:name="awais.instagrabber.fragments.SavedCollectionsFragment"
android:label="@string/saved"
tools:layout="@layout/fragment_saved_collections" >
tools:layout="@layout/fragment_saved_collections">
<argument
android:name="isSaving"
app:argType="boolean"
android:defaultValue="false" />
android:defaultValue="false"
app:argType="boolean" />
<action
android:id="@+id/action_savedCollectionsFragment_to_collectionPostsFragment"
app:destination="@id/collectionPostsFragment" />
@ -93,4 +105,9 @@
android:name="backgroundColor"
app:argType="integer" />
</fragment>
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewV2Fragment"
android:label="Post"
tools:layout="@layout/dialog_post_view" />
</navigation>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<drawable name="exo_styled_controls_play">@drawable/ic_play_arrow_24</drawable>
<drawable name="exo_styled_controls_pause">@drawable/ic_pause_24</drawable>
</resources>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/header"
android:layout_width="0dp"
android:layout_height="wrap_content"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/header"
android:layout_width="0dp"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toTopOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent" />
</ConstraintSet>
<Transition
android:id="@+id/transition"
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start">
<OnSwipe
motion:dragDirection="dragUp"
motion:onTouchUp="stop"
motion:touchAnchorId="@+id/header"
motion:touchAnchorSide="bottom" />
</Transition>
</MotionScene>