From e063eec76717f3b168203c43f9fc12e903404478 Mon Sep 17 00:00:00 2001
From: Thomas <tschneider.ac@gmail.com>
Date: Wed, 18 May 2022 11:42:45 +0200
Subject: [PATCH] Fix issue #28 & #61

---
 .../app/fedilab/android/BaseMainActivity.java | 148 +++++++++-----
 .../activities/ReorderTimelinesActivity.java  |  53 ++++-
 .../android/client/entities/BottomMenu.java   | 183 +++++++++++------
 .../android/client/entities/Pinned.java       |  19 ++
 .../app/fedilab/android/helper/Helper.java    |   2 +
 .../android/helper/PinnedTimelineHelper.java  |  20 +-
 .../ui/drawer/ReorderBottomMenuAdapter.java   | 184 ++++++++++++++++++
 .../android/ui/drawer/ReorderTabAdapter.java  |   9 +-
 .../ui/pageadapter/FedilabPageAdapter.java    |  73 ++++---
 .../android/viewmodel/mastodon/ReorderVM.java |  21 +-
 .../main/res/layout/activity_reorder_tabs.xml | 120 +++++++-----
 11 files changed, 616 insertions(+), 216 deletions(-)
 create mode 100644 app/src/main/java/app/fedilab/android/ui/drawer/ReorderBottomMenuAdapter.java

diff --git a/app/src/main/java/app/fedilab/android/BaseMainActivity.java b/app/src/main/java/app/fedilab/android/BaseMainActivity.java
index eae375dd..4bf7bb5e 100644
--- a/app/src/main/java/app/fedilab/android/BaseMainActivity.java
+++ b/app/src/main/java/app/fedilab/android/BaseMainActivity.java
@@ -136,6 +136,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
     private Pinned pinned;
     public static boolean show_boosts, show_replies, show_art_nsfw;
     public static String regex_home, regex_local, regex_public;
+    private BottomMenu bottomMenu;
 
     private final BroadcastReceiver broadcast_data = new BroadcastReceiver() {
         @Override
@@ -145,6 +146,51 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
                 if (b.getBoolean(Helper.RECEIVE_REDRAW_TOPBAR, false)) {
                     List<MastodonList> mastodonLists = (List<MastodonList>) b.getSerializable(Helper.RECEIVE_MASTODON_LIST);
                     redrawPinned(mastodonLists);
+                }
+                if (b.getBoolean(Helper.RECEIVE_REDRAW_BOTTOM, false)) {
+                    bottomMenu = new BottomMenu(BaseMainActivity.this).hydrate(account, binding.bottomNavView);
+                    if (bottomMenu != null) {
+                        //ManageClick on bottom menu items
+                        if (binding.bottomNavView.findViewById(R.id.nav_home) != null) {
+                            binding.bottomNavView.findViewById(R.id.nav_home).setOnLongClickListener(view -> {
+                                int position = BottomMenu.getPosition(bottomMenu, R.id.nav_home);
+                                if (position >= 0) {
+                                    manageFilters(position);
+                                }
+                                return false;
+                            });
+                        }
+                        if (binding.bottomNavView.findViewById(R.id.nav_local) != null) {
+                            binding.bottomNavView.findViewById(R.id.nav_local).setOnLongClickListener(view -> {
+                                int position = BottomMenu.getPosition(bottomMenu, R.id.nav_local);
+                                if (position >= 0) {
+                                    manageFilters(position);
+                                }
+                                return false;
+                            });
+                        }
+                        if (binding.bottomNavView.findViewById(R.id.nav_public) != null) {
+                            binding.bottomNavView.findViewById(R.id.nav_public).setOnLongClickListener(view -> {
+                                int position = BottomMenu.getPosition(bottomMenu, R.id.nav_public);
+                                if (position >= 0) {
+                                    manageFilters(position);
+                                }
+                                return false;
+                            });
+                        }
+                        binding.bottomNavView.setOnItemSelectedListener(item -> {
+                            int itemId = item.getItemId();
+                            int position = BottomMenu.getPosition(bottomMenu, itemId);
+                            if (position >= 0) {
+                                if (binding.viewPager.getCurrentItem() == position) {
+                                    scrollToTop();
+                                } else {
+                                    binding.viewPager.setCurrentItem(position);
+                                }
+                            }
+                            return true;
+                        });
+                    }
                 } else if (b.getBoolean(Helper.RECEIVE_RECREATE_ACTIVITY, false)) {
                     Cyanea.getInstance().edit().apply().recreate(BaseMainActivity.this);
                 } else if (b.getBoolean(Helper.RECEIVE_NEW_MESSAGE, false)) {
@@ -179,8 +225,6 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
     private void mamageNewIntent(Intent intent) {
         if (intent == null)
             return;
-        String action = intent.getAction();
-        String type = intent.getType();
         Bundle extras = intent.getExtras();
         String userIdIntent, instanceIntent;
         if (extras != null && extras.containsKey(Helper.INTENT_ACTION)) {
@@ -251,59 +295,10 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
         binding.tabLayout.setTabIconTint(ThemeHelper.getColorStateList(BaseMainActivity.this));
         binding.compose.setOnClickListener(v -> startActivity(new Intent(this, ComposeActivity.class)));
         headerMenuOpen = false;
-        new BottomMenu(BaseMainActivity.this).hydrate(account, binding.bottomNavView);
         binding.bottomNavView.setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this, R.color.cyanea_primary)));
         binding.navView.setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this, R.color.cyanea_primary)));
 
 
-        //ManageClick on bottom menu items
-        binding.bottomNavView.findViewById(R.id.nav_home).setOnLongClickListener(view -> {
-            manageFilters(0);
-            return false;
-        });
-        binding.bottomNavView.findViewById(R.id.nav_local).setOnLongClickListener(view -> {
-            manageFilters(1);
-            return false;
-        });
-        binding.bottomNavView.findViewById(R.id.nav_public).setOnLongClickListener(view -> {
-            manageFilters(2);
-            return false;
-        });
-        binding.bottomNavView.setOnItemSelectedListener(item -> {
-            int itemId = item.getItemId();
-            if (itemId == R.id.nav_home) {
-                if (binding.viewPager.getCurrentItem() == 0) {
-                    scrollToTop();
-                } else {
-                    binding.viewPager.setCurrentItem(0);
-                }
-            } else if (itemId == R.id.nav_local) {
-                if (binding.viewPager.getCurrentItem() == 1) {
-                    scrollToTop();
-                } else {
-                    binding.viewPager.setCurrentItem(1);
-                }
-            } else if (itemId == R.id.nav_public) {
-                if (binding.viewPager.getCurrentItem() == 2) {
-                    scrollToTop();
-                } else {
-                    binding.viewPager.setCurrentItem(2);
-                }
-            } else if (itemId == R.id.nav_notifications) {
-                if (binding.viewPager.getCurrentItem() == 3) {
-                    scrollToTop();
-                } else {
-                    binding.viewPager.setCurrentItem(3);
-                }
-            } else if (itemId == R.id.nav_privates) {
-                if (binding.viewPager.getCurrentItem() == 4) {
-                    scrollToTop();
-                } else {
-                    binding.viewPager.setCurrentItem(4);
-                }
-            }
-            return true;
-        });
 
 
         // Passing each menu ID as a set of Ids because each
