refactored dockbar editor

This commit is contained in:
Vologhat
2022-07-11 19:57:03 +03:00
parent 92c9ea2222
commit 4c5d83fccc
11 changed files with 511 additions and 505 deletions
@@ -60,7 +60,8 @@ import java.util.List;
import ru.vtosters.lite.ui.PreferencesUtil;
import ru.vtosters.lite.ui.dialogs.OTADialog;
import ru.vtosters.lite.ui.fragments.dockbar.DockBarFragment;
import ru.vtosters.lite.ui.fragments.dockbar.AdapterHelper;
import ru.vtosters.lite.ui.fragments.dockbar.DockBarEditorFragment;
import ru.vtosters.lite.ui.fragments.dockbar.DockBarManager;
import ru.vtosters.lite.ui.fragments.tgstickers.StickersFragment;
import ru.vtosters.lite.ui.vkui.VBottomSheetBuilder;
@@ -94,7 +95,7 @@ public class VTSettings extends MaterialPreferenceToolbarFragment{
public static String getDocksumm(){
if(disableSettingsSumms()) return null;
return Globals.getString("vtldocksumm") + ": " + DockBarManager.getInstance().getTabCount();
return Globals.getString("vtldocksumm") + ": " + (AdapterHelper.getItemCount() - 2);
}
public static String getTGSsumm(){
@@ -310,7 +311,7 @@ public class VTSettings extends MaterialPreferenceToolbarFragment{
PreferencesUtil.addPreference(this, "", Globals.getString("dockbar_editor"), docksumm, !DoNotUseOldIcons() ? "ic_list_24" : "ic_list_outline_28", preference -> {
Context context = getContext();
Intent a2 = new Navigator(DockBarFragment.class).b(context);
Intent a2 = new Navigator(DockBarEditorFragment.class).b(context);
a2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(a2);
return false;
@@ -0,0 +1,32 @@
package ru.vtosters.lite.ui.fragments.dockbar;
public class AdapterHelper {
// Adapter item types
public static final int TAB_TYPE = 1;
public static final int CATEGORY_TITLE_TYPE = 2;
// Tab types
public static final int SELECTED = 3;
public static final int DISABLED = 4;
private static final DockBarManager sManager = DockBarManager.getInstance();
public static int getItemViewType(int i) {
return i == 0 || sManager.getSelectedTabs().size() + 1 == i ? CATEGORY_TITLE_TYPE : TAB_TYPE;
}
public static int getTabType(int i) {
return i <= sManager.getSelectedTabs().size() ? SELECTED : DISABLED;
}
public static boolean needTransfer(int from, int to) {
return getItemViewType(from) == TAB_TYPE && getItemViewType(to) == CATEGORY_TITLE_TYPE;
}
public static int getItemCount() {
return sManager.getCategoryTitles().size()
+ sManager.getSelectedTabs().size()
+ sManager.getDisabledTabs().size();
}
}
@@ -1,193 +0,0 @@
package ru.vtosters.lite.ui.fragments.dockbar;
import static ru.vtosters.lite.utils.Globals.convertDpToPixel;
import static ru.vtosters.lite.utils.Globals.getContext;
import android.annotation.SuppressLint;
import android.content.res.ColorStateList;
import android.graphics.Typeface;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import ru.vtosters.lite.utils.Themes;
public class DockBarAdapter extends RecyclerView.Adapter
implements IItemTouchHelper{
public static final int SELECTED_TAB_TYPE = 1;
public static final int DISABLED_TAB_TYPE = 2;
public static final int GROUP_TITLE_TYPE = 3;
private final DockBarManager mDockBarManager = DockBarManager.getInstance();
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
if(viewType == GROUP_TITLE_TYPE){
return new GroupViewHolder(createGroupTitle());
} else {
return new DockBarEditViewHolder(createTabItem());
}
}
@Override
public int getItemViewType(int i){
return getItemType(i);
}
@SuppressLint("NewApi")
private View createTabItem(){
LinearLayout container = new LinearLayout(getContext());
container.setTag("tab_item_container");
container.setGravity(Gravity.CENTER_VERTICAL);
container.setOrientation(LinearLayout.HORIZONTAL);
container.setPadding(
convertDpToPixel(12),
convertDpToPixel(12),
convertDpToPixel(12),
convertDpToPixel(12)
);
container.setLayoutParams(new LinearLayout.LayoutParams(-1, convertDpToPixel(48)));
ImageView icon = new ImageView(getContext());
icon.setTag("icon");
icon.setImageTintList(ColorStateList.valueOf(Themes.getAccentColor()));
icon.setLayoutParams(new LinearLayout.LayoutParams(
convertDpToPixel(24),
convertDpToPixel(24)));
container.addView(icon);
TextView title = new TextView(getContext());
title.setTag("title");
title.setTextSize(16.0f);
title.setTypeface(Typeface.DEFAULT_BOLD);
title.setTextColor(Themes.getTextAttr());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(-1, -2);
params.weight = 1;
params.leftMargin = convertDpToPixel(16);
container.addView(title, params);
return container;
}
private View createGroupTitle(){
LinearLayout layout = new LinearLayout(getContext());
layout.setLayoutParams(new LinearLayout.LayoutParams(-1, -2));
TextView title = new TextView(getContext());
title.setTag("group_title");
title.setTextSize(13.0f);
title.setPadding(
convertDpToPixel(16),
convertDpToPixel(13),
convertDpToPixel(16),
convertDpToPixel(13)
);
title.setAllCaps(true);
title.setTextColor(Themes.getTextAttr());
layout.addView(title, new LinearLayout.LayoutParams(-2, -2));
return layout;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position){
if(holder instanceof GroupViewHolder){
((GroupViewHolder) holder).bind(mDockBarManager.getGroupTitle(position));
} else {
int viewType = getItemType(position);
if(viewType == SELECTED_TAB_TYPE){
((DockBarEditViewHolder) holder).bind(mDockBarManager.getSelectedTab(position));
} else if(viewType == DISABLED_TAB_TYPE){
((DockBarEditViewHolder) holder).bind(mDockBarManager.getDisabledTab(position));
}
}
}
@Override
public int getItemCount(){
return mDockBarManager.getItemCount();
}
@Override
public void onItemDismiss(int index){
mDockBarManager.move(this, index);
}
@Override
public boolean onItemMove(int fromPosition, int toPosition){
int fromViewType = getItemType(fromPosition);
int toViewType = getItemType(toPosition);
if(fromPosition < toPosition){
if(fromViewType != toViewType){
mDockBarManager.swapAndMigrate(this, fromPosition, toPosition);
} else {
List<DockBarTab> list = fromViewType == SELECTED_TAB_TYPE ? mDockBarManager.getSelectedTabs() : mDockBarManager.getDisabledTabs();
mDockBarManager.swap(this, list, fromViewType, fromPosition, toPosition);
}
} else if(toPosition != 0){
if(fromViewType != toViewType){
mDockBarManager.swapAndMigrate(this, fromPosition, toPosition);
} else {
List<DockBarTab> list = fromViewType == SELECTED_TAB_TYPE ? mDockBarManager.getSelectedTabs() : mDockBarManager.getDisabledTabs();
mDockBarManager.swap(this, list, fromViewType, fromPosition, toPosition);
}
}
return true;
}
public int getIndexByViewType(int position, int viewType){
return mDockBarManager.getIndexByViewType(position, viewType);
}
public int getItemType(int position){
return mDockBarManager.getItemType(position);
}
static class DockBarEditViewHolder extends RecyclerView.ViewHolder{
private final ImageView mIcon;
private final TextView mTitle;
public DockBarEditViewHolder(View itemView){
super(itemView);
mIcon = itemView.findViewWithTag("icon");
mTitle = itemView.findViewWithTag("title");
}
public void bind(DockBarTab tab){
mIcon.setImageResource(tab.iconID);
mTitle.setText(tab.titleID);
}
}
static class GroupViewHolder extends RecyclerView.ViewHolder{
private final TextView mGroupTitle;
public GroupViewHolder(View view){
super(view);
mGroupTitle = view.findViewWithTag("group_title");
}
public void bind(String groupTitle){
mGroupTitle.setText(groupTitle);
}
}
}
@@ -1,14 +0,0 @@
package ru.vtosters.lite.ui.fragments.dockbar;
public class DockBarDragItem{
public boolean active;
public int index;
public DockBarTab dockBarTab;
public DockBarDragItem(boolean active, int index, DockBarTab dockBarTab){
this.active = active;
this.index = index;
this.dockBarTab = dockBarTab;
}
}
@@ -0,0 +1,188 @@
package ru.vtosters.lite.ui.fragments.dockbar;
import static ru.vtosters.lite.utils.Globals.convertDpToPixel;
import static ru.vtosters.lite.utils.Globals.getContext;
import android.content.res.ColorStateList;
import android.graphics.Typeface;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import ru.vtosters.lite.utils.Themes;
public class DockBarEditorAdapter extends RecyclerView.Adapter<DockBarEditorAdapter.ItemViewHolder>
implements IItemTouchHelper {
private final DockBarManager mDockBarManager = DockBarManager.getInstance();
@Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
FrameLayout container = new FrameLayout(getContext());
container.addView(newGroupTitle(), new FrameLayout.LayoutParams(-1, -2));
container.addView(newTabItem(), new FrameLayout.LayoutParams(-1, -2));
return new ItemViewHolder(container);
}
private View newTabItem() {
LinearLayout container = new LinearLayout(getContext());
container.setTag("tab_container");
container.setGravity(Gravity.CENTER_VERTICAL);
container.setOrientation(LinearLayout.HORIZONTAL);
container.setPadding(
convertDpToPixel(12),
convertDpToPixel(12),
convertDpToPixel(12),
convertDpToPixel(12)
);
container.setLayoutParams(new LinearLayout.LayoutParams(-1, convertDpToPixel(48)));
container.setVisibility(View.INVISIBLE);
ImageView icon = new ImageView(getContext());
icon.setTag("tab_icon");
icon.setImageTintList(ColorStateList.valueOf(Themes.getAccentColor()));
icon.setLayoutParams(new LinearLayout.LayoutParams(
convertDpToPixel(24),
convertDpToPixel(24)));
container.addView(icon);
TextView name = new TextView(getContext());
name.setTag("tab_name");
name.setTextSize(16.0f);
name.setTypeface(Typeface.DEFAULT_BOLD);
name.setTextColor(Themes.getTextAttr());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(-1, -2);
params.weight = 1;
params.leftMargin = convertDpToPixel(16);
container.addView(name, params);
return container;
}
private View newGroupTitle() {
LinearLayout container = new LinearLayout(getContext());
container.setTag("category_title_container");
container.setLayoutParams(new LinearLayout.LayoutParams(-1, -2));
container.setVisibility(View.INVISIBLE);
TextView title = new TextView(getContext());
title.setTag("category_title");
title.setTextSize(13.0f);
title.setPadding(
convertDpToPixel(16),
convertDpToPixel(13),
convertDpToPixel(16),
convertDpToPixel(13)
);
title.setAllCaps(true);
title.setTextColor(Themes.getTextAttr());
container.addView(title, new LinearLayout.LayoutParams(-2, -2));
return container;
}
@Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
holder.bind(position);
}
@Override
public int getItemCount() {
return AdapterHelper.getItemCount();
}
@Override
public void onItemDismiss(int index) {
}
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
if (toPosition == 0)
return false;
var selectedTabs = mDockBarManager.getSelectedTabs();
var disabledTabs = mDockBarManager.getDisabledTabs();
DockBarTab curr;
if (AdapterHelper.getTabType(fromPosition) == AdapterHelper.SELECTED) {
curr = selectedTabs.get(fromPosition - 1);
if (AdapterHelper.getItemViewType(toPosition) == AdapterHelper.CATEGORY_TITLE_TYPE) {
if (selectedTabs.size() == DockBarManager.MIN_SELECTED_TABS_LIMIT)
return false;
selectedTabs.remove(fromPosition - 1);
disabledTabs.add(curr);
for (int i = disabledTabs.size() - 2; i >= 0; i--) {
var tmp = disabledTabs.get(i + 1);
disabledTabs.set(i + 1, disabledTabs.get(i));
disabledTabs.set(i, tmp);
}
} else {
Collections.swap(selectedTabs, fromPosition - 1, toPosition - 1);
}
} else if (AdapterHelper.getTabType(fromPosition) == AdapterHelper.DISABLED) {
curr = disabledTabs.get(fromPosition - selectedTabs.size() - 2);
if (AdapterHelper.getItemViewType(toPosition) == AdapterHelper.CATEGORY_TITLE_TYPE) {
if (selectedTabs.size() == DockBarManager.MAX_SELECTED_TABS_LIMIT)
return false;
disabledTabs.remove(0);
selectedTabs.add(curr);
} else {
Collections.swap(disabledTabs, fromPosition - selectedTabs.size() - 2, toPosition - selectedTabs.size() - 2);
}
}
notifyItemMoved(fromPosition, toPosition);
return true;
}
protected class ItemViewHolder extends RecyclerView.ViewHolder {
private LinearLayout mTabContainer;
private ImageView mTabIcon;
private TextView mTabName;
private LinearLayout mCategoryTitleContainer;
private TextView mCategoryTitle;
public ItemViewHolder(View itemView) {
super(itemView);
mTabContainer = itemView.findViewWithTag("tab_container");
mCategoryTitleContainer = itemView.findViewWithTag("category_title_container");
mTabIcon = mTabContainer.findViewWithTag("tab_icon");
mTabName = mTabContainer.findViewWithTag("tab_name");
mCategoryTitle = mCategoryTitleContainer.findViewWithTag("category_title");
}
public void bind(int pos) {
Log.d("ItemViewHolder", pos+"");
if (AdapterHelper.getItemViewType(pos) == AdapterHelper.TAB_TYPE) {
DockBarTab tab = AdapterHelper.getTabType(pos) == AdapterHelper.SELECTED
? mDockBarManager.getSelectedTabs().get(pos - 1)
: mDockBarManager.getDisabledTabs().get(pos - mDockBarManager.getSelectedTabs().size() - 2);
mTabIcon.setImageResource(tab.iconID);
mTabName.setText(tab.titleID);
mTabContainer.setVisibility(View.VISIBLE);
mCategoryTitleContainer.setVisibility(View.INVISIBLE);
} else {
mCategoryTitle.setText(mDockBarManager.getCategoryTitles().get(pos == 0 ? 0 : 1));
mCategoryTitleContainer.setVisibility(View.VISIBLE);
mTabContainer.setVisibility(View.INVISIBLE);
}
}
}
}
@@ -5,6 +5,7 @@ import static ru.vtosters.lite.utils.Globals.restartApplication;
import android.os.Bundle;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -20,19 +21,20 @@ import com.vtosters.lite.general.fragments.MaterialPreferenceToolbarFragment;
import ru.vtosters.lite.utils.Globals;
public class DockBarFragment extends MaterialPreferenceToolbarFragment{
public class DockBarEditorFragment extends MaterialPreferenceToolbarFragment {
private RecyclerView mRecyclerView;
private DockBarAdapter mAdapter;
private RecyclerView mRecycler;
private DockBarEditorAdapter mAdapter;
private ItemTouchHelperCallback mCallback;
private ItemTouchHelper mItemTouchHelper;
@Override
public View onCreateView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle bundle){
super.onCreate(bundle);
public View onCreateView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle bundle) {
super.onCreateView(layoutInflater, viewGroup, bundle);
LinearLayout container = new LinearLayout(getContext());
container.setLayoutParams(new FrameLayout.LayoutParams(-1, -1));
container.setOrientation(LinearLayout.VERTICAL);
container.setLayoutParams(new FrameLayout.LayoutParams(-1, -1));
LinearLayout buttonsContainer = new LinearLayout(getContext());
buttonsContainer.setPadding(
@@ -60,7 +62,7 @@ public class DockBarFragment extends MaterialPreferenceToolbarFragment{
TextView reset = new TextView(new ContextThemeWrapper(getContext(), com.vtosters.lite.R.style.VKUIButton_Primary));
reset.setText(Globals.getString("dockbar_reset"));
reset.setOnClickListener(v -> {
DockBarManager.getInstance().delete();
DockBarManager.getInstance().reset();
restartApplication();
});
@@ -68,26 +70,19 @@ public class DockBarFragment extends MaterialPreferenceToolbarFragment{
resetParams.weight = 1.0f;
buttonsContainer.addView(reset, resetParams);
mRecyclerView = new RecyclerView(getContext());
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mAdapter = new DockBarAdapter();
mRecyclerView.setAdapter(mAdapter);
container.addView(mRecyclerView, new LinearLayout.LayoutParams(-1, -1));
mRecycler = new RecyclerView(getContext());
mRecycler.setLayoutManager(new LinearLayoutManager(getContext()));
mRecycler.setAdapter((mAdapter = new DockBarEditorAdapter()));
mRecycler.setHasFixedSize(true);
var params = new LinearLayout.LayoutParams(-1, -1);
params.gravity = Gravity.CENTER;
container.addView(mRecycler, params);
mItemTouchHelper = new ItemTouchHelper(new ItemTouchHelperCallback(mAdapter));
mItemTouchHelper.attachToRecyclerView(mRecyclerView);
mCallback = new ItemTouchHelperCallback(mAdapter);
mItemTouchHelper = new ItemTouchHelper(mCallback);
mItemTouchHelper.attachToRecyclerView(mRecycler);
return container;
}
@Override
public void onViewCreated(View arg0, Bundle arg1){
setHasOptionsMenu(true);
super.onViewCreated(arg0, arg1);
// TODO: хз что это
//a(getString("dockbar_editor"));
}
}
@@ -8,7 +8,6 @@ import static ru.vtosters.lite.utils.Preferences.vkme;
import static ru.vtosters.lite.utils.Preferences.vkme_notifs;
import com.vk.apps.AppsFragment;
import com.vk.discover.DiscoverFragment;
import com.vk.discover.ThemedFeedFragment;
import com.vk.fave.fragments.FaveTabFragment;
import com.vk.feedlikes.d.FeedLikesFragment;
@@ -35,300 +34,272 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class DockBarManager{
import ru.vtosters.lite.utils.StreamUtils;
public class DockBarManager {
public static final int MIN_SELECTED_TABS_LIMIT = 3;
public static final int MAX_SELECTED_TABS_LIMIT = 9;
private static DockBarManager sInstance = new DockBarManager();
private final List<DockBarTab> mSelectedTabs = new ArrayList<>();
private final List<DockBarTab> mDisabledTabs = new ArrayList<>();
private final List<String> mGroups = Arrays.asList(
private final List<String> mCategoryTitles = Arrays.asList(
getString("dockbar_selected_items"),
getString("dockbar_unselected_items")
);
private File mConfig;
public DockBarManager(){
load();
public DockBarManager() {
init();
}
public static DockBarManager getInstance(){
if(sInstance == null)
sInstance = new DockBarManager();
return sInstance;
public static DockBarManager getInstance() {
return sInstance == null
? (sInstance = new DockBarManager())
: sInstance;
}
private static String readFully(InputStream is) throws IOException{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[2048];
int len;
while((len = is.read(buffer)) > 0) {
bos.write(buffer, 0, len);
}
return bos.toString();
}
private void load(){
File dockbar = new File(getContext().getFilesDir(), "dockbar.json");
if(!dockbar.exists()){
if(vkme()){
mSelectedTabs.add(new DockBarTab("tab_settings", R.drawable.ic_settings_outline_28, R.string.menu_settings, R.id.menu_settings, useNewSettings()));
if(vkme_notifs())
mSelectedTabs.add(new DockBarTab("tab_feedback", R.drawable.ic_menu_notification_outline_28, R.string.feedback, R.id.tab_feedback, NotificationsContainerFragment.class));
mSelectedTabs.add(new DockBarTab("tab_messages", R.drawable.ic_message_outline_28, R.string.messages, R.id.tab_messages, DialogsFragment.class));
mSelectedTabs.add(new DockBarTab("tab_profile", R.drawable.ic_account_outline_28, R.string.profile, R.id.tab_menu, ProfileFragment.class));
return;
}
mSelectedTabs.add(new DockBarTab("tab_news", R.drawable.ic_menu_newsfeed_outline_28, R.string.newsfeed, R.id.tab_news, milkshake() ? HomeFragment.class : NewsfeedFragment.class));
mSelectedTabs.add(new DockBarTab("tab_superapps", milkshake() ? R.drawable.ic_explore_outline_28 : R.drawable.ic_menu_search_outline_28, R.string.super_app_title, R.id.tab_discover, milkshake() ? SuperAppFragment.class : ThemedFeedFragment.class));
mSelectedTabs.add(new DockBarTab("tab_messages", R.drawable.ic_message_outline_28, R.string.messages, R.id.tab_messages, DialogsFragment.class));
mSelectedTabs.add(new DockBarTab("tab_friends", milkshake() ? R.drawable.ic_users_outline_28 : R.drawable.ic_menu_notification_outline_28, R.string.friends, R.id.tab_feedback, milkshake() ? FriendsCatalogFragment.class : NotificationsContainerFragment.class));
mSelectedTabs.add(new DockBarTab("tab_profile", milkshake() ? R.drawable.ic_user_circle_outline_28 : R.drawable.ic_menu_more_outline_28, R.string.profile, R.id.tab_menu, milkshake() ? ProfileFragment.class : MenuFragment.class));
mDisabledTabs.add(new DockBarTab("tab_feedback", R.drawable.ic_menu_notification_outline_28, R.string.feedback, R.id.tab_feedback, NotificationsContainerFragment.class));
mDisabledTabs.add(new DockBarTab("tab_groups", R.drawable.ic_users_outline_28, R.string.groups, R.id.menu_groups, GroupsSearchFragment.class));
mDisabledTabs.add(new DockBarTab("tab_photos", R.drawable.ic_camera_outline_28, R.string.photos, R.id.menu_photos, PhotosFragment.class));
mDisabledTabs.add(new DockBarTab("tab_audios", R.drawable.ic_music_outline_28, R.string.music, R.id.menu_audios, MusicFragment.class));
mDisabledTabs.add(new DockBarTab("tab_videos", R.drawable.ic_video_outline_28, R.string.videos, R.id.menu_videos, VideosFragment.class));
mDisabledTabs.add(new DockBarTab("tab_lives", R.drawable.ic_live_outline_28, R.string.sett_live, R.id.menu_lives, LivesPostListFragment.class));
mDisabledTabs.add(new DockBarTab("tab_games", R.drawable.ic_games_outline_36, R.string.games, R.id.menu_games, GamesFragment.class));
mDisabledTabs.add(new DockBarTab("tab_liked", R.drawable.ic_menu_like_24, R.string.sett_likes, R.id.menu_feed_likes, FeedLikesFragment.class));
mDisabledTabs.add(new DockBarTab("tab_fave", R.drawable.ic_favorite_outline_28, R.string.video, R.id.menu_fave, FaveTabFragment.class));
mDisabledTabs.add(new DockBarTab("tab_documents", R.drawable.ic_document_outline_24, R.string.docs, R.id.menu_documents, DocumentsViewFragment.class));
mDisabledTabs.add(new DockBarTab("tab_payments", R.drawable.ic_money_transfer_outline_28, R.string.money_transfer_money_transfers, R.id.menu_payments, MoneyTransfersFragment.class));
mDisabledTabs.add(new DockBarTab("tab_vk_apps", R.drawable.ic_services_outline_28, R.string.menu_apps, R.id.menu_vk_apps, AppsFragment.class));
mDisabledTabs.add(new DockBarTab("tab_settings", R.drawable.ic_settings_outline_28, R.string.menu_settings, R.id.menu_settings, useNewSettings()));
mDisabledTabs.add(new DockBarTab("tab_menu", R.drawable.ic_menu_more_outline_28, R.string.register, R.id.tab_menu, MenuFragment.class));
mDisabledTabs.add(new DockBarTab("tab_brtd", R.drawable.ic_menu_birthdays, R.string.birthdays_title, R.id.menu_birthdays, BirthdaysFragment.class));
private void init() {
mConfig = new File(getContext().getFilesDir(), "dockbar.json");
if (mConfig.exists()) {
readFromConfig();
} else {
try {
JSONObject json = new JSONObject(readFully(new FileInputStream(dockbar)));
JSONArray selected = json.getJSONArray("selected");
for(int i = 0; i < selected.length(); i++) {
JSONObject item = selected.getJSONObject(i);
DockBarTab tab = new DockBarTab(
item.getString("tag"),
item.getInt("iconID"),
item.getInt("titleID"),
item.getInt("id"),
Class.forName(item.getString("fragmentClass"))
);
if(milkshake()){
if(tab.fragmentClass == NewsfeedFragment.class){
tab.fragmentClass = HomeFragment.class;
} else if(tab.fragmentClass == DiscoverFragment.class){
tab.fragmentClass = DiscoverFragment.class;
}
} else {
if(tab.fragmentClass == HomeFragment.class){
tab.fragmentClass = NewsfeedFragment.class;
} else if(tab.fragmentClass == DiscoverFragment.class){
tab.fragmentClass = DiscoverFragment.class;
}
}
mSelectedTabs.add(tab);
}
JSONArray disabled = json.getJSONArray("disabled");
for(int i = 0; i < disabled.length(); i++) {
JSONObject item = disabled.getJSONObject(i);
DockBarTab tab = new DockBarTab(
item.getString("tag"),
item.getInt("iconID"),
item.getInt("titleID"),
item.getInt("id"),
Class.forName(item.getString("fragmentClass"))
);
if(milkshake()){
if(tab.fragmentClass == NewsfeedFragment.class){
tab.fragmentClass = HomeFragment.class;
} else if(tab.fragmentClass == DiscoverFragment.class){
tab.fragmentClass = DiscoverFragment.class;
}
} else {
if(tab.fragmentClass == HomeFragment.class){
tab.fragmentClass = NewsfeedFragment.class;
} else if(tab.fragmentClass == DiscoverFragment.class){
tab.fragmentClass = DiscoverFragment.class;
}
}
mDisabledTabs.add(tab);
}
} catch (JSONException | IOException | ClassNotFoundException e) {
e.printStackTrace();
}
fillDefault();
}
}
public void delete(){
File dockbar = new File(getContext().getFilesDir(), "dockbar.json");
if(dockbar.exists()) dockbar.delete();
private void readFromConfig() {
try {
JSONObject jsonObj = new JSONObject(StreamUtils.readAllLines(mConfig));
fillList(mSelectedTabs, jsonObj.getJSONArray("selected"));
fillList(mDisabledTabs, jsonObj.getJSONArray("disabled"));
} catch (JSONException | IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
public void save(){
private void fillList(List<DockBarTab> list, JSONArray array) throws JSONException, ClassNotFoundException {
for (int i = 0; i < array.length(); i++) {
JSONObject item = array.getJSONObject(i);
DockBarTab tab = DockBarTab.valuesOf(
item.getString("tag"),
item.getInt("iconID"),
item.getInt("titleID"),
item.getInt("id"),
Class.forName(item.getString("fragmentClass"))
);
if (milkshake() && NewsfeedFragment.class == tab.fragmentClass) {
tab.fragmentClass = HomeFragment.class;
} else if (!milkshake() && HomeFragment.class == tab.fragmentClass) {
tab.fragmentClass = NewsfeedFragment.class;
}
list.add(tab);
}
}
private void fillDefault() {
if (vkme()) {
mSelectedTabs.add(DockBarTab.valuesOf(
"tab_settings",
R.drawable.ic_settings_outline_28,
R.string.menu_settings,
R.id.menu_settings,
useNewSettings()));
if (vkme_notifs())
mSelectedTabs.add(DockBarTab.valuesOf(
"tab_feedback",
R.drawable.ic_menu_notification_outline_28,
R.string.feedback,
R.id.tab_feedback,
NotificationsContainerFragment.class));
mSelectedTabs.add(DockBarTab.valuesOf(
"tab_messages",
R.drawable.ic_message_outline_28,
R.string.messages,
R.id.tab_messages,
DialogsFragment.class));
mSelectedTabs.add(DockBarTab.valuesOf(
"tab_profile",
R.drawable.ic_account_outline_28,
R.string.profile,
R.id.tab_menu,
ProfileFragment.class));
return;
}
// fill selected tabs list
mSelectedTabs.add(DockBarTab.valuesOf(
"tab_news",
R.drawable.ic_menu_newsfeed_outline_28,
R.string.newsfeed,
R.id.tab_news,
milkshake() ? HomeFragment.class : NewsfeedFragment.class));
mSelectedTabs.add(DockBarTab.valuesOf(
"tab_superapps",
milkshake() ? R.drawable.ic_explore_outline_28 : R.drawable.ic_menu_search_outline_28,
R.string.super_app_title,
R.id.tab_discover,
milkshake() ? SuperAppFragment.class : ThemedFeedFragment.class));
mSelectedTabs.add(DockBarTab.valuesOf(
"tab_messages",
R.drawable.ic_message_outline_28,
R.string.messages,
R.id.tab_messages,
DialogsFragment.class));
mSelectedTabs.add(DockBarTab.valuesOf(
"tab_friends",
milkshake() ? R.drawable.ic_users_outline_28 : R.drawable.ic_menu_notification_outline_28,
R.string.friends,
R.id.tab_feedback,
milkshake() ? FriendsCatalogFragment.class : NotificationsContainerFragment.class));
mSelectedTabs.add(DockBarTab.valuesOf(
"tab_profile",
milkshake() ? R.drawable.ic_user_circle_outline_28 : R.drawable.ic_menu_more_outline_28,
R.string.profile,
R.id.tab_menu,
milkshake() ? ProfileFragment.class : MenuFragment.class));
// fill disabled tabs list
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_feedback",
R.drawable.ic_menu_notification_outline_28,
R.string.feedback,
R.id.tab_feedback,
NotificationsContainerFragment.class));
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_groups",
R.drawable.ic_users_outline_28,
R.string.groups,
R.id.menu_groups,
GroupsSearchFragment.class));
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_photos",
R.drawable.ic_camera_outline_28,
R.string.photos,
R.id.menu_photos,
PhotosFragment.class));
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_audios",
R.drawable.ic_music_outline_28,
R.string.music,
R.id.menu_audios,
MusicFragment.class));
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_videos",
R.drawable.ic_video_outline_28,
R.string.videos,
R.id.menu_videos,
VideosFragment.class));
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_lives",
R.drawable.ic_live_outline_28,
R.string.sett_live,
R.id.menu_lives,
LivesPostListFragment.class));
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_games",
R.drawable.ic_games_outline_36,
R.string.games,
R.id.menu_games,
GamesFragment.class));
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_liked",
R.drawable.ic_menu_like_24,
R.string.sett_likes,
R.id.menu_feed_likes,
FeedLikesFragment.class));
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_fave",
R.drawable.ic_favorite_outline_28,
R.string.video,
R.id.menu_fave,
FaveTabFragment.class));
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_documents",
R.drawable.ic_document_outline_24,
R.string.docs,
R.id.menu_documents,
DocumentsViewFragment.class));
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_payments",
R.drawable.ic_money_transfer_outline_28,
R.string.money_transfer_money_transfers,
R.id.menu_payments,
MoneyTransfersFragment.class));
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_vk_apps",
R.drawable.ic_services_outline_28,
R.string.menu_apps,
R.id.menu_vk_apps,
AppsFragment.class));
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_settings",
R.drawable.ic_settings_outline_28,
R.string.menu_settings,
R.id.menu_settings,
useNewSettings()));
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_menu",
R.drawable.ic_menu_more_outline_28,
R.string.register,
R.id.tab_menu,
MenuFragment.class));
mDisabledTabs.add(DockBarTab.valuesOf(
"tab_brtd",
R.drawable.ic_menu_birthdays,
R.string.birthdays_title,
R.id.menu_birthdays,
BirthdaysFragment.class));
}
public void save() {
try {
File dockbar = new File(getContext().getFilesDir(), "dockbar.json");
JSONObject jsonObj = new JSONObject()
.put("selected", makeJsonArrayWithTabs(mSelectedTabs))
.put("disabled", makeJsonArrayWithTabs(mDisabledTabs));
JSONArray selected = new JSONArray();
for(DockBarTab tab : mSelectedTabs) {
JSONObject item = new JSONObject()
.put("tag", tab.tag)
.put("iconID", tab.iconID)
.put("titleID", tab.titleID)
.put("id", tab.id)
.put("fragmentClass", tab.fragmentClass.getName());
selected.put(item);
}
JSONArray disabled = new JSONArray();
for(DockBarTab tab : mDisabledTabs) {
JSONObject item = new JSONObject()
.put("tag", tab.tag)
.put("iconID", tab.iconID)
.put("titleID", tab.titleID)
.put("id", tab.id)
.put("fragmentClass", tab.fragmentClass.getName());
disabled.put(item);
}
JSONObject json = new JSONObject();
json.put("selected", selected).put("disabled", disabled);
FileOutputStream fos = new FileOutputStream(dockbar);
fos.write(json.toString().getBytes(StandardCharsets.UTF_8));
StreamUtils.writeToFile(mConfig, jsonObj.toString());
} catch (JSONException | IOException e) {
e.printStackTrace();
}
}
public void swap(DockBarAdapter adapter, List<DockBarTab> list, int itemType, int fromPosition, int toPosition){
int curr = adapter.getIndexByViewType(fromPosition, itemType);
int target = adapter.getIndexByViewType(toPosition, itemType);
if(fromPosition < toPosition){
for(int i = curr; i < target; i++) {
Collections.swap(list, i, i + 1);
}
} else {
for(int i = curr; i > target; i--) {
Collections.swap(list, i, i - 1);
}
public void reset() {
mConfig.deleteOnExit();
}
private JSONArray makeJsonArrayWithTabs(List<DockBarTab> list) throws JSONException {
JSONArray array = new JSONArray();
for (DockBarTab tab : list) {
JSONObject item = new JSONObject()
.put("tag", tab.tag)
.put("iconID", tab.iconID)
.put("titleID", tab.titleID)
.put("id", tab.id)
.put("fragmentClass", tab.fragmentClass.getName());
array.put(item);
}
adapter.notifyItemMoved(fromPosition, toPosition);// notifyItemMoved
return array;
}
public void swapAndMigrate(DockBarAdapter adapter, int fromPosition, int toPosition){
int curr = adapter.getIndexByViewType(fromPosition, adapter.getItemType(fromPosition));
int target = adapter.getIndexByViewType(toPosition, adapter.getItemType(toPosition));
if(fromPosition < toPosition){
if(!vkme()){
if(mSelectedTabs.size() <= MIN_SELECTED_TABS_LIMIT || mSelectedTabs.get(curr).tag.equals("tab_menu")){
return;
}
}
DockBarTab tab = mSelectedTabs.get(curr);
mSelectedTabs.remove(tab);
mDisabledTabs.add(tab);
for(int i = mDisabledTabs.size() - 1; i > target; i--) {
Collections.swap(mDisabledTabs, i, i - 1);
}
for(int i = 0; i < target; i++) {
Collections.swap(mDisabledTabs, i, i + 1);
}
} else {
if(mSelectedTabs.size() >= MAX_SELECTED_TABS_LIMIT) return;
DockBarTab tab = mDisabledTabs.get(curr);
mDisabledTabs.remove(tab);
mSelectedTabs.add(tab);
}
adapter.notifyItemMoved(fromPosition, toPosition);// notifyItemMoved
}
public void move(DockBarAdapter adapter, int index){
if(getItemType(index) == 1){
DockBarTab item = mSelectedTabs.get(getIndexByViewType(index, 1));
mSelectedTabs.remove(item);
mDisabledTabs.add(item);
for(int i = mDisabledTabs.size() - 1; i > 0; i--) {
Collections.swap(mDisabledTabs, i, i - 1);
}
adapter.notifyItemRemoved(index); // notifyItemRemoved
adapter.notifyItemInserted(getItemCount() - mDisabledTabs.size()); // notifyItemInserted
}
}
public int getItemCount(){
return mSelectedTabs.size() + mDisabledTabs.size() + mGroups.size();
}
public int getIndexByViewType(int position, int viewType){
if(viewType == DockBarAdapter.SELECTED_TAB_TYPE){
return position - 1;
} else if(viewType == DockBarAdapter.DISABLED_TAB_TYPE){
return position - mSelectedTabs.size() - mGroups.size();
} else {
return position != 0 ? 1 : 0;
}
}
public int getItemType(int position){
if(position == 0 || position == mSelectedTabs.size() + 1){
return DockBarAdapter.GROUP_TITLE_TYPE;
} else if(position - 1 < mSelectedTabs.size()){
return DockBarAdapter.SELECTED_TAB_TYPE;
} else if(position - 1 >= mSelectedTabs.size()){
return DockBarAdapter.DISABLED_TAB_TYPE;
}
return -1;
}
public DockBarTab getSelectedTab(int pos){
return mSelectedTabs.get(getIndexByViewType(pos, 1));
}
public int getTabCount(){
return mSelectedTabs.size();
}
public DockBarTab getDisabledTab(int pos){
return mDisabledTabs.get(getIndexByViewType(pos, 2));
}
public String getGroupTitle(int pos){
return mGroups.get(getIndexByViewType(pos, -1));
}
public List<DockBarTab> getSelectedTabs(){
public List<DockBarTab> getSelectedTabs() {
return mSelectedTabs;
}
public List<DockBarTab> getDisabledTabs(){
public List<DockBarTab> getDisabledTabs() {
return mDisabledTabs;
}
public List<String> getCategoryTitles() {
return mCategoryTitles;
}
}
@@ -10,11 +10,25 @@ public class DockBarTab {
public int id;
public Class<? extends FragmentImpl> fragmentClass;
public DockBarTab(String tag, int iconID, int titleID, int resID, Class<?> fragmentClass){
public DockBarTab(
String tag,
int iconID,
int titleID,
int resID,
Class<?> fragmentClass) {
this.tag = tag;
this.iconID = iconID;
this.titleID = titleID;
this.id = resID;
this.fragmentClass = (Class<? extends FragmentImpl>) fragmentClass;
}
public static DockBarTab valuesOf(
String tag,
int iconID,
int titleID,
int resID,
Class<?> fragmentClass) {
return new DockBarTab(tag, iconID, titleID, resID, fragmentClass);
}
}
@@ -1,6 +1,6 @@
package ru.vtosters.lite.ui.fragments.dockbar;
public interface IItemTouchHelper{
public interface IItemTouchHelper {
void onItemDismiss(int index);
@@ -1,14 +1,15 @@
package ru.vtosters.lite.ui.fragments.dockbar;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
public class ItemTouchHelperCallback extends ItemTouchHelper.Callback{
public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
private final DockBarAdapter mAdapter;
private final DockBarEditorAdapter mAdapter;
public ItemTouchHelperCallback(DockBarAdapter mAdapter){
public ItemTouchHelperCallback(DockBarEditorAdapter mAdapter){
this.mAdapter = mAdapter;
}
@@ -23,11 +24,11 @@ public class ItemTouchHelperCallback extends ItemTouchHelper.Callback{
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder){
int pos = mAdapter.getItemType(viewHolder.getAdapterPosition());
int dragFlags = pos != DockBarAdapter.GROUP_TITLE_TYPE ? androidx.recyclerview.widget.ItemTouchHelper.UP | androidx.recyclerview.widget.ItemTouchHelper.DOWN : 0;
int swipeFlags = pos == 1 ? androidx.recyclerview.widget.ItemTouchHelper.START | androidx.recyclerview.widget.ItemTouchHelper.END : 0;
return makeMovementFlags(dragFlags, swipeFlags);
public int getMovementFlags(@NonNull RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder){
int dragFlags = AdapterHelper.getItemViewType(viewHolder.getAdapterPosition()) != AdapterHelper.CATEGORY_TITLE_TYPE
? ItemTouchHelper.UP | ItemTouchHelper.DOWN
: 0;
return makeMovementFlags(dragFlags, 0);
}
@Override
@@ -37,8 +38,6 @@ public class ItemTouchHelperCallback extends ItemTouchHelper.Callback{
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target){
if(mAdapter.getItemType(viewHolder.getPosition()) == DockBarAdapter.GROUP_TITLE_TYPE)
return false;
return mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
}
}
@@ -2,11 +2,13 @@ package ru.vtosters.lite.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
@@ -20,7 +22,7 @@ import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class StreamUtils {
private static final int BUFFER_SIZE = 2048;
public static final int BUFFER_SIZE = 0x800;
public static byte[] decodeStream(InputStream encIs, String keyURL) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IOException {
CipherInputStream cip = new CipherInputStream(encIs, getCipher(keyURL));
@@ -43,21 +45,32 @@ public class StreamUtils {
return connection.getInputStream();
}
public static String readAllLines(File file) throws IOException {
return readAllLines(new FileInputStream(file));
}
public static String readAllLines(InputStream is) throws IOException {
return new String(readAllBytes(is), "utf-8");
}
public static byte[] readAllBytes(File file) throws IOException {
return readAllBytes(new FileInputStream(file));
}
public static byte[] readAllBytes(InputStream is) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int len = 0;
int len;
while ((len = is.read(buffer)) > 0)
bos.write(buffer, 0, len);
return bos.toByteArray();
}
public static void writeToFile(File file, String content) throws IOException {
writeToFile(file, content.getBytes(StandardCharsets.UTF_8));
}
public static void writeToFile(File file, byte[] content) throws IOException {
if (!file.exists()) file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
fos.write(content);
}