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

* Add additional classes from 2019 hackathon implementation

* Make first tab work

* Make explore tab work

* Handle back button for contrib and nearby

* Fix framelayout and nav bar allignment

* Fix nav bar tint

* Fix nearby card layout

* Make contributions number visible

* Change menu icon according to fragment

* Make notification icon work and remove drawer

* Make favourites accessible from nav bar

* Turn bookmark and explore activities into fragments

* Use bottom sheet instead of more fragment

* Add actions

* Remove unused classes

* Fix indentation

* remove more fragment title

* Fix explore fragment indentation

* Make toolbar settings as we wanted

* Set card view styles

* Make colors for explore actiivty

* Remove drawer from achievements activity

* Add back button to achievements activity

* remove drawer from review activity

* Remove drawer from settings activity

* Remove drawer from about activity

* Fix dagger injection of fragment

* Implement skip login version

* Add theme missing colors

* Add style to moresheet

* refactor name

* call login with button

* Remove all old bookmarks activity dependency

* Make explore tab items clickable

* Do nothing if same tab is selected

* Fix notification icon color for dark theme

* Fix wrong drawable colors

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

* make favourites open media details

* Fix profile icon

* Make user name visible instead

* Move user back to contrib fragment

* Remove NavigationBaseAvticity

* Fix typo in bookmark fragment

* Fix menu button colors

* Remove explore activity

* remove drawer and dependencies

* Make bookmark media details visible

* Cleanup code

* Code cleanup

* Remove unused layout

* Make contriblist UI look like in mockups

* Change limited connecton toggle

* Move list menu item to nearby fragment

* Fix search button crash

* Make media detail appear

* Back button added

* Fix back button npe

* Change bookmark list view

* Fix always the firs item displayed issue

* Allign contrib list bottom line to simple drawee bottom

* fix fragment string

* Fix back button for mobile uploads

* Make lists appear

* Make fav item selected

* Make favourites clickable

* Add back button to media details

* Add toolbar of notification activity

* Change contributions icon

* Fix card UI

* Fix back button in explore

* Make card views look similar to mockups

* Solve campaign bug visible issue

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

View file

@ -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)
}
}

View file

@ -124,12 +124,6 @@
android:label="@string/title_activity_featured_images"
android:parentActivityName=".contributions.MainActivity" />
<activity
android:name=".explore.ExploreActivity"
android:label="@string/title_activity_explore"
android:parentActivityName=".contributions.MainActivity"
android:configChanges="orientation|screenSize|keyboard" />
<activity
android:name=".explore.SearchActivity"
android:label="@string/title_activity_search"
@ -143,10 +137,6 @@
android:configChanges="orientation|screenSize|keyboard"
android:label="@string/Profile" />
<activity
android:name=".bookmarks.BookmarksActivity"
android:label="@string/title_activity_bookmarks" />
<activity
android:name=".review.ReviewActivity"
android:label="@string/title_activity_review" />

View file

@ -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)

View file

@ -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();
}

View file

@ -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);
}
}

View file

@ -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() {
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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);

View file

@ -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;

View file

@ -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();
}

View file

@ -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);

View file

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

View file

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

View file

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

View file

@ -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();
}

View file

@ -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<Application
void inject(SettingsFragment fragment);
void inject(MoreBottomSheetFragment fragment);
void inject(MoreBottomSheetLoggedOutFragment fragment);
void inject(ReviewController reviewController);
//void inject(NavTabLayout view);
@Override
void inject(ApplicationlessInjection instance);

View file

