package org.wordpress.android.ui.media; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.ActionMode; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.Toast; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import org.wordpress.android.R; import org.wordpress.android.WordPress; import org.wordpress.android.fluxc.Dispatcher; import org.wordpress.android.fluxc.generated.MediaActionBuilder; import org.wordpress.android.fluxc.model.MediaModel; import org.wordpress.android.fluxc.model.SiteModel; import org.wordpress.android.fluxc.store.MediaStore; import org.wordpress.android.fluxc.store.MediaStore.FetchMediaListPayload; import org.wordpress.android.fluxc.store.MediaStore.OnMediaListFetched; import org.wordpress.android.fluxc.tools.FluxCImageLoader; import org.wordpress.android.util.ListUtils; import org.wordpress.android.util.ToastUtils; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; /** * An activity where the user can add new images to their media gallery or where the user * can choose a single image to embed into their post. */ public class MediaGalleryPickerActivity extends AppCompatActivity implements MediaGridAdapter.MediaGridAdapterCallback { public static final int REQUEST_CODE = 4000; public static final String PARAM_SELECT_ONE_ITEM = "PARAM_SELECT_ONE_ITEM"; public static final String PARAM_SELECTED_IDS = "PARAM_SELECTED_IDS"; public static final String RESULT_IDS = "RESULT_IDS"; public static final String TAG = MediaGalleryPickerActivity.class.getSimpleName(); private static final String STATE_FILTERED_ITEMS = "STATE_FILTERED_ITEMS"; private static final String STATE_SELECTED_ITEMS = "STATE_SELECTED_ITEMS"; private static final String STATE_IS_SELECT_ONE_ITEM = "STATE_IS_SELECT_ONE_ITEM"; private RecyclerView mRecycler; private MediaGridAdapter mGridAdapter; private GridLayoutManager mGridManager; private ActionMode mActionMode; private ArrayList<Long> mFilteredItems; private boolean mIsSelectOneItem; private boolean mIsFetching; private boolean mHasRetrievedAllMedia; private SiteModel mSite; @Inject Dispatcher mDispatcher; @Inject MediaStore mMediaStore; @Inject FluxCImageLoader mImageLoader; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ((WordPress) getApplication()).component().inject(this); ArrayList<Integer> selectedItems = new ArrayList<>(); mIsSelectOneItem = getIntent().getBooleanExtra(PARAM_SELECT_ONE_ITEM, false); ArrayList<Integer> prevSelectedItems = ListUtils.fromIntArray(getIntent().getIntArrayExtra(PARAM_SELECTED_IDS)); if (prevSelectedItems != null) { selectedItems.addAll(prevSelectedItems); } if (savedInstanceState != null) { mSite = (SiteModel) savedInstanceState.getSerializable(WordPress.SITE); mIsSelectOneItem = savedInstanceState.getBoolean(STATE_IS_SELECT_ONE_ITEM, mIsSelectOneItem); if (savedInstanceState.containsKey(STATE_SELECTED_ITEMS)) { ArrayList<Integer> list = ListUtils.fromIntArray(savedInstanceState.getIntArray(STATE_SELECTED_ITEMS)); selectedItems.addAll(list); } if (savedInstanceState.containsKey(STATE_FILTERED_ITEMS)) { mFilteredItems = ListUtils.fromLongArray(savedInstanceState.getLongArray(STATE_FILTERED_ITEMS)); } } else { mSite = (SiteModel) getIntent().getSerializableExtra(WordPress.SITE); } if (mSite == null) { ToastUtils.showToast(this, R.string.blog_not_found, ToastUtils.Duration.SHORT); finish(); return; } setContentView(R.layout.media_gallery_picker_layout); ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); } mRecycler = (RecyclerView) findViewById(R.id.recycler); int numColumns = MediaGridAdapter.getColumnCount(this); mGridManager = new GridLayoutManager(this, numColumns); mRecycler.setLayoutManager(mGridManager); mGridAdapter = new MediaGridAdapter(this, mSite, mImageLoader); mGridAdapter.setCallback(this); mRecycler.setAdapter(mGridAdapter); if (mIsSelectOneItem) { mGridAdapter.setAllowMultiselect(false); } else { mGridAdapter.setAllowMultiselect(true); if (selectedItems.size() > 0) { mGridAdapter.setInMultiSelect(true); mGridAdapter.setSelectedItems(selectedItems); } } } @Override public void onStart() { super.onStart(); mDispatcher.register(this); } @Override public void onStop() { mDispatcher.unregister(this); super.onStop(); } @Override public void onResume() { super.onResume(); refreshViews(); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { setResult(RESULT_CANCELED, new Intent()); finish(); } return super.onOptionsItemSelected(item); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putIntArray(STATE_SELECTED_ITEMS, ListUtils.toIntArray(mGridAdapter.getSelectedItems())); outState.putLongArray(STATE_FILTERED_ITEMS, ListUtils.toLongArray(mFilteredItems)); outState.putBoolean(STATE_IS_SELECT_ONE_ITEM, mIsSelectOneItem); outState.putSerializable(WordPress.SITE, mSite); } @SuppressWarnings("unused") @Subscribe(threadMode = ThreadMode.MAIN) public void onMediaListFetched(OnMediaListFetched event) { mIsFetching = false; if (event.isError()) { mHasRetrievedAllMedia = true; mGridAdapter.setHasRetrievedAll(true); String message = null; switch (event.error.type) { case GENERIC_ERROR: message = getString(R.string.error_refresh_media); break; } if (message != null) { Toast.makeText(MediaGalleryPickerActivity.this, message, Toast.LENGTH_SHORT).show(); } } else { mHasRetrievedAllMedia = !event.canLoadMore; mGridAdapter.setHasRetrievedAll(mHasRetrievedAllMedia); if (mMediaStore.getSiteMediaCount(mSite) == 0 && mHasRetrievedAllMedia) { // There is no media at all noMediaFinish(); } // the activity may be gone by the time this finishes, so check for it if (!isFinishing()) { List<MediaModel> mediaList; if (mFilteredItems != null && !mFilteredItems.isEmpty()) { mediaList = mMediaStore.getSiteImagesExcludingIds(mSite, mFilteredItems); } else { mediaList = mMediaStore.getSiteImages(mSite); } mGridAdapter.setMediaList(mediaList); } } } @Override public void onAdapterFetchMoreData() { if (!mHasRetrievedAllMedia) { refreshMediaFromServer(true); } } @Override public void onAdapterRetryUpload(int localMediaId) { } @Override public void onAdapterItemSelected(View sourceView, int position) { Intent intent = new Intent(); int localId = mGridAdapter.getLocalMediaIdAtPosition(position); ArrayList<Long> remoteMediaIds = new ArrayList<>(); MediaModel media = mMediaStore.getMediaWithLocalId(localId); if (media != null) { remoteMediaIds.add(media.getMediaId()); intent.putExtra(RESULT_IDS, ListUtils.toLongArray(remoteMediaIds)); setResult(RESULT_OK, intent); finish(); } } @Override public void onAdapterSelectionCountChanged(int count) { if (!mIsSelectOneItem) { if (mActionMode == null) { startActionMode(new ActionModeCallback()); } else if (count == 0) { mActionMode.finish(); } else { updateActionModeTitle(count); } } } private void updateActionModeTitle(int count) { if (mActionMode != null) { mActionMode.setTitle(String.format(getString(R.string.cab_selected), count)); MenuItem item = mActionMode.getMenu().findItem(R.id.mnu_confirm_selection); item.setVisible(count > 0); } } private void refreshViews() { List<MediaModel> mediaList; if (mFilteredItems != null) { mediaList = mMediaStore.getSiteImagesExcludingIds(mSite, mFilteredItems); } else { mediaList = mMediaStore.getAllSiteMedia(mSite); } mGridAdapter.setMediaList(mediaList); if (mediaList.size() == 0) { refreshMediaFromServer(false); } } private void refreshMediaFromServer(boolean loadMore) { if (!mIsFetching) { mIsFetching = true; FetchMediaListPayload payload = new FetchMediaListPayload(mSite, loadMore); mDispatcher.dispatch(MediaActionBuilder.newFetchMediaListAction(payload)); } } private void setResultIdsAndFinish() { Intent intent = new Intent(); if (mGridAdapter.getSelectedItemCount() > 0) { ArrayList<Long> remoteMediaIds = new ArrayList<>(); for (Integer localId : mGridAdapter.getSelectedItems()) { MediaModel media = mMediaStore.getMediaWithLocalId(localId); if (media != null) { remoteMediaIds.add(media.getMediaId()); } } intent.putExtra(RESULT_IDS, ListUtils.toLongArray(remoteMediaIds)); } setResult(RESULT_OK, intent); finish(); } private void noMediaFinish() { ToastUtils.showToast(this, R.string.media_empty_list, ToastUtils.Duration.LONG); // Delay activity finish new Handler().postDelayed(new Runnable() { @Override public void run() { finish(); } }, 1500); } private final class ActionModeCallback implements ActionMode.Callback { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { mActionMode = mode; MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.photo_picker_action_mode, menu); updateActionModeTitle(mGridAdapter.getSelectedItemCount()); return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return true; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { if (item.getItemId() == R.id.mnu_confirm_selection) { setResultIdsAndFinish(); return true; } return false; } @Override public void onDestroyActionMode(ActionMode mode) { mActionMode = null; mGridAdapter.setInMultiSelect(false); } } }