Fixes #2843 New main screen UI in v3.0 (#3891)

* Add additional classes from 2019 hackathon implementation

* Make first tab work

* Make explore tab work

* Handle back button for contrib and nearby

* Fix framelayout and nav bar allignment

* Fix nav bar tint

* Fix nearby card layout

* Make contributions number visible

* Change menu icon according to fragment

* Make notification icon work and remove drawer

* Make favourites accessible from nav bar

* Turn bookmark and explore activities into fragments

* Use bottom sheet instead of more fragment

* Add actions

* Remove unused classes

* Fix indentation

* remove more fragment title

* Fix explore fragment indentation

* Make toolbar settings as we wanted

* Set card view styles

* Make colors for explore actiivty

* Remove drawer from achievements activity

* Add back button to achievements activity

* remove drawer from review activity

* Remove drawer from settings activity

* Remove drawer from about activity

* Fix dagger injection of fragment

* Implement skip login version

* Add theme missing colors

* Add style to moresheet

* refactor name

* call login with button

* Remove all old bookmarks activity dependency

* Make explore tab items clickable

* Do nothing if same tab is selected

* Fix notification icon color for dark theme

* Fix wrong drawable colors

* Handle back button after media details is visible from contrib and explore fragments

* make favourites open media details

* Fix profile icon

* Make user name visible instead

* Move user back to contrib fragment

* Remove NavigationBaseAvticity

* Fix typo in bookmark fragment

* Fix menu button colors

* Remove explore activity

* remove drawer and dependencies

* Make bookmark media details visible

* Cleanup code

* Code cleanup

* Remove unused layout

* Make contriblist UI look like in mockups

* Change limited connecton toggle

* Move list menu item to nearby fragment

* Fix search button crash

* Make media detail appear

* Back button added

* Fix back button npe

* Change bookmark list view

* Fix always the firs item displayed issue

* Allign contrib list bottom line to simple drawee bottom

* fix fragment string

* Fix back button for mobile uploads

* Make lists appear

* Make fav item selected

* Make favourites clickable

* Add back button to media details

* Add toolbar of notification activity

* Change contributions icon

* Fix card UI

* Fix back button in explore

* Make card views look similar to mockups

* Solve campaign bug visible issue

* Make borders a little softer
This commit is contained in:
neslihanturan 2020-11-06 19:04:04 +03:00 committed by GitHub
parent 5d82629109
commit 71d200ee41
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
110 changed files with 2225 additions and 1629 deletions

View file

@ -29,6 +29,8 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
SimpleDraweeView imageView;
@BindView(R.id.contributionTitle)
TextView titleView;
@BindView(R.id.authorView)
TextView authorView;
@BindView(R.id.contributionState)
TextView stateView;
@BindView(R.id.contributionSequenceNumber)
@ -65,6 +67,7 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
this.contribution = contribution;
this.position = position;
titleView.setText(contribution.getMedia().getMostRelevantCaption());
authorView.setText(contribution.getMedia().getCreator());
imageView.getHierarchy().setPlaceholderImage(R.drawable.image_placeholder);
imageView.getHierarchy().setFailureImage(R.drawable.image_placeholder);

View file

