package org.wordpress.android.ui.main;
import android.animation.ObjectAnimator;
import android.app.Fragment;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.RemoteInput;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDialogFragment;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.wordpress.android.R;
import org.wordpress.android.WordPress;
import org.wordpress.android.analytics.AnalyticsTracker;
import org.wordpress.android.fluxc.Dispatcher;
import org.wordpress.android.fluxc.generated.AccountActionBuilder;
import org.wordpress.android.fluxc.generated.SiteActionBuilder;
import org.wordpress.android.fluxc.model.PostModel;
import org.wordpress.android.fluxc.model.SiteModel;
import org.wordpress.android.fluxc.store.AccountStore;
import org.wordpress.android.fluxc.store.AccountStore.OnAccountChanged;
import org.wordpress.android.fluxc.store.AccountStore.OnAuthenticationChanged;
import org.wordpress.android.fluxc.store.PostStore;
import org.wordpress.android.fluxc.store.SiteStore;
import org.wordpress.android.fluxc.store.SiteStore.OnSiteChanged;
import org.wordpress.android.fluxc.store.SiteStore.OnSiteRemoved;
import org.wordpress.android.networking.ConnectionChangeReceiver;
import org.wordpress.android.push.GCMMessageService;
import org.wordpress.android.push.GCMRegistrationIntentService;
import org.wordpress.android.push.NativeNotificationsUtils;
import org.wordpress.android.push.NotificationsProcessingService;
import org.wordpress.android.ui.ActivityId;
import org.wordpress.android.ui.ActivityLauncher;
import org.wordpress.android.ui.RequestCodes;
import org.wordpress.android.ui.accounts.SignInActivity;
import org.wordpress.android.ui.notifications.NotificationEvents;
import org.wordpress.android.ui.notifications.NotificationsListFragment;
import org.wordpress.android.ui.notifications.adapters.NotesAdapter;
import org.wordpress.android.ui.notifications.receivers.NotificationsPendingDraftsReceiver;
import org.wordpress.android.ui.notifications.utils.NotificationsActions;
import org.wordpress.android.ui.notifications.utils.NotificationsUtils;
import org.wordpress.android.ui.notifications.utils.PendingDraftsNotificationsUtils;
import org.wordpress.android.ui.posts.PromoDialog;
import org.wordpress.android.ui.prefs.AppPrefs;
import org.wordpress.android.ui.prefs.AppSettingsFragment;
import org.wordpress.android.ui.prefs.SiteSettingsFragment;
import org.wordpress.android.ui.reader.ReaderPostListFragment;
import org.wordpress.android.ui.reader.ReaderPostPagerActivity;
import org.wordpress.android.util.AnalyticsUtils;
import org.wordpress.android.util.AniUtils;
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.AppLog.T;
import org.wordpress.android.util.AuthenticationDialogUtils;
import org.wordpress.android.util.CoreEvents.MainViewPagerScrolled;
import org.wordpress.android.util.FluxCUtils;
import org.wordpress.android.util.NetworkUtils;
import org.wordpress.android.util.ProfilingUtils;
import org.wordpress.android.util.ToastUtils;
import org.wordpress.android.util.WPActivityUtils;
import org.wordpress.android.widgets.WPViewPager;
import java.util.List;
import javax.inject.Inject;
import de.greenrobot.event.EventBus;
/**
* Main activity which hosts sites, reader, me and notifications tabs
*/
public class WPMainActivity extends AppCompatActivity {
public static final String ARG_OPENED_FROM_PUSH = "opened_from_push";
private WPViewPager mViewPager;
private WPMainTabLayout mTabLayout;
private WPMainTabAdapter mTabAdapter;
private TextView mConnectionBar;
private int mAppBarElevation;
private SiteModel mSelectedSite;
@Inject AccountStore mAccountStore;
@Inject SiteStore mSiteStore;
@Inject PostStore mPostStore;
@Inject Dispatcher mDispatcher;
/*
* tab fragments implement this if their contents can be scrolled, called when user
* requests to scroll to the top
*/
public interface OnScrollToTopListener {
void onScrollToTop();
}
/*
* tab fragments implement this and return true if the fragment handles the back button
* and doesn't want the activity to handle it as well
*/
public interface OnActivityBackPressedListener {
boolean onActivityBackPressed();
}
@Override
public void onCreate(Bundle savedInstanceState) {
ProfilingUtils.split("WPMainActivity.onCreate");
((WordPress) getApplication()).component().inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
mViewPager = (WPViewPager) findViewById(R.id.viewpager_main);
mViewPager.setOffscreenPageLimit(WPMainTabAdapter.NUM_TABS - 1);
mTabAdapter = new WPMainTabAdapter(getFragmentManager());
mViewPager.setAdapter(mTabAdapter);
mConnectionBar = (TextView) findViewById(R.id.connection_bar);
mConnectionBar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// slide out the bar on click, then re-check connection after a brief delay
AniUtils.animateBottomBar(mConnectionBar, false);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (!isFinishing()) {
checkConnection();
}
}
}, 2000);
}
});
mTabLayout = (WPMainTabLayout) findViewById(R.id.tab_layout);
mTabLayout.createTabs();
mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
// nop
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
//scroll the active fragment's contents to the top when user taps the current tab
Fragment fragment = mTabAdapter.getFragment(tab.getPosition());
if (fragment instanceof OnScrollToTopListener) {
((OnScrollToTopListener) fragment).onScrollToTop();
}
}
});
mAppBarElevation = getResources().getDimensionPixelSize(R.dimen.appbar_elevation);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
AppPrefs.setMainTabIndex(position);
switch (position) {
case WPMainTabAdapter.TAB_MY_SITE:
setTabLayoutElevation(mAppBarElevation);
break;
case WPMainTabAdapter.TAB_READER:
setTabLayoutElevation(0);
break;
case WPMainTabAdapter.TAB_ME:
setTabLayoutElevation(mAppBarElevation);
break;
case WPMainTabAdapter.TAB_NOTIFS:
setTabLayoutElevation(mAppBarElevation);
Fragment fragment = mTabAdapter.getFragment(position);
if (fragment instanceof OnScrollToTopListener) {
((OnScrollToTopListener) fragment).onScrollToTop();
}
break;
}
trackLastVisibleTab(position, true);
}
@Override
public void onPageScrollStateChanged(int state) {
// noop
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// fire event if the "My Site" page is being scrolled so the fragment can
// animate its fab to match
if (position == WPMainTabAdapter.TAB_MY_SITE) {
EventBus.getDefault().post(new MainViewPagerScrolled(positionOffset));
}
}
});
if (savedInstanceState == null) {
if (FluxCUtils.isSignedInWPComOrHasWPOrgSite(mAccountStore, mSiteStore)) {
// open note detail if activity called from a push, otherwise return to the tab
// that was showing last time
boolean openedFromPush = (getIntent() != null && getIntent().getBooleanExtra(ARG_OPENED_FROM_PUSH,
false));
if (openedFromPush) {
getIntent().putExtra(ARG_OPENED_FROM_PUSH, false);
if (getIntent().hasExtra(NotificationsPendingDraftsReceiver.POST_ID_EXTRA)) {
launchWithPostId(getIntent().getIntExtra(NotificationsPendingDraftsReceiver.POST_ID_EXTRA, 0),
getIntent().getBooleanExtra(NotificationsPendingDraftsReceiver.IS_PAGE_EXTRA, false));
} else {
launchWithNoteId();
}
} else {
int position = AppPrefs.getMainTabIndex();
if (mTabAdapter.isValidPosition(position) && position != mViewPager.getCurrentItem()) {
mViewPager.setCurrentItem(position);
}
checkMagicLinkSignIn();
}
} else {
ActivityLauncher.showSignInForResult(this);
}
}
// ensure the deep linking activity is enabled. It may have been disabled elsewhere and failed to get re-enabled
WPActivityUtils.enableComponent(this, ReaderPostPagerActivity.class);
// monitor whether we're not the default app
trackDefaultApp();
// We need to register the dispatcher here otherwise it won't trigger if for example Site Picker is present
mDispatcher.register(this);
EventBus.getDefault().register(this);
}
private void setTabLayoutElevation(float newElevation){
if (mTabLayout == null) return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
float oldElevation = mTabLayout.getElevation();
if (oldElevation != newElevation) {
ObjectAnimator.ofFloat(mTabLayout, "elevation", oldElevation, newElevation)
.setDuration(1000L)
.start();
}
}
}
private void showNewEditorPromoDialogIfNeeded() {
if (AppPrefs.isNewEditorPromoRequired() && AppPrefs.isAztecEditorEnabled()) {
AppCompatDialogFragment newFragment = PromoDialog.newInstance(
R.drawable.img_promo_editor,
R.string.new_editor_promo_title,
R.string.new_editor_promo_description,
android.R.string.ok
);
newFragment.show(getSupportFragmentManager(), "new-editor-promo");
AppPrefs.setNewEditorPromoRequired(false);
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
AppLog.i(T.MAIN, "main activity > new intent");
if (intent.hasExtra(NotificationsListFragment.NOTE_ID_EXTRA)) {
launchWithNoteId();
}
}
/*
* called when app is launched from a push notification, switches to the notification tab
* and opens the desired note detail
*/
private void launchWithNoteId() {
if (isFinishing() || getIntent() == null) return;
if (getIntent().hasExtra(NotificationsUtils.ARG_PUSH_AUTH_TOKEN)) {
GCMMessageService.remove2FANotification(this);
NotificationsUtils.validate2FAuthorizationTokenFromIntentExtras(getIntent(),
new NotificationsUtils.TwoFactorAuthCallback() {
@Override
public void onTokenValid(String token, String title, String message) {
//we do this here instead of using the service in the background so we make sure
//the user opens the app by using an activity (and thus unlocks the screen if locked, for security).
String actionType = getIntent().getStringExtra(NotificationsProcessingService.ARG_ACTION_TYPE);
if (NotificationsProcessingService.ARG_ACTION_AUTH_APPROVE.equals(actionType)) {
// ping the push auth endpoint with the token, wp.com will take care of the rest!
NotificationsUtils.sendTwoFactorAuthToken(token);
} else {
NotificationsUtils.showPushAuthAlert(WPMainActivity.this, token, title, message);
}
}
@Override
public void onTokenInvalid() {
// Show a toast if the user took too long to open the notification
ToastUtils.showToast(WPMainActivity.this, R.string.push_auth_expired, ToastUtils.Duration.LONG);
AnalyticsTracker.track(AnalyticsTracker.Stat.PUSH_AUTHENTICATION_EXPIRED);
}
});
}
// Then hit the server
NotificationsActions.updateNotesSeenTimestamp();
mViewPager.setCurrentItem(WPMainTabAdapter.TAB_NOTIFS);
//it could be that a notification has been tapped but has been removed by the time we reach
//here. It's ok to compare to <=1 as it could be zero then.
if (GCMMessageService.getNotificationsCount() <= 1) {
String noteId = getIntent().getStringExtra(NotificationsListFragment.NOTE_ID_EXTRA);
if (!TextUtils.isEmpty(noteId)) {
GCMMessageService.bumpPushNotificationsTappedAnalytics(noteId);
//if voice reply is enabled in a wearable, it will come through the remoteInput
//extra EXTRA_VOICE_OR_INLINE_REPLY
String voiceReply = null;
Bundle remoteInput = RemoteInput.getResultsFromIntent(getIntent());
if (remoteInput != null) {
CharSequence replyText = remoteInput.getCharSequence(GCMMessageService.EXTRA_VOICE_OR_INLINE_REPLY);
if (replyText != null) {
voiceReply = replyText.toString();
}
}
if (voiceReply != null) {
NotificationsProcessingService.startServiceForReply(this, noteId, voiceReply);
finish();
// we don't want this notification to be dismissed as we still have to make sure
// we processed the voice reply, so we exit this function immediately
return;
} else {
boolean shouldShowKeyboard = getIntent().getBooleanExtra(NotificationsListFragment.NOTE_INSTANT_REPLY_EXTRA, false);
NotificationsListFragment.openNoteForReply(this, noteId, shouldShowKeyboard, null, NotesAdapter.FILTERS.FILTER_ALL);
}
} else {
AppLog.e(T.NOTIFS, "app launched from a PN that doesn't have a note_id in it!!");
return;
}
} else {
// mark all tapped here
GCMMessageService.bumpPushNotificationsTappedAllAnalytics();
}
GCMMessageService.removeAllNotifications(this);
}
/**
* called from an internal pending draft notification, so the user can land in the local draft and take action
* such as finish editing and publish, or delete the post, etc.
*/
private void launchWithPostId(int postId, boolean isPage) {
if (isFinishing() || getIntent() == null) return;
AnalyticsTracker.track(AnalyticsTracker.Stat.NOTIFICATION_PENDING_DRAFTS_TAPPED);
NativeNotificationsUtils.dismissNotification(PendingDraftsNotificationsUtils.makePendingDraftNotificationId(postId), this);
// if no specific post id passed, show the list
if (postId == 0 ) {
// show list
if (isPage) {
ActivityLauncher.viewCurrentBlogPages(this, getSelectedSite());
} else {
ActivityLauncher.viewCurrentBlogPosts(this, getSelectedSite());
}
} else {
PostModel post = mPostStore.getPostByLocalPostId(postId);
ActivityLauncher.editPostOrPageForResult(this, getSelectedSite(), post);
}
}
@Override
protected void onDestroy() {
EventBus.getDefault().unregister(this);
mDispatcher.unregister(this);
super.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
// Load selected site
initSelectedSite();
// ensure the deep linking activity is enabled. We might be returning from the external-browser
// viewing of a post
WPActivityUtils.enableComponent(this, ReaderPostPagerActivity.class);
// We need to track the current item on the screen when this activity is resumed.
// Ex: Notifications -> notifications detail -> back to notifications
int currentItem = mViewPager.getCurrentItem();
trackLastVisibleTab(currentItem, false);
if (currentItem == WPMainTabAdapter.TAB_NOTIFS) {
//if we are presenting the notifications list, it's safe to clear any outstanding
// notifications
GCMMessageService.removeAllNotifications(this);
}
checkConnection();
// Update account to update the notification unseen status
if (mAccountStore.hasAccessToken()) {
mDispatcher.dispatch(AccountActionBuilder.newFetchAccountAction());
}
ProfilingUtils.split("WPMainActivity.onResume");
ProfilingUtils.dump();
ProfilingUtils.stop();
}
@Override
public void onBackPressed() {
// let the fragment handle the back button if it implements our OnParentBackPressedListener
Fragment fragment = getActiveFragment();
if (fragment instanceof OnActivityBackPressedListener) {
boolean handled = ((OnActivityBackPressedListener) fragment).onActivityBackPressed();
if (handled) {
return;
}
}
super.onBackPressed();
}
private Fragment getActiveFragment() {
return mTabAdapter.getFragment(mViewPager.getCurrentItem());
}
private void checkMagicLinkSignIn() {
if (getIntent() != null) {
if (getIntent().getBooleanExtra(SignInActivity.MAGIC_LOGIN, false)) {
AnalyticsTracker.track(AnalyticsTracker.Stat.LOGIN_MAGIC_LINK_SUCCEEDED);
startWithNewAccount();
}
}
}
private void trackLastVisibleTab(int position, boolean trackAnalytics) {
if (position == WPMainTabAdapter.TAB_MY_SITE) {
showNewEditorPromoDialogIfNeeded();
}
switch (position) {
case WPMainTabAdapter.TAB_MY_SITE:
ActivityId.trackLastActivity(ActivityId.MY_SITE);
if (trackAnalytics) {
AnalyticsUtils.trackWithSiteDetails(AnalyticsTracker.Stat.MY_SITE_ACCESSED,
getSelectedSite());
}
break;
case WPMainTabAdapter.TAB_READER:
ActivityId.trackLastActivity(ActivityId.READER);
if (trackAnalytics) {
AnalyticsTracker.track(AnalyticsTracker.Stat.READER_ACCESSED);
}
break;
case WPMainTabAdapter.TAB_ME:
ActivityId.trackLastActivity(ActivityId.ME);
if (trackAnalytics) {
AnalyticsTracker.track(AnalyticsTracker.Stat.ME_ACCESSED);
}
break;
case WPMainTabAdapter.TAB_NOTIFS:
ActivityId.trackLastActivity(ActivityId.NOTIFICATIONS);
if (trackAnalytics) {
AnalyticsTracker.track(AnalyticsTracker.Stat.NOTIFICATIONS_ACCESSED);
}
break;
default:
break;
}
}
private void trackDefaultApp() {
Intent wpcomIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.wordpresscom_sample_post)));
ResolveInfo resolveInfo = getPackageManager().resolveActivity(wpcomIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (resolveInfo != null && !getPackageName().equals(resolveInfo.activityInfo.name)) {
// not set as default handler so, track this to evaluate. Note, a resolver/chooser might be the default.
AnalyticsUtils.trackWithDefaultInterceptor(AnalyticsTracker.Stat.DEEP_LINK_NOT_DEFAULT_HANDLER,
resolveInfo.activityInfo.name);
}
}
public void setReaderTabActive() {
if (isFinishing() || mTabLayout == null) return;
mTabLayout.setSelectedTabPosition(WPMainTabAdapter.TAB_READER);
}
/*
* re-create the fragment adapter so all its fragments are also re-created - used when
* user signs in/out so the fragments reflect the active account
*/
private void resetFragments() {
AppLog.i(AppLog.T.MAIN, "main activity > reset fragments");
// reset the timestamp that determines when followed tags/blogs are updated so they're
// updated when the fragment is recreated (necessary after signin/disconnect)
ReaderPostListFragment.resetLastUpdateDate();
// remember the current tab position, then recreate the adapter so new fragments are created
int position = mViewPager.getCurrentItem();
mTabAdapter = new WPMainTabAdapter(getFragmentManager());
mViewPager.setAdapter(mTabAdapter);
// restore previous position
if (mTabAdapter.isValidPosition(position)) {
mViewPager.setCurrentItem(position);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case RequestCodes.EDIT_POST:
case RequestCodes.CREATE_SITE:
MySiteFragment mySiteFragment = getMySiteFragment();
if (mySiteFragment != null) {
mySiteFragment.onActivityResult(requestCode, resultCode, data);
}
break;
case RequestCodes.ADD_ACCOUNT:
if (resultCode == RESULT_OK) {
// Register for Cloud messaging
startWithNewAccount();
} else if (!FluxCUtils.isSignedInWPComOrHasWPOrgSite(mAccountStore, mSiteStore)) {
// can't do anything if user isn't signed in (either to wp.com or self-hosted)
finish();
}
break;
case RequestCodes.REAUTHENTICATE:
if (resultCode == RESULT_CANCELED) {
ActivityLauncher.showSignInForResult(this);
} else {
// Register for Cloud messaging
startService(new Intent(this, GCMRegistrationIntentService.class));
}
break;
case RequestCodes.SITE_PICKER:
if (getMySiteFragment() != null) {
getMySiteFragment().onActivityResult(requestCode, resultCode, data);
if (data != null) {
int selectedSite = data.getIntExtra(SitePickerActivity.KEY_LOCAL_ID, -1);
setSelectedSite(selectedSite);
}
}
break;
case RequestCodes.SITE_SETTINGS:
if (resultCode == SiteSettingsFragment.RESULT_BLOG_REMOVED) {
handleSiteRemoved();
}
break;
case RequestCodes.APP_SETTINGS:
if (resultCode == AppSettingsFragment.LANGUAGE_CHANGED) {
resetFragments();
}
break;
case RequestCodes.NOTE_DETAIL:
if (getNotificationsListFragment() != null) {
getNotificationsListFragment().onActivityResult(requestCode, resultCode, data);
}
break;
case RequestCodes.PHOTO_PICKER:
if (getMeFragment() != null) {
getMeFragment().onActivityResult(requestCode, resultCode, data);
}
break;
}
}
private void startWithNewAccount() {
startService(new Intent(this, GCMRegistrationIntentService.class));
resetFragments();
}
/*
* returns the my site fragment from the sites tab
*/
private MySiteFragment getMySiteFragment() {
Fragment fragment = mTabAdapter.getFragment(WPMainTabAdapter.TAB_MY_SITE);
if (fragment instanceof MySiteFragment) {
return (MySiteFragment) fragment;
}
return null;
}
/*
* returns the "me" fragment from the sites tab
*/
private MeFragment getMeFragment() {
Fragment fragment = mTabAdapter.getFragment(WPMainTabAdapter.TAB_ME);
if (fragment instanceof MeFragment) {
return (MeFragment) fragment;
}
return null;
}
/*
* returns the my site fragment from the sites tab
*/
private NotificationsListFragment getNotificationsListFragment() {
Fragment fragment = mTabAdapter.getFragment(WPMainTabAdapter.TAB_NOTIFS);
if (fragment instanceof NotificationsListFragment) {
return (NotificationsListFragment) fragment;
}
return null;
}
// Events
@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
public void onAuthenticationChanged(OnAuthenticationChanged event) {
if (event.isError() && mSelectedSite != null) {
AuthenticationDialogUtils.showAuthErrorView(this, mSelectedSite);
}
}
@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
public void onAccountChanged(OnAccountChanged event) {
// Sign-out is handled in `handleSiteRemoved`, no need to show the `SignInActivity` here
if (mAccountStore.hasAccessToken()) {
mTabLayout.showNoteBadge(mAccountStore.getAccount().getHasUnseenNotes());
}
}
@SuppressWarnings("unused")
public void onEventMainThread(NotificationEvents.NotificationsChanged event) {
mTabLayout.showNoteBadge(event.hasUnseenNotes);
}
@SuppressWarnings("unused")
public void onEventMainThread(NotificationEvents.NotificationsUnseenStatus event) {
mTabLayout.showNoteBadge(event.hasUnseenNotes);
}
@SuppressWarnings("unused")
public void onEventMainThread(ConnectionChangeReceiver.ConnectionChangeEvent event) {
updateConnectionBar(event.isConnected());
}
private void checkConnection() {
updateConnectionBar(NetworkUtils.isNetworkAvailable(this));
}
private void updateConnectionBar(boolean isConnected) {
if (isConnected && mConnectionBar.getVisibility() == View.VISIBLE) {
AniUtils.animateBottomBar(mConnectionBar, false);
} else if (!isConnected && mConnectionBar.getVisibility() != View.VISIBLE) {
AniUtils.animateBottomBar(mConnectionBar, true);
}
}
private void handleSiteRemoved() {
if (!FluxCUtils.isSignedInWPComOrHasWPOrgSite(mAccountStore, mSiteStore)) {
// User signed-out or removed the last self-hosted site, show `SignInActivity`
resetFragments();
ActivityLauncher.showSignInForResult(this);
} else {
SiteModel site = getSelectedSite();
if (site != null) {
ActivityLauncher.showSitePickerForResult(this, site);
}
}
}
/**
* @return null if there is no site or if there is no selected site
*/
public @Nullable SiteModel getSelectedSite() {
return mSelectedSite;
}
public void setSelectedSite(int localSiteId) {
setSelectedSite(mSiteStore.getSiteByLocalId(localSiteId));
}
public void setSelectedSite(@Nullable SiteModel selectedSite) {
mSelectedSite = selectedSite;
if (selectedSite == null) {
AppPrefs.setSelectedSite(-1);
return;
}
// When we select a site, we want to update its information or options
mDispatcher.dispatch(SiteActionBuilder.newFetchSiteAction(selectedSite));
// Make selected site visible
selectedSite.setIsVisible(true);
AppPrefs.setSelectedSite(selectedSite.getId());
}
/**
* This should not be moved to a SiteUtils.getSelectedSite() or similar static method. We don't want
* this to be used globally like WordPress.getCurrentBlog() was used. The state is maintained by this
* Activity and the selected site parameter is passed along to other activities / fragments.
*/
public void initSelectedSite() {
int siteLocalId = AppPrefs.getSelectedSite();
if (siteLocalId != -1) {
// Site previously selected, use it
mSelectedSite = mSiteStore.getSiteByLocalId(siteLocalId);
// If saved site exist, then return, else (site has been removed?) try to select another site
if (mSelectedSite != null) {
return;
}
}
// Try to select the primary wpcom site
long siteId = mAccountStore.getAccount().getPrimarySiteId();
SiteModel primarySite = mSiteStore.getSiteBySiteId(siteId);
// Primary site found, select it
if (primarySite != null) {
setSelectedSite(primarySite);
return;
}
// Else select the first visible site in the list
List<SiteModel> sites = mSiteStore.getVisibleSites();
if (sites.size() != 0) {
setSelectedSite(sites.get(0));
return;
}
// Else select the first in the list
sites = mSiteStore.getSites();
if (sites.size() != 0) {
setSelectedSite(sites.get(0));
}
// Else no site selected
}
@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSiteChanged(OnSiteChanged event) {
// "Reload" selected site from the db
// It would be better if the OnSiteChanged provided the list of changed sites.
if (getSelectedSite() == null && mSiteStore.hasSite()) {
setSelectedSite(mSiteStore.getSites().get(0));
}
if (getSelectedSite() == null) {
return;
}
SiteModel site = mSiteStore.getSiteByLocalId(getSelectedSite().getId());
if (site != null) {
mSelectedSite = site;
}
}
@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSiteRemoved(OnSiteRemoved event) {
handleSiteRemoved();
}
}