diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt index d064cf55f..4708ca9ed 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt @@ -76,12 +76,12 @@ class LibraryFragment : BaseRxFragment(), ActionMode.Callback /** - * TODO + * Status of isFilterDownloaded */ var isFilterDownloaded = false /** - * TODO + * Status of isFilterUnread */ var isFilterUnread = false diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.kt index fdc634e6e..90c0dc309 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.kt @@ -1,7 +1,9 @@ package eu.kanade.tachiyomi.ui.manga.chapter +import android.animation.Animator +import android.animation.AnimatorListenerAdapter +import android.content.Intent import android.os.Bundle -import android.support.v4.content.ContextCompat import android.support.v7.view.ActionMode import android.support.v7.widget.LinearLayoutManager import android.view.* @@ -17,6 +19,7 @@ import eu.kanade.tachiyomi.ui.base.decoration.DividerItemDecoration import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment import eu.kanade.tachiyomi.ui.manga.MangaActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity +import eu.kanade.tachiyomi.util.getCoordinates import eu.kanade.tachiyomi.util.getResourceDrawable import eu.kanade.tachiyomi.util.toast import kotlinx.android.synthetic.main.fragment_manga_chapters.* @@ -71,10 +74,22 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac swipe_refresh.setOnRefreshListener { fetchChapters() } - next_unread_btn.setOnClickListener { v -> + fab.setOnClickListener { v -> val chapter = presenter.getNextUnreadChapter() if (chapter != null) { - openChapter(chapter) + // Create animation listener + var revealAnimationListener: Animator.AnimatorListener = object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { + // On done open chapter + openChapter(chapter, true) + } + } + + // Get coordinates and start animation + val coordinates = fab.getCoordinates() + if (!reveal_view.showRevealEffect(coordinates.x, coordinates.y, revealAnimationListener)) { + openChapter(chapter) + } } else { context.toast(R.string.no_next_chapter) } @@ -91,37 +106,49 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac super.onPause() } + override fun onResume() { + // Check if animation view is visible + if (reveal_view.visibility == View.VISIBLE) { + // Show the unReveal effect + var coordinates = fab.getCoordinates() + reveal_view.hideRevealEffect(coordinates.x, coordinates.y, 1920) + } + super.onResume() + } + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { inflater.inflate(R.menu.chapters, menu) + menu.findItem(R.id.action_filter_unread).isChecked = presenter.onlyUnread() + menu.findItem(R.id.action_filter_downloaded).isChecked = presenter.onlyDownloaded() } override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.action_display_mode -> showDisplayModeDialog() R.id.manga_download -> showDownloadDialog() + R.id.action_filter_unread -> { + item.isChecked = !item.isChecked + presenter.setReadFilter(item.isChecked) + } + R.id.action_filter_downloaded -> { + item.isChecked = !item.isChecked + presenter.setDownloadedFilter(item.isChecked) + } + R.id.action_filter_empty -> { + presenter.setReadFilter(false) + presenter.setDownloadedFilter(false) + activity.supportInvalidateOptionsMenu(); + } + R.id.action_sort -> presenter.revertSortOrder() else -> return super.onOptionsItemSelected(item) } return true } fun onNextManga(manga: Manga) { - // Remove listeners before setting the values - show_unread.setOnCheckedChangeListener(null) - show_downloaded.setOnCheckedChangeListener(null) - sort_btn.setOnClickListener(null) - // Set initial values setReadFilter() setDownloadedFilter() - setSortIcon() - - // Init listeners - show_unread.setOnCheckedChangeListener { arg, isChecked -> presenter.setReadFilter(isChecked) } - show_downloaded.setOnCheckedChangeListener { v, isChecked -> presenter.setDownloadedFilter(isChecked) } - sort_btn.setOnClickListener { - presenter.revertSortOrder() - setSortIcon() - } } fun onNextChapters(chapters: List) { @@ -158,9 +185,12 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac val isCatalogueManga: Boolean get() = (activity as MangaActivity).isCatalogueManga - protected fun openChapter(chapter: Chapter) { + protected fun openChapter(chapter: Chapter, hasAnimation: Boolean = false) { presenter.onOpenChapter(chapter) val intent = ReaderActivity.newIntent(activity) + if (hasAnimation) { + intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION) + } startActivity(intent) } @@ -341,23 +371,11 @@ class ChaptersFragment : BaseRxFragment(), ActionMode.Callbac actionMode?.title = getString(R.string.label_selected, count) } - fun setSortIcon() { - sort_btn?.let { - val aToZ = presenter.sortOrder() - it.setImageResource(if (!aToZ) R.drawable.ic_expand_less_white_36dp else R.drawable.ic_expand_more_white_36dp) - } - } - fun setReadFilter() { - show_unread?.let { - it.isChecked = presenter.onlyUnread() - } + this.activity.supportInvalidateOptionsMenu() } fun setDownloadedFilter() { - show_downloaded?.let { - it.isChecked = presenter.onlyDownloaded() - } + this.activity.supportInvalidateOptionsMenu() } - } diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt new file mode 100644 index 000000000..a2f1c5d70 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt @@ -0,0 +1,19 @@ +package eu.kanade.tachiyomi.util + +import android.graphics.Point +import android.view.View + +/** + * Returns coordinates of view. + * Used for animation + * + * @return coordinates of view + */ +fun View.getCoordinates(): Point +{ + var cx = (this.left + this.right) / 2; + var cy = (this.top + this.bottom) / 2; + + return Point(cx, cy) +} + diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/RevealAnimationView.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/RevealAnimationView.kt new file mode 100644 index 000000000..f5718e75d --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/RevealAnimationView.kt @@ -0,0 +1,79 @@ +package eu.kanade.tachiyomi.widget + +import android.animation.Animator +import android.animation.AnimatorListenerAdapter +import android.annotation.TargetApi +import android.content.Context +import android.os.Build +import android.util.AttributeSet +import android.view.View +import android.view.ViewAnimationUtils + +@TargetApi(Build.VERSION_CODES.LOLLIPOP) +class RevealAnimationView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : + View(context, attrs) { + + /** + * Hides the animation view with a animation + * + * @param centerX x starting point + * @param centerY y starting point + * @param initialRadius size of radius of animation + */ + fun hideRevealEffect(centerX: Int, centerY: Int, initialRadius: Int) { + if (Build.VERSION.SDK_INT >= 21) { + + // Make the view visible. + this.visibility = View.VISIBLE + + // Create the animation (the final radius is zero). + val anim = ViewAnimationUtils.createCircularReveal( + this, centerX, centerY, initialRadius.toFloat(), 0f) + + // Set duration of animation. + anim.duration = 500 + + // make the view invisible when the animation is done + anim.addListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { + super.onAnimationEnd(animation) + this@RevealAnimationView.visibility = View.INVISIBLE + } + }) + + anim.start() + } + } + + /** + * Fills the animation view with a animation + * + * @param centerX x starting point + * @param centerY y starting point + * @param listener animation listener + * + * @return sdk version lower then 21 + */ + fun showRevealEffect(centerX: Int, centerY: Int, listener: Animator.AnimatorListener): Boolean { + if (Build.VERSION.SDK_INT >= 21) { + + this.visibility = View.VISIBLE + + val height = this.height + + // Create animation + val anim = ViewAnimationUtils.createCircularReveal( + this, centerX, centerY, 0f, height.toFloat()) + + // Set duration of animation + anim.duration = 350 + + anim.addListener(listener) + anim.start() + return true + } + return false + } + + +} diff --git a/app/src/main/res/drawable/ic_sort_by_alpha_white_24dp.xml b/app/src/main/res/drawable/ic_sort_by_alpha_white_24dp.xml new file mode 100644 index 000000000..34602f23b --- /dev/null +++ b/app/src/main/res/drawable/ic_sort_by_alpha_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/fragment_manga_chapters.xml b/app/src/main/res/layout/fragment_manga_chapters.xml index d5f5770ba..d3a25fdff 100644 --- a/app/src/main/res/layout/fragment_manga_chapters.xml +++ b/app/src/main/res/layout/fragment_manga_chapters.xml @@ -1,11 +1,21 @@ - + + + - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/item_chapter.xml b/app/src/main/res/layout/item_chapter.xml index ec7a7e54b..8235a97eb 100644 --- a/app/src/main/res/layout/item_chapter.xml +++ b/app/src/main/res/layout/item_chapter.xml @@ -1,9 +1,9 @@ @@ -25,37 +25,38 @@ + android:textAllCaps="true"/> @@ -93,8 +93,8 @@ android:layout_alignParentEnd="false" android:layout_alignParentRight="true" android:layout_alignParentTop="true" - app:srcCompat="@drawable/ic_more_horiz_black_24dp" - android:tint="?android:attr/textColorPrimary"/> + android:tint="?android:attr/textColorPrimary" + app:srcCompat="@drawable/ic_more_horiz_black_24dp"/> diff --git a/app/src/main/res/menu/chapters.xml b/app/src/main/res/menu/chapters.xml index 5beb7871e..b4108a001 100644 --- a/app/src/main/res/menu/chapters.xml +++ b/app/src/main/res/menu/chapters.xml @@ -3,12 +3,38 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5726b84cc..0e1d97fca 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -48,6 +48,7 @@ Open in browser Change display mode Cancel + Sort OK