@ -2,10 +2,14 @@ package fr.free.nrw.commons.di;
import dagger.Module;
import dagger.android.ContributesAndroidInjector;
import fr.free.nrw.commons.bookmarks.BookmarkFragment;
import fr.free.nrw.commons.bookmarks.BookmarkListRootFragment;
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsFragment;
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesFragment;
import fr.free.nrw.commons.contributions.ContributionsFragment;
import fr.free.nrw.commons.contributions.ContributionsListFragment;
import fr.free.nrw.commons.explore.ExploreFragment;
import fr.free.nrw.commons.explore.ExploreListRootFragment;
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.search.SearchCategoryFragment;
@ -18,6 +22,8 @@ import fr.free.nrw.commons.explore.media.SearchMediaFragment;
import fr.free.nrw.commons.explore.recentsearches.RecentSearchesFragment;
import fr.free.nrw.commons.media.MediaDetailFragment;
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.nearby.fragments.NearbyParentFragment;
import fr.free.nrw.commons.profile.achievements.AchievementsFragment;
import fr.free.nrw.commons.profile.leaderboard.LeaderboardFragment;
@ -106,6 +112,24 @@ public abstract class FragmentBuilderModule {
@ContributesAndroidInjector
abstract ParentCategoriesFragment bindParentCategoriesFragment();
@ContributesAndroidInjector
abstract ExploreFragment bindExploreFragmentFragment();
@ContributesAndroidInjector
abstract ExploreListRootFragment bindExploreFeaturedRootFragment();
@ContributesAndroidInjector
abstract BookmarkListRootFragment bindBookmarkListRootFragment();
@ContributesAndroidInjector
abstract BookmarkFragment bindBookmarkFragmentFragment();
@ContributesAndroidInjector
abstract MoreBottomSheetFragment bindMoreBottomSheetFragment();
@ContributesAndroidInjector
abstract MoreBottomSheetLoggedOutFragment bindMoreBottomSheetLoggedOutFragment();
@ContributesAndroidInjector
abstract AchievementsFragment bindAchievementsFragment();

View file

@ -1,223 +0,0 @@
package fr.free.nrw.commons.explore;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.FrameLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager.widget.ViewPager;
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.explore.categories.media.CategoriesMediaFragment;
import fr.free.nrw.commons.media.MediaDetailPagerFragment;
import fr.free.nrw.commons.theme.NavigationBaseActivity;
import java.util.ArrayList;
import java.util.List;
/**
* This activity displays featured images and images uploaded via mobile
*/
public class ExploreActivity
extends NavigationBaseActivity
implements MediaDetailPagerFragment.MediaDetailProvider, CategoryImagesCallback {
private static final String FEATURED_IMAGES_CATEGORY = "Featured_pictures_on_Wikimedia_Commons";
private static final String MOBILE_UPLOADS_CATEGORY = "Uploaded_with_Mobile/Android";
@BindView(R.id.mediaContainer)
FrameLayout mediaContainer;
@BindView(R.id.tab_layout)
TabLayout tabLayout;
@BindView(R.id.viewPager)
ViewPager viewPager;
ViewPagerAdapter viewPagerAdapter;
private FragmentManager supportFragmentManager;
private MediaDetailPagerFragment mediaDetails;
private CategoriesMediaFragment mobileImagesListFragment;
private CategoriesMediaFragment featuredImagesListFragment;
/**
* 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, ExploreActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_explore);
ButterKnife.bind(this);
initDrawer();
setTitle(getString(R.string.title_activity_explore));
supportFragmentManager = getSupportFragmentManager();
viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(viewPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
setTabs();
}
/**
* Sets the titles in the tabLayout and fragments in the viewPager
*/
public void setTabs() {
List<Fragment> fragmentList = new ArrayList<>();
List<String> 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);
}
}
}

View file

@ -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<Fragment> fragmentList = new ArrayList<>();
List<String> 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);
}
}
}

View file

@ -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();
}
}
}

View file

@ -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();
}

View file