@@ -567,6 +562,51 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
                     finish();
                     return;
                 }
+                bottomMenu = new BottomMenu(BaseMainActivity.this).hydrate(account, binding.bottomNavView);
+
+                if (bottomMenu != null) {
+                    //ManageClick on bottom menu items
+                    if (binding.bottomNavView.findViewById(R.id.nav_home) != null) {
+                        binding.bottomNavView.findViewById(R.id.nav_home).setOnLongClickListener(view -> {
+                            int position = BottomMenu.getPosition(bottomMenu, R.id.nav_home);
+                            if (position >= 0) {
+                                manageFilters(position);
+                            }
+                            return false;
+                        });
+                    }
+                    if (binding.bottomNavView.findViewById(R.id.nav_local) != null) {
+                        binding.bottomNavView.findViewById(R.id.nav_local).setOnLongClickListener(view -> {
+                            int position = BottomMenu.getPosition(bottomMenu, R.id.nav_local);
+                            if (position >= 0) {
+                                manageFilters(position);
+                            }
+                            return false;
+                        });
+                    }
+                    if (binding.bottomNavView.findViewById(R.id.nav_public) != null) {
+                        binding.bottomNavView.findViewById(R.id.nav_public).setOnLongClickListener(view -> {
+                            int position = BottomMenu.getPosition(bottomMenu, R.id.nav_public);
+                            if (position >= 0) {
+                                manageFilters(position);
+                            }
+                            return false;
+                        });
+                    }
+                    binding.bottomNavView.setOnItemSelectedListener(item -> {
+                        int itemId = item.getItemId();
+                        int position = BottomMenu.getPosition(bottomMenu, itemId);
+                        if (position >= 0) {
+                            if (binding.viewPager.getCurrentItem() == position) {
+                                scrollToTop();
+                            } else {
+                                binding.viewPager.setCurrentItem(position);
+                            }
+                        }
+                        return true;
+                    });
+                }
+
                 currentInstance = account.instance;
                 currentUserID = account.user_id;
                 show_boosts = sharedpreferences.getBoolean(getString(R.string.SET_SHOW_BOOSTS) + currentUserID + currentInstance, true);
@@ -611,11 +651,11 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
                         .observe(this, pinned -> {
                             this.pinned = pinned;
                             //First it's taken from db (last stored values)
-                            PinnedTimelineHelper.redrawTopBarPinned(BaseMainActivity.this, binding, pinned, null);
+                            PinnedTimelineHelper.redrawTopBarPinned(BaseMainActivity.this, binding, pinned, bottomMenu, null);
                             //Fetch remote lists for the authenticated account and update them
                             new ViewModelProvider(BaseMainActivity.this).get(TimelinesVM.class).getLists(currentInstance, currentToken)
                                     .observe(this, mastodonLists ->
-                                            PinnedTimelineHelper.redrawTopBarPinned(BaseMainActivity.this, binding, pinned, mastodonLists)
+                                            PinnedTimelineHelper.redrawTopBarPinned(BaseMainActivity.this, binding, pinned, bottomMenu, mastodonLists)
                                     );
                         });
             };
@@ -850,7 +890,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
                 .observe(this, pinned -> {
                     this.pinned = pinned;
                     //First it's taken from db (last stored values)
-                    PinnedTimelineHelper.redrawTopBarPinned(BaseMainActivity.this, binding, pinned, mastodonLists);
+                    PinnedTimelineHelper.redrawTopBarPinned(BaseMainActivity.this, binding, pinned, bottomMenu, mastodonLists);
                     binding.viewPager.setCurrentItem(currentItem);
                 });
     }
diff --git a/app/src/main/java/app/fedilab/android/activities/ReorderTimelinesActivity.java b/app/src/main/java/app/fedilab/android/activities/ReorderTimelinesActivity.java
index 8d6e6561..be55801a 100644
--- a/app/src/main/java/app/fedilab/android/activities/ReorderTimelinesActivity.java
+++ b/app/src/main/java/app/fedilab/android/activities/ReorderTimelinesActivity.java
@@ -15,6 +15,7 @@ package app.fedilab.android.activities;
  * see <http://www.gnu.org/licenses>. */
 
 
+import static app.fedilab.android.helper.PinnedTimelineHelper.sortMenuItem;
 import static app.fedilab.android.helper.PinnedTimelineHelper.sortPositionAsc;
 
 import android.content.Intent;
@@ -47,6 +48,7 @@ import java.util.ArrayList;
 import java.util.concurrent.TimeUnit;
 
 import app.fedilab.android.R;
+import app.fedilab.android.client.entities.BottomMenu;
 import app.fedilab.android.client.entities.InstanceSocial;
 import app.fedilab.android.client.entities.Pinned;
 import app.fedilab.android.client.entities.Timeline;
@@ -60,6 +62,7 @@ import app.fedilab.android.helper.ThemeHelper;
 import app.fedilab.android.helper.itemtouchhelper.OnStartDragListener;
 import app.fedilab.android.helper.itemtouchhelper.OnUndoListener;
 import app.fedilab.android.helper.itemtouchhelper.SimpleItemTouchHelperCallback;
+import app.fedilab.android.ui.drawer.ReorderBottomMenuAdapter;
 import app.fedilab.android.ui.drawer.ReorderTabAdapter;
 import app.fedilab.android.viewmodel.mastodon.InstanceSocialVM;
 import app.fedilab.android.viewmodel.mastodon.ReorderVM;
@@ -75,12 +78,23 @@ public class ReorderTimelinesActivity extends BaseActivity implements OnStartDra
 
 
     private ItemTouchHelper touchHelper;
-    private ReorderTabAdapter adapter;
+    private ReorderTabAdapter reorderTabAdapter;
+    private ReorderBottomMenuAdapter reorderBottomMenuAdapter;
     private boolean searchInstanceRunning;
     private String oldSearch;
     private Pinned pinned;
+    private BottomMenu bottomMenu;
     private ActivityReorderTabsBinding binding;
     private boolean changes;
+    private boolean bottomChanges;
+
+    public void setChanges(boolean changes) {
+        this.changes = changes;
+    }
+
+    public void setBottomChanges(boolean bottomChanges) {
+        this.bottomChanges = bottomChanges;
+    }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -95,6 +109,7 @@ public class ReorderTimelinesActivity extends BaseActivity implements OnStartDra
         }
 
         changes = false;
