diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/FilterBottomSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/FilterBottomSheet.kt new file mode 100644 index 0000000000..c3fd18ad20 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/FilterBottomSheet.kt @@ -0,0 +1,172 @@ +package eu.kanade.tachiyomi.ui.library + +import android.content.Context +import android.transition.AutoTransition +import android.transition.TransitionManager +import android.util.AttributeSet +import android.view.View +import android.widget.LinearLayout +import com.google.android.material.bottomsheet.BottomSheetBehavior +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.database.DatabaseHelper +import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.data.preference.getOrDefault +import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.util.view.inflate +import kotlinx.android.synthetic.main.filter_bottom_sheet.view.* +import kotlinx.android.synthetic.main.filter_buttons.view.* +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get +import uy.kohesive.injekt.injectLazy +import kotlin.math.roundToInt + +class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) + : LinearLayout(context, attrs) { + + /** + * Preferences helper. + */ + private val preferences: PreferencesHelper by injectLazy() + + private lateinit var downloaded:FilterTagGroup + + private lateinit var unread:FilterTagGroup + + private lateinit var completed:FilterTagGroup + + private lateinit var tracked:FilterTagGroup + + private lateinit var categories:FilterTagGroup + + val items:List by lazy { + val list = mutableListOf() + if (Injekt.get().getCategories().executeAsBlocking().isNotEmpty()) + list.add(categories) + list.add(downloaded) + list.add(unread) + list.add(completed) + if (Injekt.get().hasLoggedServices()) + list.add(tracked) + list + } + + var onGroupClicked: (Int) -> Unit = { _ -> } + val recycler = androidx.recyclerview.widget.RecyclerView(context) + var pager:View? = null + var filters = listOf() + + init { + + } + + fun onCreate(pagerView:View) { + val sheetBehavior = BottomSheetBehavior.from(this) + topbar.setOnClickListener { + if (sheetBehavior.state != BottomSheetBehavior.STATE_EXPANDED) { + sheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED + } else { + sheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED + } + } + pager = pagerView + pager?.setPadding(0, 0, 0, topbar.height) + sheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { + override fun onSlide(bottomSheet: View, progress: Float) { + val minHeight = sheetBehavior.peekHeight + val maxHeight = bottomSheet.height + val percent = (progress * 100).roundToInt() + val value = (percent * (maxHeight - minHeight) / 100) + minHeight + pager?.setPadding(0, 0, 0, value) + line.alpha = 1 - progress + } + + override fun onStateChanged(p0: View, p1: Int) { + + } + }) + topbar.viewTreeObserver.addOnGlobalLayoutListener { + sheetBehavior.peekHeight = topbar.height + if (sheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED) { + pager?.setPadding(0, 0, 0, topbar.height) + } + } + createTags() + } + + fun createTags() { + categories = inflate(R.layout.filter_buttons) as FilterTagGroup + categories.setup(this, R.string.categories) + categories.onItemClicked = { view, index -> onFilterClicked(view, index) } + categories.firstButton.isActivated = preferences.showCategories().getOrDefault() + + downloaded = inflate(R.layout.filter_buttons) as FilterTagGroup + downloaded.setup(this, R.string.action_filter_downloaded, R.string.action_filter_not_downloaded) + downloaded.onItemClicked = { view, index -> onFilterClicked(view, index) } + downloaded.setState(preferences.filterDownloaded()) + + completed = inflate(R.layout.filter_buttons) as FilterTagGroup + completed.setup(this, R.string.completed, R.string.ongoing) + completed.onItemClicked = { view, index -> onFilterClicked(view, index) } + completed.setState(preferences.filterCompleted()) + + unread = inflate(R.layout.filter_buttons) as FilterTagGroup + unread.setup(this, R.string.action_filter_not_started, R.string.action_filter_in_progress, + R.string.action_filter_read) + unread.onItemClicked = { view, index -> onFilterClicked(view, index) } + unread.setState(preferences.filterUnread()) + + tracked = inflate(R.layout.filter_buttons) as FilterTagGroup + tracked.setup(this, R.string.action_filter_tracked, R.string.action_filter_not_tracked) + tracked.onItemClicked = { view, index -> onFilterClicked(view, index) } + tracked.setState(preferences.filterTracked()) + + items.forEach { + filterLayout.addView(it) + } + } + + private fun onFilterClicked(view: View, index: Int) { + val transition = AutoTransition() + transition.duration = 150 + TransitionManager.beginDelayedTransition(this, transition) + /*f (index > -1) { + filterScrollView.scrollX = 0 + filterLayout.removeView(view) + filterLayout.addView(view, 0) + } + else{ + filterLayout.removeView(view) + filterLayout.addView(view, items.indexOf(view as FilterTagGroup)) + }*/ + when (view) { + categories -> { + preferences.showCategories().set(index == 0) + onGroupClicked(ACTION_REFRESH) + } + downloaded -> { + preferences.filterDownloaded().set(index + 1) + onGroupClicked(ACTION_FILTER) + } + unread -> { + preferences.filterUnread().set(index + 1) + onGroupClicked(ACTION_FILTER) + } + completed -> { + preferences.filterCompleted().set(index + 1) + onGroupClicked(ACTION_FILTER) + } + tracked -> { + preferences.filterTracked().set(index + 1) + onGroupClicked(ACTION_FILTER) + } + } + } + + companion object { + const val ACTION_REFRESH = 0 + const val ACTION_SORT = 1 + const val ACTION_FILTER = 2 + const val ACTION_DISPLAY = 3 + const val ACTION_BADGE = 4 + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/FilterTagGroup.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/FilterTagGroup.kt new file mode 100644 index 0000000000..2a7a273769 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/FilterTagGroup.kt @@ -0,0 +1,101 @@ +package eu.kanade.tachiyomi.ui.library + +import android.content.Context +import android.transition.AutoTransition +import android.transition.TransitionManager +import android.util.AttributeSet +import android.view.View +import android.view.ViewGroup +import android.widget.LinearLayout +import com.f2prateek.rx.preferences.Preference +import eu.kanade.tachiyomi.data.preference.getOrDefault +import eu.kanade.tachiyomi.util.system.dpToPx +import eu.kanade.tachiyomi.util.view.gone +import eu.kanade.tachiyomi.util.view.visible +import kotlinx.android.synthetic.main.filter_buttons.view.* + +class FilterTagGroup@JvmOverloads constructor(context: Context, attrs: AttributeSet? = null): LinearLayout + (context, attrs) { + + var onItemClicked: (View, Int) -> Unit = { _, _ -> } + + private var itemCount = 0 + private var root:ViewGroup? = null + + fun setup(root: ViewGroup, firstText: Int, secondText: Int? = null, thirdText: Int? = null) { + val text1 = context.getString(firstText) + val text2 = if (secondText != null) context.getString(secondText) else null + val text3 = if (thirdText != null) context.getString(thirdText) else null + setup(root, text1, text2, text3) + } + + fun setup(root: ViewGroup, firstText: String, secondText: String? = null, thirdText: String? = + null) { + (layoutParams as? MarginLayoutParams)?.rightMargin = 5.dpToPx + (layoutParams as? MarginLayoutParams)?.leftMargin = 5.dpToPx + firstButton.text = firstText + if (secondText != null) { + secondButton.text = secondText + itemCount = 2 + if (thirdText != null) { + thirdButton.text = thirdText + itemCount = 3 + } + else { + thirdButton.gone() + separator2.gone() + } + } + else { + itemCount = 1 + secondButton.gone() + separator1.gone() + thirdButton.gone() + separator2.gone() + } + this.root = root + firstButton.setOnClickListener {toggleButton(0) } + secondButton.setOnClickListener {toggleButton(1) } + thirdButton.setOnClickListener {toggleButton(2) } + } + + fun setState(preference: Preference) { + val index = preference.getOrDefault() - 1 + if (index > 1) + toggleButton(index) + } + + private fun toggleButton(index: Int) { + if (itemCount == 0) return + if (itemCount == 1) { + firstButton.isActivated = !firstButton.isActivated + onItemClicked(this, if (firstButton.isActivated) index else -1) + return + } + val buttons = mutableListOf(firstButton, secondButton) + if (itemCount >= 3) + buttons.add(thirdButton) + val mainButton = buttons[index] + buttons.remove(mainButton) + val transition = AutoTransition() + transition.duration = 150 + TransitionManager.beginDelayedTransition(root, transition) + if (mainButton.isActivated) { + mainButton.isActivated = false + separator1.visible() + onItemClicked(this, -1) + if (itemCount >= 3) + separator2.visible() + buttons.forEach{ it.visible() } + } + else { + mainButton.isActivated = true + onItemClicked(this, index) + buttons.forEach{ it.gone() } + separator1.gone() + if (itemCount >= 3) { + separator2.gone() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 088256ab75..bc7d9388dc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -23,6 +23,8 @@ import com.afollestad.materialdialogs.MaterialDialog import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.ControllerChangeType import com.f2prateek.rx.preferences.Preference +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.snackbar.BaseTransientBottomBar import com.google.android.material.snackbar.Snackbar import com.google.android.material.tabs.TabLayout @@ -56,6 +58,7 @@ import eu.kanade.tachiyomi.util.view.snack import eu.kanade.tachiyomi.util.view.updatePaddingRelative import eu.kanade.tachiyomi.util.view.visible import eu.kanade.tachiyomi.widget.ExtendedNavigationView +import kotlinx.android.synthetic.main.filter_bottom_sheet.* import kotlinx.android.synthetic.main.library_controller.* import kotlinx.android.synthetic.main.main_activity.* import rx.Subscription @@ -204,6 +207,18 @@ class LibraryController( if (selectedMangas.isNotEmpty()) { createActionModeIfNeeded() } + + bottom_sheet.onCreate(library_pager) + + bottom_sheet?.onGroupClicked = { + when (it) { + FilterBottomSheet.ACTION_REFRESH -> onRefresh() + FilterBottomSheet.ACTION_FILTER -> onFilterChanged() + FilterBottomSheet.ACTION_SORT -> onSortChanged() + FilterBottomSheet.ACTION_DISPLAY -> reattachAdapter() + FilterBottomSheet.ACTION_BADGE -> onDownloadBadgeChanged() + } + } } fun enableReorderItems(category: Category) { @@ -361,6 +376,11 @@ class LibraryController( preferences.landscapeColumns() } + private fun onRefresh() { + activity?.invalidateOptionsMenu() + presenter.requestFullUpdate() + } + /** * Called when a filter is changed. */ diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryNavigationView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryNavigationView.kt index cf766d89a9..372b21daec 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryNavigationView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryNavigationView.kt @@ -17,6 +17,7 @@ import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Comp import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy +import kotlin.math.min /** * The navigation view shown in a drawer with the different options to show the library. @@ -90,7 +91,7 @@ class LibraryNavigationView @JvmOverloads constructor(context: Context, attrs: A private val completed = Item.TriStateGroup(R.string.completed, this) - private val tracked = Item.TriStateGroup(R.string.tracked, this) + private val tracked = Item.TriStateGroup(R.string.action_filter_tracked, this) private val categories = Item.TriStateGroup(R.string.action_hide_categories, this) @@ -115,10 +116,10 @@ class LibraryNavigationView @JvmOverloads constructor(context: Context, attrs: A categories.state = if (preferences.hideCategories().getOrDefault()) STATE_INCLUDE else STATE_IGNORE - downloaded.state = preferences.filterDownloaded().getOrDefault() - unread.state = preferences.filterUnread().getOrDefault() - completed.state = preferences.filterCompleted().getOrDefault() - tracked.state = preferences.filterTracked().getOrDefault() + downloaded.state = min(2, preferences.filterDownloaded().getOrDefault()) + unread.state = min(2, preferences.filterUnread().getOrDefault()) + completed.state = min(2, preferences.filterCompleted().getOrDefault()) + tracked.state = min(2, preferences.filterTracked().getOrDefault()) } catch (e: Exception) { preferences.upgradeFilters() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt index f70dad6f4a..cc9bc9c424 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt @@ -26,6 +26,7 @@ import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter +import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.migration.MigrationFlags import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource import eu.kanade.tachiyomi.util.lang.combineLatest @@ -34,6 +35,7 @@ import eu.kanade.tachiyomi.util.lang.removeArticles import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_EXCLUDE import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_IGNORE import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_INCLUDE +import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_REALLY_EXCLUDE import rx.Observable import rx.Subscription import rx.android.schedulers.AndroidSchedulers @@ -139,8 +141,20 @@ class LibraryPresenter( val filterFn: (LibraryItem) -> Boolean = f@ { item -> // Filter when there isn't unread chapters. - if (filterUnread == STATE_INCLUDE && item.manga.unread == 0) return@f false - if (filterUnread == STATE_EXCLUDE && item.manga.unread > 0) return@f false + if (MainActivity.bottomNav) { + if (filterUnread == STATE_INCLUDE && + (item.manga.unread == 0 || db.getChapters(item.manga).executeAsBlocking() + .size != item.manga.unread)) return@f false + if (filterUnread == STATE_EXCLUDE && + (item.manga.unread == 0 || db.getChapters(item.manga).executeAsBlocking().size == item.manga.unread)) return@f false + if (filterUnread == STATE_REALLY_EXCLUDE && item.manga.unread > 0) return@f false + } + else { + if (filterUnread == STATE_INCLUDE && item.manga.unread == 0) return@f false + if ((filterUnread == STATE_EXCLUDE || filterUnread == STATE_REALLY_EXCLUDE) && item + .manga.unread > 0) return@f false + } + if (filterCompleted == STATE_INCLUDE && item.manga.status != SManga.COMPLETED) return@f false diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt index aae50011ac..a9c7d395a9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt @@ -402,7 +402,8 @@ class MangaInfoController : NucleusController(), } val activity = activity ?: return - val intent = WebViewActivity.newIntent(activity, source.id, url, presenter.manga.originalTitle()) + val intent = WebViewActivity.newIntent(activity.applicationContext, source.id, url, presenter.manga + .originalTitle()) startActivity(intent) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewActivity.kt index b152abe7bf..f4e41301e4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewActivity.kt @@ -53,16 +53,6 @@ class WebViewActivity : BaseActivity() { } } - /*override fun getTheme(): Resources.Theme { - val theme = super.getTheme() - theme.applyStyle(when (preferences.theme()) { - 3, 6 -> R.style.Theme_Tachiyomi_Amoled - 4, 7 -> R.style.Theme_Tachiyomi_DarkBlue - else -> R.style.Theme_Tachiyomi - }, true) - return theme - }*/ - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.webview_activity) diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/ExtendedNavigationView.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/ExtendedNavigationView.kt index af5da9612c..c06759b304 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/widget/ExtendedNavigationView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/ExtendedNavigationView.kt @@ -126,6 +126,7 @@ open class ExtendedNavigationView @JvmOverloads constructor( const val STATE_IGNORE = 0 const val STATE_INCLUDE = 1 const val STATE_EXCLUDE = 2 + const val STATE_REALLY_EXCLUDE = 3 } override fun getStateDrawable(context: Context): Drawable? { diff --git a/app/src/main/res/drawable/round_textview_border.xml b/app/src/main/res/drawable/round_textview_border.xml new file mode 100644 index 0000000000..385db27cf7 --- /dev/null +++ b/app/src/main/res/drawable/round_textview_border.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_ripple.xml b/app/src/main/res/drawable/rounded_ripple.xml new file mode 100644 index 0000000000..e581e8ef98 --- /dev/null +++ b/app/src/main/res/drawable/rounded_ripple.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_text_selected.xml b/app/src/main/res/drawable/rounded_text_selected.xml new file mode 100644 index 0000000000..867628b7f3 --- /dev/null +++ b/app/src/main/res/drawable/rounded_text_selected.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/filter_bottom_sheet.xml b/app/src/main/res/layout/filter_bottom_sheet.xml new file mode 100644 index 0000000000..5a817ffed2 --- /dev/null +++ b/app/src/main/res/layout/filter_bottom_sheet.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/filter_buttons.xml b/app/src/main/res/layout/filter_buttons.xml new file mode 100644 index 0000000000..921688a333 --- /dev/null +++ b/app/src/main/res/layout/filter_buttons.xml @@ -0,0 +1,65 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/filter_rounded_text.xml b/app/src/main/res/layout/filter_rounded_text.xml new file mode 100644 index 0000000000..6ed3983de1 --- /dev/null +++ b/app/src/main/res/layout/filter_rounded_text.xml @@ -0,0 +1,19 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/library_controller.xml b/app/src/main/res/layout/library_controller.xml index a2f1274609..ea85a36cd7 100644 --- a/app/src/main/res/layout/library_controller.xml +++ b/app/src/main/res/layout/library_controller.xml @@ -1,7 +1,8 @@ + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + + diff --git a/app/src/main/res/layout/search_activity.xml b/app/src/main/res/layout/search_activity.xml index 3efeb1878f..d7a1d244df 100644 --- a/app/src/main/res/layout/search_activity.xml +++ b/app/src/main/res/layout/search_activity.xml @@ -32,8 +32,8 @@ android:theme="@style/Theme.ActionBar.Tab" android:background="?colorPrimary" app:tabRippleColor="@color/rippleColor" - app:tabIndicatorColor="?attr/tabBarIconColor" - app:tabTextColor="?attr/tabBarIconColor" + app:tabIndicatorColor="?attr/actionBarTintColor" + app:tabTextColor="?attr/actionBarTintColor" app:tabInlineLabel="true" app:tabGravity="center" app:tabMode="auto" diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 39a59c4c72..8aa8f7f66a 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -588,7 +588,7 @@ Статус Тип - Отслеживаемые + Отслеживаемые Текущая: Закончена: diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8e63682041..935ae32b48 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -35,9 +35,15 @@ Filter Downloaded + Not downloaded Bookmarked Unread + Not started + In progress Read + Tracked + Not tracked + Remove filter Alphabetically Enabled @@ -478,7 +484,6 @@ Reading Currently Reading Completed - Tracked Dropped On hold Plan to read