forked from mirrors/Fedilab
		
	
							parent
							
								
									4725ca6ce7
								
							
						
					
					
						commit
						e063eec767
					
				
					 11 changed files with 616 additions and 216 deletions
				
			
		| 
						 | 
				
			
			@ -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);
 | 
			
		||||
                });
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
        });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue