From 71d200ee41591be3e27f2a0c21de91609cc755fa Mon Sep 17 00:00:00 2001 From: neslihanturan Date: Fri, 6 Nov 2020 19:04:04 +0300 Subject: [PATCH] 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 --- .../free/nrw/commons/ExploreActivityTest.kt | 19 - app/src/main/AndroidManifest.xml | 10 - .../fr/free/nrw/commons/AboutActivity.java | 19 +- .../free/nrw/commons/auth/LoginActivity.java | 7 +- .../commons/bookmarks/BookmarkFragment.java | 80 +++ .../bookmarks/BookmarkListRootFragment.java | 201 +++++++ .../commons/bookmarks/BookmarksActivity.java | 152 ----- .../bookmarks/BookmarksPagerAdapter.java | 22 +- .../pictures/BookmarkPicturesFragment.java | 8 +- .../nrw/commons/campaigns/CampaignView.java | 4 +- .../category/CategoryDetailsActivity.java | 8 +- .../category/CategoryImagesActivity.java | 10 +- .../contributions/ContributionViewHolder.java | 3 + .../contributions/ContributionsFragment.java | 115 +++- .../commons/contributions/MainActivity.java | 535 +++++++----------- .../nrw/commons/di/ActivityBuilderModule.java | 8 - .../di/CommonsApplicationComponent.java | 9 + .../nrw/commons/di/FragmentBuilderModule.java | 24 + .../nrw/commons/explore/ExploreActivity.java | 223 -------- .../nrw/commons/explore/ExploreFragment.java | 126 +++++ .../explore/ExploreListRootFragment.java | 176 ++++++ .../nrw/commons/explore/SearchActivity.java | 9 +- .../media/CategoriesMediaFragment.kt | 1 + .../WikidataItemDetailsActivity.java | 8 +- .../explore/media/PageableMediaFragment.kt | 6 +- .../location/LocationServiceManager.java | 5 + .../commons/media/MediaDetailFragment.java | 5 +- .../media/MediaDetailPagerFragment.java | 32 +- .../navtab/MoreBottomSheetFragment.java | 153 +++++ .../MoreBottomSheetLoggedOutFragment.java | 118 ++++ .../fr/free/nrw/commons/navtab/NavTab.java | 97 ++++ .../navtab/NavTabFragmentPagerAdapter.java | 35 ++ .../free/nrw/commons/navtab/NavTabLayout.java | 41 ++ .../nrw/commons/navtab/NavTabLoggedOut.java | 70 +++ .../nearby/NearbyNotificationCardView.java | 17 +- .../fragments/CommonPlaceClickActions.kt | 4 +- .../fragments/NearbyParentFragment.java | 35 +- .../notification/NotificationActivity.java | 17 +- .../nrw/commons/profile/ProfileActivity.java | 5 +- .../achievements/AchievementsFragment.java | 12 +- .../nrw/commons/review/ReviewActivity.java | 16 +- .../commons/settings/SettingsActivity.java | 23 +- .../commons/theme/NavigationBaseActivity.java | 355 ------------ .../free/nrw/commons/utils/ActivityUtils.java | 14 + .../res/color/color_state_nav_tab_dark.xml | 5 + .../res/color/color_state_nav_tab_light.xml | 5 + .../res/drawable-anydpi-v24/pause_icon.xml | 2 +- .../res/drawable-anydpi-v24/play_icon.xml | 2 +- app/src/main/res/drawable/card_border.xml | 13 + .../res/drawable/ic_baseline_cloud_off_24.xml | 10 + .../drawable/ic_baseline_cloud_queue_24.xml | 10 + .../res/drawable/ic_baseline_person_14.xml | 5 + .../res/drawable/ic_baseline_person_24.xml | 10 + .../main/res/drawable/ic_check_black_24dp.xml | 2 +- .../drawable/ic_exit_to_app_black_24dp.xml | 2 +- .../res/drawable/ic_feedback_black_24dp.xml | 2 +- app/src/main/res/drawable/ic_globe.xml | 27 + .../main/res/drawable/ic_help_black_24dp.xml | 2 +- .../res/drawable/ic_info_outline_24dp.xml | 2 +- .../main/res/drawable/ic_list_white_24dp.xml | 2 +- .../drawable/ic_location_on_black_24dp.xml | 9 + .../main/res/drawable/ic_menu_black_24dp.xml | 5 + .../drawable/ic_notifications_blue_24dp.xml | 6 + .../res/drawable/ic_person_black_24dp.xml | 2 +- .../res/drawable/ic_settings_black_24dp.xml | 2 +- .../res/drawable/menu_ic_download_24dp.xml | 5 + .../menu_ic_round_star_border_24px.xml | 9 + .../menu_ic_round_star_filled_24px.xml | 9 + .../main/res/drawable/menu_ic_share_24dp.xml | 5 + app/src/main/res/layout-v21/drawer_view.xml | 10 - app/src/main/res/layout/activity_about.xml | 3 - .../main/res/layout/activity_bookmarks.xml | 50 -- .../res/layout/activity_category_details.xml | 2 - .../res/layout/activity_category_images.xml | 3 - .../res/layout/activity_contributions.xml | 46 -- app/src/main/res/layout/activity_explore.xml | 49 -- .../main/res/layout/activity_notification.xml | 2 - app/src/main/res/layout/activity_profile.xml | 2 - app/src/main/res/layout/activity_review.xml | 5 - app/src/main/res/layout/activity_search.xml | 2 - app/src/main/res/layout/activity_settings.xml | 4 - .../layout/activity_wikidata_item_details.xml | 2 - app/src/main/res/layout/drawer_header.xml | 55 -- app/src/main/res/layout/drawer_view.xml | 10 - .../main/res/layout/fragment_achievements.xml | 3 - .../main/res/layout/fragment_bookmarks.xml | 39 ++ .../res/layout/fragment_contributions.xml | 5 +- app/src/main/res/layout/fragment_explore.xml | 38 ++ .../res/layout/fragment_featured_root.xml | 13 + .../layout/fragment_media_detail_pager.xml | 1 - .../res/layout/fragment_more_bottom_sheet.xml | 84 +++ .../fragment_more_bottom_sheet_logged_out.xml | 62 ++ app/src/main/res/layout/layout_campagin.xml | 9 +- .../res/layout/layout_category_images.xml | 49 +- .../main/res/layout/layout_contribution.xml | 44 +- app/src/main/res/layout/main.xml | 41 ++ app/src/main/res/layout/menu_switch.xml | 5 - app/src/main/res/layout/nearby_card_view.xml | 21 +- app/src/main/res/layout/notification_icon.xml | 4 +- app/src/main/res/layout/toolbar.xml | 4 +- ...ontribution_activity_notification_menu.xml | 7 +- app/src/main/res/menu/drawer.xml | 62 -- .../main/res/menu/fragment_image_detail.xml | 6 +- .../main/res/menu/nearby_fragment_menu.xml | 9 + app/src/main/res/values/attrs.xml | 15 +- app/src/main/res/values/colors.xml | 4 + app/src/main/res/values/dimens.xml | 1 + app/src/main/res/values/strings.xml | 2 + app/src/main/res/values/styles.xml | 66 ++- app/src/main/res/xml/shortcuts.xml | 25 - 110 files changed, 2225 insertions(+), 1629 deletions(-) delete mode 100644 app/src/androidTest/java/fr/free/nrw/commons/ExploreActivityTest.kt create mode 100644 app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarkFragment.java create mode 100644 app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarkListRootFragment.java delete mode 100644 app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarksActivity.java delete mode 100644 app/src/main/java/fr/free/nrw/commons/explore/ExploreActivity.java create mode 100644 app/src/main/java/fr/free/nrw/commons/explore/ExploreFragment.java create mode 100644 app/src/main/java/fr/free/nrw/commons/explore/ExploreListRootFragment.java create mode 100644 app/src/main/java/fr/free/nrw/commons/navtab/MoreBottomSheetFragment.java create mode 100644 app/src/main/java/fr/free/nrw/commons/navtab/MoreBottomSheetLoggedOutFragment.java create mode 100644 app/src/main/java/fr/free/nrw/commons/navtab/NavTab.java create mode 100644 app/src/main/java/fr/free/nrw/commons/navtab/NavTabFragmentPagerAdapter.java create mode 100644 app/src/main/java/fr/free/nrw/commons/navtab/NavTabLayout.java create mode 100644 app/src/main/java/fr/free/nrw/commons/navtab/NavTabLoggedOut.java delete mode 100644 app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java create mode 100644 app/src/main/java/fr/free/nrw/commons/utils/ActivityUtils.java create mode 100644 app/src/main/res/color/color_state_nav_tab_dark.xml create mode 100644 app/src/main/res/color/color_state_nav_tab_light.xml create mode 100644 app/src/main/res/drawable/card_border.xml create mode 100644 app/src/main/res/drawable/ic_baseline_cloud_off_24.xml create mode 100644 app/src/main/res/drawable/ic_baseline_cloud_queue_24.xml create mode 100644 app/src/main/res/drawable/ic_baseline_person_14.xml create mode 100644 app/src/main/res/drawable/ic_baseline_person_24.xml create mode 100644 app/src/main/res/drawable/ic_globe.xml create mode 100644 app/src/main/res/drawable/ic_location_on_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_menu_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_notifications_blue_24dp.xml create mode 100644 app/src/main/res/drawable/menu_ic_download_24dp.xml create mode 100644 app/src/main/res/drawable/menu_ic_round_star_border_24px.xml create mode 100644 app/src/main/res/drawable/menu_ic_round_star_filled_24px.xml create mode 100644 app/src/main/res/drawable/menu_ic_share_24dp.xml delete mode 100644 app/src/main/res/layout-v21/drawer_view.xml delete mode 100644 app/src/main/res/layout/activity_bookmarks.xml delete mode 100644 app/src/main/res/layout/activity_contributions.xml delete mode 100644 app/src/main/res/layout/activity_explore.xml delete mode 100644 app/src/main/res/layout/drawer_header.xml delete mode 100644 app/src/main/res/layout/drawer_view.xml create mode 100644 app/src/main/res/layout/fragment_bookmarks.xml create mode 100644 app/src/main/res/layout/fragment_explore.xml create mode 100644 app/src/main/res/layout/fragment_featured_root.xml create mode 100644 app/src/main/res/layout/fragment_more_bottom_sheet.xml create mode 100644 app/src/main/res/layout/fragment_more_bottom_sheet_logged_out.xml create mode 100644 app/src/main/res/layout/main.xml delete mode 100644 app/src/main/res/layout/menu_switch.xml delete mode 100644 app/src/main/res/menu/drawer.xml create mode 100644 app/src/main/res/menu/nearby_fragment_menu.xml diff --git a/app/src/androidTest/java/fr/free/nrw/commons/ExploreActivityTest.kt b/app/src/androidTest/java/fr/free/nrw/commons/ExploreActivityTest.kt deleted file mode 100644 index 221d0fce9..000000000 --- a/app/src/androidTest/java/fr/free/nrw/commons/ExploreActivityTest.kt +++ /dev/null @@ -1,19 +0,0 @@ -package fr.free.nrw.commons - -import androidx.test.rule.ActivityTestRule -import androidx.test.runner.AndroidJUnit4 -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import fr.free.nrw.commons.explore.ExploreActivity - -@RunWith(AndroidJUnit4::class) -class ExploreActivityTest { - @get:Rule - var activityRule = ActivityTestRule(ExploreActivity::class.java) - - @Test - fun orientationChange() { - UITestHelper.changeOrientation(activityRule) - } -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9c0e80331..81b9f7153 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -124,12 +124,6 @@ android:label="@string/title_activity_featured_images" android:parentActivityName=".contributions.MainActivity" /> - - - - diff --git a/app/src/main/java/fr/free/nrw/commons/AboutActivity.java b/app/src/main/java/fr/free/nrw/commons/AboutActivity.java index e5ee73396..e60127860 100644 --- a/app/src/main/java/fr/free/nrw/commons/AboutActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/AboutActivity.java @@ -5,8 +5,6 @@ import android.app.AlertDialog; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.text.SpannableString; -import android.text.style.UnderlineSpan; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -17,22 +15,21 @@ import android.widget.Spinner; import android.widget.TextView; import androidx.annotation.NonNull; -import java.lang.ref.SoftReference; +import androidx.appcompat.widget.Toolbar; +import fr.free.nrw.commons.theme.BaseActivity; import java.util.Collections; import java.util.List; -import org.wikipedia.util.StringUtil; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; -import fr.free.nrw.commons.theme.NavigationBaseActivity; import fr.free.nrw.commons.ui.widget.HtmlTextView; import fr.free.nrw.commons.utils.ConfigUtils; /** * Represents about screen of this app */ -public class AboutActivity extends NavigationBaseActivity { +public class AboutActivity extends BaseActivity { @BindView(R.id.about_version) TextView versionText; @BindView(R.id.about_license) HtmlTextView aboutLicenseText; @BindView(R.id.about_faq) TextView faqText; @@ -41,6 +38,7 @@ public class AboutActivity extends NavigationBaseActivity { @BindView(R.id.about_privacy_policy) TextView privacyPolicyText; @BindView(R.id.about_translate) TextView translateText; @BindView(R.id.about_credits) TextView creditsText; + @BindView(R.id.toolbar) Toolbar toolbar; /** * This method helps in the creation About screen * @@ -53,7 +51,8 @@ public class AboutActivity extends NavigationBaseActivity { setContentView(R.layout.activity_about); ButterKnife.bind(this); - + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); String aboutText = getString(R.string.about_license); aboutLicenseText.setHtmlText(aboutText); @@ -68,8 +67,12 @@ public class AboutActivity extends NavigationBaseActivity { Utils.setUnderlinedText(privacyPolicyText, R.string.about_privacy_policy, getApplicationContext()); Utils.setUnderlinedText(translateText, R.string.about_translate, getApplicationContext()); Utils.setUnderlinedText(creditsText, R.string.about_credits, getApplicationContext()); + } - initDrawer(); + @Override + public boolean onSupportNavigateUp() { + onBackPressed(); + return true; } @OnClick(R.id.facebook_launch_icon) diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java index f2c552a83..919251874 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java @@ -29,6 +29,7 @@ import androidx.core.content.ContextCompat; import com.google.android.material.textfield.TextInputLayout; +import fr.free.nrw.commons.utils.ActivityUtils; import org.wikipedia.AppAdapter; import org.wikipedia.dataclient.ServiceFactory; import org.wikipedia.dataclient.WikiSite; @@ -51,9 +52,7 @@ import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.WelcomeActivity; import fr.free.nrw.commons.contributions.MainActivity; import fr.free.nrw.commons.di.ApplicationlessInjection; -import fr.free.nrw.commons.explore.ExploreActivity; import fr.free.nrw.commons.kvstore.JsonKvStore; -import fr.free.nrw.commons.theme.NavigationBaseActivity; import fr.free.nrw.commons.utils.ConfigUtils; import fr.free.nrw.commons.utils.SystemThemeUtils; import fr.free.nrw.commons.utils.ViewUtil; @@ -318,7 +317,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { */ private void performSkipLogin() { applicationKvStore.putBoolean("login_skipped", true); - ExploreActivity.startYourself(this); + MainActivity.startYourself(this); finish(); } @@ -412,7 +411,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { } public void startMainActivity() { - NavigationBaseActivity.startActivityWithFlags(this, MainActivity.class, Intent.FLAG_ACTIVITY_SINGLE_TOP); + ActivityUtils.startActivityWithFlags(this, MainActivity.class, Intent.FLAG_ACTIVITY_SINGLE_TOP); finish(); } diff --git a/app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarkFragment.java b/app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarkFragment.java new file mode 100644 index 000000000..c7738ddc1 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarkFragment.java @@ -0,0 +1,80 @@ +package fr.free.nrw.commons.bookmarks; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; + +import android.widget.FrameLayout; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.viewpager.widget.ViewPager; + +import com.google.android.material.tabs.TabLayout; + +import fr.free.nrw.commons.contributions.MainActivity; +import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; +import fr.free.nrw.commons.theme.BaseActivity; +import javax.inject.Inject; + +import butterknife.BindView; +import butterknife.ButterKnife; +import fr.free.nrw.commons.Media; +import fr.free.nrw.commons.R; +import fr.free.nrw.commons.category.CategoryImagesCallback; +import fr.free.nrw.commons.contributions.ContributionController; +import fr.free.nrw.commons.media.MediaDetailPagerFragment; + +public class BookmarkFragment extends CommonsDaggerSupportFragment { + + private FragmentManager supportFragmentManager; + private BookmarksPagerAdapter adapter; + @BindView(R.id.viewPagerBookmarks) + ViewPager viewPager; + @BindView(R.id.tab_layout) + TabLayout tabLayout; + @BindView(R.id.fragmentContainer) + FrameLayout fragmentContainer; + + @Inject + ContributionController controller; + + @NonNull + public static BookmarkFragment newInstance() { + BookmarkFragment fragment = new BookmarkFragment(); + fragment.setRetainInstance(true); + return fragment; + } + + @Override + public void onCreate(@Nullable final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Nullable + @Override + public View onCreateView(@NonNull final LayoutInflater inflater, + @Nullable final ViewGroup container, + @Nullable final Bundle savedInstanceState) { + super.onCreateView(inflater, container, savedInstanceState); + View view = inflater.inflate(R.layout.fragment_bookmarks, container, false); + ButterKnife.bind(this, view); + + // Activity can call methods in the fragment by acquiring a + // reference to the Fragment from FragmentManager, using findFragmentById() + supportFragmentManager = getChildFragmentManager(); + + adapter = new BookmarksPagerAdapter(supportFragmentManager, getContext()); + viewPager.setAdapter(adapter); + tabLayout.setupWithViewPager(viewPager); + return view; + } + + public void onBackPressed() { + ((BookmarkListRootFragment) (adapter.getItem(tabLayout.getSelectedTabPosition()))) + .backPressed(); + ((BaseActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false); + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarkListRootFragment.java b/app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarkListRootFragment.java new file mode 100644 index 000000000..16320a86e --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarkListRootFragment.java @@ -0,0 +1,201 @@ +package fr.free.nrw.commons.bookmarks; + +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.FrameLayout; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import butterknife.BindView; +import butterknife.ButterKnife; +import fr.free.nrw.commons.Media; +import fr.free.nrw.commons.R; +import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsFragment; +import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesFragment; +import fr.free.nrw.commons.category.CategoryImagesCallback; +import fr.free.nrw.commons.contributions.MainActivity; +import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; +import fr.free.nrw.commons.media.MediaDetailPagerFragment; +import fr.free.nrw.commons.navtab.NavTab; + +public class BookmarkListRootFragment extends CommonsDaggerSupportFragment implements + FragmentManager.OnBackStackChangedListener, + MediaDetailPagerFragment.MediaDetailProvider, + AdapterView.OnItemClickListener, CategoryImagesCallback{ + + private MediaDetailPagerFragment mediaDetails; + //private BookmarkPicturesFragment bookmarkPicturesFragment; + private BookmarkLocationsFragment bookmarkLocationsFragment; + public Fragment listFragment; + private BookmarksPagerAdapter bookmarksPagerAdapter; + + @BindView(R.id.explore_container) + FrameLayout container; + + public BookmarkListRootFragment(Bundle bundle, BookmarksPagerAdapter bookmarksPagerAdapter) { + String title = bundle.getString("categoryName"); + int order = bundle.getInt("order"); + if (order == 0) { + listFragment = new BookmarkPicturesFragment(); + } else { + listFragment = new BookmarkLocationsFragment(); + } + Bundle featuredArguments = new Bundle(); + featuredArguments.putString("categoryName", title); + listFragment.setArguments(featuredArguments); + this.bookmarksPagerAdapter = bookmarksPagerAdapter; + } + + @Nullable + @Override + public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, + @Nullable final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + View view = inflater.inflate(R.layout.fragment_featured_root, container, false); + ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + setFragment(listFragment, mediaDetails); + } + + public void setFragment(Fragment fragment, Fragment otherFragment) { + if (fragment.isAdded() && otherFragment != null) { + getChildFragmentManager() + .beginTransaction() + .hide(otherFragment) + .show( fragment) + .addToBackStack("CONTRIBUTION_LIST_FRAGMENT_TAG") + .commit(); + getChildFragmentManager().executePendingTransactions(); + } else if (fragment.isAdded() && otherFragment == null) { + getChildFragmentManager() + .beginTransaction() + .show( fragment) + .addToBackStack("CONTRIBUTION_LIST_FRAGMENT_TAG") + .commit(); + getChildFragmentManager().executePendingTransactions(); + }else if (!fragment.isAdded() && otherFragment != null ) { + getChildFragmentManager() + .beginTransaction() + .hide(otherFragment) + .add(R.id.explore_container, fragment) + .addToBackStack("CONTRIBUTION_LIST_FRAGMENT_TAG") + .commit(); + getChildFragmentManager().executePendingTransactions(); + } else if (!fragment.isAdded()) { + getChildFragmentManager() + .beginTransaction() + .replace(R.id.explore_container, fragment) + .addToBackStack("CONTRIBUTION_LIST_FRAGMENT_TAG") + .commit(); + getChildFragmentManager().executePendingTransactions(); + } + } + + public void removeFragment(Fragment fragment) { + getChildFragmentManager() + .beginTransaction() + .remove(fragment) + .commit(); + getChildFragmentManager().executePendingTransactions(); + } + + @Override + public void onAttach(final Context context) { + super.onAttach(context); + } + + @Override + public void onMediaClicked(int position) { + Log.d("deneme8","on media clicked"); + /*container.setVisibility(View.VISIBLE); + ((BookmarkFragment)getParentFragment()).tabLayout.setVisibility(View.GONE); + mediaDetails = new MediaDetailPagerFragment(false, true, position); + setFragment(mediaDetails, bookmarkPicturesFragment);*/ + } + + /** + * This method is called mediaDetailPagerFragment. It returns the Media Object at that Index + * + * @param i It is the index of which media object is to be returned which is same as current + * index of viewPager. + * @return Media Object + */ + @Override + public Media getMediaAtPosition(int i) { + if (bookmarksPagerAdapter.getMediaAdapter() == null) { + // not yet ready to return data + return null; + } else { + return (Media) bookmarksPagerAdapter.getMediaAdapter().getItem(i); + } + } + + /** + * This method is called on from getCount of MediaDetailPagerFragment The viewpager will contain + * same number of media items as that of media elements in adapter. + * + * @return Total Media count in the adapter + */ + @Override + public int getTotalMediaCount() { + if (bookmarksPagerAdapter.getMediaAdapter() == null) { + return 0; + } + return bookmarksPagerAdapter.getMediaAdapter().getCount(); + } + + @Override + public Integer getContributionStateAt(int position) { + return null; + } + + /** + * This method is called on success of API call for featured images or mobile uploads. The + * viewpager will notified that number of items have changed. + */ + @Override + public void viewPagerNotifyDataSetChanged() { + if (mediaDetails != null) { + mediaDetails.notifyDataSetChanged(); + } + } + + public void backPressed() { + if (mediaDetails.isVisible()) { + // todo add get list fragment + ((BookmarkFragment)getParentFragment()).tabLayout.setVisibility(View.VISIBLE); + removeFragment(mediaDetails); + setFragment(listFragment, mediaDetails); + ((MainActivity)getActivity()).showTabs(); + } else { + ((MainActivity) getActivity()).setSelectedItemId(NavTab.CONTRIBUTIONS.code()); + ((MainActivity)getActivity()).showTabs(); + } + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Log.d("deneme8","on media clicked"); + container.setVisibility(View.VISIBLE); + ((BookmarkFragment)getParentFragment()).tabLayout.setVisibility(View.GONE); + mediaDetails = new MediaDetailPagerFragment(false, true); + setFragment(mediaDetails, listFragment); + mediaDetails.showImage(position); + } + + @Override + public void onBackStackChanged() { + + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarksActivity.java b/app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarksActivity.java deleted file mode 100644 index a48d07e68..000000000 --- a/app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarksActivity.java +++ /dev/null @@ -1,152 +0,0 @@ -package fr.free.nrw.commons.bookmarks; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.view.View; -import android.widget.AdapterView; - -import androidx.fragment.app.FragmentManager; -import androidx.viewpager.widget.ViewPager; - -import com.google.android.material.tabs.TabLayout; - -import javax.inject.Inject; - -import butterknife.BindView; -import butterknife.ButterKnife; -import fr.free.nrw.commons.Media; -import fr.free.nrw.commons.R; -import fr.free.nrw.commons.category.CategoryImagesCallback; -import fr.free.nrw.commons.contributions.ContributionController; -import fr.free.nrw.commons.media.MediaDetailPagerFragment; -import fr.free.nrw.commons.theme.NavigationBaseActivity; - -public class BookmarksActivity extends NavigationBaseActivity - implements FragmentManager.OnBackStackChangedListener, - MediaDetailPagerFragment.MediaDetailProvider, - AdapterView.OnItemClickListener, CategoryImagesCallback { - - private FragmentManager supportFragmentManager; - private BookmarksPagerAdapter adapter; - private MediaDetailPagerFragment mediaDetails; - @BindView(R.id.viewPagerBookmarks) - ViewPager viewPager; - @BindView(R.id.tab_layout) - TabLayout tabLayout; - - @Inject - ContributionController controller; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_bookmarks); - ButterKnife.bind(this); - - // Activity can call methods in the fragment by acquiring a - // reference to the Fragment from FragmentManager, using findFragmentById() - supportFragmentManager = getSupportFragmentManager(); - supportFragmentManager.addOnBackStackChangedListener(this); - initDrawer(); - - adapter = new BookmarksPagerAdapter(supportFragmentManager, this); - viewPager.setAdapter(adapter); - tabLayout.setupWithViewPager(viewPager); - } - - /** - * 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, BookmarksActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); - context.startActivity(intent); - } - - @Override - public void onBackStackChanged() { - if (supportFragmentManager.getBackStackEntryCount() == 0) { - // The activity has the focus - adapter.requestPictureListUpdate(); - initDrawer(); - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - controller.handleActivityResult(this, requestCode, resultCode, data); - } - - /** - * This method is called onClick of media inside category details (CategoryImageListFragment). - */ - @Override - public void onItemClick(AdapterView adapterView, View view, int i, long l) { - if (mediaDetails == null || !mediaDetails.isVisible()) { - mediaDetails = new MediaDetailPagerFragment(false, true); - supportFragmentManager - .beginTransaction() - .hide(supportFragmentManager.getFragments().get(supportFragmentManager.getBackStackEntryCount())) - .add(R.id.fragmentContainer, mediaDetails) - .addToBackStack(null) - .commit(); - supportFragmentManager.executePendingTransactions(); - } - mediaDetails.showImage(i); - forceInitBackButton(); - } - - /** - * This method is called on success of API call for featured Images. - * The viewpager will notified that number of items have changed. - */ - @Override - public void viewPagerNotifyDataSetChanged() { - if (mediaDetails!=null){ - mediaDetails.notifyDataSetChanged(); - } - } - - - /** - * This method is called mediaDetailPagerFragment. It returns the Media Object at that Index - * @param i It is the index of which media object is to be returned which is same as - * current index of viewPager. - * @return Media Object - */ - @Override - public Media getMediaAtPosition(int i) { - if (adapter.getMediaAdapter() == null) { - // not yet ready to return data - return null; - } else { - return (Media) adapter.getMediaAdapter().getItem(i); - } - } - - /** - * This method is called on from getCount of MediaDetailPagerFragment - * The viewpager will contain same number of media items as that of media elements in adapter. - * @return Total Media count in the adapter - */ - @Override - public int getTotalMediaCount() { - if (adapter.getMediaAdapter() == null) { - return 0; - } - return adapter.getMediaAdapter().getCount(); - } - - @Override - public void onMediaClicked(int position) { - //TODO use with pagination - } - - @Override - public Integer getContributionStateAt(int position) { - return null; - } -} diff --git a/app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarksPagerAdapter.java b/app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarksPagerAdapter.java index bc2dbb432..1f5529105 100644 --- a/app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarksPagerAdapter.java +++ b/app/src/main/java/fr/free/nrw/commons/bookmarks/BookmarksPagerAdapter.java @@ -1,6 +1,7 @@ package fr.free.nrw.commons.bookmarks; import android.content.Context; +import android.os.Bundle; import android.widget.ListAdapter; import androidx.annotation.Nullable; @@ -21,14 +22,19 @@ public class BookmarksPagerAdapter extends FragmentPagerAdapter { BookmarksPagerAdapter(FragmentManager fm, Context context) { super(fm); pages = new ArrayList<>(); + Bundle picturesBundle = new Bundle(); + picturesBundle.putString("categoryName", context.getString(R.string.title_page_bookmarks_pictures)); + picturesBundle.putInt("order", 0); pages.add(new BookmarkPages( - BookmarkPicturesFragment.newInstance(), - context.getString(R.string.title_page_bookmarks_pictures) - )); + new BookmarkListRootFragment(picturesBundle, this), + context.getString(R.string.title_page_bookmarks_pictures))); + + Bundle locationBundle = new Bundle(); + locationBundle.putString("categoryName", context.getString(R.string.title_page_bookmarks_locations)); + locationBundle.putInt("order", 1); pages.add(new BookmarkPages( - BookmarkLocationsFragment.newInstance(), - context.getString(R.string.title_page_bookmarks_locations) - )); + new BookmarkListRootFragment(locationBundle, this), + context.getString(R.string.title_page_bookmarks_locations))); notifyDataSetChanged(); } @@ -53,7 +59,7 @@ public class BookmarksPagerAdapter extends FragmentPagerAdapter { * @return adapter */ public ListAdapter getMediaAdapter() { - BookmarkPicturesFragment fragment = (BookmarkPicturesFragment)(pages.get(0).getPage()); + BookmarkPicturesFragment fragment = (BookmarkPicturesFragment)(((BookmarkListRootFragment)pages.get(0).getPage()).listFragment); return fragment.getAdapter(); } @@ -61,7 +67,7 @@ public class BookmarksPagerAdapter extends FragmentPagerAdapter { * Update the pictures list for the bookmark fragment */ public void requestPictureListUpdate() { - BookmarkPicturesFragment fragment = (BookmarkPicturesFragment)(pages.get(0).getPage()); + BookmarkPicturesFragment fragment = (BookmarkPicturesFragment)(((BookmarkListRootFragment)pages.get(0).getPage()).listFragment); fragment.onResume(); } } diff --git a/app/src/main/java/fr/free/nrw/commons/bookmarks/pictures/BookmarkPicturesFragment.java b/app/src/main/java/fr/free/nrw/commons/bookmarks/pictures/BookmarkPicturesFragment.java index 7070fa40b..9265c2d54 100644 --- a/app/src/main/java/fr/free/nrw/commons/bookmarks/pictures/BookmarkPicturesFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/bookmarks/pictures/BookmarkPicturesFragment.java @@ -21,7 +21,7 @@ import butterknife.ButterKnife; import dagger.android.support.DaggerFragment; import fr.free.nrw.commons.Media; import fr.free.nrw.commons.R; -import fr.free.nrw.commons.bookmarks.BookmarksActivity; +import fr.free.nrw.commons.bookmarks.BookmarkListRootFragment; import fr.free.nrw.commons.category.GridViewAdapter; import fr.free.nrw.commons.utils.NetworkUtils; import fr.free.nrw.commons.utils.ViewUtil; @@ -67,7 +67,7 @@ public class BookmarkPicturesFragment extends DaggerFragment { @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - gridView.setOnItemClickListener((AdapterView.OnItemClickListener) getActivity()); + gridView.setOnItemClickListener((AdapterView.OnItemClickListener) getParentFragment()); initList(); } @@ -90,7 +90,7 @@ public class BookmarkPicturesFragment extends DaggerFragment { gridView.setVisibility(GONE); if (gridAdapter != null) { gridAdapter.clear(); - ((BookmarksActivity) getContext()).viewPagerNotifyDataSetChanged(); + ((BookmarkListRootFragment)getParentFragment()).viewPagerNotifyDataSetChanged(); } initList(); } @@ -191,7 +191,7 @@ public class BookmarkPicturesFragment extends DaggerFragment { return; } gridAdapter.addItems(collection); - ((BookmarksActivity) getContext()).viewPagerNotifyDataSetChanged(); + ((BookmarkListRootFragment) getParentFragment()).viewPagerNotifyDataSetChanged(); } progressBar.setVisibility(GONE); statusTextView.setVisibility(GONE); diff --git a/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignView.java b/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignView.java index fed6617b4..f644d75e6 100644 --- a/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignView.java +++ b/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignView.java @@ -57,8 +57,8 @@ public class CampaignView extends SwipableCardView { @Override public boolean onSwipe(View view) { view.setVisibility(View.GONE); - ((MainActivity) getContext()).defaultKvStore - .putBoolean("displayCampaignsCardView", false); + /*((MainActivity) getContext()).defaultKvStore + .putBoolean("displayCampaignsCardView", false);*/ ViewUtil.showLongToast(getContext(), getResources().getString(R.string.nearby_campaign_dismiss_message)); return true; diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoryDetailsActivity.java b/app/src/main/java/fr/free/nrw/commons/category/CategoryDetailsActivity.java index 8f36b9aaa..23786d974 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoryDetailsActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoryDetailsActivity.java @@ -23,7 +23,7 @@ import fr.free.nrw.commons.explore.categories.media.CategoriesMediaFragment; import fr.free.nrw.commons.explore.categories.parent.ParentCategoriesFragment; import fr.free.nrw.commons.explore.categories.sub.SubCategoriesFragment; import fr.free.nrw.commons.media.MediaDetailPagerFragment; -import fr.free.nrw.commons.theme.NavigationBaseActivity; +import fr.free.nrw.commons.theme.BaseActivity; import java.util.ArrayList; import java.util.List; @@ -33,7 +33,7 @@ import java.util.List; * a particular category on wikimedia commons. */ -public class CategoryDetailsActivity extends NavigationBaseActivity +public class CategoryDetailsActivity extends BaseActivity implements MediaDetailPagerFragment.MediaDetailProvider, CategoryImagesCallback { @@ -59,8 +59,6 @@ public class CategoryDetailsActivity extends NavigationBaseActivity tabLayout.setupWithViewPager(viewPager); setTabs(); setPageTitle(); - initDrawer(); - forceInitBackButton(); } /** @@ -104,6 +102,7 @@ public class CategoryDetailsActivity extends NavigationBaseActivity /** * This method is called onClick of media inside category details (CategoryImageListFragment). */ + @Override public void onMediaClicked(int position) { tabLayout.setVisibility(View.GONE); viewPager.setVisibility(View.GONE); @@ -120,7 +119,6 @@ public class CategoryDetailsActivity extends NavigationBaseActivity supportFragmentManager.executePendingTransactions(); } mediaDetails.showImage(position); - forceInitBackButton(); } diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoryImagesActivity.java b/app/src/main/java/fr/free/nrw/commons/category/CategoryImagesActivity.java index d9f651380..de4fa1ebc 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoryImagesActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoryImagesActivity.java @@ -16,7 +16,8 @@ import fr.free.nrw.commons.R; import fr.free.nrw.commons.explore.SearchActivity; import fr.free.nrw.commons.explore.categories.media.CategoriesMediaFragment; import fr.free.nrw.commons.media.MediaDetailPagerFragment; -import fr.free.nrw.commons.theme.NavigationBaseActivity; +import fr.free.nrw.commons.theme.BaseActivity; +import fr.free.nrw.commons.utils.ActivityUtils; /** * This activity displays pictures of a particular category @@ -26,7 +27,7 @@ import fr.free.nrw.commons.theme.NavigationBaseActivity; */ public class CategoryImagesActivity - extends NavigationBaseActivity + extends BaseActivity implements FragmentManager.OnBackStackChangedListener, MediaDetailPagerFragment.MediaDetailProvider, AdapterView.OnItemClickListener, CategoryImagesCallback { @@ -42,7 +43,6 @@ public class CategoryImagesActivity */ @Override public void onBackPressed() { - initDrawer(); super.onBackPressed(); } @@ -57,7 +57,6 @@ public class CategoryImagesActivity supportFragmentManager = getSupportFragmentManager(); setCategoryImagesFragment(); supportFragmentManager.addOnBackStackChangedListener(this); - initDrawer(); setPageTitle(); } @@ -111,7 +110,6 @@ public class CategoryImagesActivity // https://stackoverflow.com/questions/11353075/how-can-i-maintain-fragment-state-when-added-to-the-back-stack/19022550#19022550 supportFragmentManager.executePendingTransactions(); } mediaDetails.showImage(i); - forceInitBackButton(); } /** @@ -185,7 +183,7 @@ public class CategoryImagesActivity // Handle item selection switch (item.getItemId()) { case R.id.action_search: - NavigationBaseActivity.startActivityWithFlags(this, SearchActivity.class); + ActivityUtils.startActivityWithFlags(this, SearchActivity.class); return true; default: return super.onOptionsItemSelected(item); diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionViewHolder.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionViewHolder.java index 3c21c67f1..3c1905c09 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionViewHolder.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionViewHolder.java @@ -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); diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java index bb93b5777..96efcddb0 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java @@ -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 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(); + } + } } diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/MainActivity.java b/app/src/main/java/fr/free/nrw/commons/contributions/MainActivity.java index 88369d1ca..26fa55bc2 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/MainActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/MainActivity.java @@ -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 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 + } } diff --git a/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java b/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java index 1686dba3e..325a5a5e5 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java +++ b/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java @@ -6,13 +6,11 @@ import fr.free.nrw.commons.AboutActivity; import fr.free.nrw.commons.WelcomeActivity; import fr.free.nrw.commons.auth.LoginActivity; import fr.free.nrw.commons.auth.SignupActivity; -import fr.free.nrw.commons.bookmarks.BookmarksActivity; import fr.free.nrw.commons.category.CategoryDetailsActivity; import fr.free.nrw.commons.category.CategoryImagesActivity; import fr.free.nrw.commons.contributions.MainActivity; import fr.free.nrw.commons.explore.depictions.WikidataItemDetailsActivity; import fr.free.nrw.commons.explore.SearchActivity; -import fr.free.nrw.commons.explore.ExploreActivity; import fr.free.nrw.commons.notification.NotificationActivity; import fr.free.nrw.commons.profile.ProfileActivity; import fr.free.nrw.commons.review.ReviewActivity; @@ -64,15 +62,9 @@ public abstract class ActivityBuilderModule { @ContributesAndroidInjector abstract WikidataItemDetailsActivity bindDepictionDetailsActivity(); - @ContributesAndroidInjector - abstract ExploreActivity bindExploreActivity(); - @ContributesAndroidInjector abstract ProfileActivity bindAchievementsActivity(); - @ContributesAndroidInjector - abstract BookmarksActivity bindBookmarksActivity(); - @ContributesAndroidInjector abstract ReviewActivity bindReviewActivity(); } diff --git a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java index 7fc66e507..888967b48 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java @@ -3,6 +3,9 @@ package fr.free.nrw.commons.di; import com.google.gson.Gson; import fr.free.nrw.commons.explore.categories.CategoriesModule; +import fr.free.nrw.commons.navtab.MoreBottomSheetFragment; +import fr.free.nrw.commons.navtab.MoreBottomSheetLoggedOutFragment; +import fr.free.nrw.commons.navtab.NavTabLayout; import javax.inject.Singleton; import dagger.Component; @@ -48,8 +51,14 @@ public interface CommonsApplicationComponent extends AndroidInjector fragmentList = new ArrayList<>(); - List titleList = new ArrayList<>(); - - featuredImagesListFragment = new CategoriesMediaFragment(); - Bundle featuredArguments = new Bundle(); - featuredArguments.putString("categoryName", FEATURED_IMAGES_CATEGORY); - featuredImagesListFragment.setArguments(featuredArguments); - fragmentList.add(featuredImagesListFragment); - titleList.add(getString(R.string.explore_tab_title_featured).toUpperCase()); - - mobileImagesListFragment = new CategoriesMediaFragment(); - Bundle mobileArguments = new Bundle(); - mobileArguments.putString("categoryName", MOBILE_UPLOADS_CATEGORY); - mobileImagesListFragment.setArguments(mobileArguments); - fragmentList.add(mobileImagesListFragment); - titleList.add(getString(R.string.explore_tab_title_mobile).toUpperCase()); - - viewPagerAdapter.setTabData(fragmentList, titleList); - viewPagerAdapter.notifyDataSetChanged(); - } - - /** - * This method is called mediaDetailPagerFragment. It returns the Media Object at that Index - * - * @param i It is the index of which media object is to be returned which is same as - * current index of viewPager. - * @return Media Object - */ - @Override - public Media getMediaAtPosition(int i) { - if (tabLayout.getSelectedTabPosition() == 1) { - return mobileImagesListFragment.getMediaAtPosition(i); - } else if (tabLayout.getSelectedTabPosition() == 0) { - return featuredImagesListFragment.getMediaAtPosition(i); - } else { - return null; - } - } - - /** - * This method is called on from getCount of MediaDetailPagerFragment - * The viewpager will contain same number of media items as that of media elements in adapter. - * - * @return Total Media count in the adapter - */ - @Override - public int getTotalMediaCount() { - if (tabLayout.getSelectedTabPosition() == 1) { - return mobileImagesListFragment.getTotalMediaCount(); - } else if (tabLayout.getSelectedTabPosition() == 0) { - return featuredImagesListFragment.getTotalMediaCount(); - } else { - return 0; - } - } - - @Override - public Integer getContributionStateAt(int position) { - return null; - } - - /** - * This method is called on success of API call for featured images or mobile uploads. - * The viewpager will notified that number of items have changed. - */ - @Override - public void viewPagerNotifyDataSetChanged() { - if (mediaDetails != null) { - mediaDetails.notifyDataSetChanged(); - } - } - - - /** - * This method is called on backPressed of anyFragment in the activity. - * If condition is called when mediaDetailFragment is opened. - */ - @Override - public void onBackPressed() { - if (supportFragmentManager.getBackStackEntryCount() == 1) { - tabLayout.setVisibility(View.VISIBLE); - viewPager.setVisibility(View.VISIBLE); - mediaContainer.setVisibility(View.GONE); - } - initDrawer(); - super.onBackPressed(); - } - - /** - * This method is called onClick of media inside category featured images or mobile uploads. - */ - @Override - public void onMediaClicked( int position) { - tabLayout.setVisibility(View.GONE); - viewPager.setVisibility(View.GONE); - mediaContainer.setVisibility(View.VISIBLE); - if (mediaDetails == null || !mediaDetails.isVisible()) { - // set isFeaturedImage true for featured images, to include author field on media detail - mediaDetails = new MediaDetailPagerFragment(false, true); - FragmentManager supportFragmentManager = getSupportFragmentManager(); - supportFragmentManager - .beginTransaction() - .hide(supportFragmentManager.getFragments().get(supportFragmentManager.getBackStackEntryCount())) - .add(R.id.mediaContainer, mediaDetails) - .addToBackStack(null) - .commit(); - // Reason for using hide, add instead of replace is to maintain scroll position after - // coming back to the explore activity. See https://github.com/commons-app/apps-android-commons/issues/1631 - // https://stackoverflow.com/questions/11353075/how-can-i-maintain-fragment-state-when-added-to-the-back-stack/19022550#19022550 supportFragmentManager.executePendingTransactions(); - } - mediaDetails.showImage(position); - forceInitBackButton(); - } - - /** - * This method inflates the menu in the toolbar - */ - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.menu_search, menu); - return super.onCreateOptionsMenu(menu); - } - - /** - * This method handles the logic on ItemSelect in toolbar menu - * Currently only 1 choice is available to open search page of the app - */ - @Override - public boolean onOptionsItemSelected(MenuItem item) { - - // Handle item selection - switch (item.getItemId()) { - case R.id.action_search: - NavigationBaseActivity.startActivityWithFlags(this, SearchActivity.class); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - -} - diff --git a/app/src/main/java/fr/free/nrw/commons/explore/ExploreFragment.java b/app/src/main/java/fr/free/nrw/commons/explore/ExploreFragment.java new file mode 100644 index 000000000..6a6a23e20 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/ExploreFragment.java @@ -0,0 +1,126 @@ +package fr.free.nrw.commons.explore; + +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.view.ViewGroup; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; +import butterknife.BindView; +import butterknife.ButterKnife; +import com.google.android.material.tabs.TabLayout; +import fr.free.nrw.commons.R; +import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; +import fr.free.nrw.commons.theme.BaseActivity; +import fr.free.nrw.commons.utils.ActivityUtils; +import java.util.ArrayList; +import java.util.List; + +public class ExploreFragment extends CommonsDaggerSupportFragment { + + private static final String FEATURED_IMAGES_CATEGORY = "Featured_pictures_on_Wikimedia_Commons"; + private static final String MOBILE_UPLOADS_CATEGORY = "Uploaded_with_Mobile/Android"; + private static final String MEDIA_DETAILS_FRAGMENT_TAG = "MediaDetailsFragment"; + + @BindView(R.id.tab_layout) + TabLayout tabLayout; + @BindView(R.id.viewPager) + ViewPager viewPager; + ViewPagerAdapter viewPagerAdapter; + private ExploreListRootFragment featuredRootFragment; + private ExploreListRootFragment mobileRootFragment; + + @NonNull + public static ExploreFragment newInstance() { + ExploreFragment fragment = new ExploreFragment(); + fragment.setRetainInstance(true); + return fragment; + } + + @Override + public void onCreate(@Nullable final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + View view = inflater.inflate(R.layout.fragment_explore, container, false); + ButterKnife.bind(this, view); + viewPagerAdapter = new ViewPagerAdapter(getChildFragmentManager()); + viewPager.setAdapter(viewPagerAdapter); + viewPager.setId(R.id.viewPager); + tabLayout.setupWithViewPager(viewPager); + setTabs(); + setHasOptionsMenu(true); + return view; + } + + /** + * Sets the titles in the tabLayout and fragments in the viewPager + */ + public void setTabs() { + List fragmentList = new ArrayList<>(); + List titleList = new ArrayList<>(); + + Bundle featuredArguments = new Bundle(); + featuredArguments.putString("categoryName", FEATURED_IMAGES_CATEGORY); + + Bundle mobileArguments = new Bundle(); + mobileArguments.putString("categoryName", MOBILE_UPLOADS_CATEGORY); + + featuredRootFragment = new ExploreListRootFragment(featuredArguments); + mobileRootFragment = new ExploreListRootFragment(mobileArguments); + fragmentList.add(featuredRootFragment); + titleList.add(getString(R.string.explore_tab_title_featured).toUpperCase()); + + fragmentList.add(mobileRootFragment); + titleList.add(getString(R.string.explore_tab_title_mobile).toUpperCase()); + + viewPagerAdapter.setTabData(fragmentList, titleList); + viewPagerAdapter.notifyDataSetChanged(); + } + + public void onBackPressed() { + if (tabLayout.getSelectedTabPosition() == 0) { + featuredRootFragment.backPressed(); + } else { + mobileRootFragment.backPressed(); + } + ((BaseActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false); + } + + /** + * This method inflates the menu in the toolbar + */ + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.menu_search, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + /** + * This method handles the logic on ItemSelect in toolbar menu Currently only 1 choice is + * available to open search page of the app + */ + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + // Handle item selection + switch (item.getItemId()) { + case R.id.action_search: + ActivityUtils.startActivityWithFlags(getActivity(), SearchActivity.class); + return true; + default: + return super.onOptionsItemSelected(item); + } + } +} + + diff --git a/app/src/main/java/fr/free/nrw/commons/explore/ExploreListRootFragment.java b/app/src/main/java/fr/free/nrw/commons/explore/ExploreListRootFragment.java new file mode 100644 index 000000000..ad09e2ad9 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/ExploreListRootFragment.java @@ -0,0 +1,176 @@ +package fr.free.nrw.commons.explore; + +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import butterknife.BindView; +import butterknife.ButterKnife; +import com.google.android.material.tabs.TabLayout; +import fr.free.nrw.commons.Media; +import fr.free.nrw.commons.R; +import fr.free.nrw.commons.category.CategoryImagesCallback; +import fr.free.nrw.commons.contributions.ContributionsListFragment; +import fr.free.nrw.commons.contributions.MainActivity; +import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; +import fr.free.nrw.commons.explore.categories.media.CategoriesMediaFragment; +import fr.free.nrw.commons.media.MediaDetailPagerFragment; +import fr.free.nrw.commons.navtab.NavTab; +import fr.free.nrw.commons.settings.SettingsFragment; + +public class ExploreListRootFragment extends CommonsDaggerSupportFragment implements + MediaDetailPagerFragment.MediaDetailProvider, CategoryImagesCallback { + + private MediaDetailPagerFragment mediaDetails; + private CategoriesMediaFragment listFragment; + + @BindView(R.id.explore_container) + FrameLayout container; + + public ExploreListRootFragment(Bundle bundle) { + String title = bundle.getString("categoryName"); + listFragment = new CategoriesMediaFragment(); + Bundle featuredArguments = new Bundle(); + featuredArguments.putString("categoryName", title); + listFragment.setArguments(featuredArguments); + } + + @Nullable + @Override + public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, + @Nullable final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + View view = inflater.inflate(R.layout.fragment_featured_root, container, false); + ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + setFragment(listFragment, mediaDetails); + } + + public void setFragment(Fragment fragment, Fragment otherFragment) { + if (fragment.isAdded() && otherFragment != null) { + getChildFragmentManager() + .beginTransaction() + .hide(otherFragment) + .show( fragment) + .addToBackStack("CONTRIBUTION_LIST_FRAGMENT_TAG") + .commit(); + getChildFragmentManager().executePendingTransactions(); + } else if (fragment.isAdded() && otherFragment == null) { + getChildFragmentManager() + .beginTransaction() + .show( fragment) + .addToBackStack("CONTRIBUTION_LIST_FRAGMENT_TAG") + .commit(); + getChildFragmentManager().executePendingTransactions(); + }else if (!fragment.isAdded() && otherFragment != null ) { + getChildFragmentManager() + .beginTransaction() + .hide(otherFragment) + .add(R.id.explore_container, fragment) + .addToBackStack("CONTRIBUTION_LIST_FRAGMENT_TAG") + .commit(); + getChildFragmentManager().executePendingTransactions(); + } else if (!fragment.isAdded()) { + getChildFragmentManager() + .beginTransaction() + .replace(R.id.explore_container, fragment) + .addToBackStack("CONTRIBUTION_LIST_FRAGMENT_TAG") + .commit(); + getChildFragmentManager().executePendingTransactions(); + } + } + + public void removeFragment(Fragment fragment) { + getChildFragmentManager() + .beginTransaction() + .remove(fragment) + .commit(); + getChildFragmentManager().executePendingTransactions(); + } + + @Override + public void onAttach(final Context context) { + super.onAttach(context); + } + + @Override + public void onMediaClicked(int position) { + Log.d("deneme8","on media clicked"); + container.setVisibility(View.VISIBLE); + ((ExploreFragment)getParentFragment()).tabLayout.setVisibility(View.GONE); + mediaDetails = new MediaDetailPagerFragment(false, true, position); + setFragment(mediaDetails, listFragment); + } + + /** + * This method is called mediaDetailPagerFragment. It returns the Media Object at that Index + * + * @param i It is the index of which media object is to be returned which is same as current + * index of viewPager. + * @return Media Object + */ + @Override + public Media getMediaAtPosition(int i) { + if (listFragment != null) { + return listFragment.getMediaAtPosition(i); + } else { + return null; + } + } + + /** + * This method is called on from getCount of MediaDetailPagerFragment The viewpager will contain + * same number of media items as that of media elements in adapter. + * + * @return Total Media count in the adapter + */ + @Override + public int getTotalMediaCount() { + if (listFragment!=null) { + return listFragment.getTotalMediaCount(); + } else { + return 0; + } + } + + @Override + public Integer getContributionStateAt(int position) { + return null; + } + + /** + * This method is called on success of API call for featured images or mobile uploads. The + * viewpager will notified that number of items have changed. + */ + @Override + public void viewPagerNotifyDataSetChanged() { + if (mediaDetails != null) { + mediaDetails.notifyDataSetChanged(); + } + } + + public void backPressed() { + if (mediaDetails.isVisible()) { + // todo add get list fragment + ((ExploreFragment)getParentFragment()).tabLayout.setVisibility(View.VISIBLE); + removeFragment(mediaDetails); + setFragment(listFragment, mediaDetails); + ((MainActivity)getActivity()).showTabs(); + } else { + ((MainActivity) getActivity()).setSelectedItemId(NavTab.CONTRIBUTIONS.code()); + ((MainActivity)getActivity()).showTabs(); + } + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.java b/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.java index e86b06a71..316788a88 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.java @@ -26,7 +26,7 @@ import fr.free.nrw.commons.explore.recentsearches.RecentSearch; import fr.free.nrw.commons.explore.recentsearches.RecentSearchesDao; import fr.free.nrw.commons.explore.recentsearches.RecentSearchesFragment; import fr.free.nrw.commons.media.MediaDetailPagerFragment; -import fr.free.nrw.commons.theme.NavigationBaseActivity; +import fr.free.nrw.commons.theme.BaseActivity; import fr.free.nrw.commons.utils.FragmentUtils; import fr.free.nrw.commons.utils.ViewUtil; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -41,7 +41,7 @@ import timber.log.Timber; * Represents search screen of this app */ -public class SearchActivity extends NavigationBaseActivity +public class SearchActivity extends BaseActivity implements MediaDetailPagerFragment.MediaDetailProvider, CategoryImagesCallback { @BindView(R.id.toolbar_search) Toolbar toolbar; @@ -67,7 +67,6 @@ public class SearchActivity extends NavigationBaseActivity super.onCreate(savedInstanceState); setContentView(R.layout.activity_search); ButterKnife.bind(this); - initDrawer(); setTitle(getString(R.string.title_activity_search)); toolbar.setNavigationOnClickListener(v->onBackPressed()); supportFragmentManager = getSupportFragmentManager(); @@ -203,7 +202,6 @@ public class SearchActivity extends NavigationBaseActivity tabLayout.setVisibility(View.GONE); viewPager.setVisibility(View.GONE); mediaContainer.setVisibility(View.VISIBLE); - setNavigationBaseToolbarVisibility(true); if (mediaDetails == null || !mediaDetails.isVisible()) { // set isFeaturedImage true for featured images, to include author field on media detail mediaDetails = new MediaDetailPagerFragment(false, true); @@ -220,7 +218,6 @@ public class SearchActivity extends NavigationBaseActivity supportFragmentManager.executePendingTransactions(); } mediaDetails.showImage(index); - forceInitBackButton(); } /** @@ -250,10 +247,8 @@ public class SearchActivity extends NavigationBaseActivity tabLayout.setVisibility(View.VISIBLE); viewPager.setVisibility(View.VISIBLE); mediaContainer.setVisibility(View.GONE); - setNavigationBaseToolbarVisibility(false); }else { toolbar.setVisibility(View.GONE); - setNavigationBaseToolbarVisibility(true); } super.onBackPressed(); } diff --git a/app/src/main/java/fr/free/nrw/commons/explore/categories/media/CategoriesMediaFragment.kt b/app/src/main/java/fr/free/nrw/commons/explore/categories/media/CategoriesMediaFragment.kt index 8e39781ec..c13445f2b 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/categories/media/CategoriesMediaFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/categories/media/CategoriesMediaFragment.kt @@ -8,6 +8,7 @@ import javax.inject.Inject class CategoriesMediaFragment : PageableMediaFragment() { + @Inject lateinit var presenter: CategoryMediaPresenter diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/WikidataItemDetailsActivity.java b/app/src/main/java/fr/free/nrw/commons/explore/depictions/WikidataItemDetailsActivity.java index 9a22840ea..8c5874ec9 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/depictions/WikidataItemDetailsActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/WikidataItemDetailsActivity.java @@ -19,7 +19,7 @@ import fr.free.nrw.commons.explore.depictions.media.DepictedImagesFragment; import fr.free.nrw.commons.explore.depictions.parent.ParentDepictionsFragment; import fr.free.nrw.commons.explore.ViewPagerAdapter; import fr.free.nrw.commons.media.MediaDetailPagerFragment; -import fr.free.nrw.commons.theme.NavigationBaseActivity; +import fr.free.nrw.commons.theme.BaseActivity; import fr.free.nrw.commons.upload.structure.depictions.DepictedItem; import java.util.ArrayList; import java.util.List; @@ -27,7 +27,7 @@ import java.util.List; /** * Activity to show depiction media, parent classes and child classes of depicted items in Explore */ -public class WikidataItemDetailsActivity extends NavigationBaseActivity implements MediaDetailPagerFragment.MediaDetailProvider, +public class WikidataItemDetailsActivity extends BaseActivity implements MediaDetailPagerFragment.MediaDetailProvider, CategoryImagesCallback { private FragmentManager supportFragmentManager; private DepictedImagesFragment depictionImagesListFragment; @@ -58,8 +58,6 @@ public class WikidataItemDetailsActivity extends NavigationBaseActivity implemen tabLayout.setupWithViewPager(viewPager); setTabs(); setPageTitle(); - initDrawer(); - forceInitBackButton(); } /** @@ -118,6 +116,7 @@ public class WikidataItemDetailsActivity extends NavigationBaseActivity implemen /** * Shows media detail fragment when user clicks on any image in the list */ + @Override public void onMediaClicked(int position) { tabLayout.setVisibility(View.GONE); viewPager.setVisibility(View.GONE); @@ -134,7 +133,6 @@ public class WikidataItemDetailsActivity extends NavigationBaseActivity implemen supportFragmentManager.executePendingTransactions(); } mediaDetailPagerFragment.showImage(position); - forceInitBackButton(); } /** diff --git a/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaFragment.kt b/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaFragment.kt index f00420c95..ea97cfa75 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaFragment.kt @@ -25,7 +25,11 @@ abstract class PageableMediaFragment : BasePagingFragment(), MediaDetailP override fun onAttach(context: Context) { super.onAttach(context) - categoryImagesCallback = (context as CategoryImagesCallback) + if (parentFragment != null) { + categoryImagesCallback = (parentFragment as CategoryImagesCallback) + } else { + categoryImagesCallback = (activity as CategoryImagesCallback) + } } private val simpleDataObserver = diff --git a/app/src/main/java/fr/free/nrw/commons/location/LocationServiceManager.java b/app/src/main/java/fr/free/nrw/commons/location/LocationServiceManager.java index a34e8d2ad..777ad8dce 100644 --- a/app/src/main/java/fr/free/nrw/commons/location/LocationServiceManager.java +++ b/app/src/main/java/fr/free/nrw/commons/location/LocationServiceManager.java @@ -60,6 +60,11 @@ public class LocationServiceManager implements LocationListener { */ private boolean requestLocationUpdatesFromProvider(String locationProvider) { try { + // If both providers are not available + if (locationManager == null || !(locationManager.getAllProviders().contains(LocationManager.NETWORK_PROVIDER)) + || !(locationManager.getAllProviders().contains(LocationManager.GPS_PROVIDER))) { + return false; + } locationManager.requestLocationUpdates(locationProvider, MIN_LOCATION_UPDATE_REQUEST_TIME_IN_MILLIS, MIN_LOCATION_UPDATE_REQUEST_DISTANCE_IN_METERS, diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java index addc9f67c..18cdf2cbc 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java @@ -280,9 +280,11 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements if (getParentFragment() != null && getParentFragment().getParentFragment() != null) { //Added a check because, not necessarily, the parent fragment will have a parent fragment, say // in the case when MediaDetailPagerFragment is directly started by the CategoryImagesActivity - ((ContributionsFragment) (getParentFragment() + if (getParentFragment() instanceof ContributionsFragment) { + ((ContributionsFragment) (getParentFragment() .getParentFragment())).nearbyNotificationCardView .setVisibility(View.GONE); + } } categoryEditSearchRecyclerViewAdapter = new CategoryEditSearchRecyclerViewAdapter(getContext(), new ArrayList<>( @@ -795,7 +797,6 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements } private void rebuildCatList(List categories) { - Log.d("deneme","rebuild cat list size:"+categories.size()); categoryContainer.removeAllViews(); for (String category : categories) { categoryContainer.addView(buildCatLabel(sanitise(category), categoryContainer)); diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java index 84147eef9..cb23263b0 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java @@ -27,8 +27,10 @@ import fr.free.nrw.commons.bookmarks.Bookmark; import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesContentProvider; import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao; import fr.free.nrw.commons.contributions.Contribution; +import fr.free.nrw.commons.contributions.MainActivity; import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient; +import fr.free.nrw.commons.theme.BaseActivity; import fr.free.nrw.commons.utils.DownloadUtils; import fr.free.nrw.commons.utils.ImageUtils; import fr.free.nrw.commons.utils.NetworkUtils; @@ -57,6 +59,8 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple MediaDetailAdapter adapter; private Bookmark bookmark; private MediaDetailProvider provider; + private boolean isFromFeaturedRootFragment; + private int position; public MediaDetailPagerFragment() { this(false, false); @@ -66,6 +70,15 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple public MediaDetailPagerFragment(Boolean editable, boolean isFeaturedImage) { this.editable = editable; this.isFeaturedImage = isFeaturedImage; + isFromFeaturedRootFragment = false; + } + + @SuppressLint("ValidFragment") + public MediaDetailPagerFragment(Boolean editable, boolean isFeaturedImage, int position) { + this.editable = editable; + this.isFeaturedImage = isFeaturedImage; + isFromFeaturedRootFragment = true; + this.position = position; } @Override @@ -77,6 +90,7 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple pager.addOnPageChangeListener(this); adapter = new MediaDetailAdapter(getChildFragmentManager()); + ((BaseActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true); if (savedInstanceState != null) { final int pageNumber = savedInstanceState.getInt("current-page"); @@ -97,6 +111,9 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple } else { pager.setAdapter(adapter); } + if (getActivity() instanceof MainActivity) { + ((MainActivity)getActivity()).hideTabs(); + } return view; } @@ -218,8 +235,13 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple if(provider == null) { return; } + final int position; + if (isFromFeaturedRootFragment) { + position = this.position; + } else { + position = pager.getCurrentItem(); + } - final int position = pager.getCurrentItem(); Media m = provider.getMediaAtPosition(position); if (m != null) { // Enable default set of actions, then re-enable different set of actions only if it is a failed contrib @@ -276,7 +298,7 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple private void updateBookmarkState(MenuItem item) { boolean isBookmarked = bookmarkDao.findBookmark(bookmark); - int icon = isBookmarked ? R.drawable.ic_round_star_filled_24px : R.drawable.ic_round_star_border_24px; + int icon = isBookmarked ? R.drawable.menu_ic_round_star_filled_24px : R.drawable.menu_ic_round_star_border_24px; item.setIcon(icon); } @@ -349,7 +371,11 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple } pager.postDelayed(() -> getActivity().invalidateOptionsMenu(), 5); } - return MediaDetailFragment.forMedia(i, editable, isFeaturedImage, isWikipediaButtonDisplayed); + if (isFromFeaturedRootFragment) { + return MediaDetailFragment.forMedia(position+i, editable, isFeaturedImage, isWikipediaButtonDisplayed); + } else { + return MediaDetailFragment.forMedia(i, editable, isFeaturedImage, isWikipediaButtonDisplayed); + } } @Override diff --git a/app/src/main/java/fr/free/nrw/commons/navtab/MoreBottomSheetFragment.java b/app/src/main/java/fr/free/nrw/commons/navtab/MoreBottomSheetFragment.java new file mode 100644 index 000000000..b749ac5e2 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/navtab/MoreBottomSheetFragment.java @@ -0,0 +1,153 @@ +package fr.free.nrw.commons.navtab; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import fr.free.nrw.commons.AboutActivity; +import fr.free.nrw.commons.BuildConfig; +import fr.free.nrw.commons.CommonsApplication; +import fr.free.nrw.commons.R; +import fr.free.nrw.commons.WelcomeActivity; +import fr.free.nrw.commons.auth.LoginActivity; +import fr.free.nrw.commons.di.ApplicationlessInjection; +import fr.free.nrw.commons.logging.CommonsLogSender; +import fr.free.nrw.commons.profile.ProfileActivity; +import fr.free.nrw.commons.review.ReviewActivity; +import fr.free.nrw.commons.settings.SettingsActivity; +import javax.inject.Inject; +import timber.log.Timber; + +public class MoreBottomSheetFragment extends BottomSheetDialogFragment { + + @Inject + CommonsLogSender commonsLogSender; + @BindView(R.id.more_profile) + TextView moreProfile; + + @Nullable + @Override + public View onCreateView(@NonNull final LayoutInflater inflater, + @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) { + super.onCreateView(inflater, container, savedInstanceState); + final View view = inflater.inflate(R.layout.fragment_more_bottom_sheet, container, false); + ButterKnife.bind(this, view); + setUserName(); + return view; + } + + @Override + public void onAttach(@NonNull final Context context) { + super.onAttach(context); + ApplicationlessInjection + .getInstance(getActivity().getApplicationContext()) + .getCommonsApplicationComponent() + .inject(this); + } + + /** + * Set the username in navigationHeader. + */ + private void setUserName() { + AccountManager accountManager = AccountManager.get(getActivity()); + Account[] allAccounts = accountManager.getAccountsByType(BuildConfig.ACCOUNT_TYPE); + if (allAccounts.length != 0) { + moreProfile.setText(allAccounts[0].name); + } + } + + @OnClick(R.id.more_logout) + public void onLogoutClicked() { + new AlertDialog.Builder(getActivity()) + .setMessage(R.string.logout_verification) + .setCancelable(false) + .setPositiveButton(R.string.yes, (dialog, which) -> { + BaseLogoutListener logoutListener = new BaseLogoutListener(); + CommonsApplication app = (CommonsApplication) getContext().getApplicationContext(); + app.clearApplicationData(getContext(), logoutListener); + }) + .setNegativeButton(R.string.no, (dialog, which) -> dialog.cancel()) + .show(); + } + + @OnClick(R.id.more_feedback) + public void onFeedbackClicked() { + final String technicalInfo = commonsLogSender.getExtraInfo(); + + final Intent feedbackIntent = new Intent(Intent.ACTION_SENDTO); + feedbackIntent.setType("message/rfc822"); + feedbackIntent.setData(Uri.parse("mailto:")); + feedbackIntent.putExtra(Intent.EXTRA_EMAIL, + new String[]{CommonsApplication.FEEDBACK_EMAIL}); + feedbackIntent.putExtra(Intent.EXTRA_SUBJECT, + CommonsApplication.FEEDBACK_EMAIL_SUBJECT); + feedbackIntent.putExtra(Intent.EXTRA_TEXT, String.format( + "\n\n%s\n%s", CommonsApplication.FEEDBACK_EMAIL_TEMPLATE_HEADER, technicalInfo)); + try { + startActivity(feedbackIntent); + } catch (final ActivityNotFoundException e) { + Toast.makeText(getActivity(), R.string.no_email_client, Toast.LENGTH_SHORT).show(); + } + } + + @OnClick(R.id.more_about) + public void onAboutClicked() { + final Intent intent = new Intent(getActivity(), AboutActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); + getActivity().startActivity(intent); + } + + @OnClick(R.id.more_tutorial) + public void onTutorialClicked() { + WelcomeActivity.startYourself(getActivity()); + } + + @OnClick(R.id.more_settings) + public void onSettingsClicked() { + final Intent intent = new Intent(getActivity(), SettingsActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); + getActivity().startActivity(intent); + } + + @OnClick(R.id.more_profile) + public void onProfileClicked() { + final Intent intent = new Intent(getActivity(), ProfileActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); + getActivity().startActivity(intent); + } + + @OnClick(R.id.more_peer_review) + public void onPeerReviewClicked() { + ReviewActivity.startYourself(getActivity(), getString(R.string.title_activity_review)); + } + + private class BaseLogoutListener implements CommonsApplication.LogoutListener { + + @Override + public void onLogoutComplete() { + Timber.d("Logout complete callback received."); + final Intent nearbyIntent = new Intent( + getContext(), LoginActivity.class); + nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(nearbyIntent); + getActivity().finish(); + } + } +} + diff --git a/app/src/main/java/fr/free/nrw/commons/navtab/MoreBottomSheetLoggedOutFragment.java b/app/src/main/java/fr/free/nrw/commons/navtab/MoreBottomSheetLoggedOutFragment.java new file mode 100644 index 000000000..a11906bdb --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/navtab/MoreBottomSheetLoggedOutFragment.java @@ -0,0 +1,118 @@ +package fr.free.nrw.commons.navtab; + +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import butterknife.ButterKnife; +import butterknife.OnClick; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import fr.free.nrw.commons.AboutActivity; +import fr.free.nrw.commons.CommonsApplication; +import fr.free.nrw.commons.R; +import fr.free.nrw.commons.WelcomeActivity; +import fr.free.nrw.commons.auth.LoginActivity; +import fr.free.nrw.commons.di.ApplicationlessInjection; +import fr.free.nrw.commons.kvstore.JsonKvStore; +import fr.free.nrw.commons.logging.CommonsLogSender; +import fr.free.nrw.commons.settings.SettingsActivity; +import javax.inject.Inject; +import javax.inject.Named; +import timber.log.Timber; + +public class MoreBottomSheetLoggedOutFragment extends BottomSheetDialogFragment { + + @Inject + CommonsLogSender commonsLogSender; + @Inject + @Named("default_preferences") + JsonKvStore applicationKvStore; + + @Nullable + @Override + public View onCreateView(@NonNull final LayoutInflater inflater, + @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) { + super.onCreateView(inflater, container, savedInstanceState); + final View view = inflater.inflate(R.layout.fragment_more_bottom_sheet_logged_out, container, false); + ButterKnife.bind(this, view); + return view; + } + + @Override + public void onAttach(@NonNull final Context context) { + super.onAttach(context); + ApplicationlessInjection + .getInstance(getActivity().getApplicationContext()) + .getCommonsApplicationComponent() + .inject(this); + } + + @OnClick(R.id.more_login) + public void onLogoutClicked() { + applicationKvStore.putBoolean("login_skipped", false); + Intent intent = new Intent(getContext(), LoginActivity.class); + getActivity().finish(); //Kill the activity from which you will go to next activity + startActivity(intent); + } + + @OnClick(R.id.more_feedback) + public void onFeedbackClicked() { + final String technicalInfo = commonsLogSender.getExtraInfo(); + + final Intent feedbackIntent = new Intent(Intent.ACTION_SENDTO); + feedbackIntent.setType("message/rfc822"); + feedbackIntent.setData(Uri.parse("mailto:")); + feedbackIntent.putExtra(Intent.EXTRA_EMAIL, + new String[]{CommonsApplication.FEEDBACK_EMAIL}); + feedbackIntent.putExtra(Intent.EXTRA_SUBJECT, + CommonsApplication.FEEDBACK_EMAIL_SUBJECT); + feedbackIntent.putExtra(Intent.EXTRA_TEXT, String.format( + "\n\n%s\n%s", CommonsApplication.FEEDBACK_EMAIL_TEMPLATE_HEADER, technicalInfo)); + try { + startActivity(feedbackIntent); + } catch (final ActivityNotFoundException e) { + Toast.makeText(getActivity(), R.string.no_email_client, Toast.LENGTH_SHORT).show(); + } + } + + @OnClick(R.id.more_about) + public void onAboutClicked() { + final Intent intent = new Intent(getActivity(), AboutActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); + getActivity().startActivity(intent); + } + + @OnClick(R.id.more_tutorial) + public void onTutorialClicked() { + WelcomeActivity.startYourself(getActivity()); + } + + @OnClick(R.id.more_settings) + public void onSettingsClicked() { + final Intent intent = new Intent(getActivity(), SettingsActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); + getActivity().startActivity(intent); + } + + private class BaseLogoutListener implements CommonsApplication.LogoutListener { + + @Override + public void onLogoutComplete() { + Timber.d("Logout complete callback received."); + final Intent nearbyIntent = new Intent( + getContext(), LoginActivity.class); + nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(nearbyIntent); + getActivity().finish(); + } + } +} + diff --git a/app/src/main/java/fr/free/nrw/commons/navtab/NavTab.java b/app/src/main/java/fr/free/nrw/commons/navtab/NavTab.java new file mode 100644 index 000000000..f9699931a --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/navtab/NavTab.java @@ -0,0 +1,97 @@ +package fr.free.nrw.commons.navtab; + +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.fragment.app.Fragment; + +import fr.free.nrw.commons.bookmarks.BookmarkFragment; +import fr.free.nrw.commons.contributions.ContributionsFragment; +import fr.free.nrw.commons.explore.ExploreFragment; +import fr.free.nrw.commons.explore.categories.search.SearchCategoryFragment; +import fr.free.nrw.commons.nearby.fragments.NearbyParentFragment; +import org.wikipedia.model.EnumCode; +import org.wikipedia.model.EnumCodeMap; + +import fr.free.nrw.commons.R; + + + +public enum NavTab implements EnumCode { + CONTRIBUTIONS(R.string.contributions_fragment, R.drawable.ic_baseline_person_24) { + @NonNull + @Override + public Fragment newInstance() { + return ContributionsFragment.newInstance(); + } + }, + NEARBY(R.string.nearby_fragment, R.drawable.ic_location_on_black_24dp){ + @NonNull + @Override + public Fragment newInstance() { + return NearbyParentFragment.newInstance(); + } + }, + EXPLORE(R.string.navigation_item_explore, R.drawable.ic_globe) { + @NonNull + @Override + public Fragment newInstance() { + return ExploreFragment.newInstance(); + } + }, + FAVORITES(R.string.favorites, R.drawable.ic_round_star_border_24px) { + @NonNull + @Override + public Fragment newInstance() { + return BookmarkFragment.newInstance(); + } + }, + MORE(R.string.more, R.drawable.ic_menu_black_24dp) { + @NonNull + @Override + public Fragment newInstance() { + return null; + } + }; + + private static final EnumCodeMap MAP = new EnumCodeMap<>(NavTab.class); + + @StringRes + private final int text; + @DrawableRes + private final int icon; + + @NonNull + public static NavTab of(int code) { + return MAP.get(code); + } + + public static int size() { + return MAP.size(); + } + + @StringRes + public int text() { + return text; + } + + @DrawableRes + public int icon() { + return icon; + } + + @NonNull + public abstract Fragment newInstance(); + + @Override + public int code() { + // This enumeration is not marshalled so tying declaration order to presentation order is + // convenient and consistent. + return ordinal(); + } + + NavTab(@StringRes int text, @DrawableRes int icon) { + this.text = text; + this.icon = icon; + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/navtab/NavTabFragmentPagerAdapter.java b/app/src/main/java/fr/free/nrw/commons/navtab/NavTabFragmentPagerAdapter.java new file mode 100644 index 000000000..c725561e9 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/navtab/NavTabFragmentPagerAdapter.java @@ -0,0 +1,35 @@ +package fr.free.nrw.commons.navtab; + +import android.view.ViewGroup; + +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +public class NavTabFragmentPagerAdapter extends FragmentPagerAdapter { + private Fragment currentFragment; + + public NavTabFragmentPagerAdapter(FragmentManager mgr) { + super(mgr); + } + + @Nullable + public Fragment getCurrentFragment() { + return currentFragment; + } + + @Override public Fragment getItem(int pos) { + return NavTab.of(pos).newInstance(); + } + + @Override public int getCount() { + return NavTab.size(); + } + + @Override + public void setPrimaryItem(ViewGroup container, int position, Object object) { + currentFragment = ((Fragment) object); + super.setPrimaryItem(container, position, object); + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/navtab/NavTabLayout.java b/app/src/main/java/fr/free/nrw/commons/navtab/NavTabLayout.java new file mode 100644 index 000000000..b7cf63145 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/navtab/NavTabLayout.java @@ -0,0 +1,41 @@ +package fr.free.nrw.commons.navtab; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.Menu; + +import com.google.android.material.bottomnavigation.BottomNavigationView; +import fr.free.nrw.commons.contributions.MainActivity; + + +public class NavTabLayout extends BottomNavigationView { + + public NavTabLayout(Context context) { + super(context); + setTabViews(); + } + + public NavTabLayout(Context context, AttributeSet attrs) { + super(context, attrs); + setTabViews(); + } + + public NavTabLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + setTabViews(); + } + + private void setTabViews() { + if (((MainActivity)getContext()).applicationKvStore.getBoolean("login_skipped") == true) { + for (int i = 0; i < NavTabLoggedOut.size(); i++) { + NavTabLoggedOut navTab = NavTabLoggedOut.of(i); + getMenu().add(Menu.NONE, i, i, navTab.text()).setIcon(navTab.icon()); + } + } else { + for (int i = 0; i < NavTab.size(); i++) { + NavTab navTab = NavTab.of(i); + getMenu().add(Menu.NONE, i, i, navTab.text()).setIcon(navTab.icon()); + } + } + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/navtab/NavTabLoggedOut.java b/app/src/main/java/fr/free/nrw/commons/navtab/NavTabLoggedOut.java new file mode 100644 index 000000000..2220bd09c --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/navtab/NavTabLoggedOut.java @@ -0,0 +1,70 @@ +package fr.free.nrw.commons.navtab; + +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.fragment.app.Fragment; +import fr.free.nrw.commons.R; +import fr.free.nrw.commons.explore.ExploreFragment; +import org.wikipedia.model.EnumCode; +import org.wikipedia.model.EnumCodeMap; + + +public enum NavTabLoggedOut implements EnumCode { + + EXPLORE(R.string.navigation_item_explore, R.drawable.ic_globe) { + @NonNull + @Override + public Fragment newInstance() { + return ExploreFragment.newInstance(); + } + }, + MORE(R.string.more, R.drawable.ic_menu_black_24dp) { + @NonNull + @Override + public Fragment newInstance() { + return null; + } + }; + + private static final EnumCodeMap MAP = new EnumCodeMap<>(NavTabLoggedOut.class); + + @StringRes + private final int text; + @DrawableRes + private final int icon; + + @NonNull + public static NavTabLoggedOut of(int code) { + return MAP.get(code); + } + + public static int size() { + return MAP.size(); + } + + @StringRes + public int text() { + return text; + } + + @DrawableRes + public int icon() { + return icon; + } + + @NonNull + public abstract Fragment newInstance(); + + @Override + public int code() { + // This enumeration is not marshalled so tying declaration order to presentation order is + // convenient and consistent. + return ordinal(); + } + + NavTabLoggedOut(@StringRes int text, @DrawableRes int icon) { + this.text = text; + this.icon = icon; + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyNotificationCardView.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyNotificationCardView.java index 12b0f72db..e255de7b4 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyNotificationCardView.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyNotificationCardView.java @@ -14,18 +14,15 @@ import androidx.annotation.Nullable; import fr.free.nrw.commons.R; import fr.free.nrw.commons.contributions.MainActivity; -import fr.free.nrw.commons.nearby.fragments.NearbyParentFragment; import fr.free.nrw.commons.utils.SwipableCardView; import fr.free.nrw.commons.utils.ViewUtil; import timber.log.Timber; -import static fr.free.nrw.commons.contributions.MainActivity.NEARBY_TAB_POSITION; - /** * Custom card view for nearby notification card view on main screen, above contributions list */ public class NearbyNotificationCardView extends SwipableCardView { - private Button permissionRequestButton; + public Button permissionRequestButton; private LinearLayout contentLayout; private TextView notificationTitle; private TextView notificationDistance; @@ -77,22 +74,16 @@ public class NearbyNotificationCardView extends SwipableCardView { super.onAttachedToWindow(); // If you don't setVisibility after getting layout params, then you will se an empty space in place of nearby NotificationCardView if (((MainActivity)getContext()).defaultKvStore.getBoolean("displayNearbyCardView", true) && this.cardViewVisibilityState == NearbyNotificationCardView.CardViewVisibilityState.READY) { - this.setVisibility(VISIBLE); + setVisibility(VISIBLE); } else { - this.setVisibility(GONE); + setVisibility(GONE); } } private void setActionListeners(Place place) { this.setOnClickListener(view -> { - MainActivity m = (MainActivity) getContext(); - - // Change to nearby tab - m.viewPager.setCurrentItem(NEARBY_TAB_POSITION); - - // Center the map to the place - ((NearbyParentFragment) m.contributionsActivityPagerAdapter.getItem(NEARBY_TAB_POSITION)).centerMapToPlace(place); + ((MainActivity) getContext()).centerMapToPlace(place); }); } diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/fragments/CommonPlaceClickActions.kt b/app/src/main/java/fr/free/nrw/commons/nearby/fragments/CommonPlaceClickActions.kt index 15186de56..f815e5ab5 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/fragments/CommonPlaceClickActions.kt +++ b/app/src/main/java/fr/free/nrw/commons/nearby/fragments/CommonPlaceClickActions.kt @@ -13,7 +13,7 @@ import fr.free.nrw.commons.auth.LoginActivity import fr.free.nrw.commons.contributions.ContributionController import fr.free.nrw.commons.kvstore.JsonKvStore import fr.free.nrw.commons.nearby.Place -import fr.free.nrw.commons.theme.NavigationBaseActivity +import fr.free.nrw.commons.utils.ActivityUtils import fr.free.nrw.commons.wikidata.WikidataConstants import timber.log.Timber import javax.inject.Inject @@ -85,7 +85,7 @@ class CommonPlaceClickActions @Inject constructor( AlertDialog.Builder(activity) .setMessage(R.string.login_alert_message) .setPositiveButton(R.string.login) { dialog, which -> - NavigationBaseActivity.startActivityWithFlags( + ActivityUtils.startActivityWithFlags( activity, LoginActivity::class.java, Intent.FLAG_ACTIVITY_CLEAR_TOP, diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/fragments/NearbyParentFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/fragments/NearbyParentFragment.java index 1f809dc5b..7e15533f7 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/fragments/NearbyParentFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/fragments/NearbyParentFragment.java @@ -1,6 +1,5 @@ package fr.free.nrw.commons.nearby.fragments; -import static fr.free.nrw.commons.contributions.MainActivity.CONTRIBUTIONS_TAB_POSITION; import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED; import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.LOCATION_SLIGHTLY_CHANGED; import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.MAP_UPDATED; @@ -24,6 +23,10 @@ import android.text.method.LinkMovementMethod; import android.util.Log; import android.view.Gravity; 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.ViewGroup; import android.view.animation.Animation; @@ -77,11 +80,13 @@ import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.auth.LoginActivity; import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao; import fr.free.nrw.commons.contributions.ContributionController; +import fr.free.nrw.commons.contributions.ContributionsFragment; import fr.free.nrw.commons.contributions.MainActivity; import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; import fr.free.nrw.commons.kvstore.JsonKvStore; import fr.free.nrw.commons.location.LocationServiceManager; import fr.free.nrw.commons.location.LocationUpdateListener; +import fr.free.nrw.commons.navtab.NavTab; import fr.free.nrw.commons.nearby.CheckBoxTriStates; import fr.free.nrw.commons.nearby.Label; import fr.free.nrw.commons.nearby.MarkerPlaceGroup; @@ -93,6 +98,7 @@ import fr.free.nrw.commons.nearby.NearbyMarker; import fr.free.nrw.commons.nearby.Place; import fr.free.nrw.commons.nearby.contract.NearbyParentFragmentContract; import fr.free.nrw.commons.nearby.presenter.NearbyParentFragmentPresenter; +import fr.free.nrw.commons.notification.NotificationActivity; import fr.free.nrw.commons.utils.DialogUtil; import fr.free.nrw.commons.utils.ExecutorUtils; import fr.free.nrw.commons.utils.LayoutUtils; @@ -208,6 +214,13 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment private LatLngBounds latLngBounds; private PlaceAdapter adapter; + @NonNull + public static NearbyParentFragment newInstance() { + NearbyParentFragment fragment = new NearbyParentFragment(); + fragment.setRetainInstance(true); + return fragment; + } + @Override public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { @@ -215,11 +228,25 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment ButterKnife.bind(this, view); initNetworkBroadCastReceiver(); presenter=new NearbyParentFragmentPresenter(bookmarkLocationDao); + setHasOptionsMenu(true); // Inflate the layout for this fragment return view; } + @Override + public void onCreateOptionsMenu(@NonNull final Menu menu, @NonNull final MenuInflater inflater) { + inflater.inflate(R.menu.nearby_fragment_menu, menu); + MenuItem listMenu = menu.findItem(R.id.list_sheet); + listMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + listOptionMenuItemClicked(); + return false; + } + }); + } + @Override public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); @@ -306,7 +333,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment } private void performMapReadyActions() { - if (isVisible() && isVisibleToUser && isMapBoxReady) { + if (isVisible() && isMapBoxReady) { checkPermissionsAndPerformAction(() -> { lastKnownLocation = locationManager.getLastLocation(); fr.free.nrw.commons.location.LatLng target=lastFocusLocation; @@ -615,6 +642,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment * Centers the map in nearby fragment to a given place * @param place is new center of the map */ + @Override public void centerMapToPlace(final Place place) { Timber.d("Map is centered to place"); final double cameraShift; @@ -852,6 +880,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment @Override public void setTabItemContributions() { ((MainActivity)getActivity()).viewPager.setCurrentItem(0); + // TODO } @Override @@ -860,7 +889,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment PermissionUtils.checkPermissionsAndPerformAction(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION, runnable, - () -> ((MainActivity) getActivity()).viewPager.setCurrentItem(CONTRIBUTIONS_TAB_POSITION), + () -> ((MainActivity) getActivity()).setSelectedItemId(NavTab.CONTRIBUTIONS.code()), R.string.location_permission_title, R.string.location_permission_rationale_nearby); } diff --git a/app/src/main/java/fr/free/nrw/commons/notification/NotificationActivity.java b/app/src/main/java/fr/free/nrw/commons/notification/NotificationActivity.java index e93bd29e6..975629047 100644 --- a/app/src/main/java/fr/free/nrw/commons/notification/NotificationActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/notification/NotificationActivity.java @@ -13,6 +13,7 @@ import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; +import androidx.appcompat.widget.Toolbar; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; @@ -22,7 +23,7 @@ import butterknife.ButterKnife; import com.google.android.material.snackbar.Snackbar; import fr.free.nrw.commons.R; import fr.free.nrw.commons.Utils; -import fr.free.nrw.commons.theme.NavigationBaseActivity; +import fr.free.nrw.commons.theme.BaseActivity; import fr.free.nrw.commons.utils.NetworkUtils; import fr.free.nrw.commons.utils.ViewUtil; import io.reactivex.Observable; @@ -41,7 +42,7 @@ import timber.log.Timber; * Created by root on 18.12.2017. */ -public class NotificationActivity extends NavigationBaseActivity { +public class NotificationActivity extends BaseActivity { @BindView(R.id.listView) RecyclerView recyclerView; @BindView(R.id.progressBar) @@ -52,6 +53,9 @@ public class NotificationActivity extends NavigationBaseActivity { ConstraintLayout no_notification; @BindView(R.id.no_notification_text) TextView noNotificationText; + @BindView(R.id.toolbar) + Toolbar toolbar; + @Inject NotificationController controller; @@ -70,8 +74,15 @@ public class NotificationActivity extends NavigationBaseActivity { mNotificationWorkerFragment = (NotificationWorkerFragment) getFragmentManager() .findFragmentByTag(TAG_NOTIFICATION_WORKER_FRAGMENT); initListView(); - initDrawer(); setPageTitle(); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + @Override + public boolean onSupportNavigateUp() { + onBackPressed(); + return true; } @SuppressLint("CheckResult") diff --git a/app/src/main/java/fr/free/nrw/commons/profile/ProfileActivity.java b/app/src/main/java/fr/free/nrw/commons/profile/ProfileActivity.java index 70b1dccd6..5f509ebb0 100644 --- a/app/src/main/java/fr/free/nrw/commons/profile/ProfileActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/profile/ProfileActivity.java @@ -12,7 +12,7 @@ import com.google.android.material.tabs.TabLayout; import fr.free.nrw.commons.R; import fr.free.nrw.commons.profile.achievements.AchievementsFragment; import fr.free.nrw.commons.profile.leaderboard.LeaderboardFragment; -import fr.free.nrw.commons.theme.NavigationBaseActivity; +import fr.free.nrw.commons.theme.BaseActivity; import java.util.ArrayList; import java.util.List; @@ -20,7 +20,7 @@ import java.util.List; * This activity will set two tabs, achievements and * each tab will have their own fragments */ -public class ProfileActivity extends NavigationBaseActivity { +public class ProfileActivity extends BaseActivity { private FragmentManager supportFragmentManager; @@ -39,7 +39,6 @@ public class ProfileActivity extends NavigationBaseActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_profile); ButterKnife.bind(this); - initDrawer(); setTitle(R.string.Profile); supportFragmentManager = getSupportFragmentManager(); diff --git a/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java b/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java index c9e884bc0..b28714385 100644 --- a/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java @@ -22,6 +22,17 @@ import androidx.appcompat.view.ContextThemeWrapper; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.content.FileProvider; import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; + +import com.dinuscxj.progressbar.CircleProgressBar; +import org.apache.commons.lang3.StringUtils; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Objects; + +import javax.inject.Inject; + import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -147,7 +158,6 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment { params.height = (int) (height * BADGE_IMAGE_HEIGHT_RATIO); params.width = (int) (width * BADGE_IMAGE_WIDTH_RATIO); imageView.requestLayout(); - progressBar.setVisibility(View.VISIBLE); setHasOptionsMenu(true); diff --git a/app/src/main/java/fr/free/nrw/commons/review/ReviewActivity.java b/app/src/main/java/fr/free/nrw/commons/review/ReviewActivity.java index 54057b8b9..a9db9b3d3 100644 --- a/app/src/main/java/fr/free/nrw/commons/review/ReviewActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/review/ReviewActivity.java @@ -19,12 +19,11 @@ import androidx.drawerlayout.widget.DrawerLayout; import butterknife.BindView; import butterknife.ButterKnife; import com.facebook.drawee.view.SimpleDraweeView; -import com.google.android.material.navigation.NavigationView; import com.viewpagerindicator.CirclePageIndicator; import fr.free.nrw.commons.Media; import fr.free.nrw.commons.R; import fr.free.nrw.commons.delete.DeleteHelper; -import fr.free.nrw.commons.theme.NavigationBaseActivity; +import fr.free.nrw.commons.theme.BaseActivity; import fr.free.nrw.commons.utils.DialogUtil; import fr.free.nrw.commons.utils.ViewUtil; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -32,14 +31,12 @@ import io.reactivex.disposables.CompositeDisposable; import io.reactivex.schedulers.Schedulers; import javax.inject.Inject; -public class ReviewActivity extends NavigationBaseActivity { +public class ReviewActivity extends BaseActivity { @BindView(R.id.pager_indicator_review) public CirclePageIndicator pagerIndicator; @BindView(R.id.toolbar) Toolbar toolbar; - @BindView(R.id.navigation_view) - NavigationView navigationView; @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; @BindView(R.id.view_pager_review) @@ -95,8 +92,7 @@ public class ReviewActivity extends NavigationBaseActivity { setContentView(R.layout.activity_review); ButterKnife.bind(this); setSupportActionBar(toolbar); - initDrawer(); - + getSupportActionBar().setDisplayHomeAsUpEnabled(true); reviewController = new ReviewController(deleteHelper, this); @@ -132,6 +128,12 @@ public class ReviewActivity extends NavigationBaseActivity { }); } + @Override + public boolean onSupportNavigateUp() { + onBackPressed(); + return true; + } + @SuppressLint("CheckResult") public boolean runRandomizer() { progressBar.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/fr/free/nrw/commons/settings/SettingsActivity.java b/app/src/main/java/fr/free/nrw/commons/settings/SettingsActivity.java index 7322e8c88..f1902a211 100644 --- a/app/src/main/java/fr/free/nrw/commons/settings/SettingsActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/settings/SettingsActivity.java @@ -5,16 +5,19 @@ import android.view.MenuItem; import androidx.appcompat.app.AppCompatDelegate; +import androidx.appcompat.widget.Toolbar; +import butterknife.BindView; import butterknife.ButterKnife; import fr.free.nrw.commons.R; -import fr.free.nrw.commons.theme.NavigationBaseActivity; +import fr.free.nrw.commons.theme.BaseActivity; /** * allows the user to change the settings */ -public class SettingsActivity extends NavigationBaseActivity { +public class SettingsActivity extends BaseActivity { private AppCompatDelegate settingsDelegate; - + @BindView(R.id.toolbar) + Toolbar toolbar; /** * to be called when the activity starts * @param savedInstanceState the previously saved state @@ -25,7 +28,8 @@ public class SettingsActivity extends NavigationBaseActivity { setContentView(R.layout.activity_settings); ButterKnife.bind(this); - initDrawer(); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); } // Get an action bar @@ -40,11 +44,14 @@ public class SettingsActivity extends NavigationBaseActivity { settingsDelegate = AppCompatDelegate.create(this, null); } settingsDelegate.onPostCreate(savedInstanceState); - - //Get an up button - //settingsDelegate.getSupportActionBar().setDisplayHomeAsUpEnabled(true); } - + + @Override + public boolean onSupportNavigateUp() { + onBackPressed(); + return true; + } + /** * Handle action-bar clicks * @param item the selected item diff --git a/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java b/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java deleted file mode 100644 index 0dea4bf55..000000000 --- a/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java +++ /dev/null @@ -1,355 +0,0 @@ -package fr.free.nrw.commons.theme; - -import android.accounts.Account; -import android.accounts.AccountManager; -import android.app.ActivityManager; -import android.app.ProgressDialog; -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Build; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.ActionBarDrawerToggle; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.widget.Toolbar; -import androidx.core.view.GravityCompat; -import androidx.drawerlayout.widget.DrawerLayout; - -import com.google.android.material.navigation.NavigationView; - -import fr.free.nrw.commons.profile.ProfileActivity; -import org.wikipedia.dataclient.Service; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import fr.free.nrw.commons.AboutActivity; -import fr.free.nrw.commons.BuildConfig; -import fr.free.nrw.commons.CommonsApplication; -import fr.free.nrw.commons.R; -import fr.free.nrw.commons.WelcomeActivity; -import fr.free.nrw.commons.auth.LoginActivity; -import fr.free.nrw.commons.auth.LogoutClient; -import fr.free.nrw.commons.bookmarks.BookmarksActivity; -import fr.free.nrw.commons.contributions.MainActivity; -import fr.free.nrw.commons.explore.ExploreActivity; -import fr.free.nrw.commons.kvstore.JsonKvStore; -import fr.free.nrw.commons.logging.CommonsLogSender; -import fr.free.nrw.commons.review.ReviewActivity; -import fr.free.nrw.commons.settings.SettingsActivity; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.schedulers.Schedulers; -import timber.log.Timber; - -public abstract class NavigationBaseActivity extends BaseActivity - implements NavigationView.OnNavigationItemSelectedListener { - - private boolean isRestoredToTop; - - @BindView(R.id.toolbar) - Toolbar toolbar; - @BindView(R.id.navigation_view) - NavigationView navigationView; - @BindView(R.id.drawer_layout) - DrawerLayout drawerLayout; - @Inject - @Named("default_preferences") - JsonKvStore applicationKvStore; - @Inject CommonsLogSender commonsLogSender; - - - private ActionBarDrawerToggle toggle; - - @Inject - LogoutClient logoutClient; - - - private CompositeDisposable disposable = new CompositeDisposable(); - private Service service; - - private ProgressDialog progressDialog; - - public void initDrawer() { - navigationView.setNavigationItemSelectedListener(this); - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, - R.string.navigation_drawer_open, R.string.navigation_drawer_close); - drawerLayout.addDrawerListener(toggle); - toggle.setDrawerIndicatorEnabled(true); - toggle.syncState(); - Menu nav_Menu = navigationView.getMenu(); - View headerLayout = navigationView.getHeaderView(0); - ImageView userIcon = headerLayout.findViewById(R.id.user_icon); - if (applicationKvStore.getBoolean("login_skipped", false)) { - userIcon.setVisibility(View.GONE); - nav_Menu.findItem(R.id.action_login).setVisible(true); - nav_Menu.findItem(R.id.action_home).setVisible(false); - nav_Menu.findItem(R.id.action_settings).setVisible(true); - nav_Menu.findItem(R.id.action_logout).setVisible(false); - nav_Menu.findItem(R.id.action_bookmarks).setVisible(true); - nav_Menu.findItem(R.id.action_review).setVisible(false); - } else { - setUserName(); - userIcon.setVisibility(View.VISIBLE); - nav_Menu.findItem(R.id.action_login).setVisible(false); - nav_Menu.findItem(R.id.action_home).setVisible(true); - nav_Menu.findItem(R.id.action_settings).setVisible(true); - nav_Menu.findItem(R.id.action_logout).setVisible(true); - nav_Menu.findItem(R.id.action_bookmarks).setVisible(true); - nav_Menu.findItem(R.id.action_review).setVisible(true); - } - } - - public void changeDrawerIconToBackButton() { - toggle.setDrawerIndicatorEnabled(false); - toggle.setHomeAsUpIndicator(R.drawable.ic_arrow_back_white); - toggle.setToolbarNavigationClickListener(view -> onBackPressed()); - } - - public void changeDrawerIconToDefault() { - if (toggle != null) { - toggle.setDrawerIndicatorEnabled(true); - } - } - - /** - * Set the username in navigationHeader. - */ - private void setUserName() { - - View navHeaderView = navigationView.getHeaderView(0); - TextView username = navHeaderView.findViewById(R.id.username); - AccountManager accountManager = AccountManager.get(this); - Account[] allAccounts = accountManager.getAccountsByType(BuildConfig.ACCOUNT_TYPE); - if (allAccounts.length != 0) { - username.setText(allAccounts[0].name); - } - LinearLayout userIcon = navHeaderView.findViewById(R.id.user_details); - userIcon.setOnClickListener(v -> { - drawerLayout.closeDrawer(navigationView); - ProfileActivity.startYourself(NavigationBaseActivity.this); - }); - } - - public void initBackButton() { - int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount(); - toggle.setDrawerIndicatorEnabled(backStackEntryCount == 0); - toggle.setToolbarNavigationClickListener(v -> onBackPressed()); - } - - /** - * This method changes the toolbar icon to back regardless of any conditions that - * there is any fragment in the backStack or not - */ - public void forceInitBackButton() { - toggle.setDrawerIndicatorEnabled(false); - toggle.setToolbarNavigationClickListener(v -> onBackPressed()); - } - - public void initBack() { - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().setDisplayShowHomeEnabled(true); - } - - @Override - public boolean onNavigationItemSelected(@NonNull final MenuItem item) { - final int itemId = item.getItemId(); - switch (itemId) { - case R.id.action_login: - drawerLayout.closeDrawer(navigationView); - startActivityWithFlags( - this, LoginActivity.class, Intent.FLAG_ACTIVITY_CLEAR_TOP, - Intent.FLAG_ACTIVITY_SINGLE_TOP); - applicationKvStore.putBoolean("login_skipped", false); - finish(); - return true; - case R.id.action_home: - drawerLayout.closeDrawer(navigationView); - startActivityWithFlags( - this, MainActivity.class, Intent.FLAG_ACTIVITY_CLEAR_TOP, - Intent.FLAG_ACTIVITY_SINGLE_TOP); - return true; - case R.id.action_about: - drawerLayout.closeDrawer(navigationView); - startActivityWithFlags(this, AboutActivity.class, Intent.FLAG_ACTIVITY_REORDER_TO_FRONT, - Intent.FLAG_ACTIVITY_SINGLE_TOP); - return true; - case R.id.action_settings: - drawerLayout.closeDrawer(navigationView); - startActivityWithFlags(this, SettingsActivity.class, Intent.FLAG_ACTIVITY_REORDER_TO_FRONT, - Intent.FLAG_ACTIVITY_SINGLE_TOP); - return true; - case R.id.action_introduction: - drawerLayout.closeDrawer(navigationView); - WelcomeActivity.startYourself(this); - return true; - case R.id.action_feedback: - drawerLayout.closeDrawer(navigationView); - - String technicalInfo = commonsLogSender.getExtraInfo(); - - Intent feedbackIntent = new Intent(Intent.ACTION_SENDTO); - feedbackIntent.setType("message/rfc822"); - feedbackIntent.setData(Uri.parse("mailto:")); - feedbackIntent.putExtra(Intent.EXTRA_EMAIL, - new String[]{CommonsApplication.FEEDBACK_EMAIL}); - feedbackIntent.putExtra(Intent.EXTRA_SUBJECT, - CommonsApplication.FEEDBACK_EMAIL_SUBJECT); - feedbackIntent.putExtra(Intent.EXTRA_TEXT, String.format( - "\n\n%s\n%s", CommonsApplication.FEEDBACK_EMAIL_TEMPLATE_HEADER, technicalInfo)); - try { - startActivity(feedbackIntent); - } catch (ActivityNotFoundException e) { - Toast.makeText(this, R.string.no_email_client, Toast.LENGTH_SHORT).show(); - } - return true; - case R.id.action_logout: - new AlertDialog.Builder(this) - .setMessage(R.string.logout_verification) - .setCancelable(false) - .setPositiveButton(R.string.yes, (dialog, which) -> { - handleLogout(); - }) - .setNegativeButton(R.string.no, (dialog, which) -> dialog.cancel()) - .show(); - return true; - case R.id.action_explore: - drawerLayout.closeDrawer(navigationView); - ExploreActivity.startYourself(this); - return true; - case R.id.action_bookmarks: - drawerLayout.closeDrawer(navigationView); - BookmarksActivity.startYourself(this); - return true; - - case R.id.action_review: - drawerLayout.closeDrawer(navigationView); - ReviewActivity.startYourself(this, getString(R.string.title_activity_review)); - return true; - default: - Timber.e("Unknown option [%s] selected from the navigation menu", itemId); - return false; - } - } - - /** - * Ask the logout client to post the logout api - */ - private void handleLogout() { - if (null == progressDialog) { - progressDialog = new ProgressDialog(this); - progressDialog.setMessage(getString(R.string.please_wait)); - } - - progressDialog.show(); - - disposable.add(logoutClient.postLogout() - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(mwQueryResponse -> { - BaseLogoutListener logoutListener = new BaseLogoutListener(); - CommonsApplication app = (CommonsApplication) getApplication(); - app.clearApplicationData(this, logoutListener); - progressDialog.cancel(); - }, - t -> { - progressDialog.cancel(); - Toast.makeText(NavigationBaseActivity.this, - t.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); - Timber.e(t, "Something went wrong with post logout api: %s", t - .getLocalizedMessage()); - } - )); - } - - private class BaseLogoutListener implements CommonsApplication.LogoutListener { - @Override - public void onLogoutComplete() { - Timber.d("Logout complete callback received."); - Intent nearbyIntent = new Intent( - NavigationBaseActivity.this, LoginActivity.class); - nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(nearbyIntent); - finish(); - } - } - - public static void startActivityWithFlags(Context context, Class cls, int... flags) { - Intent intent = new Intent(context, cls); - for (int flag: flags) { - intent.addFlags(flag); - } - context.startActivity(intent); - } - - /* This is a workaround for a known Android bug which is present in some API levels. - https://issuetracker.google.com/issues/36986021 - */ - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - if ((intent.getFlags() | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) > 0) { - isRestoredToTop = true; - } - } - - @Override - public void finish() { - super.finish(); - if (Build.VERSION.SDK_INT == 19 || Build.VERSION.SDK_INT == 24 || Build.VERSION.SDK_INT == 25 - && !isTaskRoot() && isRestoredToTop) { - // Issue with FLAG_ACTIVITY_REORDER_TO_FRONT, - // Reordered activity back press will go to home unexpectly, - // Workaround: move reordered activity current task to front when it's finished. - ActivityManager tasksManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); - tasksManager.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_NO_USER_ACTION); - } - } - - - /** - * Handles visibility of navigation base toolbar - * @param show : Used to handle visibility of toolbar - */ - public void setNavigationBaseToolbarVisibility(boolean show){ - if (show){ - toolbar.setVisibility(View.VISIBLE); - }else { - toolbar.setVisibility(View.GONE); - } - } - - @Override - public void onBackPressed() { - DrawerLayout drawer = findViewById(R.id.drawer_layout); - if (drawer.isDrawerOpen(GravityCompat.START)) { - drawer.closeDrawer(GravityCompat.START); - } else { - super.onBackPressed(); - } - } - - @Override - protected void onStop() { - super.onStop(); - disposable.clear(); - if (progressDialog != null && progressDialog.isShowing()) { - progressDialog.cancel(); - } - } -} diff --git a/app/src/main/java/fr/free/nrw/commons/utils/ActivityUtils.java b/app/src/main/java/fr/free/nrw/commons/utils/ActivityUtils.java new file mode 100644 index 000000000..0b33ed566 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/utils/ActivityUtils.java @@ -0,0 +1,14 @@ +package fr.free.nrw.commons.utils; + +import android.content.Context; +import android.content.Intent; + +public class ActivityUtils { + public static void startActivityWithFlags(Context context, Class cls, int... flags) { + Intent intent = new Intent(context, cls); + for (int flag: flags) { + intent.addFlags(flag); + } + context.startActivity(intent); + } +} diff --git a/app/src/main/res/color/color_state_nav_tab_dark.xml b/app/src/main/res/color/color_state_nav_tab_dark.xml new file mode 100644 index 000000000..740c70a43 --- /dev/null +++ b/app/src/main/res/color/color_state_nav_tab_dark.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/color/color_state_nav_tab_light.xml b/app/src/main/res/color/color_state_nav_tab_light.xml new file mode 100644 index 000000000..6053ee8ca --- /dev/null +++ b/app/src/main/res/color/color_state_nav_tab_light.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-anydpi-v24/pause_icon.xml b/app/src/main/res/drawable-anydpi-v24/pause_icon.xml index 0e71a1771..e7e496b7d 100644 --- a/app/src/main/res/drawable-anydpi-v24/pause_icon.xml +++ b/app/src/main/res/drawable-anydpi-v24/pause_icon.xml @@ -3,7 +3,7 @@ android:height="24dp" android:viewportWidth="24" android:viewportHeight="24" - android:tint="#FFFFFF"> + android:tint="?attr/mediaDetailsHeadingText"> + android:tint="?attr/mediaDetailsHeadingText"> + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_baseline_cloud_off_24.xml b/app/src/main/res/drawable/ic_baseline_cloud_off_24.xml new file mode 100644 index 000000000..97b47f2a6 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_cloud_off_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_cloud_queue_24.xml b/app/src/main/res/drawable/ic_baseline_cloud_queue_24.xml new file mode 100644 index 000000000..5bb1e72f4 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_cloud_queue_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_person_14.xml b/app/src/main/res/drawable/ic_baseline_person_14.xml new file mode 100644 index 000000000..561f7acc9 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_person_14.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_person_24.xml b/app/src/main/res/drawable/ic_baseline_person_24.xml new file mode 100644 index 000000000..cd2463e55 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_person_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_check_black_24dp.xml b/app/src/main/res/drawable/ic_check_black_24dp.xml index 7f52972a1..adbb4db8e 100644 --- a/app/src/main/res/drawable/ic_check_black_24dp.xml +++ b/app/src/main/res/drawable/ic_check_black_24dp.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_exit_to_app_black_24dp.xml b/app/src/main/res/drawable/ic_exit_to_app_black_24dp.xml index 21ec591fc..fa8e48fc3 100644 --- a/app/src/main/res/drawable/ic_exit_to_app_black_24dp.xml +++ b/app/src/main/res/drawable/ic_exit_to_app_black_24dp.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_feedback_black_24dp.xml b/app/src/main/res/drawable/ic_feedback_black_24dp.xml index f99f442c5..16188821b 100644 --- a/app/src/main/res/drawable/ic_feedback_black_24dp.xml +++ b/app/src/main/res/drawable/ic_feedback_black_24dp.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_globe.xml b/app/src/main/res/drawable/ic_globe.xml new file mode 100644 index 000000000..7c1fa5b50 --- /dev/null +++ b/app/src/main/res/drawable/ic_globe.xml @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_help_black_24dp.xml b/app/src/main/res/drawable/ic_help_black_24dp.xml index 80de04a25..15dce67e8 100644 --- a/app/src/main/res/drawable/ic_help_black_24dp.xml +++ b/app/src/main/res/drawable/ic_help_black_24dp.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_info_outline_24dp.xml b/app/src/main/res/drawable/ic_info_outline_24dp.xml index 075dc65f2..f30d01e78 100644 --- a/app/src/main/res/drawable/ic_info_outline_24dp.xml +++ b/app/src/main/res/drawable/ic_info_outline_24dp.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_list_white_24dp.xml b/app/src/main/res/drawable/ic_list_white_24dp.xml index 0bba4193d..7a13367d3 100644 --- a/app/src/main/res/drawable/ic_list_white_24dp.xml +++ b/app/src/main/res/drawable/ic_list_white_24dp.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_location_on_black_24dp.xml b/app/src/main/res/drawable/ic_location_on_black_24dp.xml new file mode 100644 index 000000000..3b4d73da1 --- /dev/null +++ b/app/src/main/res/drawable/ic_location_on_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_menu_black_24dp.xml b/app/src/main/res/drawable/ic_menu_black_24dp.xml new file mode 100644 index 000000000..4a7ae70b0 --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_black_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_notifications_blue_24dp.xml b/app/src/main/res/drawable/ic_notifications_blue_24dp.xml new file mode 100644 index 000000000..46a0b0a80 --- /dev/null +++ b/app/src/main/res/drawable/ic_notifications_blue_24dp.xml @@ -0,0 +1,6 @@ + + + + diff --git a/app/src/main/res/drawable/ic_person_black_24dp.xml b/app/src/main/res/drawable/ic_person_black_24dp.xml index e26f4410a..b823eea15 100644 --- a/app/src/main/res/drawable/ic_person_black_24dp.xml +++ b/app/src/main/res/drawable/ic_person_black_24dp.xml @@ -5,5 +5,5 @@ android:height="30.928dp"> + android:fillColor="?attr/more_bottom_sheet_drawable_color" /> \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_settings_black_24dp.xml b/app/src/main/res/drawable/ic_settings_black_24dp.xml index d19715e50..78d4b67ed 100644 --- a/app/src/main/res/drawable/ic_settings_black_24dp.xml +++ b/app/src/main/res/drawable/ic_settings_black_24dp.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/menu_ic_download_24dp.xml b/app/src/main/res/drawable/menu_ic_download_24dp.xml new file mode 100644 index 000000000..1794c732f --- /dev/null +++ b/app/src/main/res/drawable/menu_ic_download_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/menu_ic_round_star_border_24px.xml b/app/src/main/res/drawable/menu_ic_round_star_border_24px.xml new file mode 100644 index 000000000..b298ed866 --- /dev/null +++ b/app/src/main/res/drawable/menu_ic_round_star_border_24px.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/menu_ic_round_star_filled_24px.xml b/app/src/main/res/drawable/menu_ic_round_star_filled_24px.xml new file mode 100644 index 000000000..30c1fe9eb --- /dev/null +++ b/app/src/main/res/drawable/menu_ic_round_star_filled_24px.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/menu_ic_share_24dp.xml b/app/src/main/res/drawable/menu_ic_share_24dp.xml new file mode 100644 index 000000000..c7cf3d38b --- /dev/null +++ b/app/src/main/res/drawable/menu_ic_share_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout-v21/drawer_view.xml b/app/src/main/res/layout-v21/drawer_view.xml deleted file mode 100644 index 952408da5..000000000 --- a/app/src/main/res/layout-v21/drawer_view.xml +++ /dev/null @@ -1,10 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 389aec575..55d29229d 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -163,7 +163,4 @@ - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_bookmarks.xml b/app/src/main/res/layout/activity_bookmarks.xml deleted file mode 100644 index a52af68e1..000000000 --- a/app/src/main/res/layout/activity_bookmarks.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_category_details.xml b/app/src/main/res/layout/activity_category_details.xml index 8f20ff463..29919037e 100644 --- a/app/src/main/res/layout/activity_category_details.xml +++ b/app/src/main/res/layout/activity_category_details.xml @@ -44,6 +44,4 @@ android:layout_below="@id/toolbar_layout" /> - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_category_images.xml b/app/src/main/res/layout/activity_category_images.xml index b602dac17..e7a074547 100644 --- a/app/src/main/res/layout/activity_category_images.xml +++ b/app/src/main/res/layout/activity_category_images.xml @@ -19,7 +19,4 @@ - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_contributions.xml b/app/src/main/res/layout/activity_contributions.xml deleted file mode 100644 index f53c434e2..000000000 --- a/app/src/main/res/layout/activity_contributions.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_explore.xml b/app/src/main/res/layout/activity_explore.xml deleted file mode 100644 index 27908b8da..000000000 --- a/app/src/main/res/layout/activity_explore.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_notification.xml b/app/src/main/res/layout/activity_notification.xml index ccde97f83..fe0b12a74 100644 --- a/app/src/main/res/layout/activity_notification.xml +++ b/app/src/main/res/layout/activity_notification.xml @@ -63,6 +63,4 @@ - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index 3ce7386c4..b1f4e7d31 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -36,6 +36,4 @@ android:layout_below="@id/toolbar_layout" /> - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_review.xml b/app/src/main/res/layout/activity_review.xml index b2e10c49f..ffd340d23 100644 --- a/app/src/main/res/layout/activity_review.xml +++ b/app/src/main/res/layout/activity_review.xml @@ -6,8 +6,6 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_search.xml b/app/src/main/res/layout/activity_search.xml index b43b9ae44..59bdf89e6 100644 --- a/app/src/main/res/layout/activity_search.xml +++ b/app/src/main/res/layout/activity_search.xml @@ -85,6 +85,4 @@ /> - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index d8fb53ef7..57ce935d3 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -12,7 +12,6 @@ android:layout_height="?attr/actionBarSize"> - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_wikidata_item_details.xml b/app/src/main/res/layout/activity_wikidata_item_details.xml index 8f20ff463..29919037e 100644 --- a/app/src/main/res/layout/activity_wikidata_item_details.xml +++ b/app/src/main/res/layout/activity_wikidata_item_details.xml @@ -44,6 +44,4 @@ android:layout_below="@id/toolbar_layout" /> - - \ No newline at end of file diff --git a/app/src/main/res/layout/drawer_header.xml b/app/src/main/res/layout/drawer_header.xml deleted file mode 100644 index 7ec93dc60..000000000 --- a/app/src/main/res/layout/drawer_header.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/drawer_view.xml b/app/src/main/res/layout/drawer_view.xml deleted file mode 100644 index 952408da5..000000000 --- a/app/src/main/res/layout/drawer_view.xml +++ /dev/null @@ -1,10 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_achievements.xml b/app/src/main/res/layout/fragment_achievements.xml index 9f429d233..e6597b4a8 100644 --- a/app/src/main/res/layout/fragment_achievements.xml +++ b/app/src/main/res/layout/fragment_achievements.xml @@ -544,7 +544,4 @@ - - - diff --git a/app/src/main/res/layout/fragment_bookmarks.xml b/app/src/main/res/layout/fragment_bookmarks.xml new file mode 100644 index 000000000..e6fd05cd4 --- /dev/null +++ b/app/src/main/res/layout/fragment_bookmarks.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_contributions.xml b/app/src/main/res/layout/fragment_contributions.xml index 780369919..e75f24891 100644 --- a/app/src/main/res/layout/fragment_contributions.xml +++ b/app/src/main/res/layout/fragment_contributions.xml @@ -9,15 +9,14 @@ android:id="@+id/card_view_nearby" android:layout_width="match_parent" android:layout_height="wrap_content" - app:cardBackgroundColor="?attr/mainCardBackground" - /> + android:layout_margin="@dimen/very_tiny_gap"/> + android:layout_margin="@dimen/very_tiny_gap"/> + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_featured_root.xml b/app/src/main/res/layout/fragment_featured_root.xml new file mode 100644 index 000000000..023d5b2c6 --- /dev/null +++ b/app/src/main/res/layout/fragment_featured_root.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_media_detail_pager.xml b/app/src/main/res/layout/fragment_media_detail_pager.xml index 079bde1f1..19d5d002d 100644 --- a/app/src/main/res/layout/fragment_media_detail_pager.xml +++ b/app/src/main/res/layout/fragment_media_detail_pager.xml @@ -4,7 +4,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" > - + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_more_bottom_sheet_logged_out.xml b/app/src/main/res/layout/fragment_more_bottom_sheet_logged_out.xml new file mode 100644 index 000000000..2c5a3fa3c --- /dev/null +++ b/app/src/main/res/layout/fragment_more_bottom_sheet_logged_out.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/layout_campagin.xml b/app/src/main/res/layout/layout_campagin.xml index 4dd823f5f..775a6a4ec 100644 --- a/app/src/main/res/layout/layout_campagin.xml +++ b/app/src/main/res/layout/layout_campagin.xml @@ -6,7 +6,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" + android:background="@drawable/card_border" android:minHeight="@dimen/large_height" + android:padding="@dimen/small_gap" > @@ -56,7 +59,7 @@ android:gravity="start" android:paddingTop="@dimen/miniscule_margin" android:textAlignment="textStart" - android:textColor="@android:color/white" + android:textColor="?attr/card_item_color" android:visibility="gone" app:layout_constraintTop_toBottomOf="@id/tv_title" tools:text="Campaign Description" @@ -70,7 +73,7 @@ android:layout_weight="1" android:paddingTop="@dimen/miniscule_margin" android:text="@string/ends_on" - android:textColor="@android:color/white" + android:textColor="?attr/card_item_color" app:layout_constraintTop_toBottomOf="@id/tv_description" tools:ignore="MissingConstraints" /> diff --git a/app/src/main/res/layout/layout_category_images.xml b/app/src/main/res/layout/layout_category_images.xml index 3ee1ad80a..a4de5cbbf 100644 --- a/app/src/main/res/layout/layout_category_images.xml +++ b/app/src/main/res/layout/layout_category_images.xml @@ -26,13 +26,23 @@ /> + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center|bottom" + android:background="?attr/contributionsListBackground" + android:orientation="horizontal"> + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_contribution.xml b/app/src/main/res/layout/layout_contribution.xml index 07ee2581a..a1f6cfcb9 100644 --- a/app/src/main/res/layout/layout_contribution.xml +++ b/app/src/main/res/layout/layout_contribution.xml @@ -16,7 +16,7 @@ android:textColor="#33FFFFFF" android:textSize="98sp" android:typeface="serif" /> - + + android:padding="@dimen/small_gap" + android:layout_marginStart="@dimen/tiny_gap"> + android:textColor="?attr/contributionsListTextPrimary" /> + + + + + + @@ -72,11 +95,11 @@ android:id="@+id/image_options" android:layout_width="@dimen/dimen_0" android:layout_height="wrap_content" - android:layout_gravity="right" + android:layout_gravity="end|bottom" android:layout_weight="2.6" - android:gravity="right" + android:gravity="end|bottom" android:orientation="horizontal" - android:padding="@dimen/tiny_gap" + android:paddingTop="@dimen/standard_gap" android:visibility="visible"> diff --git a/app/src/main/res/layout/main.xml b/app/src/main/res/layout/main.xml new file mode 100644 index 000000000..91ba13a35 --- /dev/null +++ b/app/src/main/res/layout/main.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/menu_switch.xml b/app/src/main/res/layout/menu_switch.xml deleted file mode 100644 index 47dec3331..000000000 --- a/app/src/main/res/layout/menu_switch.xml +++ /dev/null @@ -1,5 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/layout/nearby_card_view.xml b/app/src/main/res/layout/nearby_card_view.xml index f9a3269ea..ce301c3b9 100644 --- a/app/src/main/res/layout/nearby_card_view.xml +++ b/app/src/main/res/layout/nearby_card_view.xml @@ -1,11 +1,13 @@ - + android:background="@drawable/card_border" + android:minHeight="@dimen/large_height" + android:padding="@dimen/small_gap" + >