mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 14:27:57 +01:00 
			
		
		
		
	Merge pull request #225 from NoodleMage/manga_chapters
Updated manga chapters UI
This commit is contained in:
		| @@ -76,12 +76,12 @@ class LibraryFragment : BaseRxFragment<LibraryPresenter>(), ActionMode.Callback | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * TODO | ||||
|      * Status of isFilterDownloaded | ||||
|      */ | ||||
|     var isFilterDownloaded = false | ||||
|  | ||||
|     /** | ||||
|      * TODO | ||||
|      * Status of isFilterUnread | ||||
|      */ | ||||
|     var isFilterUnread = false | ||||
|  | ||||
|   | ||||
| @@ -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<ChaptersPresenter>(), 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<ChaptersPresenter>(), 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<Chapter>) { | ||||
| @@ -158,9 +185,12 @@ class ChaptersFragment : BaseRxFragment<ChaptersPresenter>(), 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<ChaptersPresenter>(), 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() | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
							
								
								
									
										19
									
								
								app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								app/src/main/java/eu/kanade/tachiyomi/util/ViewExtensions.kt
									
									
									
									
									
										Normal file
									
								
							| @@ -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) | ||||
| } | ||||
|  | ||||
| @@ -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 | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user