From 64630237361b97d13451d56a78164fb8b64a419c Mon Sep 17 00:00:00 2001 From: Koitharu Date: Wed, 16 Dec 2020 11:49:10 +0200 Subject: [PATCH] Edge-to-edge ui --- .../koitharu/kotatsu/base/ui/BaseActivity.kt | 21 ++++++- .../koitharu/kotatsu/base/ui/BaseFragment.kt | 18 +++++- .../kotatsu/base/ui/BaseFullscreenActivity.kt | 21 +++---- .../kotatsu/base/ui/BasePreferenceFragment.kt | 24 +++++++- .../kotatsu/browser/BrowserActivity.kt | 7 +++ .../kotatsu/details/ui/ChaptersFragment.kt | 10 ++++ .../kotatsu/details/ui/DetailsActivity.kt | 17 ++++++ .../kotatsu/details/ui/DetailsFragment.kt | 10 ++++ .../ui/FavouritesContainerFragment.kt | 9 +++ .../ui/categories/CategoriesActivity.kt | 22 ++++++++ .../kotatsu/list/ui/ListModeSelectDialog.kt | 5 ++ .../kotatsu/list/ui/MangaListFragment.kt | 15 +++++ .../org/koitharu/kotatsu/main/MainModule.kt | 2 + .../koitharu/kotatsu/main/ui/MainActivity.kt | 22 +++++++- .../main/ui/protect/AppProtectHelper.kt | 16 ++---- .../main/ui/protect/ProtectActivity.kt | 14 ++++- .../kotatsu/reader/ui/ReaderActivity.kt | 20 ++++--- .../reader/ui/SimpleSettingsActivity.kt | 10 ++++ .../kotatsu/reader/ui/pager/BaseReader.kt | 3 + .../kotatsu/search/ui/SearchActivity.kt | 10 ++++ .../search/ui/global/GlobalSearchActivity.kt | 10 ++++ .../kotatsu/settings/MainSettingsFragment.kt | 6 ++ .../NotificationSettingsLegacyFragment.kt | 18 ++++-- .../kotatsu/settings/SettingsActivity.kt | 10 ++++ .../sources/SourcesSettingsFragment.kt | 10 ++++ .../kotatsu/tracker/ui/FeedFragment.kt | 56 +++++-------------- .../kotatsu/tracker/ui/FeedViewModel.kt | 8 ++- .../widget/shelf/ShelfConfigActivity.kt | 22 ++++++++ .../res/layout-w600dp/activity_details.xml | 44 +++++++++++++++ .../res/layout-w600dp/fragment_details.xml | 1 + app/src/main/res/layout/activity_browser.xml | 1 - .../main/res/layout/activity_categories.xml | 2 +- app/src/main/res/layout/activity_details.xml | 1 + app/src/main/res/layout/activity_main.xml | 2 + app/src/main/res/layout/activity_reader.xml | 1 - app/src/main/res/layout/activity_search.xml | 1 - .../res/layout/activity_search_global.xml | 1 - app/src/main/res/layout/activity_settings.xml | 21 +++---- .../res/layout/activity_settings_simple.xml | 1 - app/src/main/res/layout/dialog_input.xml | 2 + app/src/main/res/layout/dialog_list_mode.xml | 10 +++- app/src/main/res/layout/fragment_details.xml | 1 + app/src/main/res/layout/fragment_feed.xml | 55 +++++------------- app/src/main/res/layout/fragment_list.xml | 2 + .../res/layout/fragment_settings_sources.xml | 1 + app/src/main/res/layout/item_manga_grid.xml | 7 +-- .../res/layout/item_manga_list_details.xml | 6 +- app/src/main/res/layout/item_tracklog.xml | 8 +-- app/src/main/res/values-v29/themes.xml | 12 ++++ app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/themes.xml | 1 + 51 files changed, 434 insertions(+), 164 deletions(-) create mode 100644 app/src/main/res/layout-w600dp/activity_details.xml create mode 100644 app/src/main/res/values-v29/themes.xml diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt index e8719eb19..23efa5f10 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt @@ -7,13 +7,18 @@ import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.core.app.ActivityCompat +import androidx.core.graphics.Insets +import androidx.core.view.OnApplyWindowInsetsListener +import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat import androidx.viewbinding.ViewBinding import org.koin.android.ext.android.get import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.prefs.AppSettings -abstract class BaseActivity : AppCompatActivity() { +abstract class BaseActivity : AppCompatActivity(), OnApplyWindowInsetsListener { protected lateinit var binding: B private set @@ -23,6 +28,7 @@ abstract class BaseActivity : AppCompatActivity() { setTheme(R.style.AppTheme_Amoled) } super.onCreate(savedInstanceState) + WindowCompat.setDecorFitsSystemWindows(window, false) } @Deprecated("Use ViewBinding", level = DeprecationLevel.ERROR) @@ -41,10 +47,12 @@ abstract class BaseActivity : AppCompatActivity() { this.binding = binding super.setContentView(binding.root) (binding.root.findViewById(R.id.toolbar) as? Toolbar)?.let(this::setSupportActionBar) + ViewCompat.setOnApplyWindowInsetsListener(binding.root, this) } - private fun setupToolbar() { - (findViewById(R.id.toolbar) as? Toolbar)?.let(this::setSupportActionBar) + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + onWindowInsetsChanged(insets.getInsets(WindowInsetsCompat.Type.systemBars())) + return insets } override fun onOptionsItemSelected(item: MenuItem) = if (item.itemId == android.R.id.home) { @@ -59,4 +67,11 @@ abstract class BaseActivity : AppCompatActivity() { } return super.onKeyDown(keyCode, event) } + + protected abstract fun onWindowInsetsChanged(insets: Insets) + + private fun setupToolbar() { + (findViewById(R.id.toolbar) as? Toolbar)?.let(this::setSupportActionBar) + } + } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt index 7288702b8..107bcd839 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt @@ -5,10 +5,14 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.graphics.Insets +import androidx.core.view.OnApplyWindowInsetsListener +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.Fragment import androidx.viewbinding.ViewBinding -abstract class BaseFragment : Fragment() { +abstract class BaseFragment : Fragment(), OnApplyWindowInsetsListener { private var viewBinding: B? = null @@ -25,6 +29,11 @@ abstract class BaseFragment : Fragment() { return binding.root } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(view, this) + } + override fun onDestroyView() { viewBinding = null super.onDestroyView() @@ -39,7 +48,14 @@ abstract class BaseFragment : Fragment() { } } + override fun onApplyWindowInsets(v: View?, insets: WindowInsetsCompat): WindowInsetsCompat { + onWindowInsetsChanged(insets.getInsets(WindowInsetsCompat.Type.systemBars())) + return insets + } + protected fun bindingOrNull() = viewBinding protected abstract fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): B + + protected abstract fun onWindowInsetsChanged(insets: Insets) } diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFullscreenActivity.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFullscreenActivity.kt index c84852181..3288851e7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFullscreenActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFullscreenActivity.kt @@ -3,16 +3,22 @@ package org.koitharu.kotatsu.base.ui import android.graphics.Color import android.os.Build import android.os.Bundle -import android.view.View import android.view.WindowManager +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.WindowInsetsControllerCompat import androidx.viewbinding.ViewBinding abstract class BaseFullscreenActivity : BaseActivity() { + private lateinit var insetsControllerCompat: WindowInsetsControllerCompat + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) with(window) { + insetsControllerCompat = WindowInsetsControllerCompat(this, decorView) + insetsControllerCompat.systemBarsBehavior = + WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE statusBarColor = Color.TRANSPARENT navigationBarColor = Color.TRANSPARENT if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { @@ -24,20 +30,11 @@ abstract class BaseFullscreenActivity : BaseActivity() { } protected fun hideSystemUI() { - window.decorView.systemUiVisibility = ( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // прячем панель навигации - or View.SYSTEM_UI_FLAG_FULLSCREEN // прячем строку состояния - or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY - ) + insetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars()) } protected fun showSystemUI() { - window.decorView.systemUiVisibility = - (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) + insetsControllerCompat.show(WindowInsetsCompat.Type.systemBars()) } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BasePreferenceFragment.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BasePreferenceFragment.kt index 9f02475fd..b2ec2ce8d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BasePreferenceFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BasePreferenceFragment.kt @@ -1,17 +1,39 @@ package org.koitharu.kotatsu.base.ui +import android.os.Bundle +import android.view.View import androidx.annotation.StringRes +import androidx.core.view.OnApplyWindowInsetsListener +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding import androidx.preference.PreferenceFragmentCompat import org.koin.android.ext.android.inject import org.koitharu.kotatsu.core.prefs.AppSettings abstract class BasePreferenceFragment(@StringRes private val titleId: Int) : - PreferenceFragmentCompat() { + PreferenceFragmentCompat(), OnApplyWindowInsetsListener { protected val settings by inject() + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + listView.clipToPadding = false + ViewCompat.setOnApplyWindowInsetsListener(view, this) + } + override fun onResume() { super.onResume() activity?.setTitle(titleId) } + + override fun onApplyWindowInsets(v: View?, insets: WindowInsetsCompat): WindowInsetsCompat { + val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + listView.updatePadding( + left = systemBars.left, + right = systemBars.right, + bottom = systemBars.bottom + ) + return WindowInsetsCompat.CONSUMED + } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/browser/BrowserActivity.kt b/app/src/main/java/org/koitharu/kotatsu/browser/BrowserActivity.kt index 0839ef204..da6a65805 100644 --- a/app/src/main/java/org/koitharu/kotatsu/browser/BrowserActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/browser/BrowserActivity.kt @@ -8,7 +8,9 @@ import android.net.Uri import android.os.Bundle import android.view.Menu import android.view.MenuItem +import androidx.core.graphics.Insets import androidx.core.view.isVisible +import androidx.core.view.updatePadding import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.databinding.ActivityBrowserBinding @@ -85,6 +87,11 @@ class BrowserActivity : BaseActivity(), BrowserCallback supportActionBar?.subtitle = subtitle } + override fun onWindowInsetsChanged(insets: Insets) { + binding.appbar.updatePadding(top = insets.top) + binding.webView.updatePadding(bottom = insets.bottom) + } + companion object { fun newIntent(context: Context, url: String) = Intent(context, BrowserActivity::class.java) diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt index 8b5bbbe2d..8a9baca1e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt @@ -5,7 +5,9 @@ import android.os.Bundle import android.view.* import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.view.ActionMode +import androidx.core.graphics.Insets import androidx.core.view.isVisible +import androidx.core.view.updatePadding import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.RecyclerView import org.koin.androidx.viewmodel.ext.android.sharedViewModel @@ -149,4 +151,12 @@ class ChaptersFragment : BaseFragment(), binding.recyclerViewChapters.invalidateItemDecorations() actionMode = null } + + override fun onWindowInsetsChanged(insets: Insets) { + binding.recyclerViewChapters.updatePadding( + left = insets.left, + right = insets.right, + bottom = insets.bottom + ) + } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt index 623bcabc5..5ae2f9e64 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt @@ -9,9 +9,12 @@ import android.view.MenuItem import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.appcompat.view.ActionMode +import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat import androidx.core.content.pm.ShortcutManagerCompat +import androidx.core.graphics.Insets import androidx.core.net.toFile +import androidx.core.view.updatePadding import androidx.lifecycle.lifecycleScope import com.google.android.material.snackbar.Snackbar import com.google.android.material.tabs.TabLayout @@ -77,6 +80,20 @@ class DetailsActivity : BaseActivity(), } } + override fun onWindowInsetsChanged(insets: Insets) { + binding.toolbar.updatePadding( + top = insets.top, + left = insets.left, + right = insets.right + ) + if (binding.tabs.parent !is Toolbar) { + binding.tabs.updatePadding( + left = insets.left, + right = insets.right + ) + } + } + private fun onNewChaptersChanged(newChapters: Int) { val tab = binding.tabs.getTabAt(1) ?: return if (newChapters == 0) { diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt index bca8d423a..a1356d821 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt @@ -5,9 +5,11 @@ import android.text.Spanned import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.graphics.Insets import androidx.core.net.toUri import androidx.core.text.parseAsHtml import androidx.core.view.isVisible +import androidx.core.view.updatePadding import coil.ImageLoader import coil.util.CoilUtils import kotlinx.coroutines.Dispatchers @@ -174,4 +176,12 @@ class DetailsFragment : BaseFragment(), View.OnClickList else -> return false } } + + override fun onWindowInsetsChanged(insets: Insets) { + binding.root.updatePadding( + left = insets.left, + right = insets.right, + bottom = insets.bottom + ) + } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt index 907601d1a..7a39111b8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt @@ -3,6 +3,8 @@ package org.koitharu.kotatsu.favourites.ui import android.os.Bundle import android.os.Parcelable import android.view.* +import androidx.core.graphics.Insets +import androidx.core.view.updatePadding import com.google.android.material.snackbar.Snackbar import com.google.android.material.tabs.TabLayoutMediator import org.koin.androidx.viewmodel.ext.android.viewModel @@ -66,6 +68,13 @@ class FavouritesContainerFragment : BaseFragment(), outState.putParcelable(KEY_ADAPTER_STATE, adapterState) } + override fun onWindowInsetsChanged(insets: Insets) { + binding.tabs.updatePadding( + left = insets.left, + right = insets.right + ) + } + private fun onCategoriesChanged(categories: List) { val data = ArrayList(categories.size + 1) data += FavouriteCategory(0L, getString(R.string.all_favourites), -1, Date()) diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoriesActivity.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoriesActivity.kt index 34483bb43..5efac4e2e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoriesActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoriesActivity.kt @@ -6,7 +6,11 @@ import android.content.res.ColorStateList import android.graphics.Color import android.os.Bundle import android.view.View +import android.view.ViewGroup +import androidx.core.graphics.Insets import androidx.core.view.isVisible +import androidx.core.view.updateLayoutParams +import androidx.core.view.updatePadding import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView @@ -70,6 +74,24 @@ class CategoriesActivity : BaseActivity(), return true } + override fun onWindowInsetsChanged(insets: Insets) { + binding.fabAdd.updateLayoutParams { + rightMargin = topMargin + insets.right + leftMargin = topMargin + insets.left + bottomMargin = topMargin + insets.bottom + } + binding.recyclerView.updatePadding( + left = insets.left, + right = insets.right, + bottom = insets.bottom + ) + binding.toolbar.updatePadding( + left = insets.left, + right = insets.right, + top = insets.top + ) + } + private fun onCategoriesChanged(categories: List) { // TODO check if not moved diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt index c85e571c8..c8b94d176 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt @@ -6,6 +6,7 @@ import android.view.View import android.view.ViewGroup import android.widget.SeekBar import androidx.appcompat.app.AlertDialog +import androidx.core.view.isVisible import androidx.fragment.app.FragmentManager import org.koin.android.ext.android.inject import org.koitharu.kotatsu.R @@ -44,6 +45,8 @@ class ListModeSelectDialog : AlertDialogFragment(), View. binding.buttonList.isChecked = mode == ListMode.LIST binding.buttonListDetailed.isChecked = mode == ListMode.DETAILED_LIST binding.buttonGrid.isChecked = mode == ListMode.GRID + binding.textViewGridTitle.isVisible = mode == ListMode.GRID + binding.seekbarGrid.isVisible = mode == ListMode.GRID with(binding.seekbarGrid) { progress = pendingGridSize - 50 @@ -71,6 +74,8 @@ class ListModeSelectDialog : AlertDialogFragment(), View. R.id.button_list_detailed -> mode = ListMode.DETAILED_LIST R.id.button_grid -> mode = ListMode.GRID } + binding.textViewGridTitle.isVisible = mode == ListMode.GRID + binding.seekbarGrid.isVisible = mode == ListMode.GRID settings.listMode = mode } diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt index c1ef8e674..b4f3bec58 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt @@ -4,9 +4,11 @@ import android.os.Bundle import android.view.* import androidx.annotation.CallSuper import androidx.appcompat.widget.PopupMenu +import androidx.core.graphics.Insets import androidx.core.view.GravityCompat import androidx.core.view.isGone import androidx.core.view.isVisible +import androidx.core.view.updatePadding import androidx.drawerlayout.widget.DrawerLayout import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.GridLayoutManager @@ -195,6 +197,19 @@ abstract class MangaListFragment : BaseFragment(), binding.drawer?.closeDrawers() } + override fun onWindowInsetsChanged(insets: Insets) { + binding.recyclerView.updatePadding( + bottom = insets.bottom + ) + binding.recyclerViewFilter.updatePadding( + bottom = insets.bottom + ) + binding.root.updatePadding( + left = insets.left, + right = insets.right + ) + } + private fun onGridScaleChanged(scale: Float) { spanSizeLookup.invalidateCache() spanResolver.setGridSize(scale, binding.recyclerView) diff --git a/app/src/main/java/org/koitharu/kotatsu/main/MainModule.kt b/app/src/main/java/org/koitharu/kotatsu/main/MainModule.kt index aa8bc5247..7414512d9 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/MainModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/MainModule.kt @@ -3,10 +3,12 @@ package org.koitharu.kotatsu.main import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module import org.koitharu.kotatsu.main.ui.MainViewModel +import org.koitharu.kotatsu.main.ui.protect.AppProtectHelper import org.koitharu.kotatsu.main.ui.protect.ProtectViewModel val mainModule get() = module { + single { AppProtectHelper(get()) } viewModel { MainViewModel(get(), get()) } viewModel { ProtectViewModel(get()) } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt index c6a988383..89bff0d5f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt @@ -9,12 +9,15 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.ActionBarDrawerToggle +import androidx.core.graphics.Insets import androidx.core.view.* import androidx.fragment.app.Fragment import androidx.swiperefreshlayout.widget.CircularProgressDrawable import com.google.android.material.navigation.NavigationView import com.google.android.material.snackbar.Snackbar +import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity @@ -42,6 +45,7 @@ class MainActivity : BaseActivity(), View.OnClickListener { private val viewModel by viewModel() + private val protectHelper by inject() private lateinit var drawerToggle: ActionBarDrawerToggle private var closeable: Closeable? = null @@ -72,7 +76,8 @@ class MainActivity : BaseActivity(), } ?: run { openDefaultSection() } - if (AppProtectHelper.check(this)) { + if (protectHelper.check(this)) { + finish() return } TrackWorker.setup(applicationContext) @@ -86,7 +91,7 @@ class MainActivity : BaseActivity(), override fun onDestroy() { closeable?.close() - AppProtectHelper.lock() + protectHelper.lock() super.onDestroy() } @@ -159,6 +164,19 @@ class MainActivity : BaseActivity(), return true } + override fun onWindowInsetsChanged(insets: Insets) { + binding.toolbar.updatePadding( + top = insets.top, + left = insets.left, + right = insets.right + ) + binding.fab.updateLayoutParams { + bottomMargin = insets.bottom + topMargin + leftMargin = insets.left + topMargin + rightMargin = insets.right + topMargin + } + } + private fun onOpenReader(manga: Manga) { val options = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { ActivityOptions.makeClipRevealAnimation( diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/AppProtectHelper.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/AppProtectHelper.kt index 3b622b771..0b71f21bf 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/AppProtectHelper.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/AppProtectHelper.kt @@ -2,22 +2,18 @@ package org.koitharu.kotatsu.main.ui.protect import android.app.Activity import android.content.Intent -import org.koin.core.component.KoinComponent -import org.koin.core.component.inject import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.main.ui.MainActivity -@Deprecated("TODO not object") -object AppProtectHelper : KoinComponent { +class AppProtectHelper(private val settings: AppSettings) { - val settings by inject() private var isUnlocked = settings.appPassword.isNullOrEmpty() fun unlock(activity: Activity) { isUnlocked = true with(activity) { - startActivity(Intent(this, MainActivity::class.java)) - finishAfterTransition() + startActivity(Intent(this, MainActivity::class.java) + .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)) } } @@ -27,10 +23,8 @@ object AppProtectHelper : KoinComponent { fun check(activity: Activity): Boolean { return if (!isUnlocked) { - with(activity) { - startActivity(ProtectActivity.newIntent(this)) - finishAfterTransition() - } + activity.startActivity(ProtectActivity.newIntent(activity) + .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)) true } else { false diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt index 65d7df8c8..595defa76 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt @@ -10,6 +10,9 @@ import android.view.Menu import android.view.MenuItem import android.view.inputmethod.EditorInfo import android.widget.TextView +import androidx.core.graphics.Insets +import androidx.core.view.updatePadding +import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity @@ -20,6 +23,7 @@ class ProtectActivity : BaseActivity(), TextView.OnEdito TextWatcher { private val viewModel by viewModel() + private val appProtectHelper by inject() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -49,6 +53,14 @@ class ProtectActivity : BaseActivity(), TextView.OnEdito else -> super.onOptionsItemSelected(item) } + override fun onWindowInsetsChanged(insets: Insets) { + binding.toolbar.updatePadding( + left = insets.left, + right = insets.right, + top = insets.top + ) + } + override fun onEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean { return if (actionId == EditorInfo.IME_ACTION_DONE) { viewModel.tryUnlock(binding.editPassword.text.toString().orEmpty()) @@ -67,7 +79,7 @@ class ProtectActivity : BaseActivity(), TextView.OnEdito } private fun onUnlockSuccess(unit: Unit) { - AppProtectHelper.unlock(this) + appProtectHelper.unlock(this) } private fun onError(e: Throwable) { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt index 3afba452c..707997915 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt @@ -54,8 +54,7 @@ import org.koitharu.kotatsu.utils.ext.showAnimated class ReaderActivity : BaseFullscreenActivity(), ChaptersDialog.OnChapterChangeListener, GridTouchHelper.OnGridTouchListener, OnPageSelectListener, ReaderConfigDialog.Callback, - ActivityResultCallback, OnApplyWindowInsetsListener, - ReaderControlDelegate.OnInteractionListener { + ActivityResultCallback, ReaderControlDelegate.OnInteractionListener { private val viewModel by viewModel { parametersOf(MangaIntent.from(intent), intent?.getParcelableExtra(EXTRA_STATE)) @@ -64,6 +63,7 @@ class ReaderActivity : BaseFullscreenActivity(), private lateinit var touchHelper: GridTouchHelper private lateinit var orientationHelper: ScreenOrientationHelper private lateinit var controlDelegate: ReaderControlDelegate + private var gestureInsets: Insets = Insets.NONE private val reader get() = supportFragmentManager.findFragmentById(R.id.container) as? BaseReader<*> @@ -78,8 +78,6 @@ class ReaderActivity : BaseFullscreenActivity(), binding.toolbarBottom.inflateMenu(R.menu.opt_reader_bottom) binding.toolbarBottom.setOnMenuItemClickListener(::onOptionsItemSelected) - ViewCompat.setOnApplyWindowInsetsListener(binding.rootLayout, this) - orientationHelper.observeAutoOrientation() .onEach { binding.toolbarBottom.menu.findItem(R.id.action_screen_rotate).isVisible = !it @@ -230,12 +228,17 @@ class ReaderActivity : BaseFullscreenActivity(), } override fun onProcessTouch(rawX: Int, rawY: Int): Boolean { - return if (binding.appbarTop.hasGlobalPoint(rawX, rawY) - || binding.appbarBottom.hasGlobalPoint(rawX, rawY) + return if ( + rawX <= gestureInsets.left || + rawY <= gestureInsets.top || + rawX >= binding.root.width - gestureInsets.right || + rawY >= binding.root.height - gestureInsets.bottom || + binding.appbarTop.hasGlobalPoint(rawX, rawY) || + binding.appbarBottom.hasGlobalPoint(rawX, rawY) ) { false } else { - val targets = binding.rootLayout.hitTest(rawX, rawY) + val targets = binding.root.hitTest(rawX, rawY) targets.none { it.hasOnClickListeners() } } } @@ -273,6 +276,8 @@ class ReaderActivity : BaseFullscreenActivity(), viewModel.switchMode(mode) } + override fun onWindowInsetsChanged(insets: Insets) = Unit + private fun onPageSaved(uri: Uri?) { if (uri != null) { Snackbar.make(binding.container, R.string.page_saved, Snackbar.LENGTH_LONG) @@ -308,6 +313,7 @@ class ReaderActivity : BaseFullscreenActivity(), } override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + gestureInsets = insets.getInsets(WindowInsetsCompat.Type.systemGestures()) val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) binding.appbarTop.updatePadding( top = systemBars.top, diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/SimpleSettingsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/SimpleSettingsActivity.kt index 6f646203b..1c62b2cce 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/SimpleSettingsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/SimpleSettingsActivity.kt @@ -3,6 +3,8 @@ package org.koitharu.kotatsu.reader.ui import android.content.Context import android.content.Intent import android.os.Bundle +import androidx.core.graphics.Insets +import androidx.core.view.updatePadding import androidx.fragment.app.commit import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R @@ -29,6 +31,14 @@ class SimpleSettingsActivity : BaseActivity() { } } + override fun onWindowInsetsChanged(insets: Insets) { + binding.toolbar.updatePadding( + top = insets.top, + left = insets.left, + right = insets.right + ) + } + companion object { private const val ACTION_READER = diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BaseReader.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BaseReader.kt index 39e955962..12a768b9a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BaseReader.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BaseReader.kt @@ -2,6 +2,7 @@ package org.koitharu.kotatsu.reader.ui.pager import android.os.Bundle import android.view.View +import androidx.core.graphics.Insets import androidx.lifecycle.lifecycleScope import androidx.viewbinding.ViewBinding import org.koin.android.ext.android.get @@ -42,6 +43,8 @@ abstract class BaseReader : BaseFragment() { outState.putParcelable(KEY_STATE, lastReaderState) } + override fun onWindowInsetsChanged(insets: Insets) = Unit + abstract fun switchPageBy(delta: Int) abstract fun switchPageTo(position: Int, smooth: Boolean) diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchActivity.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchActivity.kt index aa11a4959..05092438f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchActivity.kt @@ -5,6 +5,8 @@ import android.content.Intent import android.os.Bundle import android.os.Parcelable import androidx.appcompat.widget.SearchView +import androidx.core.graphics.Insets +import androidx.core.view.updatePadding import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.core.model.MangaSource @@ -44,6 +46,14 @@ class SearchActivity : BaseActivity(), SearchView.OnQuery super.onDestroy() } + override fun onWindowInsetsChanged(insets: Insets) { + binding.toolbar.updatePadding( + top = insets.top, + left = insets.left, + right = insets.right + ) + } + override fun onQueryTextSubmit(query: String?): Boolean { return if (!query.isNullOrBlank()) { title = query diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchActivity.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchActivity.kt index 798d26f33..b1228d4bf 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchActivity.kt @@ -3,6 +3,8 @@ package org.koitharu.kotatsu.search.ui.global import android.content.Context import android.content.Intent import android.os.Bundle +import androidx.core.graphics.Insets +import androidx.core.view.updatePadding import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.databinding.ActivitySearchGlobalBinding @@ -28,6 +30,14 @@ class GlobalSearchActivity : BaseActivity() { .commit() } + override fun onWindowInsetsChanged(insets: Insets) { + binding.toolbar.updatePadding( + top = insets.top, + left = insets.left, + right = insets.right + ) + } + companion object { private const val EXTRA_QUERY = "query" diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/MainSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/MainSettingsFragment.kt index 8f1e75c63..574004a70 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/MainSettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/MainSettingsFragment.kt @@ -52,6 +52,8 @@ class MainSettingsFragment : BasePreferenceFragment(R.string.settings), MultiSummaryProvider(R.string.gestures_only) findPreference(AppSettings.KEY_TRACK_SOURCES)?.summaryProvider = MultiSummaryProvider(R.string.dont_check) + findPreference(AppSettings.KEY_GRID_SIZE)?.isEnabled = + settings.listMode == ListMode.GRID } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -91,6 +93,10 @@ class MainSettingsFragment : BasePreferenceFragment(R.string.settings), ?: getString(R.string.not_available) } } + AppSettings.KEY_LIST_MODE -> { + findPreference(AppSettings.KEY_GRID_SIZE)?.isEnabled = + settings.listMode == ListMode.GRID + } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/NotificationSettingsLegacyFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/NotificationSettingsLegacyFragment.kt index 8643fae82..1d560c2d0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/NotificationSettingsLegacyFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/NotificationSettingsLegacyFragment.kt @@ -1,9 +1,11 @@ package org.koitharu.kotatsu.settings +import android.content.Context import android.media.RingtoneManager import android.os.Bundle import android.view.View import androidx.preference.Preference +import org.koin.android.ext.android.get import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BasePreferenceFragment import org.koitharu.kotatsu.core.prefs.AppSettings @@ -12,6 +14,15 @@ import org.koitharu.kotatsu.utils.ext.toUriOrNull class NotificationSettingsLegacyFragment : BasePreferenceFragment(R.string.notifications) { + private val ringtonePickContract = registerForActivityResult( + RingtonePickContract(get().getString(R.string.notification_sound)) + ) { uri -> + settings.notificationSound = uri?.toString().orEmpty() + findPreference(AppSettings.KEY_NOTIFICATIONS_SOUND)?.run { + summary = RingtoneManager.getRingtone(context, uri).getTitle(context) + } + } + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.pref_notifications) } @@ -27,12 +38,7 @@ class NotificationSettingsLegacyFragment : BasePreferenceFragment(R.string.notif override fun onPreferenceTreeClick(preference: Preference?): Boolean { return when (preference?.key) { AppSettings.KEY_NOTIFICATIONS_SOUND -> { - registerForActivityResult(RingtonePickContract(preference.title.toString())) { uri -> - settings.notificationSound = uri?.toString().orEmpty() - findPreference(AppSettings.KEY_NOTIFICATIONS_SOUND)?.run { - summary = RingtoneManager.getRingtone(context, uri).getTitle(context) - } - }.launch(settings.notificationSound.toUriOrNull()) + ringtonePickContract.launch(settings.notificationSound.toUriOrNull()) true } else -> super.onPreferenceTreeClick(preference) diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/SettingsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/settings/SettingsActivity.kt index 2972fd239..174a23057 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/SettingsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/SettingsActivity.kt @@ -3,6 +3,8 @@ package org.koitharu.kotatsu.settings import android.content.Context import android.content.Intent import android.os.Bundle +import androidx.core.graphics.Insets +import androidx.core.view.updatePadding import androidx.fragment.app.Fragment import androidx.fragment.app.commit import androidx.preference.Preference @@ -56,6 +58,14 @@ class SettingsActivity : BaseActivity(), } } + override fun onWindowInsetsChanged(insets: Insets) { + binding.toolbar.updatePadding( + top = insets.top, + left = insets.left, + right = insets.right + ) + } + companion object { fun newIntent(context: Context) = Intent(context, SettingsActivity::class.java) diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt index cc8ad3f10..9c30c32cb 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt @@ -4,6 +4,8 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.graphics.Insets +import androidx.core.view.updatePadding import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView @@ -49,6 +51,14 @@ class SourcesSettingsFragment : BaseFragment(), super.onDestroyView() } + override fun onWindowInsetsChanged(insets: Insets) { + binding.recyclerView.updatePadding( + bottom = insets.bottom, + left = insets.left, + right = insets.right + ) + } + override fun onItemClick(item: MangaSource, view: View) { (activity as? SettingsActivity)?.openMangaSourceSettings(item) } diff --git a/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt index af64c9ca8..f6d88c124 100644 --- a/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt @@ -2,7 +2,8 @@ package org.koitharu.kotatsu.tracker.ui import android.os.Bundle import android.view.* -import androidx.core.view.isVisible +import androidx.core.graphics.Insets +import androidx.core.view.updatePadding import com.google.android.material.snackbar.Snackbar import org.koin.android.ext.android.get import org.koin.androidx.viewmodel.ext.android.viewModel @@ -18,7 +19,6 @@ import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.tracker.ui.adapter.FeedAdapter import org.koitharu.kotatsu.tracker.work.TrackWorker import org.koitharu.kotatsu.utils.ext.getDisplayMessage -import org.koitharu.kotatsu.utils.ext.hasItems class FeedFragment : BaseFragment(), PaginationScrollListener.Callback, OnListItemClickListener { @@ -52,9 +52,7 @@ class FeedFragment : BaseFragment(), PaginationScrollListen } viewModel.content.observe(viewLifecycleOwner, this::onListChanged) - viewModel.isLoading.observe(viewLifecycleOwner, this::onLoadingStateChanged) viewModel.onError.observe(viewLifecycleOwner, this::onError) - viewModel.isEmptyState.observe(viewLifecycleOwner, this::onEmptyStateChanged) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { @@ -80,41 +78,24 @@ class FeedFragment : BaseFragment(), PaginationScrollListen super.onDestroyView() } + override fun onWindowInsetsChanged(insets: Insets) { + binding.recyclerView.updatePadding( + left = insets.left, + right = insets.right, + bottom = insets.bottom + ) + } + private fun onListChanged(list: List) { feedAdapter?.items = list } private fun onError(e: Throwable) { - if (binding.recyclerView.hasItems) { - Snackbar.make( - binding.recyclerView, - e.getDisplayMessage(resources), - Snackbar.LENGTH_SHORT - ).show() - } else { - with(binding.textViewHolder) { - text = e.getDisplayMessage(resources) - setCompoundDrawablesRelativeWithIntrinsicBounds( - 0, - R.drawable.ic_error_large, - 0, - 0 - ) - isVisible = true - } - } - } - - private fun onLoadingStateChanged(isLoading: Boolean) { - val hasItems = binding.recyclerView.hasItems - binding.progressBar.isVisible = isLoading && !hasItems - } - - private fun onEmptyStateChanged(isEmpty: Boolean) { - if (isEmpty) { - setUpEmptyListHolder() - } - binding.layoutHolder.isVisible = isEmpty + Snackbar.make( + binding.recyclerView, + e.getDisplayMessage(resources), + Snackbar.LENGTH_SHORT + ).show() } override fun onScrolledToEnd() { @@ -125,13 +106,6 @@ class FeedFragment : BaseFragment(), PaginationScrollListen startActivity(DetailsActivity.newIntent(context ?: return, item)) } - private fun setUpEmptyListHolder() { - with(binding.textViewHolder) { - setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null) - setText(R.string.text_feed_holder) - } - } - companion object { fun newInstance() = FeedFragment() diff --git a/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedViewModel.kt index 28fb7564e..d91e9d449 100644 --- a/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedViewModel.kt @@ -9,8 +9,10 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.flowOn +import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseViewModel import org.koitharu.kotatsu.core.model.TrackingLogItem +import org.koitharu.kotatsu.list.ui.model.EmptyState import org.koitharu.kotatsu.list.ui.model.LoadingFooter import org.koitharu.kotatsu.list.ui.model.LoadingState import org.koitharu.kotatsu.tracker.domain.TrackingRepository @@ -34,7 +36,11 @@ class FeedViewModel( }, hasNextPage ) { list, isHasNextPage -> - if (isHasNextPage && list.isNotEmpty()) list + LoadingFooter else list + when { + list.isEmpty() -> listOf(EmptyState(R.string.text_feed_holder)) + isHasNextPage -> list + LoadingFooter + else -> list + } }.flowOn(Dispatchers.Default).asLiveData(viewModelScope.coroutineContext, listOf(LoadingState)) init { diff --git a/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfConfigActivity.kt b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfConfigActivity.kt index 0d8cfa567..e8c506f5b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfConfigActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfConfigActivity.kt @@ -9,7 +9,11 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.view.View +import android.view.ViewGroup +import androidx.core.graphics.Insets import androidx.core.view.isVisible +import androidx.core.view.updateLayoutParams +import androidx.core.view.updatePadding import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.RecyclerView import com.google.android.material.snackbar.Snackbar @@ -77,6 +81,24 @@ class ShelfConfigActivity : BaseActivity(), OnListIte viewModel.checkedId = item.id } + override fun onWindowInsetsChanged(insets: Insets) { + binding.fabAdd.updateLayoutParams { + rightMargin = topMargin + insets.right + leftMargin = topMargin + insets.left + bottomMargin = topMargin + insets.bottom + } + binding.recyclerView.updatePadding( + left = insets.left, + right = insets.right, + bottom = insets.bottom + ) + binding.toolbar.updatePadding( + left = insets.left, + right = insets.right, + top = insets.top + ) + } + private fun onContentChanged(categories: List) { adapter.items = categories } diff --git a/app/src/main/res/layout-w600dp/activity_details.xml b/app/src/main/res/layout-w600dp/activity_details.xml new file mode 100644 index 000000000..b7df3ee38 --- /dev/null +++ b/app/src/main/res/layout-w600dp/activity_details.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-w600dp/fragment_details.xml b/app/src/main/res/layout-w600dp/fragment_details.xml index cc251c658..2d2640a9c 100644 --- a/app/src/main/res/layout-w600dp/fragment_details.xml +++ b/app/src/main/res/layout-w600dp/fragment_details.xml @@ -3,6 +3,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" + android:clipToPadding="false" android:layout_width="match_parent" android:layout_height="wrap_content"> diff --git a/app/src/main/res/layout/activity_browser.xml b/app/src/main/res/layout/activity_browser.xml index daa9d5374..b4976b58b 100644 --- a/app/src/main/res/layout/activity_browser.xml +++ b/app/src/main/res/layout/activity_browser.xml @@ -11,7 +11,6 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:background="?colorPrimary" - android:fitsSystemWindows="true" android:theme="@style/AppToolbarTheme" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/app/src/main/res/layout/activity_categories.xml b/app/src/main/res/layout/activity_categories.xml index 858b32c57..693a0268e 100644 --- a/app/src/main/res/layout/activity_categories.xml +++ b/app/src/main/res/layout/activity_categories.xml @@ -11,7 +11,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?colorPrimary" - android:fitsSystemWindows="true" android:theme="@style/AppToolbarTheme"> diff --git a/app/src/main/res/layout/activity_details.xml b/app/src/main/res/layout/activity_details.xml index 7141a1c98..d39f66ee8 100644 --- a/app/src/main/res/layout/activity_details.xml +++ b/app/src/main/res/layout/activity_details.xml @@ -7,6 +7,7 @@ tools:context=".details.ui.DetailsActivity"> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_reader.xml b/app/src/main/res/layout/activity_reader.xml index 0e1f66a4d..e12b2e329 100644 --- a/app/src/main/res/layout/activity_reader.xml +++ b/app/src/main/res/layout/activity_reader.xml @@ -2,7 +2,6 @@ diff --git a/app/src/main/res/layout/activity_search.xml b/app/src/main/res/layout/activity_search.xml index ed6ec9847..ae3bddf4e 100644 --- a/app/src/main/res/layout/activity_search.xml +++ b/app/src/main/res/layout/activity_search.xml @@ -10,7 +10,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?colorPrimary" - android:fitsSystemWindows="true" android:theme="@style/AppToolbarTheme"> diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 593f51174..2fa97a72c 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -7,19 +7,20 @@ android:orientation="vertical"> + android:theme="@style/AppToolbarTheme"> - + - + diff --git a/app/src/main/res/layout/dialog_list_mode.xml b/app/src/main/res/layout/dialog_list_mode.xml index d11c45009..b99d9039b 100644 --- a/app/src/main/res/layout/dialog_list_mode.xml +++ b/app/src/main/res/layout/dialog_list_mode.xml @@ -5,6 +5,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" + android:animateLayoutChanges="true" android:orientation="vertical"> + android:text="@string/grid_size" + android:visibility="gone" + tools:visibility="visible" /> + android:visibility="gone" + tools:progress="50" + tools:visibility="visible" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_details.xml b/app/src/main/res/layout/fragment_details.xml index 90cd6ce1a..ce03c8da6 100644 --- a/app/src/main/res/layout/fragment_details.xml +++ b/app/src/main/res/layout/fragment_details.xml @@ -3,6 +3,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" + android:clipToPadding="false" android:layout_width="match_parent" android:layout_height="wrap_content"> diff --git a/app/src/main/res/layout/fragment_feed.xml b/app/src/main/res/layout/fragment_feed.xml index a5fa8e6fd..81dbf4d9a 100644 --- a/app/src/main/res/layout/fragment_feed.xml +++ b/app/src/main/res/layout/fragment_feed.xml @@ -1,47 +1,18 @@ - - - - - - - - - - - - - \ No newline at end of file + android:layout_height="match_parent" + android:clipToPadding="false" + android:orientation="vertical" + android:scrollbars="vertical" + app:fastScrollEnabled="true" + app:fastScrollHorizontalThumbDrawable="@drawable/list_thumb" + app:fastScrollHorizontalTrackDrawable="@drawable/list_track" + app:fastScrollVerticalThumbDrawable="@drawable/list_thumb" + app:fastScrollVerticalTrackDrawable="@drawable/list_track" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + tools:listitem="@layout/item_tracklog" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_list.xml b/app/src/main/res/layout/fragment_list.xml index 91940022c..d7180ceef 100644 --- a/app/src/main/res/layout/fragment_list.xml +++ b/app/src/main/res/layout/fragment_list.xml @@ -21,6 +21,7 @@ android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" + android:clipToPadding="false" android:orientation="vertical" android:scrollbars="vertical" app:fastScrollEnabled="true" @@ -39,6 +40,7 @@ android:layout_height="match_parent" android:layout_gravity="end" android:background="?android:windowBackground" + android:clipToPadding="false" android:orientation="vertical" android:scrollbars="vertical" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" diff --git a/app/src/main/res/layout/fragment_settings_sources.xml b/app/src/main/res/layout/fragment_settings_sources.xml index 8ecbd9326..c65d18705 100644 --- a/app/src/main/res/layout/fragment_settings_sources.xml +++ b/app/src/main/res/layout/fragment_settings_sources.xml @@ -6,6 +6,7 @@ android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" + android:clipToPadding="false" android:orientation="vertical" android:scrollbars="vertical" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" diff --git a/app/src/main/res/layout/item_manga_grid.xml b/app/src/main/res/layout/item_manga_grid.xml index 5afef9726..7f13544f4 100644 --- a/app/src/main/res/layout/item_manga_grid.xml +++ b/app/src/main/res/layout/item_manga_grid.xml @@ -1,14 +1,9 @@ + android:layout_height="wrap_content"> + android:layout_height="@dimen/manga_list_details_item_height"> + android:layout_height="wrap_content"> + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index c8b08fa48..221e38bef 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -8,4 +8,5 @@ #212121 #99000000 #D32F2F + #33000000 \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 8767267a1..4d3014e85 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -6,6 +6,7 @@ @style/AppActionMode @style/PreferenceThemeOverlay @style/Widget.MaterialComponents.Badge + @color/status_bar