+        bottomChanges = false;
         ReorderVM reorderVM = new ViewModelProvider(ReorderTimelinesActivity.this).get(ReorderVM.class);
         reorderVM.getPinned().observe(ReorderTimelinesActivity.this, _pinned -> {
             this.pinned = _pinned;
@@ -103,16 +118,31 @@ public class ReorderTimelinesActivity extends BaseActivity implements OnStartDra
                 this.pinned.pinnedTimelines = new ArrayList<>();
             }
             sortPositionAsc(this.pinned.pinnedTimelines);
-            adapter = new ReorderTabAdapter(this.pinned, ReorderTimelinesActivity.this, ReorderTimelinesActivity.this);
+            reorderTabAdapter = new ReorderTabAdapter(this.pinned, ReorderTimelinesActivity.this, ReorderTimelinesActivity.this);
             ItemTouchHelper.Callback callback =
-                    new SimpleItemTouchHelperCallback(adapter);
+                    new SimpleItemTouchHelperCallback(reorderTabAdapter);
             touchHelper = new ItemTouchHelper(callback);
             touchHelper.attachToRecyclerView(binding.lvReorderTabs);
-            binding.lvReorderTabs.setAdapter(adapter);
+            binding.lvReorderTabs.setAdapter(reorderTabAdapter);
             LinearLayoutManager mLayoutManager = new LinearLayoutManager(ReorderTimelinesActivity.this);
             binding.lvReorderTabs.setLayoutManager(mLayoutManager);
         });
-
+        reorderVM.getBottomMenu().observe(ReorderTimelinesActivity.this, _bottomMenu -> {
+            this.bottomMenu = _bottomMenu;
+            if (this.bottomMenu == null) {
+                this.bottomMenu = new BottomMenu(getApplicationContext()).defaultBottomMenu();
+                this.bottomMenu.bottom_menu = new ArrayList<>();
+            }
+            sortMenuItem(this.bottomMenu.bottom_menu);
+            reorderBottomMenuAdapter = new ReorderBottomMenuAdapter(this.bottomMenu, ReorderTimelinesActivity.this);
+            ItemTouchHelper.Callback callback =
+                    new SimpleItemTouchHelperCallback(reorderBottomMenuAdapter);
+            touchHelper = new ItemTouchHelper(callback);
+            touchHelper.attachToRecyclerView(binding.lvReorderBottom);
+            binding.lvReorderBottom.setAdapter(reorderBottomMenuAdapter);
+            LinearLayoutManager mLayoutManager = new LinearLayoutManager(ReorderTimelinesActivity.this);
+            binding.lvReorderBottom.setLayoutManager(mLayoutManager);
+        });
     }
 
     @Override
@@ -209,7 +239,7 @@ public class ReorderTimelinesActivity extends BaseActivity implements OnStartDra
                                     try {
                                         new Pinned(ReorderTimelinesActivity.this).updatePinned(pinned);
                                         changes = true;
-                                        adapter.notifyItemInserted(pinned.pinnedTimelines.size());
+                                        reorderTabAdapter.notifyItemInserted(pinned.pinnedTimelines.size());
                                     } catch (DBException e) {
                                         e.printStackTrace();
                                     }
@@ -299,6 +329,13 @@ public class ReorderTimelinesActivity extends BaseActivity implements OnStartDra
             intentBD.putExtras(b);
             LocalBroadcastManager.getInstance(ReorderTimelinesActivity.this).sendBroadcast(intentBD);
         }
+        if (bottomChanges) {
+            Bundle b = new Bundle();
+            b.putBoolean(Helper.RECEIVE_REDRAW_BOTTOM, true);
+            Intent intentBD = new Intent(Helper.BROADCAST_DATA);
+            intentBD.putExtras(b);
+            LocalBroadcastManager.getInstance(ReorderTimelinesActivity.this).sendBroadcast(intentBD);
+        }
     }
 
     @Override
@@ -329,7 +366,7 @@ public class ReorderTimelinesActivity extends BaseActivity implements OnStartDra
                 pinned.pinnedTimelines.get(i).position -= 1;
             }
             pinned.pinnedTimelines.remove(pinnedTimeline);
-            adapter.notifyItemRemoved(position);
+            reorderTabAdapter.notifyItemRemoved(position);
             try {
                 new Pinned(ReorderTimelinesActivity.this).updatePinned(pinned);
                 changes = true;
@@ -341,7 +378,7 @@ public class ReorderTimelinesActivity extends BaseActivity implements OnStartDra
         handler.postDelayed(runnable, 4000);
         binding.undoAction.setOnClickListener(v -> {
             pinned.pinnedTimelines.add(position, pinnedTimeline);
-            adapter.notifyItemInserted(position);
+            reorderTabAdapter.notifyItemInserted(position);
             binding.undoContainer.setVisibility(View.GONE);
             handler.removeCallbacks(runnable);
         });
diff --git a/app/src/main/java/app/fedilab/android/client/entities/BottomMenu.java b/app/src/main/java/app/fedilab/android/client/entities/BottomMenu.java
index 9ee4b3b9..ff121e30 100644
--- a/app/src/main/java/app/fedilab/android/client/entities/BottomMenu.java
+++ b/app/src/main/java/app/fedilab/android/client/entities/BottomMenu.java
@@ -20,6 +20,8 @@ import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.view.Menu;
 
+import androidx.annotation.IdRes;
+
 import com.google.android.material.bottomnavigation.BottomNavigationView;
 import com.google.gson.Gson;
 import com.google.gson.annotations.SerializedName;
@@ -31,6 +33,7 @@ import java.util.List;
 
 import app.fedilab.android.BaseMainActivity;
 import app.fedilab.android.R;
+import app.fedilab.android.activities.MainActivity;
 import app.fedilab.android.exception.DBException;
 import app.fedilab.android.sqlite.Sqlite;
 
@@ -89,59 +92,62 @@ public class BottomMenu implements Serializable {
         }
     }
 
