berict/Tapad

View on GitHub
app/src/main/java/com/bedrock/padder/activity/PresetStoreActivity.java

Summary

Maintainability
D
2 days
Test Coverage
package com.bedrock.padder.activity;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.design.widget.TabLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.folderselector.FileChooserDialog;
import com.bedrock.padder.R;
import com.bedrock.padder.fragment.PresetStoreInstalledFragment;
import com.bedrock.padder.fragment.PresetStoreOnlineFragment;
import com.bedrock.padder.fragment.Refreshable;
import com.bedrock.padder.helper.AnimateHelper;
import com.bedrock.padder.helper.FabHelper;
import com.bedrock.padder.helper.FileHelper;
import com.bedrock.padder.helper.IntentHelper;
import com.bedrock.padder.helper.ToolbarHelper;
import com.bedrock.padder.helper.WindowHelper;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

import static com.bedrock.padder.activity.MainActivity.isPresetVisible;
import static com.bedrock.padder.helper.FileHelper.PROJECT_LOCATION_PRESETS;
import static com.bedrock.padder.helper.WindowHelper.getStringFromId;

public class PresetStoreActivity extends AppCompatActivity implements FileChooserDialog.FileCallback {

    private WindowHelper window = new WindowHelper();
    private AnimateHelper anim = new AnimateHelper();
    private ToolbarHelper toolbar = new ToolbarHelper();
    private IntentHelper intent = new IntentHelper();
    private FabHelper fab = new FabHelper();
    private FileHelper fileHelper = new FileHelper();

    private static final int REQUEST_WRITE_STORAGE = 112;
    private boolean hasPermission;

    public static PresetStoreInstalledFragment installedFragment;
    public static PresetStoreOnlineFragment onlineFragment;

    Activity activity = this;

    private String tapadFolderPath = Environment.getExternalStorageDirectory().getPath() + "/Tapad";
    private String themeTitle;
    private String TAG = "PresetStore";

    ViewPager viewPager;
    ViewPagerAdapter viewPagerAdapter;

    private CollapsingToolbarLayout collapsingToolbarLayout = null;