@ -2,10 +2,11 @@ package fr.free.nrw.commons.contributions;
import static fr.free.nrw.commons.contributions.Contribution.STATE_FAILED;
import static fr.free.nrw.commons.contributions.Contribution.STATE_PAUSED;
import static fr.free.nrw.commons.contributions.MainActivity.CONTRIBUTIONS_TAB_POSITION;
import static fr.free.nrw.commons.utils.LengthUtils.formatDistanceBetween;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@ -13,18 +14,29 @@ import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.SwitchCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager.OnBackStackChangedListener;
import androidx.fragment.app.FragmentTransaction;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.MediaDataExtractor;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.notification.Notification;
import fr.free.nrw.commons.notification.NotificationController;
import fr.free.nrw.commons.theme.BaseActivity;
import io.reactivex.disposables.Disposable;
import java.util.List;
@ -40,6 +52,7 @@ import fr.free.nrw.commons.campaigns.CampaignView;
import fr.free.nrw.commons.campaigns.CampaignsPresenter;
import fr.free.nrw.commons.campaigns.ICampaignsView;
import fr.free.nrw.commons.contributions.ContributionsListFragment.Callback;
import fr.free.nrw.commons.contributions.MainActivity.ActiveFragment;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.location.LatLng;
@ -51,6 +64,7 @@ import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
import fr.free.nrw.commons.nearby.NearbyController;
import fr.free.nrw.commons.nearby.NearbyNotificationCardView;
import fr.free.nrw.commons.nearby.Place;
import fr.free.nrw.commons.notification.NotificationActivity;
import fr.free.nrw.commons.upload.UploadService;
import fr.free.nrw.commons.utils.ConfigUtils;
import fr.free.nrw.commons.utils.DialogUtil;
@ -61,8 +75,6 @@ import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import javax.inject.Inject;
import javax.inject.Named;
import timber.log.Timber;
public class ContributionsFragment
@ -77,6 +89,7 @@ public class ContributionsFragment
@Inject OkHttpJsonApiClient okHttpJsonApiClient;
@Inject CampaignsPresenter presenter;
@Inject LocationServiceManager locationManager;
@Inject NotificationController notificationController;
private UploadService uploadService;
private boolean isUploadServiceConnected;
@ -102,6 +115,15 @@ public class ContributionsFragment
private View checkBoxView;
private CheckBox checkBox;
public TextView notificationCount;
@NonNull
public static ContributionsFragment newInstance() {
ContributionsFragment fragment = new ContributionsFragment();
fragment.setRetainInstance(true);
return fragment;
}
/**
* Since we will need to use parent activity on onAuthCookieAcquired, we have to wait
* fragment to be attached. Latch will be responsible for this sync.
@ -165,10 +187,63 @@ public class ContributionsFragment
&& sessionManager.getCurrentAccount() != null) {
setUploadCount();
}
setHasOptionsMenu(true);
return view;
}
@Override
public void onCreateOptionsMenu(@NonNull final Menu menu, @NonNull final MenuInflater inflater) {
inflater.inflate(R.menu.contribution_activity_notification_menu, menu);
MenuItem notificationsMenuItem = menu.findItem(R.id.notifications);
final View notification = notificationsMenuItem.getActionView();
notificationCount = notification.findViewById(R.id.notification_count_badge);
notification.setOnClickListener(view -> {
NotificationActivity.startYourself(getContext(), "unread");
});
setNotificationCount();
updateLimitedConnectionToggle(menu);
}
@SuppressLint("CheckResult")
public void setNotificationCount() {
compositeDisposable.add(notificationController.getNotifications(false)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::initNotificationViews,
throwable -> Timber.e(throwable, "Error occurred while loading notifications")));
}
private void initNotificationViews(List<Notification> notificationList) {
Timber.d("Number of notifications is %d", notificationList.size());
if (notificationList.isEmpty()) {
notificationCount.setVisibility(View.GONE);
} else {
notificationCount.setVisibility(View.VISIBLE);
notificationCount.setText(String.valueOf(notificationList.size()));
}
}
public void updateLimitedConnectionToggle(Menu menu) {
MenuItem checkable = menu.findItem(R.id.toggle_limited_connection_mode);
boolean isEnabled = store
.getBoolean(CommonsApplication.IS_LIMITED_CONNECTION_MODE_ENABLED, false);
checkable.setChecked(isEnabled);
/*final SwitchCompat switchToggleLimitedConnectionMode = checkable.getActionView()
.findViewById(R.id.switch_toggle_limited_connection_mode);*/
checkable.setIcon((isEnabled) ? R.drawable.ic_baseline_cloud_off_24:R.drawable.ic_baseline_cloud_queue_24);
checkable.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
((MainActivity) getActivity()).toggleLimitedConnectionMode();
boolean isEnabled = store.getBoolean(CommonsApplication.IS_LIMITED_CONNECTION_MODE_ENABLED, false);
checkable.setIcon((isEnabled) ? R.drawable.ic_baseline_cloud_off_24:R.drawable.ic_baseline_cloud_queue_24);
return false;
}
});
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
@ -190,8 +265,6 @@ public class ContributionsFragment
* new one if null.
*/
private void showContributionsListFragment() {
// show tabs on contribution list is visible
((MainActivity) getActivity()).showTabs();
// show nearby card view on contributions list is visible
if (nearbyNotificationCardView != null) {
if (store.getBoolean("displayNearbyCardView", true)) {
@ -207,24 +280,19 @@ public class ContributionsFragment
}
private void showMediaDetailPagerFragment() {
// hide tabs on media detail view is visible
((MainActivity) getActivity()).hideTabs();
// hide nearby card view on media detail is visible
nearbyNotificationCardView.setVisibility(View.GONE);
setupViewForMediaDetails();
showFragment(mediaDetailPagerFragment, MEDIA_DETAIL_PAGER_FRAGMENT_TAG);
}
private void setupViewForMediaDetails() {
campaignView.setVisibility(View.GONE);
nearbyNotificationCardView.setVisibility(View.GONE);
((MainActivity)getActivity()).hideTabs();
}
@Override
public void onBackStackChanged() {
((MainActivity)getActivity()).initBackButton();
fetchCampaigns();
}
/**
@ -313,6 +381,9 @@ public class ContributionsFragment
contributionsPresenter.onAttachView(this);
firstLocationUpdate = true;
locationManager.addLocationListener(this);
nearbyNotificationCardView.permissionRequestButton.setOnClickListener(v -> {
showNearbyCardPermissionRationale();
});
if (store.getBoolean("displayNearbyCardView", true)) {
checkPermissionsAndShowNearbyCardView();
@ -333,7 +404,7 @@ public class ContributionsFragment
onLocationPermissionGranted();
} else if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)
&& store.getBoolean("displayLocationPermissionForCardView", true)
&& (((MainActivity) getActivity()).viewPager.getCurrentItem() == CONTRIBUTIONS_TAB_POSITION)) {
&& (((MainActivity) getActivity()).activeFragment == ActiveFragment.CONTRIBUTIONS)) {
nearbyNotificationCardView.permissionType = NearbyNotificationCardView.PermissionType.ENABLE_LOCATION_PERMISSION;
showNearbyCardPermissionRationale();
}
@ -523,5 +594,21 @@ public class ContributionsFragment
public Integer getContributionStateAt(int position) {
return contributionsListFragment.getContributionStateAt(position);
}
public void backButtonClicked() {
if (mediaDetailPagerFragment.isVisible()) {
if (store.getBoolean("displayNearbyCardView", true)) {
if (nearbyNotificationCardView.cardViewVisibilityState == NearbyNotificationCardView.CardViewVisibilityState.READY) {
nearbyNotificationCardView.setVisibility(View.VISIBLE);
}
} else {
nearbyNotificationCardView.setVisibility(View.GONE);
}
getChildFragmentManager().popBackStack();
((BaseActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
((MainActivity)getActivity()).showTabs();
fetchCampaigns();
}
}
}

View file

@ -1,60 +1,69 @@
package fr.free.nrw.commons.contributions;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.FrameLayout;
import androidx.annotation.Nullable;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.google.android.material.tabs.TabLayout;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.bookmarks.BookmarkFragment;
import fr.free.nrw.commons.category.CategoryImagesCallback;
import fr.free.nrw.commons.explore.ExploreFragment;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.location.LocationServiceManager;
import fr.free.nrw.commons.media.MediaDetailPagerFragment;
import fr.free.nrw.commons.navtab.MoreBottomSheetFragment;
import fr.free.nrw.commons.navtab.MoreBottomSheetLoggedOutFragment;
import fr.free.nrw.commons.navtab.NavTab;
import fr.free.nrw.commons.navtab.NavTabLayout;
import fr.free.nrw.commons.navtab.NavTabLoggedOut;
import fr.free.nrw.commons.nearby.NearbyNotificationCardView;
import fr.free.nrw.commons.nearby.Place;
import fr.free.nrw.commons.nearby.fragments.NearbyParentFragment;
import fr.free.nrw.commons.notification.Notification;
import fr.free.nrw.commons.notification.NotificationActivity;
import fr.free.nrw.commons.notification.NotificationController;
import fr.free.nrw.commons.quiz.QuizChecker;
import fr.free.nrw.commons.theme.NavigationBaseActivity;
import fr.free.nrw.commons.theme.BaseActivity;
import fr.free.nrw.commons.upload.UploadService;
import fr.free.nrw.commons.utils.ViewUtil;
import fr.free.nrw.commons.utils.ViewUtilWrapper;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import timber.log.Timber;
public class MainActivity extends NavigationBaseActivity implements FragmentManager.OnBackStackChangedListener {
@BindView(R.id.tab_layout)
TabLayout tabLayout;
@BindView(R.id.pager)
public UnswipableViewPager viewPager;
public class MainActivity extends BaseActivity
implements FragmentManager.OnBackStackChangedListener {
@Inject
SessionManager sessionManager;
@Inject
ContributionController controller;
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.pager)
public UnswipableViewPager viewPager;
@BindView(R.id.fragmentContainer)
public FrameLayout fragmentContainer;
@BindView(R.id.fragment_main_nav_tab_layout)
NavTabLayout tabLayout;
private ContributionsFragment contributionsFragment;
private NearbyParentFragment nearbyParentFragment;
private ExploreFragment exploreFragment;
private BookmarkFragment bookmarkFragment;
public ActiveFragment activeFragment;
@Inject
public LocationServiceManager locationManager;
@Inject
@ -62,46 +71,152 @@ public class MainActivity extends NavigationBaseActivity implements FragmentMana
@Inject
QuizChecker quizChecker;
@Inject
@Named("default_preferences")
public
JsonKvStore applicationKvStore;
@Inject
ViewUtilWrapper viewUtilWrapper;
public Menu menu;
public ContributionsActivityPagerAdapter contributionsActivityPagerAdapter;
public static final int CONTRIBUTIONS_TAB_POSITION = 0;
public static final int NEARBY_TAB_POSITION = 1;
/**
* Consumers should be simply using this method to use this activity.
*
* @param context A Context of the application package implementing this class.
*/
public static void startYourself(Context context) {
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
}
public boolean isContributionsFragmentVisible = true; // False means nearby fragment is visible
public boolean onOrientationChanged;
private Menu menu;
private MenuItem notificationsMenuItem;
private TextView notificationCount;
private NearbyParentFragment nearbyParentFragment;
@Override
public boolean onSupportNavigateUp() {
if (activeFragment == ActiveFragment.CONTRIBUTIONS) {
contributionsFragment.backButtonClicked();
} else {
onBackPressed();
showTabs();
}
return true;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contributions);
setContentView(R.layout.main);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
if (applicationKvStore.getBoolean("login_skipped") == true) {
setTitle(getString(R.string.explore_tab_title_mobile));
setUpLoggedOutPager();
} else {
setTitle(getString(R.string.contributions_fragment));
setUpPager();
initMain();
}
}
initDrawer();
setTitle(getString(R.string.navigation_item_home)); // Should I create a new string variable with another name instead?
public void setSelectedItemId(int id) {
tabLayout.setSelectedItemId(id);
}
initMain();
private void setUpPager() {
loadFragment(ContributionsFragment.newInstance());
tabLayout.setOnNavigationItemSelectedListener(item -> {
if (!item.getTitle().equals("More")) {
// do not change title for more fragment
setTitle(item.getTitle());
}
Fragment fragment = NavTab.of(item.getOrder()).newInstance();
return loadFragment(fragment);
});
}
if (savedInstanceState != null ) {
onOrientationChanged = true; // Will be used in nearby fragment to determine significant update of map
private void setUpLoggedOutPager() {
loadFragment(ExploreFragment.newInstance());
tabLayout.setOnNavigationItemSelectedListener(item -> {
if (!item.getTitle().equals("More")) {
// do not change title for more fragment
setTitle(item.getTitle());
}
Fragment fragment = NavTabLoggedOut.of(item.getOrder()).newInstance();
return loadFragment(fragment);
});
}
//If nearby map was visible, call on Tab Selected to call all nearby operations
/*if (savedInstanceState.getInt("viewPagerCurrentItem") == 1) {
((NearbyFragment)contributionsActivityPagerAdapter.getItem(1)).onTabSelected(onOrientationChanged);
}*/
private boolean loadFragment(Fragment fragment) {
if (fragment instanceof ContributionsFragment) {
if (activeFragment == ActiveFragment.CONTRIBUTIONS) { // Do nothing if same tab
return true;
}
contributionsFragment = (ContributionsFragment) fragment;
activeFragment = ActiveFragment.CONTRIBUTIONS;
} else if (fragment instanceof NearbyParentFragment) {
if (activeFragment == ActiveFragment.NEARBY) { // Do nothing if same tab
return true;
}
nearbyParentFragment = (NearbyParentFragment) fragment;
activeFragment = ActiveFragment.NEARBY;
} else if (fragment instanceof ExploreFragment) {
if (activeFragment == ActiveFragment.EXPLORE) { // Do nothing if same tab
return true;
}
exploreFragment = (ExploreFragment) fragment;
activeFragment = ActiveFragment.EXPLORE;
} else if (fragment instanceof BookmarkFragment) {
if (activeFragment == ActiveFragment.BOOKMARK) { // Do nothing if same tab
return true;
}
bookmarkFragment = (BookmarkFragment) fragment;
activeFragment = ActiveFragment.BOOKMARK;
} else if (fragment == null) {
if (applicationKvStore.getBoolean("login_skipped") == true) { // If logged out, more sheet is different
MoreBottomSheetLoggedOutFragment bottomSheet = new MoreBottomSheetLoggedOutFragment();
bottomSheet.show(getSupportFragmentManager(),
"MoreBottomSheetLoggedOut");
} else {
MoreBottomSheetFragment bottomSheet = new MoreBottomSheetFragment();
bottomSheet.show(getSupportFragmentManager(),
"MoreBottomSheet");
}
}
if (fragment != null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragmentContainer, fragment)
.commit();
return true;
}
return false;
}
public void hideTabs() {
tabLayout.setVisibility(View.GONE);
}
public void showTabs() {
tabLayout.setVisibility(View.VISIBLE);
}
/**
* Adds number of uploads next to tab text "Contributions" then it will look like
* "Contributions (NUMBER)"
* @param uploadCount
*/
public void setNumOfUploads(int uploadCount) {
if (activeFragment == ActiveFragment.CONTRIBUTIONS) {
setTitle(getResources().getString(R.string.contributions_fragment) +" "+ getResources()
.getQuantityString(R.plurals.contributions_subtitle,
uploadCount, uploadCount));
}
}
@Override
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
quizChecker.initQuizCheck(this);
//quizChecker.initQuizCheck(this);
}
@Override
@ -111,155 +226,26 @@ public class MainActivity extends NavigationBaseActivity implements FragmentMana
}
private void initMain() {
addTabsAndFragments();
if (contributionsActivityPagerAdapter.getItem(0) != null) {
((ContributionsFragment)contributionsActivityPagerAdapter.getItem(0)).onAuthCookieAcquired();
}
}
private void addTabsAndFragments() {
contributionsActivityPagerAdapter = new ContributionsActivityPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(contributionsActivityPagerAdapter);
tabLayout.addTab(tabLayout.newTab().setText(getResources().getString(R.string.contributions_fragment)));
tabLayout.addTab(tabLayout.newTab().setText(getResources().getString(R.string.nearby_fragment)));
// Set custom view to add nearby info icon next to text
View nearbyTabLinearLayout = LayoutInflater.from(this).inflate(R.layout.custom_nearby_tab_layout, null);
ImageView nearbyInfo = nearbyTabLinearLayout.findViewById(R.id.nearby_info_image);
tabLayout.getTabAt(1).setCustomView(nearbyTabLinearLayout);
nearbyInfo.setOnClickListener(view ->
new AlertDialog.Builder(MainActivity.this).setTitle(R.string.title_activity_nearby)
.setView(getLayoutInflater().inflate(R.layout.dialog_nearby, null))
.setCancelable(true)
.setPositiveButton(android.R.string.ok, (dialog, id) -> dialog.cancel())
.create()
.show()
);
((ContributionsFragment) contributionsActivityPagerAdapter
.getItem(CONTRIBUTIONS_TAB_POSITION)).onAuthCookieAcquired();
setTabAndViewPagerSynchronisation();
}
/**
* Adds number of uploads next to tab text "Contributions" then it will look like
* "Contributions (NUMBER)"
* @param uploadCount
*/
public void setNumOfUploads(int uploadCount) {
tabLayout.getTabAt(0).setText(getResources().getString(R.string.contributions_fragment) +" "+ getResources()
.getQuantityString(R.plurals.contributions_subtitle,
uploadCount, uploadCount));
}
/**
* Normally tab layout and view pager has no relation, which means when you swipe view pager
* tab won't change and vice versa. So we have to notify each of them.
*/
private void setTabAndViewPagerSynchronisation() {
viewPager.setFocusableInTouchMode(true);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
switch (position) {
case CONTRIBUTIONS_TAB_POSITION:
Timber.d("Contributions tab selected");
tabLayout.getTabAt(CONTRIBUTIONS_TAB_POSITION).select();
isContributionsFragmentVisible = true;
ViewUtil.hideKeyboard(tabLayout.getRootView());
updateMenuItem();
break;
case NEARBY_TAB_POSITION:
Timber.d("Nearby tab selected");
tabLayout.getTabAt(NEARBY_TAB_POSITION).select();
isContributionsFragmentVisible = false;
updateMenuItem();
break;
default:
tabLayout.getTabAt(CONTRIBUTIONS_TAB_POSITION).select();
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
public void hideTabs() {
changeDrawerIconToBackButton();
if (tabLayout != null) {
tabLayout.setVisibility(View.GONE);
}
}
public void showTabs() {
changeDrawerIconToDefault();
if (tabLayout != null) {
tabLayout.setVisibility(View.VISIBLE);
}
//Do not remove this, this triggers the sync service
Intent uploadServiceIntent = new Intent(this, UploadService.class);
uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE);
startService(uploadServiceIntent);
}
@Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
String contributionsFragmentTag = ((ContributionsActivityPagerAdapter) viewPager.getAdapter()).makeFragmentName(R.id.pager, 0);
String nearbyFragmentTag = ((ContributionsActivityPagerAdapter) viewPager.getAdapter()).makeFragmentName(R.id.pager, 1);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else if (getSupportFragmentManager().findFragmentByTag(contributionsFragmentTag) != null && isContributionsFragmentVisible) {
// Meas that contribution fragment is visible (not nearby fragment)
ContributionsFragment contributionsFragment = (ContributionsFragment) getSupportFragmentManager().findFragmentByTag(contributionsFragmentTag);
if (contributionsFragment.getChildFragmentManager().getBackStackEntryCount()>0 ) {
// Means that media details fragment is visible to uer instead of contributions list fragment (As chils fragment)
// Then we want to go back to contributions list fragment on backbutton pressed from media detail fragment
contributionsFragment.getChildFragmentManager().popBackStack();
// Tabs were invisible when Media Details Fragment is active, make them visible again on Contrib List Fragment active
showTabs();
// Nearby Notification Card View was invisible when Media Details Fragment is active, make it visible again on Contrib List Fragment active, according to preferences
if (defaultKvStore.getBoolean("displayNearbyCardView", true)) {
if (contributionsFragment.nearbyNotificationCardView.cardViewVisibilityState == NearbyNotificationCardView.CardViewVisibilityState.READY) {
contributionsFragment.nearbyNotificationCardView.setVisibility(View.VISIBLE);
}
} else {
contributionsFragment.nearbyNotificationCardView.setVisibility(View.GONE);
}
} else {
super.onBackPressed();
}
} else if (getSupportFragmentManager().findFragmentByTag(nearbyFragmentTag) != null
&& !isContributionsFragmentVisible) {
// Means that nearby fragment is visible (not contributions fragment)
if (null == nearbyParentFragment || !nearbyParentFragment.backButtonClicked()) {
super.onBackPressed();
}
if (contributionsFragment != null && activeFragment == ActiveFragment.CONTRIBUTIONS) {
// Meas that contribution fragment is visible
contributionsFragment.backButtonClicked();
} else if (nearbyParentFragment != null && activeFragment == ActiveFragment.NEARBY) {
// Means that nearby fragment is visible
nearbyParentFragment.backButtonClicked();
} else if (exploreFragment != null && activeFragment == ActiveFragment.EXPLORE) {
// Means that explore fragment is visible
exploreFragment.onBackPressed();
} else if (bookmarkFragment != null && activeFragment == ActiveFragment.BOOKMARK) {
// Means that bookmark fragment is visible
bookmarkFragment.onBackPressed();
} else {
super.onBackPressed();
}
@ -267,79 +253,7 @@ public class MainActivity extends NavigationBaseActivity implements FragmentMana
@Override
public void onBackStackChanged() {
initBackButton();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.contribution_activity_notification_menu, menu);
notificationsMenuItem = menu.findItem(R.id.notifications);
final View notification = notificationsMenuItem.getActionView();
notificationCount = notification.findViewById(R.id.notification_count_badge);
notification.setOnClickListener(view -> {
NotificationActivity.startYourself(MainActivity.this, "unread");
});
this.menu = menu;
updateMenuItem();
setNotificationCount();
updateLimitedConnectionToggle(menu);
return true;
}
private void updateLimitedConnectionToggle(Menu menu) {
MenuItem checkable = menu.findItem(R.id.toggle_limited_connection_mode);
boolean isEnabled = defaultKvStore
.getBoolean(CommonsApplication.IS_LIMITED_CONNECTION_MODE_ENABLED, false);
checkable.setChecked(isEnabled);
final Switch switchToggleLimitedConnectionMode = checkable.getActionView()
.findViewById(R.id.switch_toggle_limited_connection_mode);
switchToggleLimitedConnectionMode.setChecked(isEnabled);
switchToggleLimitedConnectionMode.setOnCheckedChangeListener(
(buttonView, isChecked) -> toggleLimitedConnectionMode());
}
@SuppressLint("CheckResult")
private void setNotificationCount() {
compositeDisposable.add(notificationController.getNotifications(false)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::initNotificationViews,
throwable -> Timber.e(throwable, "Error occurred while loading notifications")));
}
private void initNotificationViews(List<Notification> notificationList) {
Timber.d("Number of notifications is %d", notificationList.size());
if (notificationList.isEmpty()) {
notificationCount.setVisibility(View.GONE);
} else {
notificationCount.setVisibility(View.VISIBLE);
notificationCount.setText(String.valueOf(notificationList.size()));
}
}
/**
* Responsible with displaying required menu items according to displayed fragment.
* Notifications icon when contributions list is visible, list sheet icon when nearby is visible
*/
private void updateMenuItem() {
if (menu != null) {
if (isContributionsFragmentVisible) {
// Display notifications menu item
menu.findItem(R.id.notifications).setVisible(true);
menu.findItem(R.id.list_sheet).setVisible(false);
Timber.d("Contributions fragment notifications menu item is visible");
} else {
// Display bottom list menu item
menu.findItem(R.id.notifications).setVisible(false);
menu.findItem(R.id.list_sheet).setVisible(true);
Timber.d("Nearby fragment list sheet menu item is visible");
}
}
//initBackButton();
}
@Override
@ -349,17 +263,12 @@ public class MainActivity extends NavigationBaseActivity implements FragmentMana
// Starts notification activity on click to notification icon
NotificationActivity.startYourself(this, "unread");
return true;
case R.id.list_sheet:
if (contributionsActivityPagerAdapter.getItem(1) != null) {
((NearbyParentFragment)contributionsActivityPagerAdapter.getItem(1)).listOptionMenuItemClicked();
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void toggleLimitedConnectionMode() {
public void toggleLimitedConnectionMode() {
defaultKvStore.putBoolean(CommonsApplication.IS_LIMITED_CONNECTION_MODE_ENABLED,
!defaultKvStore
.getBoolean(CommonsApplication.IS_LIMITED_CONNECTION_MODE_ENABLED, false));
@ -380,81 +289,9 @@ public class MainActivity extends NavigationBaseActivity implements FragmentMana
}
}
public class ContributionsActivityPagerAdapter extends FragmentPagerAdapter {
FragmentManager fragmentManager;
public ContributionsActivityPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
this.fragmentManager = fragmentManager;
}
@Override
public int getCount() {
return 2;
}
/*
* Do not use getItem method to access fragments on pager adapter. User reference variables
* instead.
* */
@Override
public Fragment getItem(int position) {
switch (position){
case 0:
ContributionsFragment retainedContributionsFragment = getContributionsFragment(0);
if (retainedContributionsFragment != null) {
return retainedContributionsFragment;
} else {
// If we reach here, retainedContributionsFragment is null
return new ContributionsFragment();
}
case 1:
nearbyParentFragment = getNearbyFragment(1);
if (nearbyParentFragment != null) {
return nearbyParentFragment;
} else {
// If we reach here, retainedNearbyFragment is null
nearbyParentFragment=new NearbyParentFragment();
return nearbyParentFragment;
}
default:
return null;
}
}
/**
* Generates fragment tag with makeFragmentName method to get retained contributions fragment
* @param position index of tabs, in our case 0 or 1
* @return
*/
private ContributionsFragment getContributionsFragment(int position) {
String tag = makeFragmentName(R.id.pager, position);
return (ContributionsFragment)fragmentManager.findFragmentByTag(tag);
}
/**
* Generates fragment tag with makeFragmentName method to get retained nearby fragment
* @param position index of tabs, in our case 0 or 1
* @return
*/
private NearbyParentFragment getNearbyFragment(int position) {
String tag = makeFragmentName(R.id.pager, position);
return (NearbyParentFragment)fragmentManager.findFragmentByTag(tag);
}
/**
* A simple hack to use retained fragment when getID is called explicitly, if we don't use
* this method, a new fragment will be initialized on each explicit calls of getID
* @param viewId id of view pager
* @param index index of tabs, in our case 0 or 1
* @return
*/
public String makeFragmentName(int viewId, int index) {
return "android:switcher:" + viewId + ":" + index;
}
public void centerMapToPlace(Place place) {
setSelectedItemId(NavTab.NEARBY.code());
nearbyParentFragment.centerMapToPlace(place);
}
@Override
@ -464,9 +301,9 @@ public class MainActivity extends NavigationBaseActivity implements FragmentMana
controller.handleActivityResult(this, requestCode, resultCode, data);
}
@Override
protected void onResume() {
super.onResume();
setNotificationCount();
}
@Override
@ -477,4 +314,12 @@ public class MainActivity extends NavigationBaseActivity implements FragmentMana
locationManager = null;
super.onDestroy();
}
public enum ActiveFragment {
CONTRIBUTIONS,
NEARBY,
EXPLORE,
BOOKMARK,
MORE
}
}