-    public void hydrate(Account account, BottomNavigationView bottomNavigationView) {
+    public static int getPosition(BottomMenu bottomMenu, @IdRes int idRes) {
+        for (MenuItem menuItem : bottomMenu.bottom_menu) {
+            if (idRes == R.id.nav_home && menuItem.item_menu_type == ItemMenuType.HOME) {
+                return menuItem.position;
+            } else if (idRes == R.id.nav_local && menuItem.item_menu_type == ItemMenuType.LOCAL) {
+                return menuItem.position;
+            } else if (idRes == R.id.nav_public && menuItem.item_menu_type == ItemMenuType.PUBLIC) {
+                return menuItem.position;
+            } else if (idRes == R.id.nav_notifications && menuItem.item_menu_type == ItemMenuType.NOTIFICATION) {
+                return menuItem.position;
+            } else if (idRes == R.id.nav_privates && menuItem.item_menu_type == ItemMenuType.DIRECT) {
+                return menuItem.position;
+            }
+        }
+        return -1;
+    }
+
+    public static ItemMenuType getType(BottomMenu bottomMenu, int position) {
+        if (bottomMenu == null || bottomMenu.bottom_menu == null || bottomMenu.bottom_menu.size() < position) {
+            return null;
+        }
+        return bottomMenu.bottom_menu.get(position).item_menu_type;
+    }
+
+    public BottomMenu hydrate(Account account, BottomNavigationView bottomNavigationView) {
         bottomNavigationView.getMenu().clear();
         BottomMenu bottomMenu;
         try {
-            bottomMenu = getBottomMenu(account);
+            bottomMenu = getAllBottomMenu(account);
         } catch (DBException e) {
             bottomMenu = defaultBottomMenu();
         }
         for (BottomMenu.MenuItem menuItem : bottomMenu.bottom_menu) {
-            if (menuItem.visible) {
-                switch (menuItem.item_menu_type) {
-                    case HOME:
-                        bottomNavigationView.getMenu().add(Menu.NONE, R.id.nav_home, menuItem.position, context.getString(R.string.home_menu)).setIcon(R.drawable.ic_baseline_home_24);
-                        break;
-                    case LOCAL:
-                        bottomNavigationView.getMenu().add(Menu.NONE, R.id.nav_local, menuItem.position, context.getString(R.string.local_menu)).setIcon(R.drawable.ic_baseline_people_alt_24);
-                        break;
-                    case PUBLIC:
-                        bottomNavigationView.getMenu().add(Menu.NONE, R.id.nav_public, menuItem.position, context.getString(R.string.v_public)).setIcon(R.drawable.ic_baseline_public_24);
-                        break;
-                    case NOTIFICATION:
-                        bottomNavigationView.getMenu().add(Menu.NONE, R.id.nav_notifications, menuItem.position, context.getString(R.string.notifications)).setIcon(R.drawable.ic_baseline_notifications_24);
-                        break;
-                    case DIRECT:
-                        bottomNavigationView.getMenu().add(Menu.NONE, R.id.nav_privates, menuItem.position, context.getString(R.string.v_private)).setIcon(R.drawable.ic_baseline_mail_24);
-                        break;
-                }
+            android.view.MenuItem menuItemLoop = null;
+            switch (menuItem.item_menu_type) {
+                case HOME:
+                    menuItemLoop = bottomNavigationView.getMenu().add(Menu.NONE, R.id.nav_home, menuItem.position, context.getString(R.string.home_menu)).setIcon(R.drawable.ic_baseline_home_24);
+                    break;
+                case LOCAL:
+                    menuItemLoop = bottomNavigationView.getMenu().add(Menu.NONE, R.id.nav_local, menuItem.position, context.getString(R.string.local_menu)).setIcon(R.drawable.ic_baseline_people_alt_24);
+                    break;
+                case PUBLIC:
+                    menuItemLoop = bottomNavigationView.getMenu().add(Menu.NONE, R.id.nav_public, menuItem.position, context.getString(R.string.v_public)).setIcon(R.drawable.ic_baseline_public_24);
+                    break;
+                case NOTIFICATION:
+                    menuItemLoop = bottomNavigationView.getMenu().add(Menu.NONE, R.id.nav_notifications, menuItem.position, context.getString(R.string.notifications)).setIcon(R.drawable.ic_baseline_notifications_24);
+                    break;
+                case DIRECT:
+                    menuItemLoop = bottomNavigationView.getMenu().add(Menu.NONE, R.id.nav_privates, menuItem.position, context.getString(R.string.v_private)).setIcon(R.drawable.ic_baseline_mail_24);
+                    break;
+            }
+            if (menuItemLoop != null && !menuItem.visible) {
+                menuItemLoop.setVisible(false);
             }
         }
-    }
-
-    /**
-     * Insert or update instance
-     *
-     * @param bottomMenu {@link BottomMenu}
-     * @return long - db id
-     * @throws DBException exception with database
-     */
-    public long insertOrUpdate(BottomMenu bottomMenu) throws DBException {
-        if (db == null) {
-            throw new DBException("db is null. Wrong initialization.");
-        }
-        if (bottomMenu == null) {
-            return -1;
-        }
-        boolean exists = bottomMenuExists(bottomMenu);
-        long idReturned;
-        if (exists) {
-            idReturned = updateBottomMenu(bottomMenu);
-        } else {
-            idReturned = insertBottomMenu(bottomMenu);
-        }
-        return idReturned;
+        return bottomMenu;
     }
 
     /**
@@ -192,13 +198,60 @@ public class BottomMenu implements Serializable {
         }
     }
 
+    /**
+     * Insert or update instance
+     *
+     * @param bottomMenu {@link BottomMenu}
+     * @return long - db id
+     * @throws DBException exception with database
+     */
+    public long insertOrUpdate(BottomMenu bottomMenu) throws DBException {
+        if (db == null) {
+            throw new DBException("db is null. Wrong initialization.");
+        }
+        if (bottomMenu == null) {
+            return -1;
+        }
+        if (bottomMenu.user_id == null) {
+            bottomMenu.user_id = MainActivity.currentUserID;
+            bottomMenu.instance = MainActivity.currentInstance;
+        }
+        boolean exists = bottomMenuExists(bottomMenu);
+        long idReturned;
+        if (exists) {
+            idReturned = updateBottomMenu(bottomMenu);
+        } else {
+            idReturned = insertBottomMenu(bottomMenu);
+        }
+        return idReturned;
+    }
+
     /**
      * Returns the bottom menu for an account
      *
      * @param account Account
-     * @return Pinned - {@link BottomMenu}
+     * @return BottomMenu - {@link BottomMenu}
      */
-    private BottomMenu getBottomMenu(Account account) throws DBException {
+    public BottomMenu getAllBottomMenu(Account account) throws DBException {
+        if (db == null) {
+            throw new DBException("db is null. Wrong initialization.");
+        }
+        try {
+            Cursor c = db.query(Sqlite.TABLE_BOTTOM_MENU, null, Sqlite.COL_INSTANCE + " = '" + account.instance + "' AND " + Sqlite.COL_USER_ID + " = '" + account.user_id + "'", null, null, null, Sqlite.COL_ID + " DESC", "1");
+            return cursorToBottomMenu(c);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return defaultBottomMenu();
+        }
+    }
+
+    /**
+     * Returns the bottom menu for an account
+     *
+     * @param account Account
+     * @return BottomMenu - {@link BottomMenu}
+     */
+    public BottomMenu getBottomMenu(Account account) throws DBException {
         if (db == null) {
             throw new DBException("db is null. Wrong initialization.");
         }
@@ -207,9 +260,12 @@ public class BottomMenu implements Serializable {
             BottomMenu bottomMenu = cursorToBottomMenu(c);
             List<MenuItem> menuItemList = new ArrayList<>();
             if (bottomMenu != null) {
+                int inc = 0;
                 for (MenuItem menuItem : bottomMenu.bottom_menu) {
                     if (menuItem.visible) {
-                        menuItemList.add(menuItem.position, menuItem);
+                        menuItem.position = inc;
+                        menuItemList.add(menuItem);
+                        inc++;
                     }
                 }
                 bottomMenu.bottom_menu = menuItemList;
@@ -219,11 +275,24 @@ public class BottomMenu implements Serializable {
             }
             return bottomMenu;
         } catch (Exception e) {
+            e.printStackTrace();
             return defaultBottomMenu();
         }
     }
 
-    private BottomMenu defaultBottomMenu() {
+    public boolean bottomMenuExists(BottomMenu bottomMenu) throws DBException {
+        if (db == null) {
+            throw new DBException("db is null. Wrong initialization.");
+        }
+        Cursor mCount = db.rawQuery("select count(*) from " + Sqlite.TABLE_BOTTOM_MENU
+                + " where " + Sqlite.COL_INSTANCE + " = '" + bottomMenu.instance + "' AND " + Sqlite.COL_USER_ID + " = '" + bottomMenu.user_id + "'", null);
+        mCount.moveToFirst();
+        int count = mCount.getInt(0);
+        mCount.close();
+        return (count > 0);
+    }
+
+    public BottomMenu defaultBottomMenu() {
         BottomMenu bottomMenu = new BottomMenu();
         bottomMenu.bottom_menu = new ArrayList<>();
         MenuItem menuItemHome = new MenuItem();
@@ -254,18 +323,6 @@ public class BottomMenu implements Serializable {
         return bottomMenu;
     }
 
-    public boolean bottomMenuExists(BottomMenu bottomMenu) throws DBException {
-        if (db == null) {
-            throw new DBException("db is null. Wrong initialization.");
-        }
-        Cursor mCount = db.rawQuery("select count(*) from " + Sqlite.TABLE_BOTTOM_MENU
-                + " where " + Sqlite.COL_INSTANCE + " = '" + bottomMenu.instance + "' AND " + Sqlite.COL_USER_ID + " = '" + bottomMenu.user_id + "'", null);
-        mCount.moveToFirst();
-        int count = mCount.getInt(0);
-        mCount.close();
-        return (count > 0);
-    }
-
     /**
      * Restore pinned from db
      *
@@ -325,10 +382,10 @@ public class BottomMenu implements Serializable {
 
     public static class MenuItem {
         @SerializedName("position")
-        int position;
+        public int position;
         @SerializedName("item_menu_type")
-        ItemMenuType item_menu_type;
+        public ItemMenuType item_menu_type;
         @SerializedName("visible")
-        boolean visible;
+        public boolean visible;
     }
 }
diff --git a/app/src/main/java/app/fedilab/android/client/entities/Pinned.java b/app/src/main/java/app/fedilab/android/client/entities/Pinned.java
index 91277aaf..3057956e 100644
--- a/app/src/main/java/app/fedilab/android/client/entities/Pinned.java
+++ b/app/src/main/java/app/fedilab/android/client/entities/Pinned.java
@@ -172,6 +172,25 @@ public class Pinned implements Serializable {
         }
     }
 
+
+    /**
+     * Returns the pinned timeline for an account
+     *
+     * @param account Account
+     * @return Pinned - {@link Pinned}
+     */
+    public Pinned getAllPinned(Account account) throws DBException {
+        if (db == null) {
+            throw new DBException("db is null. Wrong initialization.");
+        }
+        try {
+            Cursor c = db.query(Sqlite.TABLE_PINNED_TIMELINES, null, Sqlite.COL_INSTANCE + " = '" + account.instance + "' AND " + Sqlite.COL_USER_ID + " = '" + account.user_id + "'", null, null, null, Sqlite.COL_UPDATED_AT + " DESC", "1");
+            return cursorToPined(c);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
     public boolean pinnedExist(Pinned pinned) throws DBException {
         if (db == null) {
             throw new DBException("db is null. Wrong initialization.");
diff --git a/app/src/main/java/app/fedilab/android/helper/Helper.java b/app/src/main/java/app/fedilab/android/helper/Helper.java
index 1a54553a..17399903 100644
--- a/app/src/main/java/app/fedilab/android/helper/Helper.java
+++ b/app/src/main/java/app/fedilab/android/helper/Helper.java
@@ -163,6 +163,8 @@ public class Helper {
 
     public static final String BROADCAST_DATA = "BROADCAST_DATA";
     public static final String RECEIVE_REDRAW_TOPBAR = "RECEIVE_REDRAW_TOPBAR";
+    public static final String RECEIVE_REDRAW_BOTTOM = "RECEIVE_REDRAW_BOTTOM";
+
     public static final String RECEIVE_STATUS_ACTION = "RECEIVE_STATUS_ACTION";
 
     public static final String RECEIVE_RECREATE_ACTIVITY = "RECEIVE_RECREATE_ACTIVITY";
diff --git a/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java b/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java
index 979af166..5b0b8545 100644
--- a/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java
+++ b/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java
@@ -43,6 +43,7 @@ import java.util.List;
 
 import app.fedilab.android.BaseMainActivity;
 import app.fedilab.android.R;
+import app.fedilab.android.client.entities.BottomMenu;
 import app.fedilab.android.client.entities.Pinned;
 import app.fedilab.android.client.entities.Timeline;
 import app.fedilab.android.client.entities.app.PinnedTimeline;
@@ -63,7 +64,12 @@ public class PinnedTimelineHelper {
         Collections.sort(pinnedTimelineList, (obj1, obj2) -> Integer.compare(obj1.position, obj2.position));
     }
 
-    public synchronized static void redrawTopBarPinned(BaseMainActivity activity, ActivityMainBinding activityMainBinding, Pinned pinned, List<MastodonList> mastodonLists) {
+    public static void sortMenuItem(List<BottomMenu.MenuItem> menuItemList) {
+        //noinspection ComparatorCombinators
+        Collections.sort(menuItemList, (obj1, obj2) -> Integer.compare(obj1.position, obj2.position));
+    }
+
+    public synchronized static void redrawTopBarPinned(BaseMainActivity activity, ActivityMainBinding activityMainBinding, Pinned pinned, BottomMenu bottomMenu, List<MastodonList> mastodonLists) {
         //Values must be initialized if there is no records in db
         if (pinned == null) {
             pinned = new Pinned();
@@ -93,16 +99,16 @@ public class PinnedTimelineHelper {
                     if (!present) {
                         pinnedToRemove.add(pinnedTimeline);
                         needRedraw = true; //Something changed, redraw must be done
-                        try {
-                            new Pinned(activity).updatePinned(pinned);
-                        } catch (DBException e) {
-                            e.printStackTrace();
-                        }
                     }
                 }
             }
             if (pinnedToRemove.size() > 0) {
                 pinned.pinnedTimelines.removeAll(pinnedToRemove);
+                try {
+                    new Pinned(activity).updatePinned(pinned);
+                } catch (DBException e) {
+                    e.printStackTrace();
+                }
             }
 
             for (MastodonList mastodonList : mastodonLists) {
@@ -197,7 +203,7 @@ public class PinnedTimelineHelper {
         activityMainBinding.viewPager.clearOnPageChangeListeners();
         activityMainBinding.tabLayout.clearOnTabSelectedListeners();
 
-        FedilabPageAdapter fedilabPageAdapter = new FedilabPageAdapter(activity.getSupportFragmentManager(), pinned);
+        FedilabPageAdapter fedilabPageAdapter = new FedilabPageAdapter(activity.getSupportFragmentManager(), pinned, bottomMenu);
         activityMainBinding.viewPager.setAdapter(fedilabPageAdapter);
         activityMainBinding.viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(activityMainBinding.tabLayout));
         activityMainBinding.viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/ReorderBottomMenuAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/ReorderBottomMenuAdapter.java
new file mode 100644
index 00000000..8278e269
--- /dev/null
+++ b/app/src/main/java/app/fedilab/android/ui/drawer/ReorderBottomMenuAdapter.java
@@ -0,0 +1,184 @@
+package app.fedilab.android.ui.drawer;
+/* Copyright 2022 Thomas Schneider
+ *
+ * This file is a part of Fedilab
+ *
+ * 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.
+ *
+ * Fedilab 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 Fedilab; if not,
+ * see <http://www.gnu.org/licenses>. */
+
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.ViewGroup;
+import android.widget.Toast;
+
+import androidx.core.content.ContextCompat;
+import androidx.recyclerview.widget.RecyclerView;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+
+import app.fedilab.android.R;
+import app.fedilab.android.activities.ReorderTimelinesActivity;
+import app.fedilab.android.client.entities.BottomMenu;
+import app.fedilab.android.databinding.DrawerReorderBinding;
+import app.fedilab.android.exception.DBException;
+import app.fedilab.android.helper.itemtouchhelper.ItemTouchHelperAdapter;
+import app.fedilab.android.helper.itemtouchhelper.ItemTouchHelperViewHolder;
+import app.fedilab.android.helper.itemtouchhelper.OnStartDragListener;
+import es.dmoral.toasty.Toasty;
+
+
+/**
+ * Simple RecyclerView.Adapter that implements {@link ItemTouchHelperAdapter} to respond to move and
+ * dismiss events from a {@link androidx.recyclerview.widget.ItemTouchHelper}.
+ *
+ * @author Paul Burke (ipaulpro)
+ */
+public class ReorderBottomMenuAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements ItemTouchHelperAdapter {
+
+    private final OnStartDragListener mDragStartListener;
+    private final BottomMenu bottomMenu;
+    private Context context;
+
+    public ReorderBottomMenuAdapter(BottomMenu bottomMenu, OnStartDragListener dragStartListener) {
+        this.mDragStartListener = dragStartListener;
+        this.bottomMenu = bottomMenu;
+    }
+
+    @NotNull
+    @Override
+    public ReorderViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) {
+        context = parent.getContext();
+        DrawerReorderBinding itemBinding = DrawerReorderBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
+        return new ReorderViewHolder(itemBinding);
+    }
+
+    @SuppressLint("ClickableViewAccessibility")
+    @Override
+    public void onBindViewHolder(@NotNull final RecyclerView.ViewHolder viewHolder, int position) {
+
+        ReorderViewHolder holder = (ReorderViewHolder) viewHolder;
+        String title = "";
+        switch (bottomMenu.bottom_menu.get(position).item_menu_type) {
+            case HOME:
+                holder.binding.icon.setImageResource(R.drawable.ic_baseline_home_24);
+                title = context.getString(R.string.home_menu);
+                break;
+            case LOCAL:
+                holder.binding.icon.setImageResource(R.drawable.ic_baseline_people_alt_24);
+                title = context.getString(R.string.local);
+                break;
+            case PUBLIC:
+                holder.binding.icon.setImageResource(R.drawable.ic_baseline_public_24);
+                title = context.getString(R.string.v_public);
+                break;
+            case NOTIFICATION:
+                holder.binding.icon.setImageResource(R.drawable.ic_baseline_notifications_24);
+                title = context.getString(R.string.notifications);
+                break;
+            case DIRECT:
+                holder.binding.icon.setImageResource(R.drawable.ic_baseline_mail_24);
+                title = context.getString(R.string.v_private);
+                break;
+        }
+        holder.binding.text.setText(title);
+
+        if (bottomMenu.bottom_menu.get(position).visible) {
+            holder.binding.hide.setImageResource(R.drawable.ic_baseline_visibility_24);
+        } else {
+            holder.binding.hide.setImageResource(R.drawable.ic_baseline_visibility_off_24);
+        }
+
+        holder.binding.hide.setOnClickListener(v -> {
+            bottomMenu.bottom_menu.get(position).visible = !bottomMenu.bottom_menu.get(position).visible;
+            if (bottomMenu.bottom_menu.get(position).visible) {
+                holder.binding.hide.setImageResource(R.drawable.ic_baseline_visibility_24);
+            } else {
+                holder.binding.hide.setImageResource(R.drawable.ic_baseline_visibility_off_24);
+            }
+            new Thread(() -> {
+                try {
+                    new BottomMenu(context).insertOrUpdate(bottomMenu);
+                    ((ReorderTimelinesActivity) context).setBottomChanges(true);
+                } catch (DBException e) {
+                    e.printStackTrace();
+                }
+            }).start();
+        });
+
+        // Start a drag whenever the handle view it touched
+        holder.binding.handle.setOnTouchListener((v, event) -> {
+            if (event.getAction() == MotionEvent.ACTION_DOWN) {
+                mDragStartListener.onStartDrag(holder);
+                return true;
+            }
+            return false;
+        });
+
+    }
+
+    @Override
+    public void onItemDismiss(int position) {
+        BottomMenu.MenuItem menuItem = bottomMenu.bottom_menu.get(position);
+        notifyItemChanged(position);
+        Toasty.info(context, context.getString(R.string.warning_main_timeline), Toast.LENGTH_SHORT).show();
+    }
+
+    @Override
+    public boolean onItemMove(int fromPosition, int toPosition) {
+        Collections.swap(bottomMenu.bottom_menu, fromPosition, toPosition);
+        //update position value
+        for (int j = 0; j < bottomMenu.bottom_menu.size(); j++) {
+            bottomMenu.bottom_menu.get(j).position = j;
+        }
+        notifyItemMoved(fromPosition, toPosition);
+        try {
+            new BottomMenu(context).insertOrUpdate(bottomMenu);
+            ((ReorderTimelinesActivity) context).setBottomChanges(true);
+        } catch (DBException e) {
+            e.printStackTrace();
+        }
+        return true;
+    }
+
+    @Override
+    public int getItemCount() {
+        return bottomMenu.bottom_menu.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 ReorderViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {
+
+        DrawerReorderBinding binding;
+
+        ReorderViewHolder(DrawerReorderBinding itemView) {
+            super(itemView.getRoot());
+            binding = itemView;
+        }
+
+        @Override
+        public void onItemSelected() {
+            itemView.setBackgroundColor(ContextCompat.getColor(context, R.color.mastodonC3));
+        }
+
+        @Override
+        public void onItemClear() {
+            itemView.setBackgroundColor(0);
+        }
+    }
+}
diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/ReorderTabAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/ReorderTabAdapter.java
index 83effc89..82bf356f 100644
--- a/app/src/main/java/app/fedilab/android/ui/drawer/ReorderTabAdapter.java
+++ b/app/src/main/java/app/fedilab/android/ui/drawer/ReorderTabAdapter.java
@@ -30,6 +30,7 @@ import org.jetbrains.annotations.NotNull;
 import java.util.Collections;
 
 import app.fedilab.android.R;
+import app.fedilab.android.activities.ReorderTimelinesActivity;
 import app.fedilab.android.client.entities.Pinned;
 import app.fedilab.android.client.entities.Timeline;
 import app.fedilab.android.client.entities.app.PinnedTimeline;
@@ -121,14 +122,11 @@ public class ReorderTabAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
 
         holder.binding.hide.setOnClickListener(v -> {
             pinned.pinnedTimelines.get(position).displayed = !pinned.pinnedTimelines.get(position).displayed;
-            if (pinned.pinnedTimelines.get(position).displayed) {
-                holder.binding.hide.setImageResource(R.drawable.ic_baseline_visibility_24);
-            } else {
-                holder.binding.hide.setImageResource(R.drawable.ic_baseline_visibility_off_24);
-            }
+            notifyItemChanged(position);
             new Thread(() -> {
                 try {
                     new Pinned(context).updatePinned(pinned);
+                    ((ReorderTimelinesActivity) context).setChanges(true);
                 } catch (DBException e) {
                     e.printStackTrace();
                 }
@@ -169,6 +167,7 @@ public class ReorderTabAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
         notifyItemMoved(fromPosition, toPosition);
         try {
             new Pinned(context).updatePinned(pinned);
+            ((ReorderTimelinesActivity) context).setChanges(true);
         } catch (DBException e) {
             e.printStackTrace();
         }
diff --git a/app/src/main/java/app/fedilab/android/ui/pageadapter/FedilabPageAdapter.java b/app/src/main/java/app/fedilab/android/ui/pageadapter/FedilabPageAdapter.java
index 541ff484..3a499321 100644
--- a/app/src/main/java/app/fedilab/android/ui/pageadapter/FedilabPageAdapter.java
+++ b/app/src/main/java/app/fedilab/android/ui/pageadapter/FedilabPageAdapter.java
@@ -22,6 +22,7 @@ import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
 import androidx.fragment.app.FragmentStatePagerAdapter;
 
+import app.fedilab.android.client.entities.BottomMenu;
 import app.fedilab.android.client.entities.Pinned;
 import app.fedilab.android.client.entities.Timeline;
 import app.fedilab.android.client.entities.app.PinnedTimeline;
@@ -34,11 +35,13 @@ public class FedilabPageAdapter extends FragmentStatePagerAdapter {
 
     public static final int BOTTOM_TIMELINE_COUNT = 5; //home, local, public, notification, DM
     private final Pinned pinned;
+    private final BottomMenu bottomMenu;
     private Fragment mCurrentFragment;
 
-    public FedilabPageAdapter(FragmentManager fm, Pinned pinned) {
+    public FedilabPageAdapter(FragmentManager fm, Pinned pinned, BottomMenu bottomMenu) {
         super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
         this.pinned = pinned;
+        this.bottomMenu = bottomMenu;
     }
 
     public Fragment getCurrentFragment() {
@@ -62,39 +65,49 @@ public class FedilabPageAdapter extends FragmentStatePagerAdapter {
     @NonNull
     @Override
     public Fragment getItem(int position) {
-
+        FragmentMastodonTimeline fragment = new FragmentMastodonTimeline();
+        Bundle bundle = new Bundle();
         //Position 3 is for notifications
-        if (position == 3) {
-            return new FragmentNotificationContainer();
-        } else if (position == 4) { //Position 4 is for DM
-            return new FragmentMastodonConversation();
-        } else {
-            FragmentMastodonTimeline fragment = new FragmentMastodonTimeline();
-            Bundle bundle = new Bundle();
-            if (position == 0) { //Home timeline
-                bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.HOME);
-            } else if (position == 1) { //Local timeline
-                bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.LOCAL);
-            } else if (position == 2) { //Public timeline
-                bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.PUBLIC);
-            } else { //Pinned timeline
-                int pinnedPosition = position - BOTTOM_TIMELINE_COUNT; //Real position has an offset.
-                PinnedTimeline pinnedTimeline = pinned.pinnedTimelines.get(pinnedPosition);
-                bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, pinnedTimeline.type);
-
-                if (pinnedTimeline.type == Timeline.TimeLineEnum.LIST) {
-                    bundle.putString(Helper.ARG_LIST_ID, pinnedTimeline.mastodonList.id);
-                } else if (pinnedTimeline.type == Timeline.TimeLineEnum.TAG) {
-                    bundle.putSerializable(Helper.ARG_TAG_TIMELINE, pinnedTimeline.tagTimeline);
-                } else if (pinnedTimeline.type == Timeline.TimeLineEnum.REMOTE) {
-                    String instance = pinnedTimeline.remoteInstance.host;
-                    bundle.putString(Helper.ARG_REMOTE_INSTANCE, instance);
+        if (position < 5) {
+            if (bottomMenu != null) {
+                BottomMenu.ItemMenuType type = BottomMenu.getType(bottomMenu, position);
+                if (type == null) {
+                    return fragment;
                 }
+                if (type == BottomMenu.ItemMenuType.NOTIFICATION) {
+                    return new FragmentNotificationContainer();
+                } else if (type == BottomMenu.ItemMenuType.DIRECT) {
+                    return new FragmentMastodonConversation();
+                }
+                if (type == BottomMenu.ItemMenuType.HOME) { //Home timeline
+                    bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.HOME);
+                } else if (type == BottomMenu.ItemMenuType.LOCAL) { //Local timeline
+                    bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.LOCAL);
+                } else if (type == BottomMenu.ItemMenuType.PUBLIC) { //Public timeline
+                    bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.PUBLIC);
+                }
+            } else {
+                return fragment;
             }
-            bundle.putString(Helper.ARG_VIEW_MODEL_KEY, "FEDILAB_" + position);
-            fragment.setArguments(bundle);
-            return fragment;
+
+        } else {
+            int pinnedPosition = position - BOTTOM_TIMELINE_COUNT; //Real position has an offset.
+            PinnedTimeline pinnedTimeline = pinned.pinnedTimelines.get(pinnedPosition);
+            bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, pinnedTimeline.type);
+
+            if (pinnedTimeline.type == Timeline.TimeLineEnum.LIST) {
+                bundle.putString(Helper.ARG_LIST_ID, pinnedTimeline.mastodonList.id);
+            } else if (pinnedTimeline.type == Timeline.TimeLineEnum.TAG) {
+                bundle.putSerializable(Helper.ARG_TAG_TIMELINE, pinnedTimeline.tagTimeline);
+            } else if (pinnedTimeline.type == Timeline.TimeLineEnum.REMOTE) {
+                String instance = pinnedTimeline.remoteInstance.host;
+                bundle.putString(Helper.ARG_REMOTE_INSTANCE, instance);
+            }
+
         }
+        bundle.putString(Helper.ARG_VIEW_MODEL_KEY, "FEDILAB_" + position);
+        fragment.setArguments(bundle);
+        return fragment;
     }
 
     @Override
diff --git a/app/src/main/java/app/fedilab/android/viewmodel/mastodon/ReorderVM.java b/app/src/main/java/app/fedilab/android/viewmodel/mastodon/ReorderVM.java
index 8ae30044..e22398c7 100644
--- a/app/src/main/java/app/fedilab/android/viewmodel/mastodon/ReorderVM.java
+++ b/app/src/main/java/app/fedilab/android/viewmodel/mastodon/ReorderVM.java
@@ -28,6 +28,7 @@ import java.util.ArrayList;
 import java.util.concurrent.TimeUnit;
 
 import app.fedilab.android.BaseMainActivity;
+import app.fedilab.android.client.entities.BottomMenu;
 import app.fedilab.android.client.entities.Pinned;
 import app.fedilab.android.client.mastodon.MastodonSearchService;
 import app.fedilab.android.client.mastodon.entities.Results;
@@ -48,6 +49,7 @@ public class ReorderVM extends AndroidViewModel {
             .build();
     private MutableLiveData<Results> resultsMutableLiveData;
     private MutableLiveData<Pinned> pinnedMutableLiveData;
+    private MutableLiveData<BottomMenu> bottomMenuMutableLiveData;
 
     public ReorderVM(@NonNull Application application) {
         super(application);
@@ -67,7 +69,7 @@ public class ReorderVM extends AndroidViewModel {
         new Thread(() -> {
             Pinned pinned = null;
             try {
-                pinned = new Pinned(getApplication().getApplicationContext()).getPinned(BaseMainActivity.accountWeakReference.get());
+                pinned = new Pinned(getApplication().getApplicationContext()).getAllPinned(BaseMainActivity.accountWeakReference.get());
             } catch (DBException e) {
                 e.printStackTrace();
             }
@@ -80,6 +82,23 @@ public class ReorderVM extends AndroidViewModel {
     }
 
 
+    public LiveData<BottomMenu> getBottomMenu() {
+        bottomMenuMutableLiveData = new MutableLiveData<>();
+        new Thread(() -> {
+            BottomMenu bottomMenu = null;
+            try {
+                bottomMenu = new BottomMenu(getApplication().getApplicationContext()).getAllBottomMenu(BaseMainActivity.accountWeakReference.get());
+            } catch (DBException e) {
+                e.printStackTrace();
+            }
+            Handler mainHandler = new Handler(Looper.getMainLooper());
+            BottomMenu finalBottomMenu = bottomMenu;
+            Runnable myRunnable = () -> bottomMenuMutableLiveData.setValue(finalBottomMenu);
+            mainHandler.post(myRunnable);
+        }).start();
+        return bottomMenuMutableLiveData;
+    }
+
     /**
      * Search for content in accounts, statuses and hashtags with API v2
      *
diff --git a/app/src/main/res/layout/activity_reorder_tabs.xml b/app/src/main/res/layout/activity_reorder_tabs.xml
index 9a076925..72127e90 100644
--- a/app/src/main/res/layout/activity_reorder_tabs.xml
+++ b/app/src/main/res/layout/activity_reorder_tabs.xml
@@ -14,60 +14,84 @@
     You should have received a copy of the GNU General Public License along with Fedilab; if not,
     see <http://www.gnu.org/licenses>.
 -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+
+<ScrollView 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">
 
-    <androidx.recyclerview.widget.RecyclerView
-        android:id="@+id/lv_reorder_bottom"
+    <androidx.constraintlayout.widget.ConstraintLayout
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:scrollbars="none" />
+        android:layout_height="wrap_content">
 
-    <androidx.recyclerview.widget.RecyclerView
-        android:id="@+id/lv_reorder_tabs"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:scrollbars="none" />
-
-    <RelativeLayout
-        android:id="@+id/undo_container"
-        android:layout_width="match_parent"
-        android:layout_height="50dp"
-        android:layout_alignParentBottom="true"
-        android:layout_marginBottom="0dp"
-        android:background="@color/cyanea_primary_reference"
-        android:visibility="gone">
-
-        <TextView
-            android:id="@+id/undo_message"
-            android:layout_width="wrap_content"
+        <androidx.cardview.widget.CardView
+            android:id="@+id/lv_reorder_bottom_container"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_alignParentStart="true"
-            android:layout_centerInParent="true"
-            android:layout_marginStart="10dp"
-            android:paddingLeft="20dp"
-            android:paddingTop="5dp"
-            android:paddingRight="20dp"
-            android:paddingBottom="5dp"
-            android:textColor="@color/cyanea_accent_dark_reference"
-            android:textSize="14sp" />
+            android:layout_marginTop="20dp"
+            app:layout_constraintTop_toTopOf="parent">
 
-        <TextView
-            android:id="@+id/undo_action"
-            android:layout_width="wrap_content"
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/lv_reorder_bottom"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:scrollbars="none" />
+        </androidx.cardview.widget.CardView>
+
+
+        <androidx.cardview.widget.CardView
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_alignParentEnd="true"
-            android:layout_centerInParent="true"
-            android:layout_marginEnd="10dp"
-            android:paddingLeft="20dp"
-            android:paddingTop="5dp"
-            android:paddingRight="20dp"
-            android:paddingBottom="5dp"
-            android:text="@string/undo"
-            android:textAllCaps="true"
-            android:textColor="@color/cyanea_accent_dark_reference"
-            android:textSize="18sp" />
-    </RelativeLayout>
-</RelativeLayout>
+            android:layout_marginTop="20dp"
+            app:layout_constraintTop_toBottomOf="@+id/lv_reorder_bottom_container">
+
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/lv_reorder_tabs"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:scrollbars="none" />
+        </androidx.cardview.widget.CardView>
+
+        <RelativeLayout
+            android:id="@+id/undo_container"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:layout_marginBottom="0dp"
+            android:background="@color/cyanea_primary_reference"
+            android:visibility="gone"
+            app:layout_constraintBottom_toBottomOf="parent">
+
+            <TextView
+                android:id="@+id/undo_message"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentStart="true"
+                android:layout_centerInParent="true"
+                android:layout_marginStart="10dp"
+                android:paddingLeft="20dp"
+                android:paddingTop="5dp"
+                android:paddingRight="20dp"
+                android:paddingBottom="5dp"
+                android:textColor="@color/cyanea_accent_dark_reference"
+                android:textSize="14sp" />
+
+            <TextView
+                android:id="@+id/undo_action"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentEnd="true"
+                android:layout_centerInParent="true"
+                android:layout_marginEnd="10dp"
+                android:paddingLeft="20dp"
+                android:paddingTop="5dp"
+                android:paddingRight="20dp"
+                android:paddingBottom="5dp"
+                android:text="@string/undo"
+                android:textAllCaps="true"
+                android:textColor="@color/cyanea_accent_dark_reference"
+                android:textSize="18sp" />
+        </RelativeLayout>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</ScrollView>
+