/** * 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.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.DefaultItemAnimator; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; 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.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; /** * A {@link android.support.v4.app.Fragment} used by {@link FileLocalPagerFragment} to buildDisplay the public cloud {@link FileModel}. */ public class FileCloudFragment extends BackFragment implements FileLocalPagerFragment.ListController, FileModelAdapter.OnFileClickListener, FileModelAdapter.OnFileLongClickListener, FileModelListener, SwipeRefreshLayout.OnRefreshListener, FileCloudFabManager.FabController { /** * A key for the view pager position. */ private static final String ARG_POSITION_IN_VIEW_PAGER = "FileCloudFragment.Args.ARG_POSITION_IN_VIEW_PAGER"; @NonNull private final List<FileModel> mFilesList = new ArrayList<>(); @NonNull private final List<FileModel> mFilesToCut = new ArrayList<>(); private RecyclerView mRecyclerView; private FileModelAdapter mAdapterModelFile; private ProgressBar mProgressBar; private TextView mMessageTextView; private SwipeRefreshLayout mSwipeRefreshLayout; private int mPositionInViewPager; private FileManager mFileManager; private FileCloudFabManager mFileCloudFabManager; public static FileCloudFragment newInstance(final int positionInViewPager) { final FileCloudFragment fileCloudFragment = new FileCloudFragment(); final Bundle args = new Bundle(); args.putInt(ARG_POSITION_IN_VIEW_PAGER, positionInViewPager); fileCloudFragment.setArguments(args); return fileCloudFragment; } @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()"); } mFileManager = FileManager.getInstance(getContext()); mFileCloudFabManager = FileCloudFabManager.getInstance(); mPositionInViewPager = args.getInt(ARG_POSITION_IN_VIEW_PAGER); mFileCloudFabManager.addFabController(mPositionInViewPager, this); } @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(); 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)); } mAdapterModelFile = new FileModelAdapter(getContext(), mFilesList, this, this, this); mRecyclerView.setAdapter(mAdapterModelFile); mRecyclerView.setItemAnimator(/*new SlideInFromLeftItemAnimator(mRecyclerView)*/new DefaultItemAnimator()); //mRecyclerView.addItemDecoration(new FileDivider(ContextCompat.getColor(mActivity, R.color.file_divider))); refreshCurrentList(); return rootView; } @Override public boolean back() { if (hasItemSelected()) { deselectAll(); return true; } else if (!mFilesToCut.isEmpty()) { mFilesToCut.clear(); //refreshFab(); return true; } return false; } @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: FileCloudFragment.this.mFileCloudFabManager.updateFabButtons(); new FileAddDialog(getActivity(), -1, new IListener() { @Override public void execute() { refreshCurrentList(); } }, new IListener() { // Dismiss @Override public void execute() { FileCloudFragment.this.mFileCloudFabManager.updateFabButtons(); } }); break; case 1: //FileCloudFragment.this.url = ""; Toast.makeText(getActivity(), getString(R.string.not_implemented), Toast.LENGTH_SHORT).show(); FileCloudFragment.this.refreshCurrentList(); break; } } @Override public boolean isFabVisible( final @IntRange(from = 0, to = FileCloudFabManager.NUMBER_MAX_OF_FAB - 1) int fabPosition) { return false; } @Override public int getFabImageResource( final @IntRange(from = 0, to = FileCloudFabManager.NUMBER_MAX_OF_FAB - 1) int fabPosition) { switch (fabPosition) { case 0: if (!mFilesToCut.isEmpty()) { return R.drawable.ic_menu_paste_holo_dark; } else { return R.drawable.add; } case 1: return R.drawable.arrow_up; } return android.R.drawable.ic_input_add; } @Override public void onFileClick(View view, int position) { /*if (hasItemSelected()) { mFilesList.get(position).selected = !mFilesList.get(position).selected; mAdapterModelFile.notifyItemChanged(position); } else */ if (mFilesList.get(position).isDirectory()) { //FileCloudFragment.this.url = mFilesList.get(position).getUrl() + "/"; Toast.makeText(getActivity(), getString(R.string.not_implemented), Toast.LENGTH_SHORT).show(); refreshCurrentList(); } else { mFileManager.execute(getActivity(), position, mFilesList, view); } } @Override public boolean onFileLongClick(View view, int position) { /*mFilesList.get(position).selected = !mFilesList.get(position).selected; mAdapterModelFile.notifyItemChanged(position); */ return true; } @Override public void executeFileModel(final FileModel fileModel, final View view) { final AlertDialog.Builder menuAlert = new AlertDialog.Builder(getActivity()); String[] menuList = {getString(R.string.download)}; if (!fileModel.isDirectory() && mFileManager.isMine(fileModel)) { 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 { 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(getActivity(), "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 (!mFilesToCut.isEmpty()) { mFilesToCut.clear(); //refreshFab(); } } }); } }, "Cancel", null, fileModel.getFullName()); break; case 2: DialogUtils.alert( getContext(), "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 (!mFilesToCut.isEmpty()) { mFilesToCut.clear(); //refreshFab(); } } }); } }, "No", null); break; case 3: FileCloudFragment.this.mFilesToCut.add(fileModel); Toast.makeText(getContext(), "File ready to cut.", Toast.LENGTH_SHORT).show(); break; case 4: DialogUtils.alert(getContext(), getString(R.string.properties) + " : " + fileModel.getName(), mFileManager.toSpanned(getActivity(), fileModel), "OK", null, null, null); break; case 5: mFileManager.setPublic(fileModel, !fileModel.isPublic(), new IListener() { @Override public void execute() { } }); break; // Picture set as profile case 6: 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(); break; } } }); AlertDialog menuDrop = menuAlert.create(); menuDrop.show(); } /** * {@inheritDoc} */ @Override public void onRefresh() { refreshCurrentList(); } /** * {@inheritDoc} */ @Override public void refreshCurrentList() { if (!isAdded()) { return; } if (NetUtils.isInternetConnection(getContext()) && Config.isLogged()) { mFileManager.getFiles( new FileModel.FileModelBuilder().id(-1).isOnline(true).build(), false, false, new ResultCallback<List<FileModel>>() { @Override public void success(List<FileModel> result) { mSwipeRefreshLayout.setRefreshing(false); mFilesList.clear(); mFilesList.addAll(result); updateAdapter(); } @Override public void failure() { mSwipeRefreshLayout.setRefreshing(false); } }); } else { mSwipeRefreshLayout.setRefreshing(false); this.mProgressBar.setVisibility(View.GONE); if (isAdded()) { this.mMessageTextView.setText(Config.isLogged() ? getString(R.string.no_internet_connection) : getString(R.string.no_logged)); } this.mMessageTextView.setVisibility(View.VISIBLE); if (!NetUtils.isInternetConnection(getContext())) { this.setListVisibility(false); //refreshFab(); } } } public void updateAdapter() { if (mRecyclerView != null && this.isAdded()) { mProgressBar.setVisibility(View.GONE); if (!NetUtils.isInternetConnection(getContext())) { mMessageTextView.setText(getString(R.string.no_internet_connection)); } else if (mFilesList.isEmpty()) { /* if (this.url == null) this.mMessageTextView.setText(getString(R.string.no_file_server)); else if (this.url.equals("")) this.mMessageTextView.setText(getString(R.string.no_file_server)); else this.mMessageTextView.setText(getString(R.string.no_file_directory)); */ mMessageTextView.setText(getString(R.string.no_file_server)); mMessageTextView.setVisibility(View.VISIBLE); } else { this.mMessageTextView.setVisibility(View.GONE); } mAdapterModelFile.setList(mFilesList); //refreshFab(); } } public boolean hasItemSelected() { /* for (FileModel file : mFilesList) if (file.selected) return true; */ return false; } public void deselectAll() { /* for (FileModel file : mFilesList) file.selected = false; updateAdapter(); */ } private void setListVisibility(boolean visible) { if (this.mRecyclerView != null) { this.mRecyclerView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); } } }