@ -8,6 +8,7 @@ import javax.inject.Inject
class CategoriesMediaFragment : PageableMediaFragment() {
@Inject
lateinit var presenter: CategoryMediaPresenter

View file

@ -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();
}
/**

View file

@ -25,7 +25,11 @@ abstract class PageableMediaFragment : BasePagingFragment<Media>(), 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 =

View file

@ -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,

View file

@ -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<String> categories) {
Log.d("deneme","rebuild cat list size:"+categories.size());
categoryContainer.removeAllViews();
for (String category : categories) {
categoryContainer.addView(buildCatLabel(sanitise(category), categoryContainer));

View file

@ -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

View file

@ -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();
}
}
}

View file

@ -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();
}
}
}

View file

@ -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<NavTab> 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;
}
}

View file

@ -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);
}
}

View file

@ -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());
}
}
}
}

View file

@ -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<NavTabLoggedOut> 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;
}
}

View file

@ -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);
});
}

View file

@ -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,

View file

@ -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);
}

View file

@ -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")

View file

@ -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();

View file

@ -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);

View file

@ -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);

View file

@ -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,9 +44,12 @@ 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;
}
/**

View file

@ -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 <T> void startActivityWithFlags(Context context, Class<T> 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();
}
}
}

View file

@ -0,0 +1,14 @@
package fr.free.nrw.commons.utils;
import android.content.Context;
import android.content.Intent;
public class ActivityUtils {
public static <T> void startActivityWithFlags(Context context, Class<T> cls, int... flags) {
Intent intent = new Intent(context, cls);
for (int flag: flags) {
intent.addFlags(flag);
}
context.startActivity(intent);
}
}

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="@color/white" />
<item android:color="@color/black" />
</selector>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="@color/primaryDarkColor" />
<item android:color="@color/nav_tab_icon_unselected_color" />
</selector>

View file

@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="#FFFFFF">
android:tint="?attr/mediaDetailsHeadingText">
<group android:scaleX="1.44427"
android:scaleY="1.44427"
android:translateX="-5.33124"

View file

@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="#FFFFFF">
android:tint="?attr/mediaDetailsHeadingText">
<group android:scaleX="1.44427"
android:scaleY="1.44427"
android:translateX="-7.4976454"

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/drawerHeader_background_light" />
</shape>
</item>
<item android:left="1dp" android:right="1dp" android:top="1dp" android:bottom="1dp" >
<shape android:shape="rectangle">
<solid android:color="?attr/mainCardBackground" />
</shape>
</item>
</layer-list>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/menu_item_tint">
<path
android:fillColor="@android:color/white"
android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4c-1.48,0 -2.85,0.43 -4.01,1.17l1.46,1.46C10.21,6.23 11.08,6 12,6c3.04,0 5.5,2.46 5.5,5.5v0.5H19c1.66,0 3,1.34 3,3 0,1.13 -0.64,2.11 -1.56,2.62l1.45,1.45C23.16,18.16 24,16.68 24,15c0,-2.64 -2.05,-4.78 -4.65,-4.96zM3,5.27l2.75,2.74C2.56,8.15 0,10.77 0,14c0,3.31 2.69,6 6,6h11.73l2,2L21,20.73 4.27,4 3,5.27zM7.73,10l8,8H6c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4h1.73z"/>
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/menu_item_tint">
<path
android:fillColor="@android:color/white"
android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM19,18H6c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4h0.71C7.37,7.69 9.48,6 12,6c3.04,0 5.5,2.46 5.5,5.5v0.5H19c1.66,0 3,1.34 3,3s-1.34,3 -3,3z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="14dp" android:tint="?attr/colorControlNormal"
android:viewportHeight="24" android:viewportWidth="24"
android:width="14dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="?attr/contributionsListTextSecondary" android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/more_bottom_sheet_drawable_color">
<path
android:fillColor="?attr/more_bottom_sheet_drawable_color"
android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:fillColor="?attr/more_bottom_sheet_drawable_color"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:fillColor="?attr/more_bottom_sheet_drawable_color"
android:pathData="M10.09,15.59L11.5,17l5,-5 -5,-5 -1.41,1.41L12.67,11H3v2h9.67l-2.58,2.59zM19,3H5c-1.11,0 -2,0.9 -2,2v4h2V5h14v14H5v-4H3v4c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:fillColor="?attr/more_bottom_sheet_drawable_color"
android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM13,14h-2v-2h2v2zM13,10h-2L11,6h2v4z"/>
</vector>

View file

@ -0,0 +1,27 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:pathData="M8.91,2.49a10,10 0,1 0,12.6 6.42A10,10 0,0 0,8.91 2.49ZM14.47,19.61A8,8 0,1 1,19.61 9.53,8 8,0 0,1 14.47,19.61Z"
android:fillColor="#000000"/>
<path
android:pathData="M3.35,7.45s2.5,1.82 7.26,0.27 5.71,-4.49 5.71,-4.49l1.11,1.22s-1.61,3.15 -6.36,4.7 -7.91,-0.06 -7.91,-0.06Z"
android:fillColor="#000000"/>
<path
android:pathData="M7.52,20.29s1,-2.94 5.71,-4.49 7.26,0.27 7.26,0.27l0.18,-1.64s-3.15,-1.61 -7.91,-0.06 -6.36,4.7 -6.36,4.7Z"
android:fillColor="#000000"/>
<path
android:pathData="M3.97,13.82l15.6,-5.07l0.46,1.43l-6.81,2.21l-8.79,2.86l-0.46,-1.43z"
android:fillColor="#000000"/>
<path
android:pathData="M15.8,10.76A9.77,9.77 0,0 0,9.48 4.26l1.25,-1a11.16,11.16 0,0 1,6.49 7,11.16 11.16,0 0,1 -1.12,9.51l-1.6,-0.07A9.77,9.77 0,0 0,15.8 10.76Z"
android:fillColor="#000000"/>
<path
android:pathData="M8.2,13.24a9.77,9.77 0,0 1,1.29 -9l-1.6,-0.07A11.16,11.16 0,0 0,6.77 13.7a11.16,11.16 0,0 0,6.49 7l1.25,-1A9.77,9.77 0,0 1,8.2 13.24Z"
android:fillColor="#000000"/>
<path
android:pathData="M8.754,4.438l1.427,-0.464l5.068,15.597l-1.427,0.464z"
android:fillColor="#000000"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:fillColor="?attr/more_bottom_sheet_drawable_color"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:fillColor="?attr/more_bottom_sheet_drawable_color"
android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:fillColor="?attr/menu_item_tint"
android:pathData="M3,13h2v-2L3,11v2zM3,17h2v-2L3,15v2zM3,9h2L5,7L3,7v2zM7,13h14v-2L7,11v2zM7,17h14v-2L7,15v2zM7,7v2h14L21,7L7,7z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:height="@dimen/half_standard_height" android:tint="@color/primaryDarkColor"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="@dimen/half_standard_height" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@color/primaryDarkColor" android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z"/>
</vector>

View file

@ -5,5 +5,5 @@
android:height="30.928dp">
<path
android:pathData="M24.791 4.451C24.811 3.503 24.775 2.904 24.775 2.904l-9.264 -0.007 0 0 -0.047 0 -0.047 0 0 0 -9.265 0.007c0 0 -0.035 0.599 -0.015 1.547L0 4.451 0 5.463c0 0.231 0.039 5.68 3.402 8.665 1.403 1.245 3.153 1.871 5.216 1.872 0.312 0 0.633 -0.021 0.958 -0.049 1.172 1.605 2.526 2.729 4.049 3.289l0 4.445 -4.471 0 0 2.784 -1.477 0 0 1.561 7.74 0 0.094 0 7.74 0 0 -1.56 -1.478 0 0 -2.784 -4.471 0 0 -4.445c1.522 -0.56 2.877 -1.684 4.049 -3.289 0.327 0.028 0.648 0.048 0.96 0.048 2.062 -0.002 3.812 -0.627 5.215 -1.873 3.363 -2.985 3.402 -8.434 3.402 -8.665l0 -1.011 -6.137 0zM4.752 12.619C2.831 10.919 2.263 8.009 2.095 6.475l4.158 0c0.176 1.911 0.59 4.292 1.545 6.385 0.175 0.384 0.359 0.748 0.547 1.104C6.912 13.909 5.706 13.462 4.752 12.619Zm21.424 0c-0.953 0.844 -2.16 1.29 -3.592 1.345 0.188 -0.355 0.372 -0.72 0.547 -1.104 0.955 -2.093 1.369 -4.474 1.544 -6.385l4.158 0c-0.168 1.533 -0.735 4.443 -2.657 6.144z"
android:fillColor="#fff" />
android:fillColor="?attr/more_bottom_sheet_drawable_color" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:fillColor="?attr/more_bottom_sheet_drawable_color"
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="@dimen/half_standard_height" android:tint="?attr/notification_icon_text_color"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="@dimen/half_standard_height" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/half_standard_height"
android:height="@dimen/half_standard_height"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/notification_icon_text_color"
android:pathData="M19.65,9.04l-4.84,-0.42 -1.89,-4.45c-0.34,-0.81 -1.5,-0.81 -1.84,0L9.19,8.63l-4.83,0.41c-0.88,0.07 -1.24,1.17 -0.57,1.75l3.67,3.18 -1.1,4.72c-0.2,0.86 0.73,1.54 1.49,1.08l4.15,-2.5 4.15,2.51c0.76,0.46 1.69,-0.22 1.49,-1.08l-1.1,-4.73 3.67,-3.18c0.67,-0.58 0.32,-1.68 -0.56,-1.75zM12,15.4l-3.76,2.27 1,-4.28 -3.32,-2.88 4.38,-0.38L12,6.1l1.71,4.04 4.38,0.38 -3.32,2.88 1,4.28L12,15.4z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/half_standard_height"
android:height="@dimen/half_standard_height"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/notification_icon_text_color"
android:pathData="M19.65,9.04l-4.84,-0.42 -1.89,-4.45c-0.34,-0.81 -1.5,-0.81 -1.84,0L9.19,8.63l-4.83,0.41c-0.88,0.07 -1.24,1.17 -0.57,1.75l3.67,3.18 -1.1,4.72c-0.2,0.86 0.73,1.54 1.49,1.08l4.15,-2.5 4.15,2.51c0.76,0.46 1.69,-0.22 1.49,-1.08l-1.1,-4.73 3.67,-3.18c0.67,-0.58 0.32,-1.68 -0.56,-1.75z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:alpha="0.84" android:height="@dimen/half_standard_height"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="@dimen/half_standard_height" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="?attr/notification_icon_text_color" android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
</vector>

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.navigation.NavigationView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:elevation="@dimen/miniscule_margin"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/drawer" />

View file

@ -163,7 +163,4 @@
</RelativeLayout>
</ScrollView>
</LinearLayout>
<include layout="@layout/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout>

View file

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/toolbar"/>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/tabBackground"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:tabIndicatorColor="?attr/tabIndicatorColor"
app:tabMode="fixed"
app:tabSelectedTextColor="?attr/tabSelectedTextColor"
app:tabTextColor="?attr/tabTextColor" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPagerBookmarks"
android:layout_width="@dimen/dimen_0"
android:layout_height="@dimen/dimen_0"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tab_layout" />
<FrameLayout
android:id="@+id/fragmentContainer"
android:layout_width="@dimen/dimen_0"
android:layout_height="@dimen/dimen_0"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<include layout="@layout/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout>

View file

@ -44,6 +44,4 @@
android:layout_below="@id/toolbar_layout" />
</RelativeLayout>
<include layout="@layout/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout>

View file

@ -19,7 +19,4 @@
</FrameLayout>
</RelativeLayout>
<include layout="@layout/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout>

View file

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/contributionsListBackground"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
>
<include layout="@layout/toolbar"/>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/tabBackground"
app:tabIndicatorColor="?attr/tabIndicatorColor"
app:tabSelectedTextColor="?attr/tabSelectedTextColor"
app:tabTextColor="?attr/tabTextColor"
android:layout_below="@id/toolbar"
app:tabMode="fixed" />
<FrameLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/contributionsFragmentContainer"
android:orientation="horizontal"
android:layout_below="@id/tab_layout">
<fr.free.nrw.commons.contributions.UnswipableViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</RelativeLayout>
<include layout="@layout/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout>

View file

@ -1,49 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/primaryDarkColor">
<include layout="@layout/toolbar"/>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/toolbar"
android:background="?attr/tabBackground"
app:tabIndicatorColor="?attr/tabIndicatorColor"
app:tabMode="fixed"
app:tabSelectedTextColor="?attr/tabSelectedTextColor"
app:tabTextColor="?attr/tabTextColor" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mediaContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar_layout"
android:orientation="horizontal"
android:visibility="gone" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar_layout" />
</RelativeLayout>
<include layout="@layout/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout>

View file

@ -63,6 +63,4 @@
</RelativeLayout>
<include layout="@layout/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout>

View file

@ -36,6 +36,4 @@
android:layout_below="@id/toolbar_layout" />
</RelativeLayout>
<include layout="@layout/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout>

View file

@ -6,8 +6,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -116,9 +114,6 @@
</RelativeLayout>
</LinearLayout>
<include layout="@layout/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout>

View file

@ -85,6 +85,4 @@
/>
</RelativeLayout>
<include layout="@layout/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout>

View file

@ -12,7 +12,6 @@
android:layout_height="?attr/actionBarSize">
<include layout="@layout/toolbar" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -27,7 +26,4 @@
tools:layout="@xml/preferences"
/>
</RelativeLayout>
<include layout="@layout/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout>

View file

@ -44,6 +44,4 @@
android:layout_below="@id/toolbar_layout" />
</RelativeLayout>
<include layout="@layout/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout>

View file

@ -1,55 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/drawerHeaderBackground"
android:orientation="vertical">
<ImageView
android:id="@+id/pictureOfTheDay"
android:layout_width="match_parent"
android:layout_height="172dp"
android:background="?attr/drawerHeaderBackground"
android:paddingLeft="@dimen/standard_gap"
android:paddingTop="@dimen/standard_gap"
android:paddingRight="@dimen/standard_gap"
android:paddingBottom="@dimen/small_gap"
app:srcCompat="@drawable/commons_logo"/>
<LinearLayout
android:id="@+id/user_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/tiny_margin"
android:layout_marginTop="@dimen/activity_margin_horizontal"
android:layout_marginEnd="@dimen/tiny_margin"
android:layout_marginBottom="@dimen/activity_margin_horizontal"
android:paddingBottom="@dimen/small_gap"
android:textColor="@color/item_white_background"
android:textSize="@dimen/subheading_text_size"
tools:text="TextView" />
<ImageView
android:id="@+id/user_icon"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginStart="@dimen/tiny_margin"
android:layout_marginTop="@dimen/activity_margin_horizontal"
android:layout_marginEnd="@dimen/tiny_margin"
android:layout_marginBottom="@dimen/activity_margin_horizontal"
android:textColor="@color/item_white_background"
android:textSize="@dimen/subheading_text_size"
app:srcCompat="@drawable/ic_person_black_24dp" />
</LinearLayout>
</LinearLayout>

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.navigation.NavigationView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:elevation="@dimen/miniscule_margin"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/drawer" />

View file

@ -544,7 +544,4 @@
</LinearLayout>
</LinearLayout>
</ScrollView>
<include layout="@layout/drawer_view" />
</androidx.drawerlayout.widget.DrawerLayout>

View file

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/card_light_grey">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/toolbar"
android:background="?attr/tabBackground"
app:tabIndicatorColor="?attr/tabIndicatorColor"
app:tabMode="fixed"
app:tabSelectedTextColor="?attr/tabSelectedTextColor"
app:tabTextColor="?attr/tabTextColor" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar_layout"
android:orientation="horizontal"
android:visibility="gone"/>
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPagerBookmarks"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar_layout" />
</RelativeLayout>

View file

@ -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"/>
<fr.free.nrw.commons.campaigns.CampaignView
android:id="@+id/campaigns_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/miniscule_margin"
app:cardBackgroundColor="?attr/mainCardBackground" />
android:layout_margin="@dimen/very_tiny_gap"/>
<FrameLayout
android:id="@+id/root_frame"

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/card_light_grey">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/toolbar"
android:background="?attr/tabBackground"
app:tabIndicatorColor="?attr/tabIndicatorColor"
app:tabMode="fixed"
app:tabSelectedTextColor="?attr/tabSelectedTextColor"
app:tabTextColor="?attr/tabTextColor" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mediaContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar_layout"
android:orientation="horizontal"
android:visibility="gone" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar_layout" />
</RelativeLayout>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/explore_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
android:orientation="horizontal" />
</RelativeLayout>

View file

@ -4,7 +4,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<androidx.viewpager.widget.ViewPager
android:id="@+id/mediaDetailsPager"
android:layout_width="match_parent"

View file

@ -0,0 +1,84 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize"
android:theme="?attr/more_bottom_sheet_style"
android:orientation="vertical">
<TextView
android:id="@+id/more_profile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:drawableStart="@drawable/ic_person_black_24dp"
android:drawablePadding="12dp"
android:padding="8dp"
android:text="@string/Profile"
android:textSize="18sp" />
<TextView
android:id="@+id/more_peer_review"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:drawableStart="@drawable/ic_check_black_24dp"
android:drawablePadding="12dp"
android:padding="8dp"
android:text="@string/navigation_item_review"
android:textSize="18sp" />
<TextView
android:id="@+id/more_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:drawableStart="@drawable/ic_settings_black_24dp"
android:drawablePadding="12dp"
android:padding="8dp"
android:text="@string/menu_settings"
android:textSize="18sp" />
<TextView
android:id="@+id/more_tutorial"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:drawableStart="@drawable/ic_help_black_24dp"
android:drawablePadding="12dp"
android:padding="8dp"
android:text="@string/navigation_item_info"
android:textSize="18sp" />
<TextView
android:id="@+id/more_feedback"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:drawableLeft="@drawable/ic_feedback_black_24dp"
android:drawablePadding="12dp"
android:padding="8dp"
android:text="@string/navigation_item_feedback"
android:textSize="18sp" />
<TextView
android:id="@+id/more_about"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:drawableStart="@drawable/ic_info_outline_24dp"
android:drawablePadding="12dp"
android:padding="8dp"
android:text="@string/navigation_item_about"
android:textSize="18sp" />
<TextView
android:id="@+id/more_logout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:drawableStart="@drawable/ic_exit_to_app_black_24dp"
android:drawablePadding="12dp"
android:padding="8dp"
android:text="@string/navigation_item_logout"
android:textSize="18sp" />
</LinearLayout>

View file

@ -0,0 +1,62 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize"
android:theme="?attr/more_bottom_sheet_style"
android:orientation="vertical">
<TextView
android:id="@+id/more_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:drawableStart="@drawable/ic_settings_black_24dp"
android:drawablePadding="12dp"
android:padding="8dp"
android:text="@string/menu_settings"
android:textSize="18sp" />
<TextView
android:id="@+id/more_tutorial"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:drawableStart="@drawable/ic_help_black_24dp"
android:drawablePadding="12dp"
android:padding="8dp"
android:text="@string/navigation_item_info"
android:textSize="18sp" />
<TextView
android:id="@+id/more_feedback"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:drawableLeft="@drawable/ic_feedback_black_24dp"
android:drawablePadding="12dp"
android:padding="8dp"
android:text="@string/navigation_item_feedback"
android:textSize="18sp" />
<TextView
android:id="@+id/more_about"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:drawableStart="@drawable/ic_info_outline_24dp"
android:drawablePadding="12dp"
android:padding="8dp"
android:text="@string/navigation_item_about"
android:textSize="18sp" />
<TextView
android:id="@+id/more_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:drawableStart="@drawable/ic_baseline_person_24"
android:drawablePadding="12dp"
android:padding="8dp"
android:text="@string/navigation_item_login"
android:textSize="18sp" />
</LinearLayout>

View file

@ -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"
>
<LinearLayout
android:layout_width="match_parent"
@ -21,6 +23,7 @@
android:layout_marginStart="@dimen/standard_gap"
android:scaleType="centerCrop"
app:srcCompat="@drawable/ic_campaign"
android:tint="?attr/card_item_color"
/>
<LinearLayout
android:layout_width="match_parent"
@ -43,7 +46,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/standard_gap"
android:textColor="@android:color/white"
android:textColor="?attr/card_item_color"
android:textStyle="bold"
tools:text="Campaign Title"
tools:ignore="MissingConstraints" />
@ -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" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -26,13 +26,23 @@
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|bottom"
android:background="#AA000000"
android:orientation="vertical"
android:padding="@dimen/small_gap"
>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|bottom"
android:background="?attr/contributionsListBackground"
android:orientation="horizontal">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|bottom"
android:orientation="vertical"
android:padding="@dimen/small_gap"
android:background="?attr/contributionsListBackground">
<ProgressBar
android:id="@+id/categoryProgress"
android:layout_width="match_parent"
@ -45,23 +55,36 @@
<TextView
android:id="@+id/categoryImageTitle"
android:textStyle="bold"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
style="?android:textAppearanceLarge"
android:maxLines="1"
android:ellipsize="end"
android:maxLines="2"
android:textColor="?attr/contributionsListTextPrimary"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_baseline_person_14"/>
<TextView
android:id="@+id/categoryImageAuthor"
android:textStyle="normal"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
style="?android:textAppearanceMedium"
android:maxLines="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?attr/contributionsListTextSecondary"
/>
</LinearLayout>
</LinearLayout>
</FrameLayout>

View file

@ -29,7 +29,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|bottom"
android:background="#AA000000"
android:background="?attr/contributionsListBackground"
android:orientation="horizontal">
<LinearLayout
@ -38,7 +38,8 @@
android:layout_gravity="center|bottom"
android:layout_weight="5"
android:orientation="vertical"
android:padding="@dimen/small_gap">
android:padding="@dimen/small_gap"
android:layout_marginStart="@dimen/tiny_gap">
<ProgressBar
android:id="@+id/contributionProgress"
@ -54,17 +55,39 @@
style="?android:textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textColor="?attr/contributionsListTextSecondary"
android:visibility="gone" />
<TextView
android:id="@+id/contributionTitle"
style="?android:textAppearanceMedium"
android:textStyle="bold"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textColor="#FFFFFFFF" />
android:textColor="?attr/contributionsListTextPrimary" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_baseline_person_14"/>
<TextView
android:id="@+id/authorView"
android:textStyle="normal"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?attr/contributionsListTextSecondary" />
</LinearLayout>
</LinearLayout>
@ -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">
<ImageButton
@ -98,6 +121,7 @@
android:background="@android:color/transparent"
android:padding="@dimen/activity_margin_horizontal"
android:src="@drawable/ic_cancel_white"
android:tint="?attr/contributionsListTextSecondary"
android:text="@string/menu_cancel_upload" />
<ImageButton
@ -109,6 +133,7 @@
android:background="@android:color/transparent"
android:padding="@dimen/activity_margin_horizontal"
android:src="@drawable/ic_retry_white"
android:tint="?attr/contributionsListTextSecondary"
android:text="@string/menu_retry_upload" />
<ImageButton
@ -120,6 +145,7 @@
android:background="@android:color/transparent"
android:padding="@dimen/activity_margin_horizontal"
android:src="@drawable/ic_wikipedia"
android:tint="?attr/contributionsListTextSecondary"
android:text="@string/menu_cancel_upload"
android:visibility="visible" />

View file

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/fragment_main_nav_tab_layout"
android:orientation="horizontal">
<fr.free.nrw.commons.contributions.UnswipableViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<fr.free.nrw.commons.navtab.NavTabLayout
android:id="@+id/fragment_main_nav_tab_layout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:background="?attr/nav_bar_background"
android:elevation="6dp"
app:itemIconTint="?attr/nav_tab_item_color_state"
app:itemTextColor="?attr/navbar_item_text_color" />
</RelativeLayout>
</LinearLayout>

View file

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Switch xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/switch_toggle_limited_connection_mode"/>

View file

@ -1,11 +1,13 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="?attr/mainCardBackground"
android:layout_centerVertical="true"
android:minHeight="@dimen/large_height">
android:background="@drawable/card_border"
android:minHeight="@dimen/large_height"
android:padding="@dimen/small_gap"
>
<Button
android:layout_width="wrap_content"
@ -17,7 +19,7 @@
android:layout_marginRight="@dimen/activity_margin_horizontal"
android:layout_marginTop="@dimen/activity_margin_horizontal"
android:minWidth="@dimen/fragment_height"
android:textColor="@android:color/white"
android:textColor="?attr/card_item_color"
android:singleLine="true"
android:theme="?attr/mainScreenNearbyPermissionbutton"
style="@style/Widget.AppCompat.Button.Borderless"/>
@ -28,6 +30,7 @@
android:layout_height="wrap_content"
android:id="@+id/content_layout"
android:layout_centerInParent="true"
android:orientation="horizontal"
>
<ProgressBar
@ -44,7 +47,9 @@
android:layout_marginLeft="@dimen/standard_gap"
android:layout_marginStart="@dimen/standard_gap"
android:scaleType="centerCrop"
app:srcCompat="@drawable/ic_location_white_24dp"/>
app:srcCompat="@drawable/ic_location_white_24dp"
android:tint="?attr/card_item_color"
/>
<LinearLayout
@ -66,7 +71,7 @@
android:layout_marginLeft="@dimen/standard_gap"
android:layout_marginRight="@dimen/standard_gap"
tools:text="test distance"
android:textColor="@android:color/white"
android:textColor="?attr/card_item_color"
android:singleLine="true"
>
</TextView>
@ -81,7 +86,7 @@
android:minWidth="@dimen/fragment_height"
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
tools:text="test distance"
android:textColor="@android:color/white"
android:textColor="?attr/card_item_color"
android:singleLine="true"
>
@ -91,4 +96,4 @@
</LinearLayout>
</RelativeLayout>
</LinearLayout>

View file

@ -17,7 +17,7 @@
android:layout_marginEnd="@dimen/activity_margin_horizontal"
android:gravity="center"
android:layout_marginRight="@dimen/activity_margin_horizontal"
app:srcCompat="@drawable/ic_notifications_white_24dp" />
app:srcCompat="?attr/notification_icon_drawable" />
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/notification_count_badge"
@ -29,7 +29,7 @@
android:background="@drawable/notification_badge"
android:gravity="center"
android:padding="@dimen/miniscule_margin"
android:textColor="#ffffffff"
android:textColor="?attr/notification_icon_text_color"
android:textSize="7sp"
android:textStyle="bold"
android:visibility="gone"

View file

@ -4,6 +4,6 @@
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimaryDark"
android:fitsSystemWindows="true"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
app:titleTextColor="?attr/toolbar_text_color"
/>

Some files were not shown because too many files have changed in this diff Show more