diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 93c779e23..4eb55986c 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -95,7 +95,7 @@ complexity: excludeStringsWithLessThan5Characters: true ignoreStringsRegex: '$^' TooManyFunctions: - active: true + active: false excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" thresholdInFiles: 11 thresholdInClasses: 11 diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/bookmark/BookmarksActivity.java b/core/src/main/java/org/kiwix/kiwixmobile/core/bookmark/BookmarksActivity.java deleted file mode 100644 index 4a486a8c4..000000000 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/bookmark/BookmarksActivity.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Kiwix Android - * Copyright (c) 2019 Kiwix - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package org.kiwix.kiwixmobile.core.bookmark; - -import android.content.Intent; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.ImageView; -import android.widget.Switch; -import android.widget.TextView; -import android.widget.Toast; -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.view.ActionMode; -import androidx.appcompat.widget.SearchView; -import androidx.appcompat.widget.Toolbar; -import androidx.core.content.ContextCompat; -import androidx.recyclerview.widget.RecyclerView; -import butterknife.BindView; -import com.google.android.material.snackbar.Snackbar; -import java.util.ArrayList; -import java.util.List; -import javax.inject.Inject; -import kotlin.Unit; -import kotlin.jvm.functions.Function0; -import org.kiwix.kiwixmobile.core.Intents; -import org.kiwix.kiwixmobile.core.R; -import org.kiwix.kiwixmobile.core.R2; -import org.kiwix.kiwixmobile.core.base.BaseActivity; -import org.kiwix.kiwixmobile.core.di.components.CoreComponent; -import org.kiwix.kiwixmobile.core.extensions.ImageViewExtensionsKt; -import org.kiwix.kiwixmobile.core.main.CoreMainActivity; -import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer; -import org.kiwix.kiwixmobile.core.utils.DialogShower; -import org.kiwix.kiwixmobile.core.utils.KiwixDialog; - -import static org.kiwix.kiwixmobile.core.utils.ConstantsKt.EXTRA_CHOSE_X_FILE; -import static org.kiwix.kiwixmobile.core.utils.ConstantsKt.EXTRA_CHOSE_X_TITLE; -import static org.kiwix.kiwixmobile.core.utils.ConstantsKt.EXTRA_CHOSE_X_URL; - -public class BookmarksActivity extends BaseActivity implements BookmarksContract.View, - BookmarksAdapter.OnItemClickListener { - - private final List bookmarksList = new ArrayList<>(); - private final List allBookmarks = new ArrayList<>(); - private final List deleteList = new ArrayList<>(); - - @BindView(R2.id.toolbar) - Toolbar toolbar; - @BindView(R2.id.recycler_view) - RecyclerView recyclerView; - @BindView(R2.id.no_bookmarks) - TextView noBookmarks; - @BindView(R2.id.bookmarks_switch) - Switch bookmarksSwitch; - @Inject - BookmarksContract.Presenter presenter; - @Inject - ZimReaderContainer zimReaderContainer; - @Inject - DialogShower dialogShower; - - private boolean refreshAdapter = true; - private BookmarksAdapter bookmarksAdapter; - private ActionMode actionMode; - - private final ActionMode.Callback actionModeCallback = new ActionMode.Callback() { - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - mode.getMenuInflater().inflate(R.menu.menu_context_delete, menu); - bookmarksSwitch.setEnabled(false); - return true; - } - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return false; - } - - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - refreshAdapter = false; - if (item.getItemId() == R.id.menu_context_delete) { - dialogShower.show(KiwixDialog.DeleteBookmarks.INSTANCE,(Function0)() ->{ - allBookmarks.removeAll(deleteList); - for (BookmarkItem bookmark : deleteList) { - int position = bookmarksList.indexOf(bookmark); - bookmarksList.remove(bookmark); - bookmarksAdapter.notifyItemRemoved(position); - bookmarksAdapter.notifyItemRangeChanged(position, bookmarksAdapter.getItemCount()); - } - presenter.deleteBookmarks(new ArrayList<>(deleteList)); - mode.finish(); - return Unit.INSTANCE; - }); - return true; - } - return false; - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - if (deleteList.size() != 0) { - deleteList.clear(); - } - actionMode = null; - if (refreshAdapter) { - bookmarksAdapter.notifyDataSetChanged(); - } - bookmarksSwitch.setEnabled(true); - } - }; - - @Override protected void injection(CoreComponent coreComponent) { - coreComponent.activityComponentBuilder().activity(this).build().inject(this); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - presenter.attachView(this); - setContentView(R.layout.activity_bookmarks); - setSupportActionBar(toolbar); - - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - actionBar.setTitle(R.string.bookmarks); - } - - setupBookmarksAdapter(); - recyclerView.setAdapter(bookmarksAdapter); - - bookmarksSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - sharedPreferenceUtil.setShowBookmarksCurrentBook(!isChecked); - presenter.loadBookmarks(sharedPreferenceUtil.getShowBookmarksCurrentBook()); - }); - bookmarksSwitch.setChecked(!sharedPreferenceUtil.getShowBookmarksCurrentBook()); - } - - private void setupBookmarksAdapter() { - bookmarksAdapter = new BookmarksAdapter(bookmarksList, deleteList, this); - bookmarksAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { - @Override public void onChanged() { - super.onChanged(); - noBookmarks.setVisibility(bookmarksList.size() == 0 ? View.VISIBLE : View.GONE); - } - }); - } - - @Override - protected void onResume() { - super.onResume(); - presenter.loadBookmarks(sharedPreferenceUtil.getShowBookmarksCurrentBook()); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - - getMenuInflater().inflate(R.menu.menu_bookmarks, menu); - - SearchView search = (SearchView) menu.findItem(R.id.menu_bookmarks_search).getActionView(); - search.setQueryHint(getString(R.string.search_bookmarks)); - search.setOnQueryTextListener(new SearchView.OnQueryTextListener() { - @Override - public boolean onQueryTextSubmit(String query) { - return false; - } - - @Override - public boolean onQueryTextChange(String newText) { - bookmarksList.clear(); - bookmarksList.addAll(allBookmarks); - if ("".equals(newText)) { - bookmarksAdapter.notifyDataSetChanged(); - return true; - } - presenter.filterBookmarks(bookmarksList, newText); - return true; - } - }); - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - int itemId = item.getItemId(); - if (itemId == android.R.id.home) { - onBackPressed(); - return true; - } else if (itemId == R.id.menu_bookmarks_clear) { - dialogShower.show(KiwixDialog.DeleteBookmarks.INSTANCE, (Function0) () -> { - presenter.deleteBookmarks(new ArrayList<>(allBookmarks)); - allBookmarks.clear(); - bookmarksList.clear(); - bookmarksAdapter.notifyDataSetChanged(); - Snackbar.make(noBookmarks, R.string.all_bookmarks_cleared, Snackbar.LENGTH_SHORT).show(); - return Unit.INSTANCE; - }); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - protected void onDestroy() { - presenter.detachView(); - super.onDestroy(); - } - - @Override - public void updateBookmarksList(List bookmarksList) { - allBookmarks.clear(); - allBookmarks.addAll(bookmarksList); - notifyBookmarksListFiltered(bookmarksList); - } - - @Override - public void notifyBookmarksListFiltered(List bookmarksList) { - this.bookmarksList.clear(); - this.bookmarksList.addAll(bookmarksList); - bookmarksAdapter.notifyDataSetChanged(); - } - - @Override - public void onItemClick(ImageView favicon, BookmarkItem bookmark) { - if (actionMode == null) { - Intent intent = Intents.internal(CoreMainActivity.class); - if ("null".equals(bookmark.getBookmarkUrl())) { - intent.putExtra(EXTRA_CHOSE_X_TITLE, bookmark.getBookmarkTitle()); - } else { - intent.putExtra(EXTRA_CHOSE_X_URL, bookmark.getBookmarkUrl()); - } - if (bookmark.getZimFilePath() != null && !bookmark.getZimFilePath() - .equals(zimReaderContainer.getZimCanonicalPath())) { - intent.putExtra(EXTRA_CHOSE_X_FILE, bookmark.getZimFilePath()); - } - setResult(RESULT_OK, intent); - finish(); - } else { - toggleSelection(favicon, bookmark); - } - } - - @Override - public boolean onItemLongClick(ImageView favicon, BookmarkItem bookmark) { - if (actionMode != null) { - return false; - } - actionMode = startSupportActionMode(actionModeCallback); - refreshAdapter = true; - toggleSelection(favicon, bookmark); - return true; - } - - private void toggleSelection(ImageView favicon, BookmarkItem bookmark) { - if (deleteList.remove(bookmark)) { - ImageViewExtensionsKt.setBitmapFromString(favicon, bookmark.getFavicon()); - } else { - favicon.setImageDrawable( - ContextCompat.getDrawable(this, R.drawable.ic_check_circle_blue_24dp)); - deleteList.add(bookmark); - } - actionMode.setTitle(getString(R.string.selected_items, deleteList.size())); - - if (deleteList.size() == 0) { - actionMode.finish(); - } - } -} diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/bookmark/BookmarksActivity.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/bookmark/BookmarksActivity.kt new file mode 100644 index 000000000..eb4d28f4b --- /dev/null +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/bookmark/BookmarksActivity.kt @@ -0,0 +1,247 @@ +/* + * Kiwix Android + * Copyright (c) 2019 Kiwix + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package org.kiwix.kiwixmobile.core.bookmark + +import android.app.Activity +import android.os.Bundle +import android.view.Menu +import android.view.MenuItem +import android.view.View +import android.widget.CompoundButton +import android.widget.ImageView +import androidx.appcompat.view.ActionMode +import androidx.appcompat.widget.SearchView +import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver +import kotlinx.android.synthetic.main.activity_bookmarks.bookmarks_switch +import kotlinx.android.synthetic.main.activity_bookmarks.no_bookmarks +import kotlinx.android.synthetic.main.activity_bookmarks.recycler_view +import kotlinx.android.synthetic.main.layout_toolbar.toolbar +import org.kiwix.kiwixmobile.core.Intents.internal +import org.kiwix.kiwixmobile.core.R +import org.kiwix.kiwixmobile.core.base.BaseActivity +import org.kiwix.kiwixmobile.core.di.components.CoreComponent +import org.kiwix.kiwixmobile.core.downloader.model.Base64String +import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.coreActivityComponent +import org.kiwix.kiwixmobile.core.extensions.setBitmap +import org.kiwix.kiwixmobile.core.extensions.setImageDrawableCompat +import org.kiwix.kiwixmobile.core.extensions.snack +import org.kiwix.kiwixmobile.core.main.CoreMainActivity +import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer +import org.kiwix.kiwixmobile.core.utils.DialogShower +import org.kiwix.kiwixmobile.core.utils.EXTRA_CHOSE_X_FILE +import org.kiwix.kiwixmobile.core.utils.EXTRA_CHOSE_X_TITLE +import org.kiwix.kiwixmobile.core.utils.EXTRA_CHOSE_X_URL +import org.kiwix.kiwixmobile.core.utils.KiwixDialog +import org.kiwix.kiwixmobile.core.utils.SimpleTextListener +import java.util.ArrayList +import javax.inject.Inject + +class BookmarksActivity : BaseActivity(), + BookmarksContract.View, BookmarksAdapter.OnItemClickListener { + private val bookmarksList: MutableList = ArrayList() + private val allBookmarks: MutableList = ArrayList() + private val deleteList: MutableList = ArrayList() + private val activityComponent by lazy { coreActivityComponent } + + @Inject + lateinit var presenter: BookmarksContract.Presenter + + @Inject + lateinit var zimReaderContainer: ZimReaderContainer + + @Inject + lateinit var dialogShower: DialogShower + private var refreshAdapter = true + private lateinit var bookmarksAdapter: BookmarksAdapter + private var actionMode: ActionMode? = null + private val actionModeCallback: ActionMode.Callback = + object : ActionMode.Callback { + override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { + mode.menuInflater.inflate(R.menu.menu_context_delete, menu) + bookmarks_switch.isEnabled = false + return true + } + + override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean = false + + override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { + refreshAdapter = false + if (item.itemId == R.id.menu_context_delete) { + dialogShower.show(KiwixDialog.DeleteBookmarks, { + allBookmarks.removeAll(deleteList) + for (bookmark in deleteList) { + val position = bookmarksList.indexOf(bookmark) + bookmarksList.remove(bookmark) + bookmarksAdapter.notifyItemRemoved(position) + bookmarksAdapter.notifyItemRangeChanged(position, bookmarksAdapter.itemCount) + } + presenter.deleteBookmarks(ArrayList(deleteList)) + mode.finish() + }) + return true + } + return false + } + + override fun onDestroyActionMode(mode: ActionMode) { + if (deleteList.size != 0) { + deleteList.clear() + } + actionMode = null + if (refreshAdapter) { + bookmarksAdapter.notifyDataSetChanged() + } + bookmarks_switch!!.isEnabled = true + } + } + + override fun injection(coreComponent: CoreComponent) { + activityComponent.inject(this) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + presenter.attachView(this) + setContentView(R.layout.activity_bookmarks) + setSupportActionBar(toolbar) + val actionBar = supportActionBar + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true) + actionBar.setTitle(R.string.bookmarks) + } + setupBookmarksAdapter() + recycler_view.adapter = bookmarksAdapter + bookmarks_switch.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean -> + sharedPreferenceUtil.showBookmarksCurrentBook = !isChecked + presenter.loadBookmarks(sharedPreferenceUtil.showBookmarksCurrentBook) + } + bookmarks_switch.isChecked = !sharedPreferenceUtil.showBookmarksCurrentBook + } + + private fun setupBookmarksAdapter() { + bookmarksAdapter = BookmarksAdapter(bookmarksList, deleteList, this) + bookmarksAdapter.registerAdapterDataObserver(object : AdapterDataObserver() { + override fun onChanged() { + super.onChanged() + no_bookmarks.visibility = if (bookmarksList.size == 0) View.VISIBLE else View.GONE + } + }) + } + + override fun onResume() { + super.onResume() + presenter.loadBookmarks(sharedPreferenceUtil.showBookmarksCurrentBook) + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + menuInflater.inflate(R.menu.menu_bookmarks, menu) + val search = menu.findItem(R.id.menu_bookmarks_search) + .actionView as SearchView + search.queryHint = getString(R.string.search_bookmarks) + search.setOnQueryTextListener(SimpleTextListener { + bookmarksList.clear() + bookmarksList.addAll(allBookmarks) + if ("" == it) { + bookmarksAdapter.notifyDataSetChanged() + } + presenter.filterBookmarks(bookmarksList, it) + }) + return true + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + android.R.id.home -> { + onBackPressed() + } + R.id.menu_bookmarks_clear -> { + dialogShower.show(KiwixDialog.DeleteBookmarks, { + presenter.deleteBookmarks(ArrayList(allBookmarks)) + allBookmarks.clear() + bookmarksList.clear() + bookmarksAdapter.notifyDataSetChanged() + no_bookmarks.snack(R.string.all_bookmarks_cleared) + }) + } + else -> return super.onOptionsItemSelected(item) + } + return true + } + + override fun onDestroy() { + presenter.detachView() + super.onDestroy() + } + + override fun updateBookmarksList(bookmarksList: List) { + allBookmarks.clear() + allBookmarks.addAll(bookmarksList) + notifyBookmarksListFiltered(bookmarksList) + } + + override fun notifyBookmarksListFiltered(bookmarksList: List) { + this.bookmarksList.clear() + this.bookmarksList.addAll(bookmarksList) + bookmarksAdapter.notifyDataSetChanged() + } + + override fun onItemClick(favicon: ImageView, bookmark: BookmarkItem) { + if (actionMode == null) { + val intent = internal( + CoreMainActivity::class.java + ) + if ("null" == bookmark.bookmarkUrl) { + intent.putExtra(EXTRA_CHOSE_X_TITLE, bookmark.bookmarkTitle) + } else { + intent.putExtra(EXTRA_CHOSE_X_URL, bookmark.bookmarkUrl) + } + if (bookmark.zimFilePath != null && + bookmark.zimFilePath != zimReaderContainer.zimCanonicalPath + ) { + intent.putExtra(EXTRA_CHOSE_X_FILE, bookmark.zimFilePath) + } + setResult(Activity.RESULT_OK, intent) + finish() + } else { + toggleSelection(favicon, bookmark) + } + } + + override fun onItemLongClick(favicon: ImageView, bookmark: BookmarkItem): Boolean { + if (actionMode != null) { + return false + } + actionMode = startSupportActionMode(actionModeCallback) + refreshAdapter = true + toggleSelection(favicon, bookmark) + return true + } + + private fun toggleSelection(favicon: ImageView, bookmark: BookmarkItem) { + if (deleteList.remove(bookmark)) { + favicon.setBitmap(Base64String(bookmark.favicon)) + } else { + favicon.setImageDrawableCompat(R.drawable.ic_check_circle_blue_24dp) + deleteList.add(bookmark) + } + actionMode!!.title = getString(R.string.selected_items, deleteList.size) + if (deleteList.size == 0) { + actionMode!!.finish() + } + } +} diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/bookmark/BookmarksContract.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/bookmark/BookmarksContract.kt index d846500e0..d5777d9a8 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/bookmark/BookmarksContract.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/bookmark/BookmarksContract.kt @@ -19,7 +19,7 @@ package org.kiwix.kiwixmobile.core.bookmark import org.kiwix.kiwixmobile.core.base.BaseContract -internal interface BookmarksContract { +interface BookmarksContract { interface View : BaseContract.View { fun updateBookmarksList(bookmarks: List) fun notifyBookmarksListFiltered(bookmarks: List)