/**
* This file is part of FileSpace for Android, an app for managing your server (files, talks...).
* <p>
* Copyright (c) 2014-2015 FileSpace for Android contributors (http://mercandalli.com)
* <p>
* LICENSE:
* <p>
* FileSpace for Android 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 2 of the License, or (at your option) any
* later version.
* <p>
* FileSpace for Android 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.
*
* @author Jonathan Mercandalli
* @license http://www.gnu.org/licenses/gpl.html
* @copyright 2014-2015 FileSpace for Android contributors (http://mercandalli.com)
*/
package com.mercandalli.android.apps.files.file.cloud;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.mercandalli.android.apps.files.R;
import com.mercandalli.android.apps.files.common.animation.ScaleAnimationAdapter;
import com.mercandalli.android.apps.files.common.fragment.BackFragment;
import com.mercandalli.android.apps.files.common.listener.IListener;
import com.mercandalli.android.apps.files.common.listener.IPostExecuteListener;
import com.mercandalli.android.apps.files.common.listener.ResultCallback;
import com.mercandalli.android.apps.files.common.net.TaskPost;
import com.mercandalli.android.apps.files.common.util.StringPair;
import com.mercandalli.android.apps.files.file.FileAddDialog;
import com.mercandalli.android.apps.files.file.FileManager;
import com.mercandalli.android.apps.files.file.FileModel;
import com.mercandalli.android.apps.files.file.FileModelAdapter;
import com.mercandalli.android.apps.files.file.FileModelListener;
import com.mercandalli.android.apps.files.file.FileTypeModelENUM;
import com.mercandalli.android.apps.files.file.cloud.fab.FileCloudFabManager;
import com.mercandalli.android.apps.files.file.local.FileLocalPagerFragment;
import com.mercandalli.android.apps.files.main.Config;
import com.mercandalli.android.apps.files.main.Constants;
import com.mercandalli.android.apps.files.main.network.NetUtils;
import com.mercandalli.android.library.base.dialog.DialogUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class FileMyCloudFragment extends BackFragment implements
FileLocalPagerFragment.ListController,
SwipeRefreshLayout.OnRefreshListener,
FileCloudFabManager.FabController {
/**
* A key for the view pager position.
*/
private static final String ARG_POSITION_IN_VIEW_PAGER = "FileMyCloudFragment.Args.ARG_POSITION_IN_VIEW_PAGER";
@NonNull
private final ArrayList<FileModel> mFilesList = new ArrayList<>();
@NonNull
private final Stack<Integer> mIdFileDirectoryStack = new Stack<>();
@NonNull
private final List<FileModel> mFilesToCutList = new ArrayList<>();
private RecyclerView mRecyclerView;
private FileModelAdapter mFileModelAdapter;
private ProgressBar mProgressBar;
private TextView mMessageTextView;
private SwipeRefreshLayout mSwipeRefreshLayout;
private int mPositionInViewPager;
private boolean mForceFab0Hidden = false;
private ScaleAnimationAdapter scaleAnimationAdapter;
private FileManager mFileManager;
private FileCloudFabManager mFileCloudFabManager;
public static FileMyCloudFragment newInstance(final int positionInViewPager) {
final FileMyCloudFragment fileMyCloudLocalFragment = new FileMyCloudFragment();
final Bundle args = new Bundle();
args.putInt(ARG_POSITION_IN_VIEW_PAGER, positionInViewPager);
fileMyCloudLocalFragment.setArguments(args);
return fileMyCloudLocalFragment;
}
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Bundle args = getArguments();
if (!args.containsKey(ARG_POSITION_IN_VIEW_PAGER)) {
throw new IllegalStateException("Missing args. Please use newInstance()");
}
mPositionInViewPager = args.getInt(ARG_POSITION_IN_VIEW_PAGER);
mFileCloudFabManager = FileCloudFabManager.getInstance();
mFileCloudFabManager.addFabController(mPositionInViewPager, this);
mFileManager = FileManager.getInstance(getContext());
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_file_files, container, false);
final Activity activity = getActivity();
final String succeed = "succeed";
mProgressBar = (ProgressBar) rootView.findViewById(R.id.circularProgressBar);
mMessageTextView = (TextView) rootView.findViewById(R.id.message);
mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.fragment_file_files_swipe_refresh_layout);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.setColorSchemeResources(
android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_file_files_recycler_view);
mRecyclerView.setHasFixedSize(true);
final int nbColumn = getResources().getInteger(R.integer.column_number_card);
if (nbColumn <= 1) {
mRecyclerView.setLayoutManager(new LinearLayoutManager(activity));
} else {
mRecyclerView.setLayoutManager(new GridLayoutManager(activity, nbColumn));
}
resetPath();
mFileModelAdapter = new FileModelAdapter(getContext(), mFilesList, new FileModelListener() {
@Override
public void executeFileModel(final FileModel fileModel, final View view) {
final AlertDialog.Builder menuAlert = new AlertDialog.Builder(getContext());
String[] menuList = {getString(R.string.download), getString(R.string.rename), getString(R.string.delete), getString(R.string.cut), getString(R.string.properties)};
if (!fileModel.isDirectory()) {
if (FileTypeModelENUM.IMAGE.type.equals(fileModel.getType())) {
menuList = new String[]{getString(R.string.download), getString(R.string.rename), getString(R.string.delete), getString(R.string.cut), getString(R.string.properties), (fileModel.isPublic()) ? "Become private" : "Become public", "Set as profile"};
} else if (FileTypeModelENUM.APK.type.equals(fileModel.getType()) && Config.isUserAdmin()) {
menuList = new String[]{getString(R.string.download), getString(R.string.rename), getString(R.string.delete), getString(R.string.cut), getString(R.string.properties), (fileModel.isPublic()) ? "Become private" : "Become public", (fileModel.isApkUpdate()) ? "Remove the update" : "Set as update"};
} else {
menuList = new String[]{getString(R.string.download), getString(R.string.rename), getString(R.string.delete), getString(R.string.cut), getString(R.string.properties), (fileModel.isPublic()) ? "Become private" : "Become public"};
}
}
menuAlert.setTitle(getString(R.string.action));
menuAlert.setItems(menuList,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
switch (item) {
case 0:
mFileManager.download(getActivity(), fileModel, new IListener() {
@Override
public void execute() {
Toast.makeText(getContext(), "Download finished.", Toast.LENGTH_SHORT).show();
}
});
break;
case 1:
DialogUtils.prompt(
getActivity(),
"Rename",
"Rename " + (fileModel.isDirectory() ? "directory" : "file") + " " + fileModel.getName() + " ?",
"Ok",
new DialogUtils.OnDialogUtilsStringListener() {
@Override
public void onDialogUtilsStringCalledBack(String text) {
mFileManager.rename(fileModel, text, new IListener() {
@Override
public void execute() {
if (mFilesToCutList.size() != 0) {
mFilesToCutList.clear();
mFileCloudFabManager.updateFabButtons();
}
refreshCurrentList();
}
});
}
}, "Cancel", null, fileModel.getFullName());
break;
case 2:
DialogUtils.alert(
getActivity(),
"Delete",
"Delete " + (fileModel.isDirectory() ? "directory" : "file") + " " + fileModel.getName() + " ?",
"Yes",
new DialogUtils.OnDialogUtilsListener() {
@Override
public void onDialogUtilsCalledBack() {
mFileManager.delete(fileModel, new IListener() {
@Override
public void execute() {
if (mFilesToCutList.size() != 0) {
mFilesToCutList.clear();
mFileCloudFabManager.updateFabButtons();
}
refreshCurrentList();
}
});
}
}, "No", null);
break;
case 3:
mFilesToCutList.add(fileModel);
Toast.makeText(getContext(), "File ready to cut.", Toast.LENGTH_SHORT).show();
mFileCloudFabManager.updateFabButtons();
break;
case 4:
DialogUtils.alert(getActivity(),
getString(R.string.properties) + " : " + fileModel.getName(),
mFileManager.toSpanned(getContext(), fileModel),
"OK",
null,
null,
null);
Html.fromHtml("");
break;
case 5:
mFileManager.setPublic(fileModel, !fileModel.isPublic(), new IListener() {
@Override
public void execute() {
}
});
break;
case 6:
// Picture set as profile
if (FileTypeModelENUM.IMAGE.type.equals(fileModel.getType())) {
List<StringPair> parameters = new ArrayList<>();
parameters.add(new StringPair("id_file_profile_picture", "" + fileModel.getId()));
(new TaskPost(getActivity(), Constants.URL_DOMAIN + Config.ROUTE_USER_PUT, new IPostExecuteListener() {
@Override
public void onPostExecute(JSONObject json, String body) {
try {
if (json != null && json.has(succeed) && json.getBoolean(succeed)) {
Config.setUserIdFileProfilePicture(getActivity(), fileModel.getId());
}
} catch (JSONException e) {
Log.e(getClass().getName(), "Failed to convert Json", e);
}
}
}, parameters)).execute();
} else if (FileTypeModelENUM.APK.type.equals(fileModel.getType()) && Config.isUserAdmin()) {
List<StringPair> parameters = new ArrayList<>();
parameters.add(new StringPair("is_apk_update", "" + !fileModel.isApkUpdate()));
(new TaskPost(getActivity(), Constants.URL_DOMAIN + Config.ROUTE_FILE + "/" + fileModel.getId(), new IPostExecuteListener() {
@Override
public void onPostExecute(JSONObject json, String body) {
try {
if (json != null && json.has(succeed) && json.getBoolean(succeed)) {
}
} catch (JSONException e) {
Log.e(getClass().getName(), "Failed to convert Json", e);
}
}
}, parameters)).execute();
}
break;
}
}
});
AlertDialog menuDrop = menuAlert.create();
menuDrop.show();
}
}, new FileModelAdapter.OnFileClickListener() {
@Override
public void onFileClick(View view, int position) {
/*
if (hasItemSelected()) {
mFilesList.get(position).selected = !mFilesList.get(position).selected;
mFileModelAdapter.notifyItemChanged(position);
}
else
*/
if (mFilesList.get(position).isDirectory()) {
mIdFileDirectoryStack.add(mFilesList.get(position).getId());
refreshCurrentList(true);
} else {
mFileManager.execute(getActivity(), position, mFilesList, view);
}
}
}, new FileModelAdapter.OnFileLongClickListener() {
@Override
public boolean onFileLongClick(View view, int position) {
/*
mFilesList.get(position).selected = !mFilesList.get(position).selected;
mFileModelAdapter.notifyItemChanged(position);
*/
return true;
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
scaleAnimationAdapter = new ScaleAnimationAdapter(mRecyclerView, mFileModelAdapter);
scaleAnimationAdapter.setDuration(220);
scaleAnimationAdapter.setOffsetDuration(32);
mRecyclerView.setAdapter(scaleAnimationAdapter);
} else {
mRecyclerView.setAdapter(mFileModelAdapter);
}
refreshCurrentList(true);
return rootView;
}
@Override
public void refreshCurrentList() {
if (!isAdded()) {
return;
}
final boolean internetConnection = NetUtils.isInternetConnection(getContext());
if (!internetConnection || !Config.isLogged()) {
mSwipeRefreshLayout.setRefreshing(false);
mProgressBar.setVisibility(View.GONE);
if (isAdded()) {
mMessageTextView.setText(Config.isLogged() ? getString(R.string.no_internet_connection) : getString(R.string.no_logged));
}
mMessageTextView.setVisibility(View.VISIBLE);
if (!internetConnection) {
mRecyclerView.setVisibility(View.GONE);
mFileCloudFabManager.updateFabButtons();
}
return;
}
mFileManager.getFiles(
new FileModel.FileModelBuilder().id(mIdFileDirectoryStack.peek()).isOnline(true).build(),
true,
new ResultCallback<List<FileModel>>() {
@Override
public void success(List<FileModel> result) {
mSwipeRefreshLayout.setRefreshing(false);
mFilesList.clear();
mFilesList.addAll(result);
updateAdapter();
}
@Override
public void failure() {
Toast.makeText(getContext(), R.string.action_failed, Toast.LENGTH_SHORT).show();
mSwipeRefreshLayout.setRefreshing(false);
}
});
}
@Override
public void updateAdapter() {
if (mRecyclerView != null && isAdded()) {
if (mFilesList.size() == 0) {
if (mIdFileDirectoryStack.peek() == -1) {
mMessageTextView.setText(getString(R.string.no_file_server));
} else {
mMessageTextView.setText(getString(R.string.no_file_directory));
}
mMessageTextView.setVisibility(View.VISIBLE);
} else {
mMessageTextView.setVisibility(View.GONE);
}
mRecyclerView.scrollToPosition(0);
scaleAnimationAdapter.reset();
mFileModelAdapter.setList(mFilesList);
mFileCloudFabManager.updateFabButtons();
mProgressBar.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.VISIBLE);
}
}
@Override
public boolean back() {
if (hasItemSelected()) {
deselectAll();
return true;
} else if (mIdFileDirectoryStack.peek() != -1) {
mIdFileDirectoryStack.pop();
refreshCurrentList();
return true;
} else if (mFilesToCutList.size() != 0) {
mFilesToCutList.clear();
mFileCloudFabManager.updateFabButtons();
return true;
} else {
return false;
}
}
//region FloatingActionButton
@Override
public void onFabClick(
final @IntRange(from = 0, to = FileCloudFabManager.NUMBER_MAX_OF_FAB - 1) int fabPosition,
final @NonNull FloatingActionButton floatingActionButton) {
switch (fabPosition) {
case 0:
if (mFilesToCutList.size() != 0) {
for (FileModel file : mFilesToCutList) {
mFileManager.setParent(file, mIdFileDirectoryStack.peek(), new IListener() {
@Override
public void execute() {
FileMyCloudFragment.this.refreshCurrentList();
}
});
}
mFilesToCutList.clear();
} else {
mForceFab0Hidden = true;
new FileAddDialog(getActivity(), mIdFileDirectoryStack.peek(), new IListener() {
@Override
public void execute() {
refreshCurrentList(true);
}
}, new IListener() { // Dismiss
@Override
public void execute() {
mForceFab0Hidden = false;
FileMyCloudFragment.this.mFileCloudFabManager.updateFabButtons();
}
});
}
FileMyCloudFragment.this.mFileCloudFabManager.updateFabButtons();
break;
case 1:
if (mIdFileDirectoryStack.peek() != -1) {
mIdFileDirectoryStack.pop();
refreshCurrentList(true);
}
break;
}
}
@Override
public boolean isFabVisible(
final @IntRange(from = 0, to = FileCloudFabManager.NUMBER_MAX_OF_FAB - 1) int fabPosition) {
if ((!NetUtils.isInternetConnection(getContext()) || !Config.isLogged())) {
return false;
}
switch (fabPosition) {
case 0:
return !mForceFab0Hidden;
case 1:
return !(mIdFileDirectoryStack.size() == 0) && mIdFileDirectoryStack.peek() != -1;
}
return false;
}
@Override
public int getFabImageResource(
final @IntRange(from = 0, to = FileCloudFabManager.NUMBER_MAX_OF_FAB - 1) int fabPosition) {
switch (fabPosition) {
case 0:
if (mFilesToCutList.size() != 0) {
return R.drawable.ic_menu_paste_holo_dark;
} else {
return R.drawable.add;
}
case 1:
return R.drawable.arrow_up;
}
return R.drawable.add;
}
//endregion FloatingActionButton
/*
@Override
public void onFabClick(int fabId, final FloatingActionButton fab) {
switch (fabId) {
case 0:
if (mFilesToCutList.size() != 0) {
for (FileModel file : mFilesToCutList) {
mFileManager.setParent(file, mIdFileDirectoryStack.peek(), new IListener() {
@Override
public void execute() {
mApplicationCallback.refreshData();
}
});
}
mFilesToCutList.clear();
} else {
fab.hide();
new FileAddDialog(getActivity(), mApplicationCallback, mIdFileDirectoryStack.peek(), new IListener() {
@Override
public void execute() {
refreshCurrentList(true);
}
}, new IListener() { // Dismiss
@Override
public void execute() {
fab.show();
}
});
}
refreshFab();
break;
case 1:
if (mIdFileDirectoryStack.peek() != -1) {
mIdFileDirectoryStack.pop();
refreshCurrentList(true);
}
break;
}
}
@Override
public boolean isFabVisible(int fabId) {
if (mApplicationCallback != null && (!NetUtils.isInternetConnection(getContext()) || !mApplicationCallback.isLogged())) {
return false;
}
switch (fabId) {
case 0:
return true;
case 1:
return !(mIdFileDirectoryStack.size() == 0) && mIdFileDirectoryStack.peek() != -1;
}
return false;
}
@Override
public int getFabImageResource(int fabId) {
switch (fabId) {
case 0:
if (mFilesToCutList.size() != 0) {
return R.drawable.ic_menu_paste_holo_dark;
} else {
return R.drawable.add;
}
case 1:
return R.drawable.arrow_up;
}
return R.drawable.add;
}
*/
@Override
public void onRefresh() {
refreshCurrentList();
}
public boolean hasItemSelected() {
/*
for (ModelFile file : mFilesList)
if (file.selected)
return true;
*/
return false;
}
public void deselectAll() {
/*
for (ModelFile file : mFilesList)
file.selected = false;
*/
updateAdapter();
}
public void resetPath() {
mIdFileDirectoryStack.clear();
mIdFileDirectoryStack.add(-1);
}
private void refreshCurrentList(final boolean showProgressBar) {
if (showProgressBar) {
mProgressBar.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.GONE);
mFileModelAdapter.setList(new ArrayList<FileModel>());
}
refreshCurrentList();
}
}