From 94aba5f3a02fc695e56e5b0a9097aa66132acb9d Mon Sep 17 00:00:00 2001 From: tom79 Date: Mon, 22 Apr 2019 14:32:07 +0200 Subject: [PATCH] Drag to move timelines --- .../mastodon/drawers/ReorderTabAdapter.java | 241 ++++++++++++++++++ .../fragments/DisplayReorderTabFragment.java | 86 +++++++ .../ItemTouchHelperAdapter.java | 59 +++++ .../ItemTouchHelperViewHolder.java | 42 +++ .../itemtouchhelper/OnStartDragListener.java | 34 +++ .../SimpleItemTouchHelperCallback.java | 124 +++++++++ app/src/main/res/drawable/ic_drag_handle.xml | 9 + .../main/res/drawable/ic_list_timeline.xml | 9 + .../res/drawable/ic_make_tab_unvisible.xml | 9 + .../main/res/drawable/ic_make_tab_visible.xml | 9 + app/src/main/res/drawable/ic_tag_timeline.xml | 9 + app/src/main/res/layout/drawer_reorder.xml | 60 +++++ .../main/res/layout/fragment_reorder_tabs.xml | 32 +++ app/src/main/res/values/strings.xml | 3 + 14 files changed, 726 insertions(+) create mode 100644 app/src/main/java/fr/gouv/etalab/mastodon/drawers/ReorderTabAdapter.java create mode 100644 app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayReorderTabFragment.java create mode 100644 app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/ItemTouchHelperAdapter.java create mode 100644 app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/ItemTouchHelperViewHolder.java create mode 100644 app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/OnStartDragListener.java create mode 100644 app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/SimpleItemTouchHelperCallback.java create mode 100644 app/src/main/res/drawable/ic_drag_handle.xml create mode 100644 app/src/main/res/drawable/ic_list_timeline.xml create mode 100644 app/src/main/res/drawable/ic_make_tab_unvisible.xml create mode 100644 app/src/main/res/drawable/ic_make_tab_visible.xml create mode 100644 app/src/main/res/drawable/ic_tag_timeline.xml create mode 100644 app/src/main/res/layout/drawer_reorder.xml create mode 100644 app/src/main/res/layout/fragment_reorder_tabs.xml diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/ReorderTabAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/ReorderTabAdapter.java new file mode 100644 index 000000000..83b5d435d --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/ReorderTabAdapter.java @@ -0,0 +1,241 @@ +package fr.gouv.etalab.mastodon.drawers; +/* + * Copyright (C) 2015 Paul Burke + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import android.content.Context; +import android.content.SharedPreferences; +import android.database.sqlite.SQLiteDatabase; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.support.v4.content.ContextCompat; +import android.support.v4.view.MotionEventCompat; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import fr.gouv.etalab.mastodon.R; +import fr.gouv.etalab.mastodon.client.Entities.ManageTimelines; +import fr.gouv.etalab.mastodon.client.Entities.RemoteInstance; +import fr.gouv.etalab.mastodon.helper.Helper; +import fr.gouv.etalab.mastodon.helper.itemtouchhelper.ItemTouchHelperAdapter; +import fr.gouv.etalab.mastodon.helper.itemtouchhelper.ItemTouchHelperViewHolder; +import fr.gouv.etalab.mastodon.helper.itemtouchhelper.OnStartDragListener; +import fr.gouv.etalab.mastodon.sqlite.InstancesDAO; +import fr.gouv.etalab.mastodon.sqlite.Sqlite; +import fr.gouv.etalab.mastodon.sqlite.TimelinesDAO; + +import static fr.gouv.etalab.mastodon.helper.Helper.THEME_LIGHT; + + +/** + * Simple RecyclerView.Adapter that implements {@link ItemTouchHelperAdapter} to respond to move and + * dismiss events from a {@link android.support.v7.widget.helper.ItemTouchHelper}. + * + * @author Paul Burke (ipaulpro) + */ +public class ReorderTabAdapter extends RecyclerView.Adapter implements ItemTouchHelperAdapter { + + private List mItems; + + private final OnStartDragListener mDragStartListener; + + private Context context; + private SharedPreferences sharedpreferences; + public ReorderTabAdapter(Context context, List manageTimelines, OnStartDragListener dragStartListener) { + this. mDragStartListener = dragStartListener; + this.mItems = manageTimelines; + this.context = context; + sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + } + + @NotNull + @Override + public ItemViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.drawer_reorder, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NotNull final ItemViewHolder holder, int position) { + + + int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); + ManageTimelines tl = mItems.get(position); + switch (tl.getType()){ + case HOME: + holder.iconView.setImageResource(R.drawable.ic_home); + holder.textView.setText(context.getString(R.string.home_menu)); + break; + case NOTIFICATION: + holder.iconView.setImageResource(R.drawable.ic_notifications); + holder.textView.setText(context.getString(R.string.notifications)); + break; + case DIRECT: + holder.iconView.setImageResource(R.drawable.ic_direct_messages); + holder.textView.setText(context.getString(R.string.direct_message)); + break; + case LOCAL: + holder.iconView.setImageResource(R.drawable.ic_people); + holder.textView.setText(context.getString(R.string.local_menu)); + break; + case PUBLIC: + holder.iconView.setImageResource(R.drawable.ic_public); + holder.textView.setText(context.getString(R.string.global_menu)); + break; + case ART: + holder.iconView.setImageResource(R.drawable.ic_color_lens); + holder.textView.setText(context.getString(R.string.art_menu)); + break; + case PEERTUBE: + holder.iconView.setImageResource(R.drawable.ic_video_peertube); + holder.textView.setText(context.getString(R.string.peertube_menu)); + break; + case INSTANCE: + switch ( tl.getRemoteInstance().getType()){ + case "PEERTUBE": + holder.iconView.setImageResource(R.drawable.peertube_icon); + break; + case "MASTODON": + holder.iconView.setImageResource(R.drawable.mastodon_icon); + break; + case "PIXELFED": + holder.iconView.setImageResource(R.drawable.pixelfed); + break; + case "MISSKEY": + holder.iconView.setImageResource(R.drawable.misskey); + break; + } + holder.textView.setText( tl.getRemoteInstance().getHost()); + break; + case TAG: + holder.iconView.setImageResource(R.drawable.ic_tag_timeline); + if( tl.getTagTimeline().getDisplayname() != null) + holder.textView.setText( tl.getTagTimeline().getDisplayname()); + else + holder.textView.setText( tl.getTagTimeline().getName()); + break; + case LIST: + holder.iconView.setImageResource(R.drawable.ic_list); + holder.textView.setText( tl.getListTimeline().getTitle()); + break; + } + if( tl.getType() != ManageTimelines.Type.INSTANCE){ + if (theme == THEME_LIGHT) { + holder.iconView.setColorFilter(ContextCompat.getColor(context, R.color.action_light_header), PorterDuff.Mode.SRC_IN); + } else { + holder.iconView.setColorFilter(ContextCompat.getColor(context, R.color.dark_text), PorterDuff.Mode.SRC_IN); + } + } + + if (theme == THEME_LIGHT) { + holder.handleView.setColorFilter(ContextCompat.getColor(context, R.color.action_light_header), PorterDuff.Mode.SRC_IN); + holder.hideView.setColorFilter(ContextCompat.getColor(context, R.color.action_light_header), PorterDuff.Mode.SRC_IN); + } else { + holder.handleView.setColorFilter(ContextCompat.getColor(context, R.color.dark_text), PorterDuff.Mode.SRC_IN); + holder.hideView.setColorFilter(ContextCompat.getColor(context, R.color.dark_text), PorterDuff.Mode.SRC_IN); + } + + holder.hideView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + tl.setDisplayed(! tl.isDisplayed()); + if(tl.isDisplayed()){ + holder.handleView.setImageResource(R.drawable.ic_make_tab_unvisible); + }else{ + holder.handleView.setImageResource(R.drawable.ic_make_tab_visible); + } + SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + new TimelinesDAO(context, db).update(tl); + } + }); + + // Start a drag whenever the handle view it touched + holder.handleView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) { + mDragStartListener.onStartDrag(holder); + } + return false; + } + }); + } + + @Override + public void onItemDismiss(int position) { + mItems.remove(position); + notifyItemRemoved(position); + } + + @Override + public boolean onItemMove(int fromPosition, int toPosition) { + Collections.swap(mItems, fromPosition, toPosition); + notifyItemMoved(fromPosition, toPosition); + SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + for(ManageTimelines timelines: mItems){ + new TimelinesDAO(context, db).update(timelines); + } + return true; + } + + @Override + public int getItemCount() { + return mItems.size(); + } + + /** + * Simple example of a view holder that implements {@link ItemTouchHelperViewHolder} and has a + * "handle" view that initiates a drag event when touched. + */ + public class ItemViewHolder extends RecyclerView.ViewHolder implements + ItemTouchHelperViewHolder { + + final TextView textView; + final ImageView handleView; + final ImageView hideView; + final ImageView iconView; + + ItemViewHolder(View itemView) { + super(itemView); + textView = itemView.findViewById(R.id.text); + handleView = itemView.findViewById(R.id.handle); + iconView = itemView.findViewById(R.id.icon); + hideView = itemView.findViewById(R.id.hide); + } + + @Override + public void onItemSelected() { + int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); + itemView.setBackgroundColor(Color.LTGRAY); + } + + @Override + public void onItemClear() { + itemView.setBackgroundColor(0); + } + } +} diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayReorderTabFragment.java b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayReorderTabFragment.java new file mode 100644 index 000000000..c0c54a460 --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayReorderTabFragment.java @@ -0,0 +1,86 @@ +package fr.gouv.etalab.mastodon.fragments; +/* Copyright 2019 Thomas Schneider + * + * This file is a part of Mastalab + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Mastalab; if not, + * see . */ + +import android.content.Context; +import android.content.SharedPreferences; +import android.database.sqlite.SQLiteDatabase; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.Fragment; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import java.util.List; + +import fr.gouv.etalab.mastodon.R; +import fr.gouv.etalab.mastodon.client.Entities.ManageTimelines; +import fr.gouv.etalab.mastodon.drawers.ReorderTabAdapter; +import fr.gouv.etalab.mastodon.helper.Helper; +import fr.gouv.etalab.mastodon.helper.itemtouchhelper.OnStartDragListener; +import fr.gouv.etalab.mastodon.sqlite.Sqlite; +import fr.gouv.etalab.mastodon.sqlite.TimelinesDAO; + + +/** + * Created by Thomas on 31/03/2019. + * Fragment to display tags + */ +public class DisplayReorderTabFragment extends Fragment implements OnStartDragListener { + + + private Context context; + + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) { + + View rootView = inflater.inflate(R.layout.fragment_reorder_tabs, container, false); + context = getContext(); + + RecyclerView lv_reorder_tabs = rootView.findViewById(R.id.lv_reorder_tabs); + LinearLayoutManager mLayoutManager = new LinearLayoutManager(context); + lv_reorder_tabs.setLayoutManager(mLayoutManager); + + SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + List timelines = new TimelinesDAO(context, db).getAllTimelines(); + new ReorderTabAdapter(context, timelines, DisplayReorderTabFragment.this); + return rootView; + } + + + + @Override + public void onCreate(Bundle saveInstance) { + super.onCreate(saveInstance); + } + + + @Override + public void onAttach(Context context) { + super.onAttach(context); + this.context = context; + } + + + @Override + public void onStartDrag(RecyclerView.ViewHolder viewHolder) { + + } +} diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/ItemTouchHelperAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/ItemTouchHelperAdapter.java new file mode 100644 index 000000000..a386253e8 --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/ItemTouchHelperAdapter.java @@ -0,0 +1,59 @@ +package fr.gouv.etalab.mastodon.helper.itemtouchhelper; + +/* + * Copyright (C) 2015 Paul Burke + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.helper.ItemTouchHelper; + +/** + * Interface to listen for a move or dismissal event from a {@link ItemTouchHelper.Callback}. + * + * @author Paul Burke (ipaulpro) + */ +public interface ItemTouchHelperAdapter { + + /** + * Called when an item has been dragged far enough to trigger a move. This is called every time + * an item is shifted, and not at the end of a "drop" event.
+ *
+ * Implementations should call {@link RecyclerView.Adapter#notifyItemMoved(int, int)} after + * adjusting the underlying data to reflect this move. + * + * @param fromPosition The start position of the moved item. + * @param toPosition Then resolved position of the moved item. + * @return True if the item was moved to the new adapter position. + * + * @see RecyclerView#getAdapterPositionFor(RecyclerView.ViewHolder) + * @see RecyclerView.ViewHolder#getAdapterPosition() + */ + boolean onItemMove(int fromPosition, int toPosition); + + + /** + * Called when an item has been dismissed by a swipe.
+ *
+ * Implementations should call {@link RecyclerView.Adapter#notifyItemRemoved(int)} after + * adjusting the underlying data to reflect this removal. + * + * @param position The position of the item dismissed. + * + * @see RecyclerView#getAdapterPositionFor(RecyclerView.ViewHolder) + * @see RecyclerView.ViewHolder#getAdapterPosition() + */ + void onItemDismiss(int position); +} \ No newline at end of file diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/ItemTouchHelperViewHolder.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/ItemTouchHelperViewHolder.java new file mode 100644 index 000000000..335cb54f4 --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/ItemTouchHelperViewHolder.java @@ -0,0 +1,42 @@ +package fr.gouv.etalab.mastodon.helper.itemtouchhelper; + +/* + * Copyright (C) 2015 Paul Burke + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import android.support.v7.widget.helper.ItemTouchHelper; + +/** + * Interface to notify an item ViewHolder of relevant callbacks from {@link + * android.support.v7.widget.helper.ItemTouchHelper.Callback}. + * + * @author Paul Burke (ipaulpro) + */ +public interface ItemTouchHelperViewHolder { + + /** + * Called when the {@link ItemTouchHelper} first registers an item as being moved or swiped. + * Implementations should update the item view to indicate it's active state. + */ + void onItemSelected(); + + + /** + * Called when the {@link ItemTouchHelper} has completed the move or swipe, and the active item + * state should be cleared. + */ + void onItemClear(); +} \ No newline at end of file diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/OnStartDragListener.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/OnStartDragListener.java new file mode 100644 index 000000000..34943166d --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/OnStartDragListener.java @@ -0,0 +1,34 @@ +package fr.gouv.etalab.mastodon.helper.itemtouchhelper; + +/* + * Copyright (C) 2015 Paul Burke + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import android.support.v7.widget.RecyclerView; + +/** + * Listener for manual initiation of a drag. + */ +public interface OnStartDragListener { + + /** + * Called when a view is requesting a start of a drag. + * + * @param viewHolder The holder of the view to drag. + */ + void onStartDrag(RecyclerView.ViewHolder viewHolder); + +} diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/SimpleItemTouchHelperCallback.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/SimpleItemTouchHelperCallback.java new file mode 100644 index 000000000..1c93c115b --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/itemtouchhelper/SimpleItemTouchHelperCallback.java @@ -0,0 +1,124 @@ +package fr.gouv.etalab.mastodon.helper.itemtouchhelper; + +/* + * Copyright (C) 2015 Paul Burke + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import android.graphics.Canvas; +import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.helper.ItemTouchHelper; + +/** + * An implementation of {@link ItemTouchHelper.Callback} that enables basic drag & drop and + * swipe-to-dismiss. Drag events are automatically started by an item long-press.
+ *
+ * Expects the RecyclerView.Adapter to listen for {@link + * ItemTouchHelperAdapter} callbacks and the RecyclerView.ViewHolder to implement + * {@link ItemTouchHelperViewHolder}. + * + * @author Paul Burke (ipaulpro) + */ +public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback { + + public static final float ALPHA_FULL = 1.0f; + + private final ItemTouchHelperAdapter mAdapter; + + public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) { + mAdapter = adapter; + } + + @Override + public boolean isLongPressDragEnabled() { + return true; + } + + @Override + public boolean isItemViewSwipeEnabled() { + return true; + } + + @Override + public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + // Set movement flags based on the layout manager + if (recyclerView.getLayoutManager() instanceof GridLayoutManager) { + final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; + final int swipeFlags = 0; + return makeMovementFlags(dragFlags, swipeFlags); + } else { + final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; + final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; + return makeMovementFlags(dragFlags, swipeFlags); + } + } + + @Override + public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) { + if (source.getItemViewType() != target.getItemViewType()) { + return false; + } + + // Notify the adapter of the move + mAdapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition()); + return true; + } + + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) { + // Notify the adapter of the dismissal + mAdapter.onItemDismiss(viewHolder.getAdapterPosition()); + } + + @Override + public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { + if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { + // Fade out the view as it is swiped out of the parent's bounds + final float alpha = ALPHA_FULL - Math.abs(dX) / (float) viewHolder.itemView.getWidth(); + viewHolder.itemView.setAlpha(alpha); + viewHolder.itemView.setTranslationX(dX); + } else { + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); + } + } + + @Override + public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { + // We only want the active item to change + if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { + if (viewHolder instanceof ItemTouchHelperViewHolder) { + // Let the view holder know that this item is being moved or dragged + ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder; + itemViewHolder.onItemSelected(); + } + } + + super.onSelectedChanged(viewHolder, actionState); + } + + @Override + public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + super.clearView(recyclerView, viewHolder); + + viewHolder.itemView.setAlpha(ALPHA_FULL); + + if (viewHolder instanceof ItemTouchHelperViewHolder) { + // Tell the view holder it's time to restore the idle state + ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder; + itemViewHolder.onItemClear(); + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_drag_handle.xml b/app/src/main/res/drawable/ic_drag_handle.xml new file mode 100644 index 000000000..68a719052 --- /dev/null +++ b/app/src/main/res/drawable/ic_drag_handle.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_list_timeline.xml b/app/src/main/res/drawable/ic_list_timeline.xml new file mode 100644 index 000000000..4c2fb8834 --- /dev/null +++ b/app/src/main/res/drawable/ic_list_timeline.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_make_tab_unvisible.xml b/app/src/main/res/drawable/ic_make_tab_unvisible.xml new file mode 100644 index 000000000..689f3f47c --- /dev/null +++ b/app/src/main/res/drawable/ic_make_tab_unvisible.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_make_tab_visible.xml b/app/src/main/res/drawable/ic_make_tab_visible.xml new file mode 100644 index 000000000..e02f1d191 --- /dev/null +++ b/app/src/main/res/drawable/ic_make_tab_visible.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_tag_timeline.xml b/app/src/main/res/drawable/ic_tag_timeline.xml new file mode 100644 index 000000000..1aa8d10ab --- /dev/null +++ b/app/src/main/res/drawable/ic_tag_timeline.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/drawer_reorder.xml b/app/src/main/res/layout/drawer_reorder.xml new file mode 100644 index 000000000..bb7a7d207 --- /dev/null +++ b/app/src/main/res/layout/drawer_reorder.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_reorder_tabs.xml b/app/src/main/res/layout/fragment_reorder_tabs.xml new file mode 100644 index 000000000..11b85bf93 --- /dev/null +++ b/app/src/main/res/layout/fragment_reorder_tabs.xml @@ -0,0 +1,32 @@ + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 10aa7667a..22f3d1842 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -920,6 +920,9 @@ A poll you have voted in has ended Display Peertube timeline Peertube + Hide the tab + Move timeline + Hide timeline %d vote