    private int themeColor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_preset_store);

        themeColor = getResources().getColor(R.color.colorPresetStore);
        themeTitle = getResources().getString(R.string.preset_store);

        toolbar.setActionBar(this);
        toolbar.setActionBarDisplayHomeAsUp(true);
        toolbar.setStatusBarTint(this);

        collapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
        collapsingToolbarLayout.setCollapsedTitleTextAppearance(R.style.collapsedAppBar);
        collapsingToolbarLayout.setExpandedTitleTextAppearance(R.style.expandedAppBar);

        window.setNavigationBar(R.color.transparent, activity);

        View statusBar = findViewById(R.id.status_bar);
        if (Build.VERSION.SDK_INT < 21) {
            statusBar.setVisibility(View.GONE);
        } else {
            try {
                statusBar.getLayoutParams().height = window.getStatusBarFromPrefs(activity);
            } catch (NullPointerException e) {
                Log.d("NullExp", e.getMessage());
                statusBar.setVisibility(View.GONE);
            }
        }

        window.setMarginRelativePX(R.id.layout_relative, 0, window.getStatusBarFromPrefs(activity), 0, 0, activity);
        activity.findViewById(R.id.layout_margin).getLayoutParams().height = window.getNavigationBarFromPrefs(activity) + window.convertDPtoPX(10, activity);

        hasPermission = ContextCompat.checkSelfPermission(
                activity,
                Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;

        enterAnim();
        setUi();
        setDirectory();
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case REQUEST_WRITE_STORAGE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // reload my activity with permission granted or use the features what required the permission
                    hasPermission = true;
                    setViewPager();
                } else {
                    // show dialog to grant access
                    new MaterialDialog.Builder(activity)
                            .title(R.string.preset_store_permission_dialog_title)
                            .titleColorRes(R.color.dark_primary)
                            .content(R.string.preset_store_permission_dialog_text)
                            .contentColorRes(R.color.dark_action)
                            .positiveText(R.string.preset_store_permission_dialog_positive)
                            .positiveColorRes(R.color.dark_primary)
                            .onPositive(new MaterialDialog.SingleButtonCallback() {
                                @Override
                                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                                    // go to settings
                                    intent.intentAppDetailSettings(activity, 0);
                                }
                            })
                            .negativeText(R.string.preset_store_permission_dialog_negative)
                            .negativeColorRes(R.color.red_400)
                            .onNegative(new MaterialDialog.SingleButtonCallback() {
                                @Override
                                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                                    // close current activity
                                    finish(100);
                                }
                            })
                            .show();
                    Log.e(TAG, "Permission error");
                }
        }
    }

    private void finish(int delay) {
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                finish();
            }
        }, delay);
    }

    private void setDirectory() {
        // loading start
        Log.d(TAG, "setDirectory");
        if (!hasPermission) {
            // no permission granted
            ActivityCompat.requestPermissions(
                    activity,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    REQUEST_WRITE_STORAGE);
        } else {
            // got the permission
            // Make sdcard/Tapad folder
            File folder = new File(tapadFolderPath);
            if (folder.mkdirs()) {
                Log.i(TAG, "folder successfully created");
            } else {
                // folder exists
                Log.e(TAG, "folder already exists");
            }

            // Make sdcard/Tapad/presets folder
            File presets = new File(tapadFolderPath + "/presets");
            if (presets.mkdirs()) {
                Log.i(TAG, "folder successfully created");
            } else {
                // folder exists
                Log.e(TAG, "folder already exists");
            }
        }
    }

    private void openPreset() {
        new FileChooserDialog.Builder(this)
                .initialPath(Environment.getExternalStorageDirectory().getPath())
                .mimeType("application/zip")
                .tag("optional-identifier")
                .show(this);
        Toast.makeText(activity, R.string.preset_store_open_preset, Toast.LENGTH_LONG).show();
    }

    @Override
    public void onFileSelection(@NonNull FileChooserDialog dialog, @NonNull File file) {
        Log.d(TAG, file.getAbsolutePath());
        final String presetName = getCustomFolderName();

        // install zip
        fileHelper.unzip(file.getAbsolutePath(),
                PROJECT_LOCATION_PRESETS,
                presetName,
                activity,
                new Runnable() {
                    @Override
                    public void run() {
                        Log.d(TAG, "installed " + presetName);
                        setViewPager();
                        setCustomPresetTag(presetName);
                    }
                }
        );
    }

    public void setCustomPresetTag(String tag) {
        String result = fileHelper.getStringFromFile(PROJECT_LOCATION_PRESETS + "/" + tag + "/about/json");

        if (result != null) {
            int tagStart = result.indexOf("\"tag\"") + 7;
            int tagFinish = result.indexOf("\"", tagStart) - 1;
            String previousTag = result.substring(tagStart, tagFinish);

            Log.e(TAG, previousTag);

            result = result.replace(previousTag, tag);

            try {
                FileOutputStream outputStream = openFileOutput(PROJECT_LOCATION_PRESETS + "/" + tag + "/about/json", MODE_PRIVATE);
                OutputStreamWriter streamWriter = new OutputStreamWriter(outputStream);

                streamWriter.write(result);
                streamWriter.flush();
                streamWriter.close();

                Log.i(TAG, "wrote: " + result);
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }

    @Override
    public void onFileChooserDismissed(@NonNull FileChooserDialog dialog) {
    }

    String getCustomFolderName() {
        File files[] = new File(PROJECT_LOCATION_PRESETS).listFiles();
        String folderName = getResources().getString(R.string.custom_preset_folder_name);
        int fileNameCount = 0;
        for (File folder : files) {
            if (folder.getName().startsWith(folderName)) {
                int num = Integer.parseInt(folder.getName().replace(folderName, ""));
                if (fileNameCount < num) {
                    fileNameCount = num;
                }
            }
        }
        // make directory which name is custom-preset-{maxInt + 1}
        File customFolder = new File(PROJECT_LOCATION_PRESETS + "/" + folderName + ++fileNameCount + "/");
        if (customFolder.mkdirs()) {
            Log.d(TAG, "folder created at " + customFolder.getAbsolutePath());
        } else {
            Log.e(TAG, "folder failed to create at " + customFolder.getAbsolutePath());
        }
        return (folderName + fileNameCount);
    }

    private void setViewPager() {
        if (hasPermission) {
            Log.d(TAG, "setViewPager");

            installedFragment = new PresetStoreInstalledFragment();
            onlineFragment = new PresetStoreOnlineFragment();

            viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
            viewPagerAdapter.addFragment(installedFragment, getStringFromId(R.string.tab_1, activity));
            viewPagerAdapter.addFragment(onlineFragment, getStringFromId(R.string.tab_2, activity));

            viewPager = findViewById(R.id.layout_viewpager);
            viewPager.setAdapter(viewPagerAdapter);

            final PresetStoreOnlineFragment onlineFragment = (PresetStoreOnlineFragment) viewPagerAdapter.instantiateItem(viewPager, 1);

            viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                int position = 0;

                // from: https://stackoverflow.com/questions/31319758/how-can-i-animate-the-new-floating-action-button-between-tab-fragment-transition
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                    if (position != 1) {
                        if (positionOffset < 0.5) {
                            if (!fab.isVisible()) {
                                fab.setVisibility(true);
                            }
                            fab.setScale((0.5 - positionOffset) * 2);
                        } else if (positionOffset >= 0.5) {
                            fab.setVisibility(false);
                        }
                    } else {
                        fab.setVisibility(false);
                    }
                }

                @Override
                public void onPageSelected(int position) {
                    this.position = position;
                }

                @Override
                public void onPageScrollStateChanged(int state) {
                    // from: https://stackoverflow.com/questions/20412379/viewpager-update-fragment-on-swipe
                    if (state == ViewPager.SCROLL_STATE_IDLE) {
                        final Fragment fragment = (Fragment) viewPagerAdapter.instantiateItem(viewPager, position);
                        if (fragment != null) {
                            if (fragment instanceof Refreshable) {
                                ((Refreshable) fragment).refresh();
//                                new Handler().postDelayed(new Runnable() {
//                                    @Override
//                                    public void run() {
//                                    }
//                                }, 2000);
                            } else {
                                Log.d(TAG, "Not an instance of any sub fragment");
                            }
                        }
                    } else {
                        onlineFragment.setLoadingFinished(false);
                    }
                }
            });

            TabLayout tabLayout = findViewById(R.id.layout_tab_layout);
            tabLayout.setupWithViewPager(viewPager);
//            tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
//                @Override
//                public void onTabSelected(TabLayout.Tab tab) {
//                    if (tab.getPosition() == 0) {
//                        // show open preset fab
//                        if (!fab.isVisible()) {
//                            Log.d(TAG, "show from tabLayout");
//                            fab.show();
//                        }
//                    } else {
//                        if (onlineFragment != null) {
//                            ((PresetStoreOnlineFragment) onlineFragment).clear();
//                        }
//                        if (fab.isVisible()) {
//                            fab.hide();
//                        }
//                    }
//                }
//
//                @Override
//                public void onTabUnselected(TabLayout.Tab tab) {}
//
//                @Override
//                public void onTabReselected(TabLayout.Tab tab) {}
//            });
        }
    }

    private void setFab() {
        fab.set(activity);
        fab.setIcon(R.drawable.ic_search_white, activity);
        fab.setOnClickListener(new Runnable() {
            @Override
            public void run() {
                openPreset();
            }
        });

        // set bottom margin
        window.setMarginRelativePX(R.id.fab, 0, 0,
                window.convertDPtoPX(20, activity),
                window.getNavigationBarFromPrefs(activity) + window.convertDPtoPX(20, activity),
                activity);
    }

    private void setUi() {
        // status bar
        activity.findViewById(R.id.status_bar).setBackgroundColor(themeColor);

        // action bar
        collapsingToolbarLayout.setContentScrimColor(themeColor);
        collapsingToolbarLayout.setStatusBarScrimColor(themeColor);
        collapsingToolbarLayout.setTitle(themeTitle);

        // set taskDesc
        window.setRecentColor(themeTitle, themeColor, activity);

        // title image / text
        ((ImageView) activity.findViewById(R.id.layout_image)).setImageResource(R.drawable.about_image_preset_store);

        // fab
        setFab();

        // viewpager
        setViewPager();
    }

    @Override
    protected void onDestroy() {
        // remove all callbacks
        super.onDestroy();
    }

    @Override
    public void onBackPressed() {
        isPresetVisible = true;
        anim.fadeOut(R.id.layout_nested_scrollview, 0, 200, activity);
        anim.fadeOut(R.id.layout_text, 100, 200, activity);
        Handler delay = new Handler();
        delay.postDelayed(new Runnable() {
            @Override
            public void run() {
                PresetStoreActivity.super.onBackPressed();
            }
        }, 300);
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        pressBack();
        return true;
    }

    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);

        if (hasFocus) {
            window.setGone(R.id.layout_placeholder, 0, activity);
            // reset taskDesc
            window.setRecentColor(themeTitle, themeColor, activity);
        }
    }

    void enterAnim() {
        anim.fadeIn(R.id.layout_text, 100, 200, "titleIn", activity);
        anim.fadeIn(R.id.layout_preset_store, 200, 200, "presetIn", activity);
    }

    void pressBack() {
        KeyEvent kDown = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
        activity.dispatchKeyEvent(kDown);
        KeyEvent kUp = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
        activity.dispatchKeyEvent(kUp);
    }

    private class ViewPagerAdapter extends FragmentStatePagerAdapter {
        private final List<Fragment> mFragmentList = new ArrayList<>();
        private final List<String> mFragmentTitleList = new ArrayList<>();

        public ViewPagerAdapter(FragmentManager manager) {
            super(manager);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragmentList.get(position);
        }

        @Override
        public int getCount() {
            return mFragmentList.size();
        }

        public void addFragment(Fragment fragment, String title) {
            mFragmentList.add(fragment);
            mFragmentTitleList.add(title);
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mFragmentTitleList.get(position);
        }

        @Override
        public int getItemPosition(Object object) {
            return POSITION_NONE;
        }
    }
}