Resolved conflicts

This commit is contained in:
Saifuddin 2024-12-14 12:15:57 +05:30
parent 7b799227ba
commit 16eb639b31
9 changed files with 664 additions and 734 deletions

View file

@ -1,105 +1,109 @@
package fr.free.nrw.commons.bookmarks;
package fr.free.nrw.commons.bookmarks
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentManager;
import fr.free.nrw.commons.contributions.MainActivity;
import fr.free.nrw.commons.databinding.FragmentBookmarksBinding;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.theme.BaseActivity;
import javax.inject.Inject;
import fr.free.nrw.commons.contributions.ContributionController;
import javax.inject.Named;
import androidx.fragment.app.FragmentManager
import fr.free.nrw.commons.contributions.MainActivity
import fr.free.nrw.commons.databinding.FragmentBookmarksBinding
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment
import fr.free.nrw.commons.kvstore.JsonKvStore
import fr.free.nrw.commons.theme.BaseActivity
import javax.inject.Inject
import fr.free.nrw.commons.contributions.ContributionController
import javax.inject.Named
public class BookmarkFragment extends CommonsDaggerSupportFragment {
private FragmentManager supportFragmentManager;
private BookmarksPagerAdapter adapter;
FragmentBookmarksBinding binding;
class BookmarkFragment : CommonsDaggerSupportFragment() {
var binding: FragmentBookmarksBinding? = null
private var adapter: BookmarksPagerAdapter? = null
@Inject
ContributionController controller;
lateinit var controller: ContributionController
/**
* To check if the user is loggedIn or not.
*/
@Inject
@Named("default_preferences")
public
JsonKvStore applicationKvStore;
@field: Named("default_preferences")
lateinit var applicationKvStore: JsonKvStore
@NonNull
public static BookmarkFragment newInstance() {
BookmarkFragment fragment = new BookmarkFragment();
fragment.setRetainInstance(true);
return fragment;
}
public void setScroll(boolean canScroll) {
if (binding!=null) {
binding.viewPagerBookmarks.setCanScroll(canScroll);
companion object {
fun newInstance(): BookmarkFragment {
val fragment = BookmarkFragment()
fragment.retainInstance = true
return fragment
}
}
@Override
public void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fun setScroll(canScroll: Boolean) {
binding?.viewPagerBookmarks?.isCanScroll = canScroll
}
@Nullable
@Override
public View onCreateView(@NonNull final LayoutInflater inflater,
@Nullable final ViewGroup container,
@Nullable final Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
binding = FragmentBookmarksBinding.inflate(inflater, container, false);
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreateView(inflater, container, savedInstanceState)
binding = FragmentBookmarksBinding.inflate(inflater, container, false)
// Activity can call methods in the fragment by acquiring a
// reference to the Fragment from FragmentManager, using findFragmentById()
supportFragmentManager = getChildFragmentManager();
val supportFragmentManager = childFragmentManager
adapter = new BookmarksPagerAdapter(supportFragmentManager, getContext(),
applicationKvStore.getBoolean("login_skipped"));
binding.viewPagerBookmarks.setAdapter(adapter);
binding.tabLayout.setupWithViewPager(binding.viewPagerBookmarks);
adapter = BookmarksPagerAdapter(
supportFragmentManager,
requireContext(),
applicationKvStore.getBoolean("login_skipped")
)
binding?.apply {
viewPagerBookmarks.adapter = adapter
tabLayout.setupWithViewPager(viewPagerBookmarks)
}
((MainActivity) getActivity()).showTabs();
((BaseActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
(requireActivity() as MainActivity).showTabs()
(requireActivity() as BaseActivity).supportActionBar?.setDisplayHomeAsUpEnabled(false)
setupTabLayout();
return binding.getRoot();
setupTabLayout()
return binding?.root
}
/**
* This method sets up the tab layout. If the adapter has only one element it sets the
* visibility of tabLayout to gone.
*/
public void setupTabLayout() {
binding.tabLayout.setVisibility(View.VISIBLE);
if (adapter.getCount() == 1) {
binding.tabLayout.setVisibility(View.GONE);
fun setupTabLayout() {
binding?.apply {
tabLayout.visibility = View.VISIBLE
if (adapter?.count == 1) {
tabLayout.visibility = View.GONE
}
}
}
fun onBackPressed() {
val selectedFragment = adapter?.getItem(binding?.tabLayout?.selectedTabPosition ?: 0)
as? BookmarkListRootFragment
public void onBackPressed() {
if (((BookmarkListRootFragment) (adapter.getItem(binding.tabLayout.getSelectedTabPosition())))
.backPressed()) {
// The event is handled internally by the adapter , no further action required.
return;
if (selectedFragment?.backPressed() == true) {
// The event is handled internally by the adapter, no further action required.
return
}
// Event is not handled by the adapter ( performed back action ) change action bar.
((BaseActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
// Event is not handled by the adapter (performed back action) change action bar.
(requireActivity() as BaseActivity).supportActionBar?.setDisplayHomeAsUpEnabled(false)
}
@Override
public void onDestroy() {
super.onDestroy();
binding = null;
override fun onDestroy() {
super.onDestroy()
binding = null
}
}

View file

@ -1,266 +1,192 @@
package fr.free.nrw.commons.bookmarks;
package fr.free.nrw.commons.bookmarks
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.bookmarks.category.BookmarkCategoriesFragment;
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsFragment;
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.category.GridViewAdapter;
import fr.free.nrw.commons.contributions.MainActivity;
import fr.free.nrw.commons.databinding.FragmentFeaturedRootBinding;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.media.MediaDetailPagerFragment;
import fr.free.nrw.commons.navtab.NavTab;
import java.util.ArrayList;
import java.util.Iterator;
import timber.log.Timber;
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.R
import fr.free.nrw.commons.bookmarks.category.BookmarkCategoriesFragment
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsFragment
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.category.GridViewAdapter
import fr.free.nrw.commons.contributions.MainActivity
import fr.free.nrw.commons.databinding.FragmentFeaturedRootBinding
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment
import fr.free.nrw.commons.media.MediaDetailPagerFragment
import fr.free.nrw.commons.navtab.NavTab
import timber.log.Timber
public class BookmarkListRootFragment extends CommonsDaggerSupportFragment implements
class BookmarkListRootFragment : CommonsDaggerSupportFragment,
FragmentManager.OnBackStackChangedListener,
MediaDetailPagerFragment.MediaDetailProvider,
AdapterView.OnItemClickListener, CategoryImagesCallback {
AdapterView.OnItemClickListener,
CategoryImagesCallback {
private MediaDetailPagerFragment mediaDetails;
//private BookmarkPicturesFragment bookmarkPicturesFragment;
private BookmarkLocationsFragment bookmarkLocationsFragment;
public Fragment listFragment;
private BookmarksPagerAdapter bookmarksPagerAdapter;
private var mediaDetails: MediaDetailPagerFragment? = null
private var bookmarkLocationsFragment: BookmarkLocationsFragment? = null
var listFragment: Fragment? = null
private var bookmarksPagerAdapter: BookmarksPagerAdapter? = null
FragmentFeaturedRootBinding binding;
private var binding: FragmentFeaturedRootBinding? = null
public BookmarkListRootFragment() {
//empty constructor necessary otherwise crashes on recreate
constructor() : super() {
// Empty constructor necessary otherwise crashes on recreate
}
public BookmarkListRootFragment(Bundle bundle, BookmarksPagerAdapter bookmarksPagerAdapter) {
String title = bundle.getString("categoryName");
int order = bundle.getInt("order");
final int orderItem = bundle.getInt("orderItem");
switch (order){
case 0: listFragment = new BookmarkPicturesFragment();
break;
case 1: listFragment = new BookmarkLocationsFragment();
break;
case 3: listFragment = new BookmarkCategoriesFragment();
break;
constructor(bundle: Bundle, bookmarksPagerAdapter: BookmarksPagerAdapter) : this() {
val title = bundle.getString("categoryName")
val order = bundle.getInt("order")
val orderItem = bundle.getInt("orderItem")
listFragment = when (order) {
0 -> BookmarkPicturesFragment()
1 -> BookmarkLocationsFragment()
3 -> BookmarkCategoriesFragment()
else -> null
}
if(orderItem == 2) {
listFragment = new BookmarkItemsFragment();
}
Bundle featuredArguments = new Bundle();
featuredArguments.putString("categoryName", title);
listFragment.setArguments(featuredArguments);
this.bookmarksPagerAdapter = bookmarksPagerAdapter;
if(orderItem == 2) {
listFragment = BookmarkItemsFragment()
}
val featuredArguments = Bundle().apply {
putString("categoryName", title)
}
listFragment?.arguments = featuredArguments
this.bookmarksPagerAdapter = bookmarksPagerAdapter
}
@Nullable
@Override
public View onCreateView(@NonNull final LayoutInflater inflater,
@Nullable final ViewGroup container,
@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = FragmentFeaturedRootBinding.inflate(inflater, container, false);
return binding.getRoot();
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreateView(inflater, container, savedInstanceState)
binding = FragmentFeaturedRootBinding.inflate(inflater, container, false)
return binding?.root
}
@Override
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (savedInstanceState == null) {
setFragment(listFragment, mediaDetails);
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();
fun setFragment(fragment: Fragment?, otherFragment: Fragment?) {
val transaction = childFragmentManager.beginTransaction()
when {
fragment?.isAdded == true && otherFragment != null -> {
transaction.hide(otherFragment).show(fragment)
}
fragment?.isAdded == true && otherFragment == null -> {
transaction.show(fragment)
}
fragment?.isAdded == false && otherFragment != null -> {
transaction.hide(otherFragment).add(R.id.explore_container, fragment)
}
fragment?.isAdded == false -> {
transaction.replace(R.id.explore_container, fragment)
}
}
transaction.addToBackStack("CONTRIBUTION_LIST_FRAGMENT_TAG").commit()
childFragmentManager.executePendingTransactions()
}
fun removeFragment(fragment: Fragment) {
childFragmentManager.beginTransaction().remove(fragment).commit()
childFragmentManager.executePendingTransactions()
}
override fun onMediaClicked(position: Int) {
Timber.tag("deneme8").d("on media clicked")
// container.setVisibility(View.VISIBLE);
// ((BookmarkFragment)getParentFragment()).tabLayout.setVisibility(View.GONE);
// mediaDetails = new MediaDetailPagerFragment(false, true, position);
// setFragment(mediaDetails, bookmarkPicturesFragment);
}
override fun getMediaAtPosition(i: Int): Media? {
return bookmarksPagerAdapter?.getMediaAdapter()?.let {
it.getItem(i) as? Media
}
}
public void removeFragment(Fragment fragment) {
getChildFragmentManager()
.beginTransaction()
.remove(fragment)
.commit();
getChildFragmentManager().executePendingTransactions();
override fun getTotalMediaCount(): Int {
return bookmarksPagerAdapter?.getMediaAdapter()?.count ?: 0
}
@Override
public void onAttach(final Context context) {
super.onAttach(context);
override fun getContributionStateAt(position: Int): Int? {
return null
}
@Override
public void onMediaClicked(int position) {
Timber.d("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);
override fun refreshNominatedMedia(index: Int) {
if (mediaDetails != null && listFragment?.isVisible == false) {
removeFragment(mediaDetails!!)
mediaDetails = MediaDetailPagerFragment.newInstance(false, true)
(parentFragment as? BookmarkFragment)?.setScroll(false)
setFragment(mediaDetails, listFragment)
mediaDetails?.showImage(index)
}
}
/**
* 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 fun viewPagerNotifyDataSetChanged() {
mediaDetails?.notifyDataSetChanged()
}
@Override
public Integer getContributionStateAt(int position) {
return null;
}
/**
* Reload media detail fragment once media is nominated
*
* @param index item position that has been nominated
*/
@Override
public void refreshNominatedMedia(int index) {
if (mediaDetails != null && !listFragment.isVisible()) {
removeFragment(mediaDetails);
mediaDetails = MediaDetailPagerFragment.newInstance(false, true);
((BookmarkFragment) getParentFragment()).setScroll(false);
setFragment(mediaDetails, listFragment);
mediaDetails.showImage(index);
}
}
/**
* 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() {
fun backPressed(): Boolean {
if (mediaDetails != null) {
mediaDetails.notifyDataSetChanged();
}
}
public boolean backPressed() {
//check mediaDetailPage fragment is not null then we check mediaDetail.is Visible or not to avoid NullPointerException
if (mediaDetails != null) {
if (mediaDetails.isVisible()) {
// todo add get list fragment
((BookmarkFragment) getParentFragment()).setupTabLayout();
ArrayList<Integer> removed = mediaDetails.getRemovedItems();
removeFragment(mediaDetails);
((BookmarkFragment) getParentFragment()).setScroll(true);
setFragment(listFragment, mediaDetails);
((MainActivity) getActivity()).showTabs();
if (listFragment instanceof BookmarkPicturesFragment) {
GridViewAdapter adapter = ((GridViewAdapter) ((BookmarkPicturesFragment) listFragment)
.getAdapter());
Iterator i = removed.iterator();
while (i.hasNext()) {
adapter.remove(adapter.getItem((int) i.next()));
if (mediaDetails!!.isVisible) {
(parentFragment as? BookmarkFragment)?.setupTabLayout()
val removed = mediaDetails!!.removedItems
removeFragment(mediaDetails!!)
(parentFragment as? BookmarkFragment)?.setScroll(true)
setFragment(listFragment, mediaDetails)
(activity as? MainActivity)?.showTabs()
if (listFragment is BookmarkPicturesFragment) {
val adapter = (listFragment as BookmarkPicturesFragment).getAdapter()
as GridViewAdapter
for (i in removed) {
adapter.remove(adapter.getItem(i))
}
mediaDetails.clearRemoved();
mediaDetails!!.clearRemoved()
}
} else {
moveToContributionsFragment();
moveToContributionsFragment()
}
} else {
moveToContributionsFragment();
moveToContributionsFragment()
}
// notify mediaDetails did not handled the backPressed further actions required.
return false;
return false
}
void moveToContributionsFragment() {
((MainActivity) getActivity()).setSelectedItemId(NavTab.CONTRIBUTIONS.code());
((MainActivity) getActivity()).showTabs();
private fun moveToContributionsFragment() {
(activity as? MainActivity)?.apply {
setSelectedItemId(NavTab.CONTRIBUTIONS.code())
showTabs()
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Timber.d("on media clicked");
binding.exploreContainer.setVisibility(View.VISIBLE);
((BookmarkFragment) getParentFragment()).binding.tabLayout.setVisibility(View.GONE);
mediaDetails = MediaDetailPagerFragment.newInstance(false, true);
((BookmarkFragment) getParentFragment()).setScroll(false);
setFragment(mediaDetails, listFragment);
mediaDetails.showImage(position);
override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
Timber.tag("deneme8").d("on media clicked")
binding?.exploreContainer?.visibility = View.VISIBLE
(parentFragment as? BookmarkFragment)?.binding?.tabLayout?.visibility = View.GONE
mediaDetails = MediaDetailPagerFragment.newInstance(false, true)
(parentFragment as? BookmarkFragment)?.setScroll(false)
setFragment(mediaDetails, listFragment)
mediaDetails?.showImage(position)
}
@Override
public void onBackStackChanged() {
override fun onBackStackChanged() {}
}
@Override
public void onDestroy() {
super.onDestroy();
binding = null;
override fun onDestroy() {
super.onDestroy()
binding = null
}
}

View file

@ -1,94 +1,104 @@
package fr.free.nrw.commons.bookmarks;
package fr.free.nrw.commons.bookmarks
import android.content.Context;
import android.os.Bundle;
import android.widget.ListAdapter;
import android.content.Context
import android.os.Bundle
import android.widget.ListAdapter
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import java.util.ArrayList;
import java.util.ArrayList
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesFragment;
import fr.free.nrw.commons.R
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesFragment
public class BookmarksPagerAdapter extends FragmentPagerAdapter {
private ArrayList<BookmarkPages> pages;
class BookmarksPagerAdapter(
fm: FragmentManager,
private val context: Context,
onlyPictures: Boolean
) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
/**
* Default Constructor
* @param fm
* @param context
* @param onlyPictures is true if the fragment requires only BookmarkPictureFragment
* (i.e. when no user is logged in).
*/
BookmarksPagerAdapter(FragmentManager fm, Context context,boolean onlyPictures) {
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(
new BookmarkListRootFragment(picturesBundle, this),
context.getString(R.string.title_page_bookmarks_pictures)));
if (!onlyPictures) {
// if onlyPictures is false we also add the location fragment.
Bundle locationBundle = new Bundle();
locationBundle.putString("categoryName",
context.getString(R.string.title_page_bookmarks_locations));
locationBundle.putInt("order", 1);
pages.add(new BookmarkPages(
new BookmarkListRootFragment(locationBundle, this),
context.getString(R.string.title_page_bookmarks_locations)));
private val pages: ArrayList<BookmarkPages> = ArrayList()
locationBundle.putInt("orderItem", 2);
pages.add(new BookmarkPages(
new BookmarkListRootFragment(locationBundle, this),
context.getString(R.string.title_page_bookmarks_items)));
init {
val picturesBundle = Bundle().apply {
putString("categoryName", context.getString(R.string.title_page_bookmarks_pictures))
putInt("order", 0)
}
final Bundle categoriesBundle = new Bundle();
categoriesBundle.putString("categoryName",
context.getString(R.string.title_page_bookmarks_categories));
categoriesBundle.putInt("order", 3);
pages.add(new BookmarkPages(
new BookmarkListRootFragment(categoriesBundle, this),
context.getString(R.string.title_page_bookmarks_categories)));
notifyDataSetChanged();
pages.add(
BookmarkPages(
BookmarkListRootFragment(picturesBundle, this),
context.getString(R.string.title_page_bookmarks_pictures)
)
)
if (!onlyPictures) {
// Add the location fragment if onlyPictures is false
val locationBundle = Bundle().apply {
putString("categoryName", context.getString(
R.string.title_page_bookmarks_locations
))
putInt("order", 1)
}
pages.add(
BookmarkPages(
BookmarkListRootFragment(locationBundle, this),
context.getString(R.string.title_page_bookmarks_locations)
)
)
locationBundle.putInt("orderItem", 2)
pages.add(
BookmarkPages(
BookmarkListRootFragment(locationBundle, this),
context.getString(R.string.title_page_bookmarks_items)
)
)
}
val categoriesBundle = Bundle().apply {
putString("categoryName", context.getString(R.string.title_page_bookmarks_categories))
putInt("order", 3)
}
pages.add(
BookmarkPages(
BookmarkListRootFragment(categoriesBundle, this),
context.getString(R.string.title_page_bookmarks_categories)
)
)
notifyDataSetChanged()
}
@Override
public Fragment getItem(int position) {
return pages.get(position).getPage();
override fun getItem(position: Int): Fragment {
return pages[position].page!!
}
@Override
public int getCount() {
return pages.size();
override fun getCount(): Int {
return pages.size
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return pages.get(position).getTitle();
override fun getPageTitle(position: Int): CharSequence? {
return pages[position].title
}
/**
* Return the Adapter used to display the picture gridview
* Return the adapter used to display the picture gridview
* @return adapter
*/
public ListAdapter getMediaAdapter() {
BookmarkPicturesFragment fragment = (BookmarkPicturesFragment)(((BookmarkListRootFragment)pages.get(0).getPage()).listFragment);
return fragment.getAdapter();
fun getMediaAdapter(): ListAdapter? {
val fragment = (pages[0].page as BookmarkListRootFragment).listFragment
as BookmarkPicturesFragment
return fragment.getAdapter()
}
/**
* Update the pictures list for the bookmark fragment
*/
public void requestPictureListUpdate() {
BookmarkPicturesFragment fragment = (BookmarkPicturesFragment)(((BookmarkListRootFragment)pages.get(0).getPage()).listFragment);
fragment.onResume();
fun requestPictureListUpdate() {
val fragment = (pages[0].page as BookmarkListRootFragment).listFragment as BookmarkPicturesFragment
fragment.onResume()
}
}

View file

@ -1,46 +1,42 @@
package fr.free.nrw.commons.bookmarks.pictures;
package fr.free.nrw.commons.bookmarks.pictures
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
// We can get uri using java.Net.Uri, but andoid implimentation is faster (but it's forgiving with handling exceptions though)
import android.net.Uri;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import android.content.ContentValues
import android.database.Cursor
import android.database.sqlite.SQLiteQueryBuilder
import android.net.Uri
import fr.free.nrw.commons.BuildConfig
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao.Table.COLUMN_MEDIA_NAME
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao.Table.TABLE_NAME
import fr.free.nrw.commons.data.DBOpenHelper
import fr.free.nrw.commons.di.CommonsDaggerContentProvider
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Inject;
import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.data.DBOpenHelper;
import fr.free.nrw.commons.di.CommonsDaggerContentProvider;
import timber.log.Timber;
import static fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao.Table.COLUMN_MEDIA_NAME;
import static fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao.Table.TABLE_NAME;
/**
* Handles private storage for Bookmark pictures
*/
public class BookmarkPicturesContentProvider extends CommonsDaggerContentProvider {
class BookmarkPicturesContentProvider : CommonsDaggerContentProvider() {
private static final String BASE_PATH = "bookmarks";
public static final Uri BASE_URI = Uri.parse("content://" + BuildConfig.BOOKMARK_AUTHORITY + "/" + BASE_PATH);
companion object {
private const val BASE_PATH = "bookmarks"
val BASE_URI: Uri = Uri
.parse("content://" + BuildConfig.BOOKMARK_AUTHORITY + "/" + BASE_PATH)
/**
* Append bookmark pictures name to the base uri
*/
public static Uri uriForName(String name) {
return Uri.parse(BASE_URI.toString() + "/" + name);
/**
* Append bookmark pictures name to the base uri
*/
fun uriForName(name: String): Uri {
return Uri.parse("$BASE_URI/$name")
}
}
@Inject
DBOpenHelper dbOpenHelper;
lateinit var dbOpenHelper: DBOpenHelper
@Override
public String getType(@NonNull Uri uri) {
return null;
override fun getType(uri: Uri): String? {
return null
}
/**
@ -51,70 +47,88 @@ public class BookmarkPicturesContentProvider extends CommonsDaggerContentProvide
* @param selectionArgs : the condition of Where clause
* @param sortOrder : ascending or descending
*/
@SuppressWarnings("ConstantConditions")
@Override
public Cursor query(@NonNull Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(TABLE_NAME);
override fun query(
uri: Uri,
projection: Array<out String>?,
selection: String?,
selectionArgs: Array<out String>?,
sortOrder: String?
): Cursor? {
val queryBuilder = SQLiteQueryBuilder().apply {
tables = TABLE_NAME
}
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
val db = dbOpenHelper.readableDatabase
val cursor = queryBuilder.query(
db,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
)
cursor.setNotificationUri(context?.contentResolver, uri)
return cursor;
return cursor
}
/**
* Handles the update query of local SQLite Database
* Handles the update query of local SQLite Database
* @param uri : contains the uri for bookmark pictures
* @param contentValues : new values to be entered to db
* @param selection : handles Where
* @param selectionArgs : the condition of Where clause
*/
@SuppressWarnings("ConstantConditions")
@Override
public int update(@NonNull Uri uri, ContentValues contentValues, String selection,
String[] selectionArgs) {
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
int rowsUpdated;
if (TextUtils.isEmpty(selection)) {
int id = Integer.valueOf(uri.getLastPathSegment());
rowsUpdated = sqlDB.update(TABLE_NAME,
contentValues,
COLUMN_MEDIA_NAME + " = ?",
new String[]{String.valueOf(id)});
override fun update(
uri: Uri,
contentValues: ContentValues?,
selection: String?,
selectionArgs: Array<out String>?
): Int {
val sqlDB = dbOpenHelper.writableDatabase
val rowsUpdated: Int
if (selection.isNullOrEmpty()) {
val id = uri.lastPathSegment?.toInt()
?: throw IllegalArgumentException("Invalid ID in URI")
rowsUpdated = sqlDB.update(
TABLE_NAME,
contentValues,
"$COLUMN_MEDIA_NAME = ?",
arrayOf(id.toString())
)
} else {
throw new IllegalArgumentException(
"Parameter `selection` should be empty when updating an ID");
throw IllegalArgumentException(
"Parameter `selection` should be empty when updating an ID"
)
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
context?.contentResolver?.notifyChange(uri, null)
return rowsUpdated
}
/**
* Handles the insertion of new bookmark pictures record to local SQLite Database
*/
@SuppressWarnings("ConstantConditions")
@Override
public Uri insert(@NonNull Uri uri, ContentValues contentValues) {
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
long id = sqlDB.insert(BookmarkPicturesDao.Table.TABLE_NAME, null, contentValues);
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(BASE_URI + "/" + id);
override fun insert(uri: Uri, contentValues: ContentValues?): Uri? {
val sqlDB = dbOpenHelper.writableDatabase
val id = sqlDB.insert(TABLE_NAME, null, contentValues)
context?.contentResolver?.notifyChange(uri, null)
return Uri.parse("$BASE_URI/$id")
}
@SuppressWarnings("ConstantConditions")
@Override
public int delete(@NonNull Uri uri, String s, String[] strings) {
int rows;
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
Timber.d("Deleting bookmark name %s", uri.getLastPathSegment());
rows = db.delete(TABLE_NAME,
"media_name = ?",
new String[]{uri.getLastPathSegment()}
);
getContext().getContentResolver().notifyChange(uri, null);
return rows;
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int {
val db = dbOpenHelper.readableDatabase
Timber.d("Deleting bookmark name %s", uri.lastPathSegment)
val rows = db.delete(
TABLE_NAME,
"media_name = ?",
arrayOf(uri.lastPathSegment)
)
context?.contentResolver?.notifyChange(uri, null)
return rows
}
}

View file

@ -1,63 +1,53 @@
package fr.free.nrw.commons.bookmarks.pictures;
package fr.free.nrw.commons.bookmarks.pictures
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.bookmarks.models.Bookmark
import fr.free.nrw.commons.media.MediaClient
import io.reactivex.Observable
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.bookmarks.models.Bookmark;
import fr.free.nrw.commons.media.MediaClient;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Single;
import io.reactivex.functions.Function;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class BookmarkPicturesController {
class BookmarkPicturesController @Inject constructor(
private val mediaClient: MediaClient,
private val bookmarkDao: BookmarkPicturesDao
) {
private final MediaClient mediaClient;
private final BookmarkPicturesDao bookmarkDao;
private List<Bookmark> currentBookmarks;
@Inject
public BookmarkPicturesController(MediaClient mediaClient, BookmarkPicturesDao bookmarkDao) {
this.mediaClient = mediaClient;
this.bookmarkDao = bookmarkDao;
currentBookmarks = new ArrayList<>();
}
private var currentBookmarks: List<Bookmark> = emptyList()
/**
* Loads the Media objects from the raw data stored in DB and the API.
* @return a list of bookmarked Media object
*/
Single<List<Media>> loadBookmarkedPictures() {
List<Bookmark> bookmarks = bookmarkDao.getAllBookmarks();
currentBookmarks = bookmarks;
fun loadBookmarkedPictures(): Single<List<Media>> {
val bookmarks = bookmarkDao.getAllBookmarks()
currentBookmarks = bookmarks
return Observable.fromIterable(bookmarks)
.flatMap((Function<Bookmark, ObservableSource<Media>>) this::getMediaFromBookmark)
.toList();
.flatMap { bookmark -> getMediaFromBookmark(bookmark) }
.toList()
}
private Observable<Media> getMediaFromBookmark(Bookmark bookmark) {
return mediaClient.getMedia(bookmark.getMediaName())
.toObservable()
.onErrorResumeNext(Observable.empty());
private fun getMediaFromBookmark(bookmark: Bookmark): Observable<Media> {
return mediaClient.getMedia(bookmark.mediaName)
.toObservable()
.onErrorResumeNext(Observable.empty())
}
/**
* Loads the Media objects from the raw data stored in DB and the API.
* @return a list of bookmarked Media object
*/
boolean needRefreshBookmarkedPictures() {
List<Bookmark> bookmarks = bookmarkDao.getAllBookmarks();
return bookmarks.size() != currentBookmarks.size();
fun needRefreshBookmarkedPictures(): Boolean {
val bookmarks = bookmarkDao.getAllBookmarks()
return bookmarks.size != currentBookmarks.size
}
/**
* Cancels the requests to the API and the DB
*/
void stop() {
//noop
fun stop() {
// noop
}
}

View file

@ -1,83 +1,67 @@
package fr.free.nrw.commons.bookmarks.pictures;
package fr.free.nrw.commons.bookmarks.pictures
import android.annotation.SuppressLint;
import android.content.ContentProviderClient;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.RemoteException;
import androidx.annotation.NonNull;
import android.annotation.SuppressLint
import android.content.ContentProviderClient
import android.content.ContentValues
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.os.RemoteException
import fr.free.nrw.commons.bookmarks.models.Bookmark
import javax.inject.Inject
import javax.inject.Named
import javax.inject.Provider
import javax.inject.Singleton
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;
import fr.free.nrw.commons.bookmarks.models.Bookmark;
import static fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesContentProvider.BASE_URI;
@Singleton
public class BookmarkPicturesDao {
private final Provider<ContentProviderClient> clientProvider;
@Inject
public BookmarkPicturesDao(@Named("bookmarks") Provider<ContentProviderClient> clientProvider) {
this.clientProvider = clientProvider;
}
class BookmarkPicturesDao @Inject constructor(
@Named("bookmarks") private val clientProvider: Provider<ContentProviderClient>
) {
/**
* Find all persisted pictures bookmarks on database
*
* @return list of bookmarks
*/
@NonNull
public List<Bookmark> getAllBookmarks() {
List<Bookmark> items = new ArrayList<>();
Cursor cursor = null;
ContentProviderClient db = clientProvider.get();
fun getAllBookmarks(): List<Bookmark> {
val items = mutableListOf<Bookmark>()
var cursor: Cursor? = null
val db = clientProvider.get()
try {
cursor = db.query(
BookmarkPicturesContentProvider.BASE_URI,
Table.ALL_FIELDS,
null,
new String[]{},
null);
while (cursor != null && cursor.moveToNext()) {
items.add(fromCursor(cursor));
BookmarkPicturesContentProvider.BASE_URI,
Table.ALL_FIELDS,
null,
emptyArray(),
null
)
while (cursor?.moveToNext() == true) {
items.add(fromCursor(cursor))
}
} catch (RemoteException e) {
throw new RuntimeException(e);
} catch (e: RemoteException) {
throw RuntimeException(e)
} finally {
if (cursor != null) {
cursor.close();
}
db.release();
cursor?.close()
db.close()
}
return items;
return items
}
/**
* Look for a bookmark in database and in order to insert or delete it
*
* @param bookmark : Bookmark object
* @return boolean : is bookmark now fav ?
* @return boolean : is bookmark now fav?
*/
public boolean updateBookmark(Bookmark bookmark) {
boolean bookmarkExists = findBookmark(bookmark);
fun updateBookmark(bookmark: Bookmark): Boolean {
val bookmarkExists = findBookmark(bookmark)
if (bookmarkExists) {
deleteBookmark(bookmark);
deleteBookmark(bookmark)
} else {
addBookmark(bookmark);
addBookmark(bookmark)
}
return !bookmarkExists;
return !bookmarkExists
}
/**
@ -85,14 +69,14 @@ public class BookmarkPicturesDao {
*
* @param bookmark : Bookmark to add
*/
private void addBookmark(Bookmark bookmark) {
ContentProviderClient db = clientProvider.get();
private fun addBookmark(bookmark: Bookmark) {
val db = clientProvider.get()
try {
db.insert(BASE_URI, toContentValues(bookmark));
} catch (RemoteException e) {
throw new RuntimeException(e);
db.insert(BookmarkPicturesContentProvider.BASE_URI, toContentValues(bookmark))
} catch (e: RemoteException) {
throw RuntimeException(e)
} finally {
db.release();
db.close()
}
}
@ -101,18 +85,19 @@ public class BookmarkPicturesDao {
*
* @param bookmark : Bookmark to delete
*/
private void deleteBookmark(Bookmark bookmark) {
ContentProviderClient db = clientProvider.get();
private fun deleteBookmark(bookmark: Bookmark) {
val db = clientProvider.get()
try {
if (bookmark.getContentUri() == null) {
throw new RuntimeException("tried to delete item with no content URI");
val contentUri = bookmark.contentUri
if (contentUri == null) {
throw RuntimeException("Tried to delete item with no content URI")
} else {
db.delete(bookmark.getContentUri(), null, null);
db.delete(contentUri, null, null)
}
} catch (RemoteException e) {
throw new RuntimeException(e);
} catch (e: RemoteException) {
throw RuntimeException(e)
} finally {
db.release();
db.close()
}
}
@ -120,107 +105,102 @@ public class BookmarkPicturesDao {
* Find a bookmark from database based on its name
*
* @param bookmark : Bookmark to find
* @return boolean : is bookmark in database ?
* @return boolean : is bookmark in database?
*/
public boolean findBookmark(Bookmark bookmark) {
if (bookmark == null) {//Avoiding NPE's
return false;
fun findBookmark(bookmark: Bookmark?): Boolean {
if (bookmark == null) {
// Avoiding NPEs
return false
}
Cursor cursor = null;
ContentProviderClient db = clientProvider.get();
var cursor: Cursor? = null
val db = clientProvider.get()
try {
cursor = db.query(
BookmarkPicturesContentProvider.BASE_URI,
Table.ALL_FIELDS,
Table.COLUMN_MEDIA_NAME + "=?",
new String[]{bookmark.getMediaName()},
null);
if (cursor != null && cursor.moveToFirst()) {
return true;
BookmarkPicturesContentProvider.BASE_URI,
Table.ALL_FIELDS,
"${Table.COLUMN_MEDIA_NAME} = ?",
arrayOf(bookmark.mediaName),
null
)
if (cursor?.moveToFirst() == true) {
return true
}
} catch (RemoteException e) {
} catch (e: RemoteException) {
// This feels lazy, but to hell with checked exceptions. :)
throw new RuntimeException(e);
throw RuntimeException(e)
} finally {
if (cursor != null) {
cursor.close();
}
db.release();
cursor?.close()
db.close()
}
return false;
return false
}
@SuppressLint("Range")
@NonNull
Bookmark fromCursor(Cursor cursor) {
String fileName = cursor.getString(cursor.getColumnIndex(Table.COLUMN_MEDIA_NAME));
return new Bookmark(
fileName,
cursor.getString(cursor.getColumnIndex(Table.COLUMN_CREATOR)),
BookmarkPicturesContentProvider.uriForName(fileName)
);
private fun fromCursor(cursor: Cursor): Bookmark {
val fileName = cursor.getString(cursor.getColumnIndex(Table.COLUMN_MEDIA_NAME))
return Bookmark(
fileName,
cursor.getString(cursor.getColumnIndex(Table.COLUMN_CREATOR)),
BookmarkPicturesContentProvider.uriForName(fileName)
)
}
private ContentValues toContentValues(Bookmark bookmark) {
ContentValues cv = new ContentValues();
cv.put(BookmarkPicturesDao.Table.COLUMN_MEDIA_NAME, bookmark.getMediaName());
cv.put(BookmarkPicturesDao.Table.COLUMN_CREATOR, bookmark.getMediaCreator());
return cv;
private fun toContentValues(bookmark: Bookmark): ContentValues {
return ContentValues().apply {
put(Table.COLUMN_MEDIA_NAME, bookmark.mediaName)
put(Table.COLUMN_CREATOR, bookmark.mediaCreator)
}
}
object Table {
const val TABLE_NAME = "bookmarks"
public static class Table {
public static final String TABLE_NAME = "bookmarks";
public static final String COLUMN_MEDIA_NAME = "media_name";
public static final String COLUMN_CREATOR = "media_creator";
const val COLUMN_MEDIA_NAME = "media_name"
const val COLUMN_CREATOR = "media_creator"
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
public static final String[] ALL_FIELDS = {
COLUMN_MEDIA_NAME,
COLUMN_CREATOR
};
val ALL_FIELDS = arrayOf(
COLUMN_MEDIA_NAME,
COLUMN_CREATOR
)
public static final String DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS " + TABLE_NAME;
const val DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS $TABLE_NAME"
public static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
+ COLUMN_MEDIA_NAME + " STRING PRIMARY KEY,"
+ COLUMN_CREATOR + " STRING"
+ ");";
const val CREATE_TABLE_STATEMENT = """
CREATE TABLE $TABLE_NAME (
$COLUMN_MEDIA_NAME STRING PRIMARY KEY,
$COLUMN_CREATOR STRING
);
"""
public static void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_STATEMENT);
fun onCreate(db: SQLiteDatabase) {
db.execSQL(CREATE_TABLE_STATEMENT)
}
public static void onDelete(SQLiteDatabase db) {
db.execSQL(DROP_TABLE_STATEMENT);
onCreate(db);
fun onDelete(db: SQLiteDatabase) {
db.execSQL(DROP_TABLE_STATEMENT)
onCreate(db)
}
public static void onUpdate(SQLiteDatabase db, int from, int to) {
if (from == to) {
return;
}
fun onUpdate(db: SQLiteDatabase, from: Int, to: Int) {
if (from == to) return
if (from < 7) {
// doesn't exist yet
from++;
onUpdate(db, from, to);
return;
onUpdate(db, from + 1, to)
return
}
if (from == 7) {
// table added in version 8
onCreate(db);
from++;
onUpdate(db, from, to);
return;
onCreate(db)
onUpdate(db, from + 1, to)
return
}
if (from == 8) {
from++;
onUpdate(db, from, to);
return;
onUpdate(db, from + 1, to)
}
}
}

View file

@ -1,89 +1,82 @@
package fr.free.nrw.commons.bookmarks.pictures;
package fr.free.nrw.commons.bookmarks.pictures
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ListAdapter
import dagger.android.support.DaggerFragment
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.R
import fr.free.nrw.commons.bookmarks.BookmarkListRootFragment
import fr.free.nrw.commons.category.GridViewAdapter
import fr.free.nrw.commons.databinding.FragmentBookmarksPicturesBinding
import fr.free.nrw.commons.utils.NetworkUtils
import fr.free.nrw.commons.utils.ViewUtil
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import timber.log.Timber
import javax.inject.Inject
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import dagger.android.support.DaggerFragment;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.bookmarks.BookmarkListRootFragment;
import fr.free.nrw.commons.category.GridViewAdapter;
import fr.free.nrw.commons.databinding.FragmentBookmarksPicturesBinding;
import fr.free.nrw.commons.utils.NetworkUtils;
import fr.free.nrw.commons.utils.ViewUtil;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import java.util.List;
import javax.inject.Inject;
import timber.log.Timber;
public class BookmarkPicturesFragment extends DaggerFragment {
class BookmarkPicturesFragment : DaggerFragment() {
private GridViewAdapter gridAdapter;
private CompositeDisposable compositeDisposable = new CompositeDisposable();
private var gridAdapter: GridViewAdapter? = null
private val compositeDisposable = CompositeDisposable()
private var binding: FragmentBookmarksPicturesBinding? = null
private FragmentBookmarksPicturesBinding binding;
@Inject
BookmarkPicturesController controller;
lateinit var controller: BookmarkPicturesController
/**
* Create an instance of the fragment with the right bundle parameters
* @return an instance of the fragment
*/
public static BookmarkPicturesFragment newInstance() {
return new BookmarkPicturesFragment();
companion object {
fun newInstance(): BookmarkPicturesFragment {
return BookmarkPicturesFragment()
}
}
@Override
public View onCreateView(
@NonNull LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState
) {
binding = FragmentBookmarksPicturesBinding.inflate(inflater, container, false);
return binding.getRoot();
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentBookmarksPicturesBinding.inflate(inflater, container, false)
return binding?.root
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.bookmarkedPicturesList.setOnItemClickListener((AdapterView.OnItemClickListener) getParentFragment());
initList();
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding?.bookmarkedPicturesList?.onItemClickListener = parentFragment as? AdapterView.OnItemClickListener
initList()
}
@Override
public void onStop() {
super.onStop();
controller.stop();
override fun onStop() {
super.onStop()
controller.stop()
}
@Override
public void onDestroy() {
super.onDestroy();
compositeDisposable.clear();
binding = null;
override fun onDestroy() {
super.onDestroy()
compositeDisposable.clear()
binding = null
}
@Override
public void onResume() {
super.onResume();
override fun onResume() {
super.onResume()
if (controller.needRefreshBookmarkedPictures()) {
binding.bookmarkedPicturesList.setVisibility(GONE);
if (gridAdapter != null) {
gridAdapter.clear();
((BookmarkListRootFragment)getParentFragment()).viewPagerNotifyDataSetChanged();
binding?.bookmarkedPicturesList?.visibility = View.GONE
gridAdapter?.let {
it.clear()
(parentFragment as? BookmarkListRootFragment)?.viewPagerNotifyDataSetChanged()
}
initList();
initList()
}
}
@ -92,31 +85,37 @@ public class BookmarkPicturesFragment extends DaggerFragment {
* the recycler view with bookmarked pictures
*/
@SuppressLint("CheckResult")
private void initList() {
if (!NetworkUtils.isInternetConnectionEstablished(getContext())) {
handleNoInternet();
return;
private fun initList() {
if (!NetworkUtils.isInternetConnectionEstablished(requireContext())) {
handleNoInternet()
return
}
binding.loadingImagesProgressBar.setVisibility(VISIBLE);
binding.statusMessage.setVisibility(GONE);
binding?.apply {
loadingImagesProgressBar.visibility = View.VISIBLE
statusMessage.visibility = View.GONE
}
compositeDisposable.add(controller.loadBookmarkedPictures()
compositeDisposable.add(
controller.loadBookmarkedPictures()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::handleSuccess, this::handleError));
.subscribe(::handleSuccess, ::handleError)
)
}
/**
* Handles the UI updates for no internet scenario
*/
private void handleNoInternet() {
binding.loadingImagesProgressBar.setVisibility(GONE);
if (gridAdapter == null || gridAdapter.isEmpty()) {
binding.statusMessage.setVisibility(VISIBLE);
binding.statusMessage.setText(getString(R.string.no_internet));
} else {
ViewUtil.showShortSnackbar(binding.parentLayout, R.string.no_internet);
private fun handleNoInternet() {
binding?.apply {
loadingImagesProgressBar.visibility = View.GONE
if (gridAdapter == null || gridAdapter?.isEmpty == true) {
statusMessage.visibility = View.VISIBLE
statusMessage.text = getString(R.string.no_internet)
} else {
ViewUtil.showShortSnackbar(parentLayout, R.string.no_internet)
}
}
}
@ -124,39 +123,43 @@ public class BookmarkPicturesFragment extends DaggerFragment {
* Logs and handles API error scenario
* @param throwable
*/
private void handleError(Throwable throwable) {
Timber.e(throwable, "Error occurred while loading images inside a category");
try{
ViewUtil.showShortSnackbar(binding.getRoot(), R.string.error_loading_images);
initErrorView();
}catch (Exception e){
e.printStackTrace();
private fun handleError(throwable: Throwable) {
Timber.e(throwable, "Error occurred while loading images inside a category")
try {
ViewUtil.showShortSnackbar(binding?.root ?: return, R.string.error_loading_images)
initErrorView()
} catch (e: Exception) {
e.printStackTrace()
}
}
/**
* Handles the UI updates for a error scenario
* Handles the UI updates for an error scenario
*/
private void initErrorView() {
binding.loadingImagesProgressBar.setVisibility(GONE);
if (gridAdapter == null || gridAdapter.isEmpty()) {
binding.statusMessage.setVisibility(VISIBLE);
binding.statusMessage.setText(getString(R.string.no_images_found));
} else {
binding.statusMessage.setVisibility(GONE);
private fun initErrorView() {
binding?.apply {
loadingImagesProgressBar.visibility = View.GONE
if (gridAdapter == null || gridAdapter?.isEmpty == true) {
statusMessage.visibility = View.VISIBLE
statusMessage.text = getString(R.string.no_images_found)
} else {
statusMessage.visibility = View.GONE
}
}
}
/**
* Handles the UI updates when there is no bookmarks
* Handles the UI updates when there are no bookmarks
*/
private void initEmptyBookmarkListView() {
binding.loadingImagesProgressBar.setVisibility(GONE);
if (gridAdapter == null || gridAdapter.isEmpty()) {
binding.statusMessage.setVisibility(VISIBLE);
binding.statusMessage.setText(getString(R.string.bookmark_empty));
} else {
binding.statusMessage.setVisibility(GONE);
private fun initEmptyBookmarkListView() {
binding?.apply {
loadingImagesProgressBar.visibility = View.GONE
if (gridAdapter == null || gridAdapter?.isEmpty == true) {
statusMessage.visibility = View.VISIBLE
statusMessage.text = getString(R.string.bookmark_empty)
} else {
statusMessage.visibility = View.GONE
}
}
}
@ -165,54 +168,57 @@ public class BookmarkPicturesFragment extends DaggerFragment {
* On first load, it initializes the grid view. On subsequent loads, it adds items to the adapter
* @param collection List of new Media to be displayed
*/
private void handleSuccess(List<Media> collection) {
private fun handleSuccess(collection: List<Media>?) {
if (collection == null) {
initErrorView();
return;
initErrorView()
return
}
if (collection.isEmpty()) {
initEmptyBookmarkListView();
return;
initEmptyBookmarkListView()
return
}
if (gridAdapter == null) {
setAdapter(collection);
setAdapter(collection)
} else {
if (gridAdapter.containsAll(collection)) {
binding.loadingImagesProgressBar.setVisibility(GONE);
binding.statusMessage.setVisibility(GONE);
binding.bookmarkedPicturesList.setVisibility(VISIBLE);
binding.bookmarkedPicturesList.setAdapter(gridAdapter);
return;
if (gridAdapter?.containsAll(collection) == true) {
binding?.apply {
loadingImagesProgressBar.visibility = View.GONE
statusMessage.visibility = View.GONE
bookmarkedPicturesList.visibility = View.VISIBLE
bookmarkedPicturesList.adapter = gridAdapter
}
return
}
gridAdapter.addItems(collection);
((BookmarkListRootFragment) getParentFragment()).viewPagerNotifyDataSetChanged();
gridAdapter?.addItems(collection)
(parentFragment as? BookmarkListRootFragment)?.viewPagerNotifyDataSetChanged()
}
binding?.apply {
loadingImagesProgressBar.visibility = View.GONE
statusMessage.visibility = View.GONE
bookmarkedPicturesList.visibility = View.VISIBLE
}
binding.loadingImagesProgressBar.setVisibility(GONE);
binding.statusMessage.setVisibility(GONE);
binding.bookmarkedPicturesList.setVisibility(VISIBLE);
}
/**
* Initializes the adapter with a list of Media objects
* @param mediaList List of new Media to be displayed
*/
private void setAdapter(List<Media> mediaList) {
gridAdapter = new GridViewAdapter(
this.getContext(),
R.layout.layout_category_images,
mediaList
);
binding.bookmarkedPicturesList.setAdapter(gridAdapter);
private fun setAdapter(mediaList: List<Media>) {
gridAdapter = GridViewAdapter(
requireContext(),
R.layout.layout_category_images,
mediaList.toMutableList()
)
binding?.bookmarkedPicturesList?.adapter = gridAdapter
}
/**
* It return an instance of gridView adapter which helps in extracting media details
* It returns an instance of gridView adapter which helps in extracting media details
* used by the gridView
* @return GridView Adapter
* @return GridView Adapter
*/
public ListAdapter getAdapter() {
return binding.bookmarkedPicturesList.getAdapter();
fun getAdapter(): ListAdapter? {
return binding?.bookmarkedPicturesList?.adapter
}
}

View file

@ -344,7 +344,7 @@ public class MainActivity extends BaseActivity
loadFragment(ExploreFragment.newInstance(), false);
} else if (fragmentName.equals(ActiveFragment.BOOKMARK.name())) {
setTitle(getString(R.string.bookmarks));
loadFragment(BookmarkFragment.newInstance(), false);
loadFragment(BookmarkFragment.Companion.newInstance(), false);
}
}

View file

@ -422,7 +422,7 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
bookmark = new Bookmark(
m.getFilename(),
m.getAuthor(),
BookmarkPicturesContentProvider.uriForName(m.getFilename())
BookmarkPicturesContentProvider.Companion.uriForName(m.getFilename())
);
updateBookmarkState(menu.findItem(R.id.menu_bookmark_current_image));
final Integer contributionState = provider.getContributionStateAt(position);