Java tutorial
/* * Copyright (C) 2014 ChatWing * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.chatwing.whitelabel.activities; import android.app.ProgressDialog; import android.content.ComponentName; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.media.SoundPool; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.IBinder; import android.support.design.widget.Snackbar; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.app.DialogFragment; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v4.widget.DrawerLayout; import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.TextView; import com.chatwing.whitelabel.ChatWing; import com.chatwing.whitelabel.Constants; import com.chatwing.whitelabel.R; import com.chatwing.whitelabel.contentproviders.ChatWingContentProvider; import com.chatwing.whitelabel.events.AccountSwitchEvent; import com.chatwing.whitelabel.events.AllSyncsCompletedEvent; import com.chatwing.whitelabel.events.BlockedEvent; import com.chatwing.whitelabel.events.ChatServiceEvent; import com.chatwing.whitelabel.events.DeleteBookmarkEvent; import com.chatwing.whitelabel.events.NetworkStatusEvent; import com.chatwing.whitelabel.events.SyncCommunicationBoxEvent; import com.chatwing.whitelabel.events.SyncUnreadEvent; import com.chatwing.whitelabel.events.UpdateUserEvent; import com.chatwing.whitelabel.events.UserSelectedDefaultUsersEvent; import com.chatwing.whitelabel.events.UserUnauthenticatedEvent; import com.chatwing.whitelabel.events.ViewMessageContentImageEvent; import com.chatwing.whitelabel.events.ViewVideoEvent; import com.chatwing.whitelabel.events.faye.ChannelSubscriptionChangedEvent; import com.chatwing.whitelabel.events.faye.FayeFailedEvent; import com.chatwing.whitelabel.events.faye.FayePublishEvent; import com.chatwing.whitelabel.events.faye.MessageReceivedEvent; import com.chatwing.whitelabel.events.faye.ServerConnectionChangedEvent; import com.chatwing.whitelabel.fragments.AccountDialogFragment; import com.chatwing.whitelabel.fragments.AdminListFragment; import com.chatwing.whitelabel.fragments.BlockUserDialogFragment; import com.chatwing.whitelabel.fragments.BookmarkedChatBoxesDrawerFragment; import com.chatwing.whitelabel.fragments.CategoriesFragment; import com.chatwing.whitelabel.fragments.ChatMessagesFragment; import com.chatwing.whitelabel.fragments.ColorPickerDialogFragment; import com.chatwing.whitelabel.fragments.CommunicationDrawerFragment; import com.chatwing.whitelabel.fragments.CommunicationMessagesFragment; import com.chatwing.whitelabel.fragments.ConversationMessagesFragment; import com.chatwing.whitelabel.fragments.ConversationsFragment; import com.chatwing.whitelabel.fragments.FeedDrawerFragment; import com.chatwing.whitelabel.fragments.FeedFragment; import com.chatwing.whitelabel.fragments.GooglePlusDialogFragment; import com.chatwing.whitelabel.fragments.InjectableFragmentDelegate; import com.chatwing.whitelabel.fragments.MusicDrawerFragment; import com.chatwing.whitelabel.fragments.MusicFragment; import com.chatwing.whitelabel.fragments.NavigatableFragmentListener; import com.chatwing.whitelabel.fragments.NewContentFragment; import com.chatwing.whitelabel.fragments.OnlineUsersFragment; import com.chatwing.whitelabel.fragments.PasswordDialogFragment; import com.chatwing.whitelabel.fragments.PhotoPickerDialogFragment; import com.chatwing.whitelabel.interfaces.MediaControlInterface; import com.chatwing.whitelabel.managers.ApiManager; import com.chatwing.whitelabel.managers.BuildManager; import com.chatwing.whitelabel.managers.ChatboxModeManager; import com.chatwing.whitelabel.managers.ChatboxUnreadDownloadManager; import com.chatwing.whitelabel.managers.CommunicationActivityManager; import com.chatwing.whitelabel.managers.CommunicationModeManager; import com.chatwing.whitelabel.managers.ConversationModeManager; import com.chatwing.whitelabel.managers.CurrentChatBoxManager; import com.chatwing.whitelabel.managers.CurrentConversationManager; import com.chatwing.whitelabel.managers.FeedModeManager; import com.chatwing.whitelabel.managers.GcmManager; import com.chatwing.whitelabel.managers.MusicModeManager; import com.chatwing.whitelabel.managers.SyncManager; import com.chatwing.whitelabel.managers.UserManager; import com.chatwing.whitelabel.modules.CommunicationActivityModule; import com.chatwing.whitelabel.parsers.BBCodePair; import com.chatwing.whitelabel.parsers.BBCodeParser; import com.chatwing.whitelabel.parsers.EventParser; import com.chatwing.whitelabel.pojos.ChatBox; import com.chatwing.whitelabel.pojos.Conversation; import com.chatwing.whitelabel.pojos.Event; import com.chatwing.whitelabel.pojos.Message; import com.chatwing.whitelabel.pojos.Song; import com.chatwing.whitelabel.pojos.User; import com.chatwing.whitelabel.pojos.errors.ChatWingError; import com.chatwing.whitelabel.pojos.params.CreateConversationParams; import com.chatwing.whitelabel.pojos.responses.ChatBoxDetailsResponse; import com.chatwing.whitelabel.pojos.responses.DeleteBookmarkResponse; import com.chatwing.whitelabel.services.AckChatboxIntentService; import com.chatwing.whitelabel.services.AckConversationIntentService; import com.chatwing.whitelabel.services.ChatWingChatService; import com.chatwing.whitelabel.services.CreateConversationIntentService; import com.chatwing.whitelabel.services.DownloadUserDetailIntentService; import com.chatwing.whitelabel.services.MusicService; import com.chatwing.whitelabel.services.OfflineIntentService; import com.chatwing.whitelabel.services.SyncBookmarkIntentService; import com.chatwing.whitelabel.services.SyncCommunicationBoxesIntentService; import com.chatwing.whitelabel.services.UpdateAvatarIntentService; import com.chatwing.whitelabel.services.UpdateGcmIntentService; import com.chatwing.whitelabel.tables.MessageTable; import com.chatwing.whitelabel.utils.LogUtils; import com.chatwing.whitelabel.utils.StringUtils; import com.chatwing.whitelabel.views.BBCodeEditText; import com.flurry.android.FlurryAgent; import com.google.android.gms.ads.AdRequest; import com.google.android.gms.ads.AdView; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.gson.Gson; import com.soundcloud.android.crop.Crop; import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; import org.json.JSONException; import java.io.Serializable; import java.util.Arrays; import java.util.List; import javax.inject.Inject; /** * This activity is the base where {@link com.chatwing.whitelabel.fragments.CommunicationMessagesFragment} * and drawers are attached. Depend on which mode the activity is in, * appropriate {@link com.chatwing.whitelabel.managers.CommunicationModeManager} is activated * <p/> * <p> * Due to otto limitation, subclasses must override * </p> * * @author cuongthai */ public class CommunicationActivity extends BaseABFragmentActivity implements NewContentFragment.Listener, ColorPickerDialogFragment.Listener, CommunicationMessagesFragment.Delegate, CommunicationModeManager.Delegate, InjectableFragmentDelegate, CommunicationDrawerFragment.Listener, OnlineUsersFragment.OnlineUsersFragmentDelegate, NavigatableFragmentListener, MediaControlInterface { public static final String AVATAR_PICKER_DIALOG_FRAGMENT_TAG = "AvatarPickerDialogFragment"; public static final String BLOCK_USER_DIALOG_FRAGMENT_TAG = "BlockUserDialogFragment"; public static final String ACCOUNT_DIALOG_FRAGMENT_TAG = "AccountDialogFragmentTag"; public static final String ACTION_STOP_MEDIA = "ACTION_STOP_MEDIA"; public static final String PASSWORD_DIALOG_FRAGMENT_TAG = "PasswordDialogFragmentTAG"; public static final String CHATBOX_ID = "CHATBOX_ID"; public static final String ACTION_OPEN_CHATBOX = "ACTION_OPEN_CHATBOX"; public static final String ACTION_OPEN_CONVERSATION = "ACTION_OPEN_CONVERSATION"; public static final String CONVERSATION_ID = "CONVERSATION_ID"; private static final String EXTRA_CURRENT_MODE = "current_mode"; private static final String ATTACHMENT_CONTENT_FRAGMENT_TAG = "NewContentFragment"; private static final int MODE_CHAT_BOX = 0; private static final int MODE_NONE = -1; private static final int MODE_CONVERSATION = 1; public static final int REQUEST_CODE_AUTHENTICATION = 10000; private static final int REQUEST_CODE_GET_GOOGLE_PLAY_SERVICES = 9000; @Inject protected GcmManager mGcmManager; @Inject protected ChatboxModeManager mChatboxModeManager; @Inject protected BuildManager mBuildManager; @Inject protected ConversationModeManager mConversationModeManager; @Inject protected Bus mBus; @Inject protected EventParser mEventParser; @Inject protected SyncManager mSyncManager; @Inject protected CurrentConversationManager mCurrentConversationManager; @Inject protected CurrentChatBoxManager mCurrentChatboxManager; @Inject protected CommunicationActivityManager mCommunicationActivityManager; @Inject protected ApiManager mApiManager; @Inject protected UserManager mUserManager; @Inject protected ChatboxUnreadDownloadManager chatboxUnreadDownloadManager; @Inject protected FeedModeManager mFeedModeManager; @Inject protected MusicModeManager mMusicModeManager; @Inject protected SoundPool mSoundEffectsPool; protected CommunicationModeManager mCurrentCommunicationMode; private View mContentView; private View mProgressView; private ProgressBar mProgressBar; private TextView mProgressText; private DrawerLayout mDrawerLayout; private ActionBarDrawerToggle mDrawerToggle; // Flag to determined onCreate is called. It is used onStart to decide // whether a sync operation should be triggered or not and reset right // after that. private boolean mIsCreated; private ProgressBar mLoadingView; private MusicService musicService; private Intent playIntent; private boolean musicBound = false; private int mNewMessageSoundId; private Snackbar snackbar; private View.OnClickListener snackbarRetryAction = new View.OnClickListener() { @Override public void onClick(View view) { ensureFayeIsConnected(); } }; /** * This class makes the ad request and loads the ad. */ public static class AdFragment extends Fragment { private AdView mAdView; public AdFragment() { } @Override public void onActivityCreated(Bundle bundle) { super.onActivityCreated(bundle); // Gets the ad view defined in layout/ad_fragment.xml with ad unit ID set in // values/strings.xml. mAdView = (AdView) getView().findViewById(R.id.adView); // Create an ad request. Check logcat output for the hashed device ID to // get test ads on a physical device. e.g. // "Use AdRequest.Builder.addTestDevice("ABCDEF012345") to get test ads on this device." AdRequest adRequest = new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR) .addTestDevice("8852195CD9EACCCF36E4DEBF3288370B").build(); // Start loading the ad in the background. mAdView.loadAd(adRequest); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_ad, container, false); } /** * Called when leaving the activity */ @Override public void onPause() { if (mAdView != null) { mAdView.pause(); } super.onPause(); } /** * Called when returning to the activity */ @Override public void onResume() { super.onResume(); if (mAdView != null) { mAdView.resume(); } } /** * Called before the activity is destroyed */ @Override public void onDestroy() { if (mAdView != null) { mAdView.destroy(); } super.onDestroy(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ChatWing.instance(getApplicationContext()).getChatwingGraph().plus(); setContentView(R.layout.activity_communication); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setDisplayShowHomeEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_menu_white_24dp); mBus.register(this); mContentView = findViewById(R.id.fragment_container); mProgressView = findViewById(R.id.progress_container); mProgressBar = (ProgressBar) mProgressView.findViewById(R.id.loading_view); mProgressText = (TextView) mProgressView.findViewById(R.id.progress_text); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mLoadingView = (ProgressBar) findViewById(R.id.progress_bar); mNewMessageSoundId = getSoundNewMessageId(); mChatboxModeManager.onCreate(savedInstanceState); mConversationModeManager.onCreate(savedInstanceState); stopRefreshAnimation(); //This mode is priority due to user action requesting open int actionMode = getActionMode(getIntent()); LogUtils.v("Intent to use actionMode mode " + actionMode); int pauseSavedMode = mCommunicationActivityManager.getInt(R.string.current_mode_state, 0); int currentMode = MODE_CHAT_BOX; //Default mode is chatbox if (pauseSavedMode != 0) { currentMode = pauseSavedMode; } if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_CURRENT_MODE)) { currentMode = savedInstanceState.getInt(EXTRA_CURRENT_MODE); } //Override current mode by priority mode if (actionMode != MODE_NONE) { currentMode = actionMode; } if (currentMode == MODE_CHAT_BOX) { setupChatboxMode(); } else { setupConversationMode(); } mIsCreated = true; String action = getIntent().getAction(); if (ACTION_STOP_MEDIA.equals(action)) { startService(new Intent(MusicService.ACTION_STOP)); } if (!mBuildManager.isOfficialChatWingApp() && userManager.getCurrentUser() == null) { startActivity(new Intent(this, WhiteLabelCoverActivity.class)); finish(); return; } String onlineFragmentTag = getString(R.string.fragment_tag_online_user); if (getSupportFragmentManager().findFragmentByTag(onlineFragmentTag) == null) { FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); fragmentTransaction.add(R.id.right_drawer_container, new OnlineUsersFragment(), onlineFragmentTag); fragmentTransaction.commit(); } String adsFragmentTag = getString(R.string.fragment_tag_ads); if (mBuildManager.isSupportedAds() && getSupportFragmentManager().findFragmentByTag(adsFragmentTag) == null) { getSupportFragmentManager().beginTransaction().add(R.id.ads_container, new AdFragment(), adsFragmentTag) .commit(); } //We start our lovely ChatService so that it listen to faye server startService(new Intent(this, ChatWingChatService.class)); } private void setupSnackbar(View contentView) { snackbar = Snackbar.make(contentView, "", Snackbar.LENGTH_SHORT); styleInfoSnackbar(); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); int actionMode = getActionMode(intent); LogUtils.v("Action Mode " + actionMode); if (actionMode == MODE_CHAT_BOX) { setupChatboxMode(); } else if (actionMode == MODE_CONVERSATION) { setupConversationMode(); } if (mCurrentCommunicationMode != null) { mCurrentCommunicationMode.onNewIntent(intent); } } @Override protected void onStart() { super.onStart(); deployGCM(); // Determine whether a sync categories operation should be // performed right now or not. // It should start if the activity is newly created (onCreate is called). // Thus, we don't refresh when the activity has been in background for a // short period of time. if (mIsCreated) { startSyncingCommunications(false); mIsCreated = false; } startAndBindMusicService(); FlurryAgent.onStartSession(this, getString(R.string.flurry_api_key)); } @Override protected void onStop() { super.onStop(); FlurryAgent.onEndSession(this); if (isBindMediaService()) { unbindService(musicConnection); } } @Override public void onBackPressed() { if (mCurrentCommunicationMode.isSecondaryDrawerOpening()) { ((ChatboxModeManager) mCurrentCommunicationMode).closeSecondaryDrawer(); } else if (!mCurrentCommunicationMode.isCommunicationBoxDrawerOpening()) { // Both online users and chat boxes/conversation lists are closed. // Open chat boxes/conversation list now. mCurrentCommunicationMode.openCommunicationBoxDrawer(); } else { // Online users list is closed, chat boxes list is opened. // User probably is trying to quit the app. FragmentManager fragmentManager = getSupportFragmentManager(); int stackSize = fragmentManager.getBackStackEntryCount(); if (stackSize == 0) { finish(); } else { String fragmentTag = fragmentManager.getBackStackEntryAt(stackSize - 1).getName(); fragmentManager.popBackStack(fragmentTag, FragmentManager.POP_BACK_STACK_INCLUSIVE); } } } @Override public void onContextMenuClosed(Menu menu) { super.onContextMenuClosed(menu); String fragmentTag = getString(R.string.tag_communication_messages); FragmentManager fragmentManager = getSupportFragmentManager(); Fragment currentFragment = fragmentManager.findFragmentByTag(fragmentTag); if (currentFragment instanceof CommunicationMessagesFragment) { ((CommunicationMessagesFragment) currentFragment).onContextMenuClosed(menu); } } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mChatboxModeManager.onRestoreInstanceState(savedInstanceState); mConversationModeManager.onRestoreInstanceState(savedInstanceState); } @Override protected void onSaveInstanceState(Bundle outState) { outState.putString("WORKAROUND_FOR_BUG_19917_KEY", "WORKAROUND_FOR_BUG_19917_VALUE"); super.onSaveInstanceState(outState); LogUtils.v("onSaveInstanceState save mode"); mChatboxModeManager.onSaveInstanceState(outState); mConversationModeManager.onSaveInstanceState(outState); if (isInChatBoxMode()) { outState.putInt(EXTRA_CURRENT_MODE, MODE_CHAT_BOX); } else if (isInConversationMode()) { outState.putInt(EXTRA_CURRENT_MODE, MODE_CONVERSATION); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); LogUtils.v("onActivityResult " + requestCode + ":" + resultCode); mCurrentCommunicationMode.onActivityResult(requestCode, resultCode, intent); if (requestCode == REQUEST_CODE_AUTHENTICATION && resultCode == RESULT_OK) { startSyncingCommunications(true); } if (requestCode == Crop.REQUEST_CROP && resultCode == RESULT_OK) { Uri output = Crop.getOutput(intent); startUpdateAvatar(output.getPath()); } } @Override protected void onDestroy() { super.onDestroy(); LogUtils.v("On Destroy Activity"); //Faye connection will stop receiving msg when the is destroyed //Either by user(backpress) or system destroy mBus.unregister(this); mCurrentCommunicationMode.onDestroy(); mCurrentCommunicationMode = null; } @Override protected void onResume() { super.onResume(); ensureFayeIsConnected(); syncRefreshAnimationState(); mChatboxModeManager.onResume(); mConversationModeManager.onResume(); invalidateOptionsMenu(); chatboxUnreadDownloadManager.downloadUnread(); } @Override protected void onPause() { super.onPause(); mChatboxModeManager.onPause(); mConversationModeManager.onPause(); if (isInChatBoxMode()) { mCommunicationActivityManager.setInt(R.string.current_mode_state, MODE_CHAT_BOX); } else if (isInConversationMode()) { mCommunicationActivityManager.setInt(R.string.current_mode_state, MODE_CONVERSATION); } //Notify server that user does not attention to the app //Go to background, sleep, etc... and start receiving push notification //Although msg is still coming in the background to prevent reload in onResume startService(new Intent(this, OfflineIntentService.class)); } @Override protected void onPostResume() { super.onPostResume(); mCurrentCommunicationMode.onPostResume(); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. mDrawerToggle.syncState(); } @Override public boolean onCreateOptionsMenu(Menu menu) { if (mCurrentCommunicationMode == null) return false; return mCurrentCommunicationMode.onCreateOptionsMenu(menu); } @Override public boolean onPrepareOptionsMenu(Menu menu) { return mCurrentCommunicationMode.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { int i = item.getItemId(); if (i == android.R.id.home) { if (getDrawerLayout().isDrawerOpen(Gravity.LEFT)) { getDrawerLayout().closeDrawer(Gravity.LEFT); } else { getDrawerLayout().openDrawer(Gravity.LEFT); } return true; } if (i == R.id.refresh) { startSyncingCommunications(true); return true; } else { return mCurrentCommunicationMode.onOptionsItemSelected(item); } } @Override protected List<Object> getModules() { return Arrays.<Object>asList(new CommunicationActivityModule(this)); } @Override public final void onItemClicked(NewContentFragment.Item item) { switch (item) { case BBCODES: getCommunicationMessagesFragment().showBBCodeControls(); break; } } ////////////////////////////////////////////////////////////////// // CommunicationMessagesFragment.Delegate ///////////////////////////////////////////////////////////////// @Override public final void showColorPickerDialogFragment(BBCodeParser.BBCode code) { if (code == null) { throw new IllegalArgumentException("Code is required."); } ColorPickerDialogFragment fragment = ColorPickerDialogFragment.newInstance(code); fragment.show(getSupportFragmentManager(), code.toString()); } @Override public final void showNewContentFragment() { boolean hasBBCodes = !getCommunicationMessagesFragment().isShowingBBControls(); NewContentFragment fragment = NewContentFragment.newInstance(hasBBCodes); fragment.show(getSupportFragmentManager(), ATTACHMENT_CONTENT_FRAGMENT_TAG); } @Override public void showPasswordDialogFragment() { FragmentManager fragmentManager = getSupportFragmentManager(); PasswordDialogFragment oldFragment = (PasswordDialogFragment) fragmentManager .findFragmentByTag(PASSWORD_DIALOG_FRAGMENT_TAG); if (oldFragment == null || oldFragment.isDismissingByUser()) { PasswordDialogFragment newFragment = new PasswordDialogFragment(); newFragment.show(getSupportFragmentManager(), PASSWORD_DIALOG_FRAGMENT_TAG); } } @Override public final void inject(BBCodeEditText mCommunicationBoxEditText) { super.inject(mCommunicationBoxEditText); } @Override public void showConversation(CreateConversationParams.SimpleUser simpleUser) { initConversationMenu(); if (!isInConversationMode()) { setupConversationMode(); } addToLeftDrawer(new ConversationsFragment(), false); Intent createConversation = new Intent(getActivity(), CreateConversationIntentService.class); createConversation.putExtra(CreateConversationIntentService.EXTRA_USER, simpleUser); startService(createConversation); } @Override public void showBlockUserDialogFragment(Message message) { FragmentManager fragmentManager = getSupportFragmentManager(); BlockUserDialogFragment oldFragment = (BlockUserDialogFragment) fragmentManager .findFragmentByTag(BLOCK_USER_DIALOG_FRAGMENT_TAG); if (oldFragment == null || oldFragment.isDismissingByUser()) { BlockUserDialogFragment newFragment = BlockUserDialogFragment.newInstance(message); newFragment.show(getSupportFragmentManager(), BLOCK_USER_DIALOG_FRAGMENT_TAG); } } @Override public final void onConfirmColor(Serializable code, int color) { BBCodePair pair = new BBCodePair((BBCodeParser.BBCode) code, color); getCommunicationMessagesFragment().appendBBCode(pair); } @Override public final void inject(Fragment fragment) { super.inject(fragment); } //////////////////////////////////////////////////// // CommunicationModeManager.Delegate /////////////////////////////////////////////////// @Override public void handle(Exception exception, int generalErrorMessageResId) { if (exception instanceof ApiManager.InvalidIdentityException) { onInvalidAuthentication((ApiManager.InvalidIdentityException) exception); } else if (exception instanceof ApiManager.UserUnauthenticatedException) { onUserUnauthenticated(); } else if (exception instanceof ApiManager.InvalidAccessTokenException) { onAccessTokenExpired(); } else if (exception instanceof ApiManager.NotVerifiedEmailException) { mErrorMessageView.show(R.string.error_email_not_verified); } else if (exception instanceof ApiManager.OtherApplicationException) { mErrorMessageView.show(((ApiManager.OtherApplicationException) exception).getError().getMessage()); logout(); } if (exception instanceof ApiManager.RequiredPermissionException) { mErrorMessageView.show(R.string.error_no_permission); } else { // General Error if (generalErrorMessageResId != 0) { mErrorMessageView.show(exception, getString(generalErrorMessageResId)); } else { mErrorMessageView.show(exception, getString(R.string.error_unknown)); } } } @Override public void dismissAuthenticationDialog() { Fragment authenticationDialog = getSupportFragmentManager().findFragmentByTag(ACCOUNT_DIALOG_FRAGMENT_TAG); if (authenticationDialog != null) ((DialogFragment) authenticationDialog).dismiss(); } @Subscribe @Override public void onAccountSwitch(AccountSwitchEvent accountSwitchEvent) { getDrawerLayout().closeDrawers(); if (isInConversationMode()) { mCurrentConversationManager.removeCurrentConversation(); } mBus.post(ChatServiceEvent.unsubscribeAllChannels()); //clean up irrelevant data try { mGcmManager.clearRegistrationId(); getContentResolver().applyBatch(ChatWingContentProvider.AUTHORITY, ChatWingContentProvider.getClearAllDataBatch()); startSyncingCommunications(true); deployGCM(); invalidateOptionsMenu(); } catch (Exception e) { LogUtils.e(e); } } @Subscribe public void onNetworkStatusEvent(NetworkStatusEvent event) { if (event.getStatus() == NetworkStatusEvent.Status.ON) { chatboxUnreadDownloadManager.downloadUnread(); } } @Override public final BaseABFragmentActivity getActivity() { return this; } @Override public final CommunicationMessagesFragment getCommunicationMessagesFragment() { String tag = getString(R.string.tag_communication_messages); return (CommunicationMessagesFragment) getSupportFragmentManager().findFragmentByTag(tag); } @Override public final void setProgressText(int resId, boolean showProgressBar) { setContentShown(false); mProgressBar.setVisibility(showProgressBar ? View.VISIBLE : View.GONE); mProgressText.setText(resId); } @Override public final void setContentShown(boolean shown) { if (shown) { mContentView.setVisibility(View.VISIBLE); mProgressView.setVisibility(View.GONE); } else { mContentView.setVisibility(View.GONE); mProgressView.setVisibility(View.VISIBLE); } } @Override public final DrawerLayout getDrawerLayout() { return mDrawerLayout; } public void ensureFayeIsConnected() { if (snackbar != null) { snackbar.dismiss(); } mBus.post(ChatServiceEvent.connect()); } @Override public void showConversations() { if (mUserManager.userCanLoadConversations()) { setTitle(getActivity().getString(R.string.title_activity_conversation)); invalidateOptionsMenu(); if (isInChatBoxMode()) { setupConversationMode(); } addToLeftDrawer(new ConversationsFragment()); } else { mErrorMessageView.show(R.string.error_required_login_except_guest); } } /** * Calls this in subclass to use it as Conversation Mode */ private void setupConversationMode() { setupMode(mConversationModeManager, ConversationMessagesFragment.newInstance()); } /** * Calls this in subclass to use it as Public ChatBox Mode */ private void setupChatboxMode() { setupMode(mChatboxModeManager, ChatMessagesFragment.newInstance()); } ///////////////////////////////////////////////// // CommunicationDrawerFragment.Listener ////////////////////////////////////////////////// @Override public void showCategories() { setTitle(getActivity().getString(R.string.title_chat_boxes)); invalidateOptionsMenu(); if (!isInChatBoxMode()) { setupChatboxMode(); } addToLeftDrawer(getChatBoxesFragment()); } @Override public void showAdminList() { if (mBuildManager.canShowAdminList()) { addToLeftDrawer(new AdminListFragment()); } else { mErrorMessageView.show(R.string.error_empty_message); } } @Override public void showSettings() { Intent i = new Intent(this, MainPreferenceActivity.class); startActivity(i); } @Override public void updateAvatar() { getDrawerLayout().closeDrawers(); showAvatarPicker(); } @Override public void searchChatBox() { setTitle(getActivity().getString(R.string.title_chat_boxes)); invalidateOptionsMenu(); if (isInConversationMode()) { setupChatboxMode(); } Intent i = new Intent(this, SearchChatBoxActivity.class); startActivityForResult(i, REQUEST_SEARCH_CHAT_BOX); } @Override public void createChatBox() { if (mUserManager.userCanCreateChatBox()) { setTitle(getActivity().getString(R.string.title_chat_boxes)); invalidateOptionsMenu(); if (isInConversationMode()) { setupChatboxMode(); } Intent i = new Intent(this, CreateChatBoxActivity.class); startActivityForResult(i, REQUEST_CREATE_CHAT_BOX); } else { mErrorMessageView.show(R.string.error_required_chat_wing_login_to_create_chat_boxes); } } @Override public void showBookmarks() { if (mUserManager.userCanBookmark()) { setTitle(getActivity().getString(R.string.title_chat_boxes)); invalidateOptionsMenu(); if (isInConversationMode()) { setupChatboxMode(); } addToLeftDrawer(new BookmarkedChatBoxesDrawerFragment()); } else { mErrorMessageView.show(R.string.error_required_chat_wing_login); } } @Override public void openAccountPicker() { if (!mBuildManager.isOfficialChatWingApp()) return; getDrawerLayout().closeDrawers(); showAccountPicker(null); } @Override public void showFeedsSources() { setTitle(getActivity().getString(R.string.title_feeds)); invalidateOptionsMenu(); if (!isInFeedMode()) { setupFeedMode(); } addToLeftDrawer(new FeedDrawerFragment()); } @Override public void showMusicBox() { setTitle(getActivity().getString(R.string.title_music_box)); invalidateOptionsMenu(); if (!isInMusicBoxMode()) { setupMusicBoxMode(); } addToLeftDrawer(new MusicDrawerFragment()); } @Override public void logout() { if (mUserManager.getCurrentUser() == null) { return; } new AsyncTask<Void, Void, Void>() { public ProgressDialog dialog; @Override protected void onPreExecute() { super.onPreExecute(); dialog = ProgressDialog.show(getDialogContext(), "", getString(R.string.logging_out), true, false); } @Override protected Void doInBackground(Void... params) { try { String regId = mGcmManager.getRegistrationId(); mApiManager.updateGcm(mUserManager.getCurrentUser(), regId, ApiManager.GCM_ACTION_REMOVE); } catch (Exception e) { LogUtils.e(e); } mGcmManager.clearRegistrationId(); try { getContentResolver().applyBatch(ChatWingContentProvider.AUTHORITY, ChatWingContentProvider.getClearAllDataBatch()); } catch (Exception e) { LogUtils.e(e); } return null; } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); if (dialog.isShowing()) { dialog.dismiss(); } mCurrentCommunicationMode.logout(); mUserManager.removeUsers(); mBus.post(ChatServiceEvent.unsubscribeAllChannels()); mCurrentCommunicationMode.deactivate(); Intent i = new Intent(CommunicationActivity.this, getEntranceActivityClass()); startActivity(i); finish(); } }.execute(); } @Override public void back(Fragment from) { getSupportFragmentManager().beginTransaction().setCustomAnimations(0, R.anim.slide_out_left).remove(from) .commit(); invalidateOptionsMenu(); } @Override public boolean onSwipe() { return startSyncingCommunications(true); } ////////////////////////////////////////// /// Otto ////////////////////////////////////////// @Subscribe public void onAllSyncsCompleted(AllSyncsCompletedEvent event) { ensureFayeIsConnected(); if (event.needReload() && mCurrentCommunicationMode != null) { mCurrentCommunicationMode.reloadCurrentBox(); } chatboxUnreadDownloadManager.downloadUnread(); syncRefreshAnimationState(); } @Subscribe public void onSyncUnreadEvent(SyncUnreadEvent event) { syncRefreshAnimationState(); AckChatboxIntentService.ack(this, event.getUnAckChatboxIds()); } @Subscribe public void onUpdateUserProfileEvent(UpdateUserEvent event) { Exception exception = event.getException(); if (exception != null) { handle(exception, R.string.error_failed_to_update_user_profile); } } @Subscribe public void onSyncCommunicationBoxEvent(SyncCommunicationBoxEvent event) { SyncCommunicationBoxEvent.Status status = event.getStatus(); syncRefreshAnimationState(); switch (status) { case STARTED: break; case SUCCEED: /* * TODO when succeed, may need to check if the current chat * box is still valid. * And un-subscribe to all invalid chat boxes. */ ensureFayeIsConnected(); startSyncingBookmarks(); startSyncingCurrentUser(); break; case FAILED: handle(event.getException(), R.string.error_failed_to_sync_data); break; } } /** * After deleting bookmark on server, we delete on client * * @param event */ @Subscribe public void onDeletedBookmarkEvent(DeleteBookmarkEvent event) { if (handleDeleteBookmarkEvent(event)) { return; } DeleteBookmarkResponse.DeletedBookmark deletedBookmark = event.getResponse().getData(); if (deletedBookmark == null) { LogUtils.e("Hmm... No data again.." + event.getResponse()); return; } Uri syncedBookmarkWithChatBoxIdUri = ChatWingContentProvider .getSyncedBookmarkWithChatBoxIdUri(deletedBookmark.getChatBoxId()); int delete = getContentResolver().delete(syncedBookmarkWithChatBoxIdUri, null, null); if (delete != 1) { //Weird thing happen LogUtils.e("After deleting on server, bookmark removal on client side has broken chatbox_id" + deletedBookmark.getChatBoxId()); } } @Subscribe public void onBlockedUser(BlockedEvent event) { if (event.getException() == null) { Fragment fragmentByTag = getSupportFragmentManager().findFragmentByTag(BLOCK_USER_DIALOG_FRAGMENT_TAG); if (fragmentByTag != null) { ((DialogFragment) fragmentByTag).dismiss(); } mErrorMessageView.show(R.string.message_blocked); return; } if (event.getException() instanceof ApiManager.ValidationException) { //Ignore this exception since it handle on BlockFragmentDialog return; } if (event.getException() instanceof ApiManager.RequiredPermissionException) { mErrorMessageView.show(event.getException(), getString(R.string.error_require_permission_to_view_ip)); return; } handle(event.getException(), R.string.error_while_blocking_user); } @Subscribe public void onUserUnAuthenticatedEvent(UserUnauthenticatedEvent event) { mQuickMessageView.show(R.string.message_need_login); } @Subscribe public void onChannelSubscriptionChanged(ChannelSubscriptionChangedEvent event) { //Faye if (event.getStatus() == ChannelSubscriptionChangedEvent.Status.SUCCEED) { if (Constants.DEBUG) { mQuickMessageView.show(getString(R.string.message_subscribed_to_channel) + event.getChannel()); } LogUtils.v("Subscribed to channel: " + event.getChannel()); } else { // Failed mErrorMessageView.show(getString(R.string.message_error) + event.getError()); LogUtils.e(event.getError()); } } @Subscribe public void onFayePublished(FayePublishEvent event) { //Faye if (event.getStatus() == FayePublishEvent.Status.SUCCEED) { if (Constants.DEBUG) { mQuickMessageView.show(R.string.message_published); } LogUtils.v("Published: " + event.toString()); } else { // Failed mErrorMessageView.show(getString(R.string.message_error) + event.getError()); LogUtils.e(event.getError()); } } @Subscribe public void onMessageReceived(MessageReceivedEvent event) { //Faye try { Event e = mEventParser.parse(event.getMessage()); processEvent(e); } catch (JSONException ex) { handle(ex, R.string.message_error); } } @Subscribe public void onServerConnectionChangedEvent(ServerConnectionChangedEvent event) { //Faye if (event.getStatus() == ServerConnectionChangedEvent.Status.CONNECTED) { if (Constants.DEBUG) { mQuickMessageView.show(R.string.message_connected_to_server); } LogUtils.v("Connected to server."); setupSnackbar(mContentView); styleInfoSnackbar(); snackbar.setText(R.string.message_connected_to_server); snackbar.setDuration(Snackbar.LENGTH_SHORT); snackbar.show(); } else { // Disconnected if (Constants.DEBUG) { mQuickMessageView.show(R.string.message_disconnected_from_server); } LogUtils.v("Disconnected from server."); setupSnackbar(mContentView); styleErrorSnackbar(); snackbar.setAction("RETRY", snackbarRetryAction); snackbar.setText(R.string.error_faye_closed); snackbar.setDuration(Snackbar.LENGTH_INDEFINITE); snackbar.show(); } } @Subscribe public void onFayeFailedEvent(FayeFailedEvent event) { mErrorMessageView.show(R.string.error_faye_fail_event); } @Subscribe public void onUserSelectedDefaultUsersEvent(UserSelectedDefaultUsersEvent event) { showConversation(event.getSimpleUser()); } @Subscribe public void onViewMessageContentImageEvent(ViewMessageContentImageEvent event) { Intent i = new Intent(this, PhotoViewerActivity.class); i.putExtra(PhotoViewerActivity.PHOTO_URL, event.getImageUrl()); startActivity(i); } @Subscribe public void onViewVideoEvent(ViewVideoEvent event) { String youtubeID = StringUtils.extractYoutubeId(event.getVideoUrl()); if (youtubeID != null) { Intent i = new Intent(this, PlayerViewActivity.class); i.putExtra(PlayerViewActivity.YOUTUBE_VIDEO_ID, youtubeID); startActivity(i); } else { mErrorMessageView.show(R.string.error_youtube_error); LogUtils.e("Error while opening youtube " + event.getVideoUrl()); } } private void processEvent(Event event) { String name = event.getName(); LogUtils.v("event " + event.getParams()); if (name.equals(EventParser.EVENT_DELETE_MESSAGE)) { mCurrentCommunicationMode.processDeleteMessageEvent(event); } else if (name.equals(EventParser.EVENT_DELETE_MESSAGE_BY_SOCIAL)) { mCurrentCommunicationMode.processDeleteMessagesBySocialAccountEvent(event); } else if (name.equals(EventParser.EVENT_DELETE_MESSAGE_BY_IP)) { mCurrentCommunicationMode.processDeleteMessagesByIPEvent(event); } else if (name.equals(EventParser.EVENT_NEW_MESSAGE) || name.equals(EventParser.EVENT_NETWORK_NEW_MESSAGE)) { Message message = (Message) event.getParams(); message.setStatus(Message.Status.PUBLISHED); if (!isFromMe(message)) { // New message, insert it into DB. Uri uri = ChatWingContentProvider.getMessagesUri(); ContentValues contentValues = MessageTable.getContentValues(message); Uri result = getContentResolver().insert(uri, contentValues); if ("-1".equals(result.getLastPathSegment())) { // Failed to insert the message. Stop here. LogUtils.e("Insert message failed "); return; } } boolean added; boolean isInCurrentCommunicationBox = mCurrentCommunicationMode.isInCurrentCommunicationBox(message); if (!isInCurrentCommunicationBox) { added = mCurrentCommunicationMode.processMessageNotInCurrentCommunicationBox(message); } else { CommunicationMessagesFragment fragment = getCommunicationMessagesFragment(); added = (fragment != null && fragment.addNewMessage(message)); mCurrentCommunicationMode.processMessageInCurrentCommunicationBox(message); } //Handle sound when app is visible //When app not visible chatservice will handle it if (mUserManager.isSoundEnabled() && (!appIsNotVisible() && !isInCurrentCommunicationBox)) { mSoundEffectsPool.play(mNewMessageSoundId, 1.0f, 1.0f, 0, 0, 1); } } } ////////////////////////// // Instance methods ////////////////////////// private boolean isFromMe(Message message) { User currentUser = mUserManager.getCurrentUser(); if (currentUser == null) { return false; } return mUserManager.isCurrentUser(message.getUserIdentifier()); } private void initConversationMenu() { setTitle(getActivity().getString(R.string.title_activity_conversation)); if (!isInConversationMode()) { setupConversationMode(); } invalidateOptionsMenu(); } private void onUserUnauthenticated() { //Right now we only show this lovely message, future we will show other login options mErrorMessageView.show(R.string.error_auth_required); } protected boolean isInChatBoxMode() { return mCurrentCommunicationMode == null || mCurrentCommunicationMode instanceof ChatboxModeManager; } protected boolean isInConversationMode() { return mCurrentCommunicationMode == null || mCurrentCommunicationMode instanceof ConversationModeManager; } protected void addToLeftDrawer(Fragment fragment) { addToLeftDrawer(fragment, true); } private void addToLeftDrawer(Fragment fragment, boolean animate) { if (animate) { getSupportFragmentManager().beginTransaction() .setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_right, R.anim.slide_out_left) .replace(R.id.left_drawer_container, fragment).addToBackStack(null).commit(); } else { getSupportFragmentManager().beginTransaction().replace(R.id.left_drawer_container, fragment) .addToBackStack(null).commit(); } } private Fragment getChatBoxesFragment() { return new CategoriesFragment(); } protected void setupMode(CommunicationModeManager newMode, Fragment newFragment) { /* * Update fragments */ String fragmentTag = getString(R.string.tag_communication_messages); FragmentManager fragmentManager = getSupportFragmentManager(); Fragment oldFragment = fragmentManager.findFragmentByTag(fragmentTag); FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); if (oldFragment != null) { fragmentTransaction.remove(oldFragment); } fragmentTransaction.add(R.id.fragment_container, newFragment, fragmentTag); fragmentTransaction.commit(); /* * Deactivate old mode and activate the new one */ if (mCurrentCommunicationMode != null) { mCurrentCommunicationMode.deactivate(); } mCurrentCommunicationMode = newMode; mCurrentCommunicationMode.activate(); /* * Setup drawer layout */ // Set custom shadows that overlay the main content when a drawer opens mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow_left, Gravity.LEFT); mDrawerToggle = mCurrentCommunicationMode.getDrawerToggleListener(); mDrawerToggle.setDrawerIndicatorEnabled(true); getSupportActionBar().setHomeButtonEnabled(true); mDrawerLayout.setDrawerListener(mDrawerToggle); // Don't allow the drawer layout to catch back button and close itself // on back key is pressed. This activity will handle it. mDrawerLayout.setFocusableInTouchMode(false); invalidateOptionsMenu(); } private Context getDialogContext() { Context context; if (getParent() != null) context = getParent(); else context = this; return context; } private Class<? extends BaseABFragmentActivity> getEntranceActivityClass() { return mBuildManager.isOfficialChatWingApp() ? CommunicationActivity.class : WhiteLabelCoverActivity.class; } private boolean startSyncingCommunications(boolean needReload) { if (SyncCommunicationBoxesIntentService.isInProgress()) { // A sync operation is running. Just wait for it. return false; } mSyncManager.resetQueue(); mSyncManager.setNeedReload(needReload); mSyncManager.addToQueue(SyncCommunicationBoxesIntentService.class); Conversation conversation = mCurrentConversationManager.getCurrentConversation(); ChatBox chatBox = mCurrentChatboxManager.getCurrentChatBox(); Intent intent = new Intent(this, SyncCommunicationBoxesIntentService.class); if (conversation != null) { intent.putExtra(SyncCommunicationBoxesIntentService.EXTRA_CONVERSATION_ID, conversation.getId()); } startService(intent); //Send ack, we reset unread_count for current opening conversation if (conversation != null) { LogUtils.v("Test ACK startSyncingCommunications"); AckConversationIntentService.ack(this, conversation.getId()); } if (chatBox != null) { AckChatboxIntentService.ack(this, chatBox.getId()); } mSyncManager.addToQueue(DownloadUserDetailIntentService.class); return true; } private int getActionMode(Intent intent) { if (ACTION_OPEN_CONVERSATION.equals(intent.getAction())) { return MODE_CONVERSATION; } if (ACTION_OPEN_CHATBOX.equals(intent.getAction())) { return MODE_CHAT_BOX; } return MODE_NONE; } /** * Check the device to make sure it has the Google Play Services APK. If * it doesn't, display a dialog that allows users to download the APK from * the Google Play Store or enable it in the device's system settings. */ private boolean checkPlayServices() { int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); if (resultCode != ConnectionResult.SUCCESS) { showGooglePlusDialogFragment(resultCode, REQUEST_CODE_GET_GOOGLE_PLAY_SERVICES); return false; } return true; } private void showGooglePlusDialogFragment(int errorCode, int requestCode) { GooglePlusDialogFragment fragment = GooglePlusDialogFragment.newInstance(errorCode, requestCode); if (fragment != null) { fragment.show(getSupportFragmentManager(), GooglePlusDialogFragment.DIALOG_TAG); } } private void updateGcm(String action, boolean shouldSupplyUser) { User user = mUserManager.getCurrentUser(); if (user == null) { // User is required by the server, so do nothing if it is unavailable. return; } Intent i = new Intent(this, UpdateGcmIntentService.class); i.setAction(action); if (shouldSupplyUser) { i.putExtra(UpdateGcmIntentService.EXTRA_USER, user); } startService(i); } protected void syncRefreshAnimationState() { LogUtils.v("syncRefreshAnimationState " + syncingInProcess()); // Start refresh animation if the chat boxes drawer is opened and a // sync operation is running. // Stop the animation if that drawer is closed. if (syncingInProcess()) { startRefreshAnimation(); } else { stopRefreshAnimation(); } } protected void stopRefreshAnimation() { mLoadingView.setVisibility(View.GONE); } protected void startRefreshAnimation() { mLoadingView.setVisibility(View.VISIBLE); } private boolean syncingInProcess() { return SyncCommunicationBoxesIntentService.isInProgress() || SyncBookmarkIntentService.isInProgress() || ChatboxUnreadDownloadManager.isRunning(); } private void onAccessTokenExpired() { mErrorMessageView.show(R.string.error_invalid_access_token); logout(); } /////////////////////////////////////////////////////// /// OnlineUsersFragmentDelegate //////////////////////////////////////////////////////////// @Override public void createConversation(CreateConversationParams.SimpleUser simpleUser) { showConversation(simpleUser); } ///////////////////////////////////////////////////////// // MediaControlInterface ///////////////////////////////////////////////////////// @Override public MusicService.STATUS getMediaStatus() { if (musicBound) { return musicService.getStatus(); } return null; } @Override public MusicService getMediaService() { return musicService; } @Override public void playLastMediaIfStopping() { Intent service = new Intent(MusicService.ACTION_PLAY_LAST_MEDIA_IF_STOPPING); startService(service); } @Override public boolean isBindMediaService() { return musicBound; } @Override public void enqueue(Song song) { Intent i = new Intent(MusicService.ACTION_URL); i.putExtra(MusicService.SONG_EXTRA, song); startService(i); } @Override public void updateUIForPlayerPreparing(boolean preparing) { if (preparing) { startRefreshAnimation(); } else { stopRefreshAnimation(); syncRefreshAnimationState(); // Make sure if sync is in progress, continue show } } private void startAndBindMusicService() { if (mBuildManager.isSupportedMusicBox()) { if (playIntent == null) { playIntent = new Intent(this, MusicService.class); startService(playIntent); } bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE); } } private synchronized void showAccountPicker(String message) { Fragment oldFragment = getSupportFragmentManager().findFragmentByTag(ACCOUNT_DIALOG_FRAGMENT_TAG); if (oldFragment == null && isActive()) { // To prevent showdialog when activity is paused. // Better Workaround http://stackoverflow.com/questions/8040280/how-to-handle-handler-messages-when-activity-fragment-is-paused AccountDialogFragment accountDialogFragment = AccountDialogFragment.newInstance(message); accountDialogFragment.show(getSupportFragmentManager(), ACCOUNT_DIALOG_FRAGMENT_TAG); //This to prevent duplication dialog. This should be used together with findFragmentByTag getSupportFragmentManager().executePendingTransactions(); } } private void showAvatarPicker() { Fragment oldFragment = getSupportFragmentManager().findFragmentByTag(AVATAR_PICKER_DIALOG_FRAGMENT_TAG); if (oldFragment == null) { PhotoPickerDialogFragment accountDialogFragment = PhotoPickerDialogFragment.newInstance(); accountDialogFragment.show(getSupportFragmentManager(), AVATAR_PICKER_DIALOG_FRAGMENT_TAG); //This to prevent duplication dialog. This should be used together with findFragmentByTag getSupportFragmentManager().executePendingTransactions(); } } private boolean isInFeedMode() { return mCurrentCommunicationMode == null || mCurrentCommunicationMode instanceof FeedModeManager; } private boolean isInMusicBoxMode() { return mCurrentCommunicationMode == null || mCurrentCommunicationMode instanceof MusicModeManager; } private void setupFeedMode() { setupMode(mFeedModeManager, FeedFragment.newInstance()); setContentShown(true); } private void setupMusicBoxMode() { setupMode(mMusicModeManager, MusicFragment.newInstance()); setContentShown(true); } private void startUpdateAvatar(String filePath) { if (UpdateAvatarIntentService.isInProgress()) { return; } Intent startIntent = new Intent(this, UpdateAvatarIntentService.class); startIntent.putExtra(UpdateAvatarIntentService.EXTRA_AVATAR_PATH, filePath); startService(startIntent); } private boolean onInvalidAuthentication(ApiManager.InvalidIdentityException invalidIdentityException) { ChatWingError error = invalidIdentityException.getError(); ChatBoxDetailsResponse.ChatBoxDetailErrorParams chatBoxDetailErrorParams = new Gson() .fromJson(error.getParams(), ChatBoxDetailsResponse.ChatBoxDetailErrorParams.class); if (chatBoxDetailErrorParams == null) { return true; } if (chatBoxDetailErrorParams.isForceLogin() && mUserManager.getCurrentUser() == null) { denyAccessCurrentManager(); showAccountPicker(getString(R.string.message_need_login)); return true; } if (!mUserManager.acceptAccessChatbox(mUserManager.getCurrentUser(), chatBoxDetailErrorParams)) { denyAccessCurrentManager(); showAccountPicker(getString(R.string.message_need_switch_account, chatBoxDetailErrorParams.getAuthenticationMethodString())); return true; } //No one can access this chatbox except admin, etc... return false; } /** * User has been denied to access chatbox, they should be kicked out */ private void denyAccessCurrentManager() { if (isInChatBoxMode()) { mCurrentChatboxManager.removeCurrentChatBox(); } else { mCurrentConversationManager.removeCurrentConversation(); } } private void startSyncingCurrentUser() { if (mUserManager.getCurrentUser() == null || DownloadUserDetailIntentService.isInProgress()) { // A sync operation is running. Just wait for it. return; } getActivity().startService(new Intent(getActivity(), DownloadUserDetailIntentService.class)); } private boolean handleDeleteBookmarkEvent(DeleteBookmarkEvent event) { if (event.getException() == null) return false; handle(event.getException(), R.string.error_while_deleting_bookmark); return true; } //connect to the service private ServiceConnection musicConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { MusicService.MusicBinder binder = (MusicService.MusicBinder) service; //get service musicService = binder.getService(); musicBound = true; } @Override public void onServiceDisconnected(ComponentName name) { musicBound = false; } }; private void startSyncingBookmarks() { if (!mBuildManager.isOfficialChatWingApp()) return; if (mUserManager.getCurrentUser() == null || SyncBookmarkIntentService.isInProgress()) { // A sync operation is running. Just wait for it. return; } mSyncManager.addToQueue(SyncBookmarkIntentService.class); getActivity().startService(new Intent(getActivity(), SyncBookmarkIntentService.class)); } private void deployGCM() { // Check GCM and register if needed if (checkPlayServices()) { String regId = mGcmManager.getRegistrationId(); if (TextUtils.isEmpty(regId)) { updateGcm(ApiManager.GCM_ACTION_ADD, false); } } } private int getSoundNewMessageId() { return mSoundEffectsPool.load(this, R.raw.new_message, 1); } private boolean appIsNotVisible() { return !isVisible(); } private void styleInfoSnackbar() { ViewGroup group = (ViewGroup) snackbar.getView(); group.setBackgroundColor(getResources().getColor(R.color.primary)); snackbar.setActionTextColor(getResources().getColor(R.color.accent)); TextView tv = (TextView) group.findViewById(android.support.design.R.id.snackbar_text); tv.setTextColor(getResources().getColor(R.color.text_on_primary)); } private void styleErrorSnackbar() { ViewGroup group = (ViewGroup) snackbar.getView(); group.setBackgroundColor(getResources().getColor(android.R.color.holo_red_light)); snackbar.setActionTextColor(getResources().getColor(R.color.white)); TextView tv = (TextView) group.findViewById(android.support.design.R.id.snackbar_text); tv.setTextColor(getResources().getColor(R.color.white)); } }