1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/* 2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project 3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License"); 5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License. 6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at 7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * http://www.apache.org/licenses/LICENSE-2.0 9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software 11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS, 12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and 14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License. 15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging.ui.conversationlist; 17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.app.Activity; 19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.app.Fragment; 20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Context; 21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.database.Cursor; 22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.graphics.Rect; 23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.net.Uri; 24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Bundle; 25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Parcelable; 26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v4.view.ViewCompat; 27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v4.view.ViewGroupCompat; 28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v7.widget.LinearLayoutManager; 29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v7.widget.RecyclerView; 30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.LayoutInflater; 31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.Menu; 32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.MenuInflater; 33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.MenuItem; 34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.View; 35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.View.OnClickListener; 36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.ViewGroup; 37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.ViewGroup.MarginLayoutParams; 38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.ViewPropertyAnimator; 39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.accessibility.AccessibilityManager; 40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.widget.AbsListView; 41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.widget.ImageView; 42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.R; 44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.annotation.VisibleForAnimation; 45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.DataModel; 46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.binding.Binding; 47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.binding.BindingBase; 48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.ConversationListData; 49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.ConversationListData.ConversationListDataListener; 50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.ConversationListItemData; 51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.BugleAnimationTags; 52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.ListEmptyView; 53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.SnackBarInteraction; 54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.UIIntents; 55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.AccessibilityUtil; 56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.Assert; 57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.ImeUtil; 58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.LogUtil; 59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.UiUtils; 60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.google.common.annotations.VisibleForTesting; 61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.ArrayList; 63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.List; 64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/** 66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Shows a list of conversations. 67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class ConversationListFragment extends Fragment implements ConversationListDataListener, 69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ConversationListItemView.HostInterface { 70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String BUNDLE_ARCHIVED_MODE = "archived_mode"; 71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String BUNDLE_FORWARD_MESSAGE_MODE = "forward_message_mode"; 72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final boolean VERBOSE = false; 73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private MenuItem mShowBlockedMenuItem; 75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private boolean mArchiveMode; 76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private boolean mBlockedAvailable; 77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private boolean mForwardMessageMode; 78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public interface ConversationListFragmentHost { 80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onConversationClick(final ConversationListData listData, 81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ConversationListItemData conversationListItemData, 82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final boolean isLongClick, 83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ConversationListItemView conversationView); 84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onCreateConversationClick(); 85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isConversationSelected(final String conversationId); 86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isSwipeAnimatable(); 87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isSelectionMode(); 88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean hasWindowFocus(); 89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private ConversationListFragmentHost mHost; 92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private RecyclerView mRecyclerView; 93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private ImageView mStartNewConversationButton; 94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private ListEmptyView mEmptyListMessageView; 95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private ConversationListAdapter mAdapter; 96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Saved Instance State Data - only for temporal data which is nice to maintain but not 98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // critical for correctness. 99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String SAVED_INSTANCE_STATE_LIST_VIEW_STATE_KEY = 100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd "conversationListViewState"; 101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private Parcelable mListState; 102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @VisibleForTesting 104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Binding<ConversationListData> mListBinding = BindingBase.createBinding(this); 105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static ConversationListFragment createArchivedConversationListFragment() { 107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return createConversationListFragment(BUNDLE_ARCHIVED_MODE); 108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static ConversationListFragment createForwardMessageConversationListFragment() { 111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return createConversationListFragment(BUNDLE_FORWARD_MESSAGE_MODE); 112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static ConversationListFragment createConversationListFragment(String modeKeyName) { 115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ConversationListFragment fragment = new ConversationListFragment(); 116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Bundle bundle = new Bundle(); 117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd bundle.putBoolean(modeKeyName, true); 118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd fragment.setArguments(bundle); 119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return fragment; 120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@inheritDoc} from Fragment 124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onCreate(final Bundle bundle) { 127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super.onCreate(bundle); 128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mListBinding.getData().init(getLoaderManager(), mListBinding); 129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mAdapter = new ConversationListAdapter(getActivity(), null, this); 130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onResume() { 134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super.onResume(); 135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Assert.notNull(mHost); 137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd setScrolledToNewestConversationIfNeeded(); 138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd updateUi(); 140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void setScrolledToNewestConversationIfNeeded() { 143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!mArchiveMode 144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd && !mForwardMessageMode 145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd && isScrolledToFirstConversation() 146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd && mHost.hasWindowFocus()) { 147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mListBinding.getData().setScrolledToNewestConversation(true); 148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private boolean isScrolledToFirstConversation() { 152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int firstItemPosition = ((LinearLayoutManager) mRecyclerView.getLayoutManager()) 153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd .findFirstCompletelyVisibleItemPosition(); 154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return firstItemPosition == 0; 155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@inheritDoc} from Fragment 159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onDestroy() { 162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super.onDestroy(); 163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mListBinding.unbind(); 164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mHost = null; 165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@inheritDoc} from Fragment 169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public View onCreateView(final LayoutInflater inflater, final ViewGroup container, 172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Bundle savedInstanceState) { 173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.conversation_list_fragment, 174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd container, false); 175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mRecyclerView = (RecyclerView) rootView.findViewById(android.R.id.list); 176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mEmptyListMessageView = (ListEmptyView) rootView.findViewById(R.id.no_conversations_view); 177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mEmptyListMessageView.setImageHint(R.drawable.ic_oobe_conv_list); 178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // The default behavior for default layout param generation by LinearLayoutManager is to 179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // provide width and height of WRAP_CONTENT, but this is not desirable for 180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // ConversationListFragment; the view in each row should be a width of MATCH_PARENT so that 181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // the entire row is tappable. 182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Activity activity = getActivity(); 183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final LinearLayoutManager manager = new LinearLayoutManager(activity) { 184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public RecyclerView.LayoutParams generateDefaultLayoutParams() { 186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ViewGroup.LayoutParams.WRAP_CONTENT); 188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }; 190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mRecyclerView.setLayoutManager(manager); 191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mRecyclerView.setHasFixedSize(true); 192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mRecyclerView.setAdapter(mAdapter); 193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { 194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int mCurrentState = AbsListView.OnScrollListener.SCROLL_STATE_IDLE; 195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onScrolled(final RecyclerView recyclerView, final int dx, final int dy) { 198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mCurrentState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL 199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd || mCurrentState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) { 200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ImeUtil.get().hideImeKeyboard(getActivity(), mRecyclerView); 201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (isScrolledToFirstConversation()) { 204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd setScrolledToNewestConversationIfNeeded(); 205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mListBinding.getData().setScrolledToNewestConversation(false); 207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onScrollStateChanged(final RecyclerView recyclerView, final int newState) { 212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mCurrentState = newState; 213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }); 215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mRecyclerView.addOnItemTouchListener(new ConversationListSwipeHelper(mRecyclerView)); 216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (savedInstanceState != null) { 218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mListState = savedInstanceState.getParcelable(SAVED_INSTANCE_STATE_LIST_VIEW_STATE_KEY); 219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mStartNewConversationButton = (ImageView) rootView.findViewById( 222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd R.id.start_new_conversation_button); 223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mArchiveMode) { 224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mStartNewConversationButton.setVisibility(View.GONE); 225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mStartNewConversationButton.setVisibility(View.VISIBLE); 227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mStartNewConversationButton.setOnClickListener(new OnClickListener() { 228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onClick(final View clickView) { 230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mHost.onCreateConversationClick(); 231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }); 233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ViewCompat.setTransitionName(mStartNewConversationButton, BugleAnimationTags.TAG_FABICON); 235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // The root view has a non-null background, which by default is deemed by the framework 237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // to be a "transition group," where all child views are animated together during an 238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // activity transition. However, we want each individual items in the recycler view to 239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // show explode animation themselves, so we explicitly tag the root view to be a non-group. 240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ViewGroupCompat.setTransitionGroup(rootView, false); 241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd setHasOptionsMenu(true); 243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return rootView; 244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onAttach(final Activity activity) { 248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super.onAttach(activity); 249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (VERBOSE) { 250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.v(LogUtil.BUGLE_TAG, "Attaching List"); 251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Bundle arguments = getArguments(); 253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (arguments != null) { 254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mArchiveMode = arguments.getBoolean(BUNDLE_ARCHIVED_MODE, false); 255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mForwardMessageMode = arguments.getBoolean(BUNDLE_FORWARD_MESSAGE_MODE, false); 256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mListBinding.bind(DataModel.get().createConversationListData(activity, this, mArchiveMode)); 258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onSaveInstanceState(final Bundle outState) { 263d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super.onSaveInstanceState(outState); 264d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mListState != null) { 265d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd outState.putParcelable(SAVED_INSTANCE_STATE_LIST_VIEW_STATE_KEY, mListState); 266d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 267d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 268d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 269d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 270d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onPause() { 271d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super.onPause(); 272d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mListState = mRecyclerView.getLayoutManager().onSaveInstanceState(); 273d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mListBinding.getData().setScrolledToNewestConversation(false); 274d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 275d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 276d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 277d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Call this immediately after attaching the fragment 278d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 279d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void setHost(final ConversationListFragmentHost host) { 280d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Assert.isNull(mHost); 281d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mHost = host; 282d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 283d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 284d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 285d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onConversationListCursorUpdated(final ConversationListData data, 286d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Cursor cursor) { 287d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mListBinding.ensureBound(data); 288d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Cursor oldCursor = mAdapter.swapCursor(cursor); 289d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd updateEmptyListUi(cursor == null || cursor.getCount() == 0); 290d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mListState != null && cursor != null && oldCursor == null) { 291d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mRecyclerView.getLayoutManager().onRestoreInstanceState(mListState); 292d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 293d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 294d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 295d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 296d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void setBlockedParticipantsAvailable(final boolean blockedAvailable) { 297d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mBlockedAvailable = blockedAvailable; 298d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mShowBlockedMenuItem != null) { 299d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mShowBlockedMenuItem.setVisible(blockedAvailable); 300d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 301d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 302d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 303d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void updateUi() { 304d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mAdapter.notifyDataSetChanged(); 305d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 306d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 307d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 308d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onPrepareOptionsMenu(final Menu menu) { 309d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super.onPrepareOptionsMenu(menu); 310d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final MenuItem startNewConversationMenuItem = 311d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd menu.findItem(R.id.action_start_new_conversation); 312d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (startNewConversationMenuItem != null) { 313d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // It is recommended for the Floating Action button functionality to be duplicated as a 314d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // menu 315d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd AccessibilityManager accessibilityManager = (AccessibilityManager) 316d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd getActivity().getSystemService(Context.ACCESSIBILITY_SERVICE); 317d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd startNewConversationMenuItem.setVisible(accessibilityManager 318d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd .isTouchExplorationEnabled()); 319d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 320d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 321d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final MenuItem archive = menu.findItem(R.id.action_show_archived); 322d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (archive != null) { 323d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd archive.setVisible(true); 324d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 325d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 326d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 327d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 328d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { 329d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!isAdded()) { 330d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Guard against being called before we're added to the activity 331d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return; 332d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 333d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 334d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mShowBlockedMenuItem = menu.findItem(R.id.action_show_blocked_contacts); 335d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mShowBlockedMenuItem != null) { 336d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mShowBlockedMenuItem.setVisible(mBlockedAvailable); 337d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 338d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 339d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 340d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 341d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@inheritDoc} from ConversationListItemView.HostInterface 342d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 343d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 344d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void onConversationClicked(final ConversationListItemData conversationListItemData, 345d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final boolean isLongClick, final ConversationListItemView conversationView) { 346d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ConversationListData listData = mListBinding.getData(); 347d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mHost.onConversationClick(listData, conversationListItemData, isLongClick, 348d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd conversationView); 349d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 350d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 351d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 352d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * {@inheritDoc} from ConversationListItemView.HostInterface 353d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 354d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 355d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isConversationSelected(final String conversationId) { 356d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mHost.isConversationSelected(conversationId); 357d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 358d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 359d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 360d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isSwipeAnimatable() { 361d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mHost.isSwipeAnimatable(); 362d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 363d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 364d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Show and hide empty list UI as needed with appropriate text based on view specifics 365d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private void updateEmptyListUi(final boolean isEmpty) { 366d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (isEmpty) { 367d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int emptyListText; 368d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!mListBinding.getData().getHasFirstSyncCompleted()) { 369d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd emptyListText = R.string.conversation_list_first_sync_text; 370d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (mArchiveMode) { 371d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd emptyListText = R.string.archived_conversation_list_empty_text; 372d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 373d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd emptyListText = R.string.conversation_list_empty_text; 374d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 375d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mEmptyListMessageView.setTextHint(emptyListText); 376d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mEmptyListMessageView.setVisibility(View.VISIBLE); 377d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mEmptyListMessageView.setIsImageVisible(true); 378d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mEmptyListMessageView.setIsVerticallyCentered(true); 379d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 380d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mEmptyListMessageView.setVisibility(View.GONE); 381d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 382d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 383d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 384d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 385d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public List<SnackBarInteraction> getSnackBarInteractions() { 386d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final List<SnackBarInteraction> interactions = new ArrayList<SnackBarInteraction>(1); 387d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final SnackBarInteraction fabInteraction = 388d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new SnackBarInteraction.BasicSnackBarInteraction(mStartNewConversationButton); 389d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd interactions.add(fabInteraction); 390d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return interactions; 391d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 392d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 393d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private ViewPropertyAnimator getNormalizedFabAnimator() { 394d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mStartNewConversationButton.animate() 395d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd .setInterpolator(UiUtils.DEFAULT_INTERPOLATOR) 396d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd .setDuration(getActivity().getResources().getInteger( 397d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd R.integer.fab_animation_duration_ms)); 398d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 399d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 400d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public ViewPropertyAnimator dismissFab() { 401d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // To prevent clicking while animating. 402d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mStartNewConversationButton.setEnabled(false); 403d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final MarginLayoutParams lp = 404d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd (MarginLayoutParams) mStartNewConversationButton.getLayoutParams(); 405d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final float fabWidthWithLeftRightMargin = mStartNewConversationButton.getWidth() 406d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + lp.leftMargin + lp.rightMargin; 407d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int direction = AccessibilityUtil.isLayoutRtl(mStartNewConversationButton) ? -1 : 1; 408d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getNormalizedFabAnimator().translationX(direction * fabWidthWithLeftRightMargin); 409d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 410d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 411d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public ViewPropertyAnimator showFab() { 412d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return getNormalizedFabAnimator().translationX(0).withEndAction(new Runnable() { 413d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 414d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void run() { 415d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Re-enable clicks after the animation. 416d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mStartNewConversationButton.setEnabled(true); 417d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 418d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }); 419d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 420d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 421d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public View getHeroElementForTransition() { 422d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mArchiveMode ? null : mStartNewConversationButton; 423d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 424d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 425d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @VisibleForAnimation 426d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public RecyclerView getRecyclerView() { 427d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mRecyclerView; 428d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 429d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 430d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 431d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void startFullScreenPhotoViewer( 432d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Uri initialPhoto, final Rect initialPhotoBounds, final Uri photosUri) { 433d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd UIIntents.get().launchFullScreenPhotoViewer( 434d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd getActivity(), initialPhoto, initialPhotoBounds, photosUri); 435d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 436d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 437d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 438d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void startFullScreenVideoViewer(final Uri videoUri) { 439d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd UIIntents.get().launchFullScreenVideoViewer(getActivity(), videoUri); 440d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 441d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 442d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 443d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean isSelectionMode() { 444d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mHost != null && mHost.isSelectionMode(); 445d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 446d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd} 447