Merge branch 'feature/desktop-ui' into devel
This commit is contained in:
@@ -31,7 +31,7 @@ abstract class BaseActivity<B : ViewBinding> : AppCompatActivity(), OnApplyWindo
|
|||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
protected val exceptionResolver = ExceptionResolver(this)
|
protected val exceptionResolver = ExceptionResolver(this)
|
||||||
|
|
||||||
private var lastInsets: Insets = Insets.NONE
|
private var lastInsets: Insets? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
val settings = get<AppSettings>()
|
val settings = get<AppSettings>()
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ abstract class BaseBottomSheet<B : ViewBinding> : BottomSheetDialogFragment() {
|
|||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
return if (resources.getBoolean(R.bool.is_tablet)) {
|
return if (resources.getBoolean(R.bool.is_tablet)) {
|
||||||
AppCompatDialog(context, theme)
|
AppCompatDialog(context, R.style.Theme_Kotatsu_Dialog)
|
||||||
} else super.onCreateDialog(savedInstanceState)
|
} else super.onCreateDialog(savedInstanceState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import androidx.core.graphics.Insets
|
|||||||
import androidx.core.view.OnApplyWindowInsetsListener
|
import androidx.core.view.OnApplyWindowInsetsListener
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.core.view.doOnNextLayout
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
|
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
|
||||||
@@ -22,7 +23,7 @@ abstract class BaseFragment<B : ViewBinding> : Fragment(), OnApplyWindowInsetsLi
|
|||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
protected val exceptionResolver = ExceptionResolver(this)
|
protected val exceptionResolver = ExceptionResolver(this)
|
||||||
|
|
||||||
private var lastInsets: Insets = Insets.NONE
|
private var lastInsets: Insets? = null
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
@@ -36,12 +37,18 @@ abstract class BaseFragment<B : ViewBinding> : Fragment(), OnApplyWindowInsetsLi
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
lastInsets = Insets.NONE
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(view, this)
|
ViewCompat.setOnApplyWindowInsetsListener(view, this)
|
||||||
|
view.doOnNextLayout {
|
||||||
|
// Listener may not be called
|
||||||
|
if (lastInsets == null) {
|
||||||
|
onWindowInsetsChanged(Insets.NONE)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
viewBinding = null
|
viewBinding = null
|
||||||
|
lastInsets = null
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.app.ActivityOptions
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.widget.AdapterView
|
import android.widget.AdapterView
|
||||||
|
import android.widget.Spinner
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
import androidx.core.graphics.Insets
|
import androidx.core.graphics.Insets
|
||||||
@@ -24,6 +25,7 @@ import org.koitharu.kotatsu.download.ui.service.DownloadService
|
|||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
import org.koitharu.kotatsu.reader.ui.ReaderActivity
|
import org.koitharu.kotatsu.reader.ui.ReaderActivity
|
||||||
import org.koitharu.kotatsu.reader.ui.ReaderState
|
import org.koitharu.kotatsu.reader.ui.ReaderState
|
||||||
|
import org.koitharu.kotatsu.utils.RecyclerViewScrollCallback
|
||||||
|
|
||||||
class ChaptersFragment : BaseFragment<FragmentChaptersBinding>(),
|
class ChaptersFragment : BaseFragment<FragmentChaptersBinding>(),
|
||||||
OnListItemClickListener<ChapterListItem>,
|
OnListItemClickListener<ChapterListItem>,
|
||||||
@@ -56,21 +58,9 @@ class ChaptersFragment : BaseFragment<FragmentChaptersBinding>(),
|
|||||||
setHasFixedSize(true)
|
setHasFixedSize(true)
|
||||||
adapter = chaptersAdapter
|
adapter = chaptersAdapter
|
||||||
}
|
}
|
||||||
val branchesAdapter = BranchesAdapter()
|
binding.spinnerBranches?.let(::initSpinner)
|
||||||
binding.spinnerBranches.adapter = branchesAdapter
|
|
||||||
binding.spinnerBranches.onItemSelectedListener = this
|
|
||||||
|
|
||||||
viewModel.isLoading.observe(viewLifecycleOwner, this::onLoadingStateChanged)
|
viewModel.isLoading.observe(viewLifecycleOwner, this::onLoadingStateChanged)
|
||||||
viewModel.chapters.observe(viewLifecycleOwner, this::onChaptersChanged)
|
viewModel.chapters.observe(viewLifecycleOwner, this::onChaptersChanged)
|
||||||
viewModel.branches.observe(viewLifecycleOwner) {
|
|
||||||
branchesAdapter.setItems(it)
|
|
||||||
binding.spinnerBranches.isVisible = it.size > 1
|
|
||||||
}
|
|
||||||
viewModel.selectedBranchIndex.observe(viewLifecycleOwner) {
|
|
||||||
if (it != -1 && it != binding.spinnerBranches.selectedItemPosition) {
|
|
||||||
binding.spinnerBranches.setSelection(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
viewModel.isChaptersReversed.observe(viewLifecycleOwner) {
|
viewModel.isChaptersReversed.observe(viewLifecycleOwner) {
|
||||||
activity?.invalidateOptionsMenu()
|
activity?.invalidateOptionsMenu()
|
||||||
}
|
}
|
||||||
@@ -79,7 +69,7 @@ class ChaptersFragment : BaseFragment<FragmentChaptersBinding>(),
|
|||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
chaptersAdapter = null
|
chaptersAdapter = null
|
||||||
selectionDecoration = null
|
selectionDecoration = null
|
||||||
binding.spinnerBranches.adapter = null
|
binding.spinnerBranches?.adapter = null
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +156,8 @@ class ChaptersFragment : BaseFragment<FragmentChaptersBinding>(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||||
viewModel.setSelectedBranch(binding.spinnerBranches.selectedItem as String?)
|
val spinner = binding.spinnerBranches ?: return
|
||||||
|
viewModel.setSelectedBranch(spinner.selectedItem as String?)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNothingSelected(parent: AdapterView<*>?) = Unit
|
override fun onNothingSelected(parent: AdapterView<*>?) = Unit
|
||||||
@@ -201,14 +192,37 @@ class ChaptersFragment : BaseFragment<FragmentChaptersBinding>(),
|
|||||||
|
|
||||||
override fun onWindowInsetsChanged(insets: Insets) {
|
override fun onWindowInsetsChanged(insets: Insets) {
|
||||||
binding.recyclerViewChapters.updatePadding(
|
binding.recyclerViewChapters.updatePadding(
|
||||||
left = insets.left,
|
bottom = insets.bottom + (binding.spinnerBranches?.height ?: 0),
|
||||||
right = insets.right,
|
|
||||||
bottom = insets.bottom + binding.spinnerBranches.height
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initSpinner(spinner: Spinner) {
|
||||||
|
val branchesAdapter = BranchesAdapter()
|
||||||
|
spinner.adapter = branchesAdapter
|
||||||
|
spinner.onItemSelectedListener = this
|
||||||
|
viewModel.branches.observe(viewLifecycleOwner) {
|
||||||
|
branchesAdapter.setItems(it)
|
||||||
|
spinner.isVisible = it.size > 1
|
||||||
|
}
|
||||||
|
viewModel.selectedBranchIndex.observe(viewLifecycleOwner) {
|
||||||
|
if (it != -1 && it != spinner.selectedItemPosition) {
|
||||||
|
spinner.setSelection(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun onChaptersChanged(list: List<ChapterListItem>) {
|
private fun onChaptersChanged(list: List<ChapterListItem>) {
|
||||||
chaptersAdapter?.items = list
|
val adapter = chaptersAdapter ?: return
|
||||||
|
if (adapter.itemCount == 0) {
|
||||||
|
val position = list.indexOfFirst { it.hasFlag(ChapterListItem.FLAG_CURRENT) } - 1
|
||||||
|
if (position > 0) {
|
||||||
|
adapter.setItems(list, RecyclerViewScrollCallback(binding.recyclerViewChapters, position))
|
||||||
|
} else {
|
||||||
|
adapter.items = list
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
adapter.items = list
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onLoadingStateChanged(isLoading: Boolean) {
|
private fun onLoadingStateChanged(isLoading: Boolean) {
|
||||||
|
|||||||
@@ -6,25 +6,26 @@ import android.net.Uri
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.AdapterView
|
||||||
|
import android.widget.Spinner
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
import androidx.appcompat.widget.Toolbar
|
|
||||||
import androidx.core.content.pm.ShortcutManagerCompat
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
import androidx.core.graphics.Insets
|
import androidx.core.graphics.Insets
|
||||||
import androidx.core.net.toFile
|
import androidx.core.net.toFile
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.updateLayoutParams
|
import androidx.core.view.updateLayoutParams
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.android.material.snackbar.Snackbar
|
|
||||||
import com.google.android.material.tabs.TabLayout
|
import com.google.android.material.tabs.TabLayout
|
||||||
import com.google.android.material.tabs.TabLayoutMediator
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koin.android.ext.android.get
|
import org.koin.android.ext.android.get
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
import org.koin.core.parameter.parametersOf
|
import org.koin.core.parameter.parametersOf
|
||||||
import org.koitharu.kotatsu.BuildConfig
|
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.base.domain.MangaIntent
|
import org.koitharu.kotatsu.base.domain.MangaIntent
|
||||||
import org.koitharu.kotatsu.base.ui.BaseActivity
|
import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||||
@@ -34,6 +35,7 @@ import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException
|
|||||||
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
||||||
import org.koitharu.kotatsu.core.os.ShortcutsRepository
|
import org.koitharu.kotatsu.core.os.ShortcutsRepository
|
||||||
import org.koitharu.kotatsu.databinding.ActivityDetailsBinding
|
import org.koitharu.kotatsu.databinding.ActivityDetailsBinding
|
||||||
|
import org.koitharu.kotatsu.details.ui.adapter.BranchesAdapter
|
||||||
import org.koitharu.kotatsu.download.ui.service.DownloadService
|
import org.koitharu.kotatsu.download.ui.service.DownloadService
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
@@ -43,8 +45,8 @@ import org.koitharu.kotatsu.search.ui.global.GlobalSearchActivity
|
|||||||
import org.koitharu.kotatsu.utils.ShareHelper
|
import org.koitharu.kotatsu.utils.ShareHelper
|
||||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||||
|
|
||||||
class DetailsActivity : BaseActivity<ActivityDetailsBinding>(),
|
class DetailsActivity : BaseActivity<ActivityDetailsBinding>(), TabLayoutMediator.TabConfigurationStrategy,
|
||||||
TabLayoutMediator.TabConfigurationStrategy {
|
AdapterView.OnItemSelectedListener {
|
||||||
|
|
||||||
private val viewModel by viewModel<DetailsViewModel> {
|
private val viewModel by viewModel<DetailsViewModel> {
|
||||||
parametersOf(MangaIntent(intent))
|
parametersOf(MangaIntent(intent))
|
||||||
@@ -53,9 +55,16 @@ class DetailsActivity : BaseActivity<ActivityDetailsBinding>(),
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(ActivityDetailsBinding.inflate(layoutInflater))
|
setContentView(ActivityDetailsBinding.inflate(layoutInflater))
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.run {
|
||||||
binding.pager.adapter = MangaDetailsAdapter(this)
|
setDisplayHomeAsUpEnabled(true)
|
||||||
TabLayoutMediator(binding.tabs, binding.pager, this).attach()
|
setDisplayShowTitleEnabled(false)
|
||||||
|
}
|
||||||
|
val pager = binding.pager
|
||||||
|
if (pager != null) {
|
||||||
|
pager.adapter = MangaDetailsAdapter(this)
|
||||||
|
TabLayoutMediator(checkNotNull(binding.tabs), pager, this).attach()
|
||||||
|
}
|
||||||
|
binding.spinnerBranches?.let(::initSpinner)
|
||||||
|
|
||||||
viewModel.manga.observe(this, ::onMangaUpdated)
|
viewModel.manga.observe(this, ::onMangaUpdated)
|
||||||
viewModel.newChaptersCount.observe(this, ::onNewChaptersChanged)
|
viewModel.newChaptersCount.observe(this, ::onNewChaptersChanged)
|
||||||
@@ -96,25 +105,17 @@ class DetailsActivity : BaseActivity<ActivityDetailsBinding>(),
|
|||||||
binding.snackbar.updatePadding(
|
binding.snackbar.updatePadding(
|
||||||
bottom = insets.bottom
|
bottom = insets.bottom
|
||||||
)
|
)
|
||||||
with(binding.toolbar) {
|
binding.toolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
updatePadding(
|
|
||||||
left = insets.left,
|
|
||||||
right = insets.right
|
|
||||||
)
|
|
||||||
updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
|
||||||
topMargin = insets.top
|
topMargin = insets.top
|
||||||
}
|
}
|
||||||
}
|
binding.root.updatePadding(
|
||||||
if (binding.tabs.parent !is Toolbar) {
|
|
||||||
binding.tabs.updatePadding(
|
|
||||||
left = insets.left,
|
left = insets.left,
|
||||||
right = insets.right
|
right = insets.right
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun onNewChaptersChanged(newChapters: Int) {
|
private fun onNewChaptersChanged(newChapters: Int) {
|
||||||
val tab = binding.tabs.getTabAt(1) ?: return
|
val tab = binding.tabs?.getTabAt(1) ?: return
|
||||||
if (newChapters == 0) {
|
if (newChapters == 0) {
|
||||||
tab.removeBadge()
|
tab.removeBadge()
|
||||||
} else {
|
} else {
|
||||||
@@ -208,11 +209,7 @@ class DetailsActivity : BaseActivity<ActivityDetailsBinding>(),
|
|||||||
viewModel.manga.value?.let {
|
viewModel.manga.value?.let {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
if (!get<ShortcutsRepository>().requestPinShortcut(it)) {
|
if (!get<ShortcutsRepository>().requestPinShortcut(it)) {
|
||||||
Snackbar.make(
|
binding.snackbar.show(getString(R.string.operation_not_supported))
|
||||||
binding.pager,
|
|
||||||
R.string.operation_not_supported,
|
|
||||||
Snackbar.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,19 +228,25 @@ class DetailsActivity : BaseActivity<ActivityDetailsBinding>(),
|
|||||||
|
|
||||||
override fun onSupportActionModeStarted(mode: ActionMode) {
|
override fun onSupportActionModeStarted(mode: ActionMode) {
|
||||||
super.onSupportActionModeStarted(mode)
|
super.onSupportActionModeStarted(mode)
|
||||||
binding.pager.isUserInputEnabled = false
|
binding.pager?.isUserInputEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSupportActionModeFinished(mode: ActionMode) {
|
override fun onSupportActionModeFinished(mode: ActionMode) {
|
||||||
super.onSupportActionModeFinished(mode)
|
super.onSupportActionModeFinished(mode)
|
||||||
binding.pager.isUserInputEnabled = true
|
binding.pager?.isUserInputEnabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||||
|
val spinner = binding.spinnerBranches ?: return
|
||||||
|
viewModel.setSelectedBranch(spinner.selectedItem as String?)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNothingSelected(parent: AdapterView<*>?) = Unit
|
||||||
|
|
||||||
fun showChapterMissingDialog(chapterId: Long) {
|
fun showChapterMissingDialog(chapterId: Long) {
|
||||||
val remoteManga = viewModel.getRemoteManga()
|
val remoteManga = viewModel.getRemoteManga()
|
||||||
if (remoteManga == null) {
|
if (remoteManga == null) {
|
||||||
Snackbar.make(binding.pager, R.string.chapter_is_missing, Snackbar.LENGTH_LONG)
|
binding.snackbar.show(getString( R.string.chapter_is_missing))
|
||||||
.show()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
MaterialAlertDialogBuilder(this).apply {
|
MaterialAlertDialogBuilder(this).apply {
|
||||||
@@ -266,9 +269,22 @@ class DetailsActivity : BaseActivity<ActivityDetailsBinding>(),
|
|||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
private fun initSpinner(spinner: Spinner) {
|
||||||
|
val branchesAdapter = BranchesAdapter()
|
||||||
|
spinner.adapter = branchesAdapter
|
||||||
|
spinner.onItemSelectedListener = this
|
||||||
|
viewModel.branches.observe(this) {
|
||||||
|
branchesAdapter.setItems(it)
|
||||||
|
spinner.isVisible = it.size > 1
|
||||||
|
}
|
||||||
|
viewModel.selectedBranchIndex.observe(this) {
|
||||||
|
if (it != -1 && it != spinner.selectedItemPosition) {
|
||||||
|
spinner.setSelection(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const val ACTION_MANGA_VIEW = "${BuildConfig.APPLICATION_ID}.action.VIEW_MANGA"
|
companion object {
|
||||||
|
|
||||||
fun newIntent(context: Context, manga: Manga): Intent {
|
fun newIntent(context: Context, manga: Manga): Intent {
|
||||||
return Intent(context, DetailsActivity::class.java)
|
return Intent(context, DetailsActivity::class.java)
|
||||||
|
|||||||
@@ -243,9 +243,7 @@ class DetailsFragment : BaseFragment<FragmentDetailsBinding>(), View.OnClickList
|
|||||||
|
|
||||||
override fun onWindowInsetsChanged(insets: Insets) {
|
override fun onWindowInsetsChanged(insets: Insets) {
|
||||||
binding.root.updatePadding(
|
binding.root.updatePadding(
|
||||||
left = insets.left,
|
bottom = insets.bottom,
|
||||||
right = insets.right,
|
|
||||||
bottom = insets.bottom
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -176,17 +176,19 @@ abstract class MangaListFragment : BaseFragment<FragmentListBinding>(),
|
|||||||
val headerHeight = (activity as? AppBarOwner)?.appBar?.measureHeight() ?: insets.top
|
val headerHeight = (activity as? AppBarOwner)?.appBar?.measureHeight() ?: insets.top
|
||||||
binding.root.updatePadding(
|
binding.root.updatePadding(
|
||||||
left = insets.left,
|
left = insets.left,
|
||||||
right = insets.right
|
right = insets.right,
|
||||||
)
|
)
|
||||||
if (activity is MainActivity) {
|
if (activity is MainActivity) {
|
||||||
|
val topOffsetDiff = binding.recyclerView.paddingTop - headerHeight
|
||||||
binding.recyclerView.updatePadding(
|
binding.recyclerView.updatePadding(
|
||||||
top = headerHeight,
|
top = headerHeight,
|
||||||
bottom = insets.bottom
|
bottom = insets.bottom,
|
||||||
)
|
)
|
||||||
|
binding.recyclerView.scrollBy(0, topOffsetDiff)
|
||||||
binding.swipeRefreshLayout.setProgressViewOffset(
|
binding.swipeRefreshLayout.setProgressViewOffset(
|
||||||
true,
|
true,
|
||||||
headerHeight + resources.resolveDp(-72),
|
headerHeight + resources.resolveDp(-72),
|
||||||
headerHeight + resources.resolveDp(10)
|
headerHeight + resources.resolveDp(10),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,15 @@ import android.view.ViewGroup.MarginLayoutParams
|
|||||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.graphics.Insets
|
import androidx.core.graphics.Insets
|
||||||
import androidx.core.view.*
|
import androidx.core.view.GravityCompat
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.updateLayoutParams
|
||||||
|
import androidx.core.view.updatePadding
|
||||||
import androidx.drawerlayout.widget.DrawerLayout
|
import androidx.drawerlayout.widget.DrawerLayout
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentTransaction
|
import androidx.fragment.app.FragmentTransaction
|
||||||
import androidx.fragment.app.commit
|
import androidx.fragment.app.commit
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import androidx.swiperefreshlayout.widget.CircularProgressDrawable
|
import androidx.swiperefreshlayout.widget.CircularProgressDrawable
|
||||||
import com.google.android.material.appbar.AppBarLayout
|
import com.google.android.material.appbar.AppBarLayout
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
@@ -55,10 +57,7 @@ import org.koitharu.kotatsu.suggestions.ui.SuggestionsFragment
|
|||||||
import org.koitharu.kotatsu.suggestions.ui.SuggestionsWorker
|
import org.koitharu.kotatsu.suggestions.ui.SuggestionsWorker
|
||||||
import org.koitharu.kotatsu.tracker.ui.FeedFragment
|
import org.koitharu.kotatsu.tracker.ui.FeedFragment
|
||||||
import org.koitharu.kotatsu.tracker.work.TrackWorker
|
import org.koitharu.kotatsu.tracker.work.TrackWorker
|
||||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
import org.koitharu.kotatsu.utils.ext.*
|
||||||
import org.koitharu.kotatsu.utils.ext.hideKeyboard
|
|
||||||
import org.koitharu.kotatsu.utils.ext.measureHeight
|
|
||||||
import org.koitharu.kotatsu.utils.ext.resolveDp
|
|
||||||
|
|
||||||
private const val TAG_PRIMARY = "primary"
|
private const val TAG_PRIMARY = "primary"
|
||||||
private const val TAG_SEARCH = "search"
|
private const val TAG_SEARCH = "search"
|
||||||
@@ -71,7 +70,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>(),
|
|||||||
private val searchSuggestionViewModel by viewModel<SearchSuggestionViewModel>()
|
private val searchSuggestionViewModel by viewModel<SearchSuggestionViewModel>()
|
||||||
|
|
||||||
private lateinit var navHeaderBinding: NavigationHeaderBinding
|
private lateinit var navHeaderBinding: NavigationHeaderBinding
|
||||||
private lateinit var drawerToggle: ActionBarDrawerToggle
|
private var drawerToggle: ActionBarDrawerToggle? = null
|
||||||
|
private var drawer: DrawerLayout? = null
|
||||||
|
|
||||||
override val appBar: AppBarLayout
|
override val appBar: AppBarLayout
|
||||||
get() = binding.appbar
|
get() = binding.appbar
|
||||||
@@ -80,36 +80,35 @@ class MainActivity : BaseActivity<ActivityMainBinding>(),
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(ActivityMainBinding.inflate(layoutInflater))
|
setContentView(ActivityMainBinding.inflate(layoutInflater))
|
||||||
navHeaderBinding = NavigationHeaderBinding.inflate(layoutInflater)
|
navHeaderBinding = NavigationHeaderBinding.inflate(layoutInflater)
|
||||||
drawerToggle = ActionBarDrawerToggle(
|
drawer = binding.root as? DrawerLayout
|
||||||
|
drawerToggle = drawer?.let {
|
||||||
|
ActionBarDrawerToggle(
|
||||||
this,
|
this,
|
||||||
binding.drawer,
|
it,
|
||||||
binding.toolbar,
|
binding.toolbar,
|
||||||
R.string.open_menu,
|
R.string.open_menu,
|
||||||
R.string.close_menu
|
R.string.close_menu
|
||||||
)
|
).apply {
|
||||||
drawerToggle.setHomeAsUpIndicator(ContextCompat.getDrawable(this, R.drawable.ic_arrow_back))
|
setHomeAsUpIndicator(ContextCompat.getDrawable(this@MainActivity, R.drawable.ic_arrow_back))
|
||||||
drawerToggle.setToolbarNavigationClickListener {
|
setToolbarNavigationClickListener {
|
||||||
binding.searchView.hideKeyboard()
|
binding.searchView.hideKeyboard()
|
||||||
onBackPressed()
|
onBackPressed()
|
||||||
}
|
}
|
||||||
binding.drawer.addDrawerListener(drawerToggle)
|
it.addDrawerListener(this)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
with(binding.searchView) {
|
with(binding.searchView) {
|
||||||
onFocusChangeListener = this@MainActivity
|
onFocusChangeListener = this@MainActivity
|
||||||
searchSuggestionListener = this@MainActivity
|
searchSuggestionListener = this@MainActivity
|
||||||
|
if (drawer == null) {
|
||||||
|
drawableStart = ContextCompat.getDrawable(context, R.drawable.ic_search)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
with(binding.navigationView) {
|
with(binding.navigationView) {
|
||||||
val menuView =
|
ViewCompat.setOnApplyWindowInsetsListener(this, NavigationViewInsetsListener())
|
||||||
findViewById<RecyclerView>(com.google.android.material.R.id.design_navigation_view)
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(navHeaderBinding.root) { v, insets ->
|
|
||||||
val systemWindowInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
|
||||||
v.updatePadding(top = systemWindowInsets.top)
|
|
||||||
// NavigationView doesn't dispatch insets to the menu view, so pad the bottom here.
|
|
||||||
menuView.updatePadding(bottom = systemWindowInsets.bottom)
|
|
||||||
insets
|
|
||||||
}
|
|
||||||
addHeaderView(navHeaderBinding.root)
|
addHeaderView(navHeaderBinding.root)
|
||||||
setNavigationItemSelectedListener(this@MainActivity)
|
setNavigationItemSelectedListener(this@MainActivity)
|
||||||
}
|
}
|
||||||
@@ -134,26 +133,27 @@ class MainActivity : BaseActivity<ActivityMainBinding>(),
|
|||||||
|
|
||||||
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
|
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
|
||||||
super.onRestoreInstanceState(savedInstanceState)
|
super.onRestoreInstanceState(savedInstanceState)
|
||||||
drawerToggle.isDrawerIndicatorEnabled =
|
drawerToggle?.isDrawerIndicatorEnabled =
|
||||||
binding.drawer.getDrawerLockMode(GravityCompat.START) == DrawerLayout.LOCK_MODE_UNLOCKED
|
drawer?.getDrawerLockMode(GravityCompat.START) == DrawerLayout.LOCK_MODE_UNLOCKED
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPostCreate(savedInstanceState: Bundle?) {
|
override fun onPostCreate(savedInstanceState: Bundle?) {
|
||||||
super.onPostCreate(savedInstanceState)
|
super.onPostCreate(savedInstanceState)
|
||||||
drawerToggle.syncState()
|
drawerToggle?.syncState()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||||
super.onConfigurationChanged(newConfig)
|
super.onConfigurationChanged(newConfig)
|
||||||
drawerToggle.onConfigurationChanged(newConfig)
|
drawerToggle?.onConfigurationChanged(newConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
val fragment = supportFragmentManager.findFragmentByTag(TAG_SEARCH)
|
val fragment = supportFragmentManager.findFragmentByTag(TAG_SEARCH)
|
||||||
binding.searchView.clearFocus()
|
binding.searchView.clearFocus()
|
||||||
when {
|
when {
|
||||||
binding.drawer.isDrawerOpen(binding.navigationView) -> binding.drawer.closeDrawer(
|
drawer?.isDrawerOpen(binding.navigationView) == true -> {
|
||||||
binding.navigationView)
|
drawer?.closeDrawer(binding.navigationView)
|
||||||
|
}
|
||||||
fragment != null -> supportFragmentManager.commit {
|
fragment != null -> supportFragmentManager.commit {
|
||||||
remove(fragment)
|
remove(fragment)
|
||||||
setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
|
setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
|
||||||
@@ -164,7 +164,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
return drawerToggle.onOptionsItemSelected(item) || when (item.itemId) {
|
return drawerToggle?.onOptionsItemSelected(item) == true || when (item.itemId) {
|
||||||
else -> super.onOptionsItemSelected(item)
|
else -> super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,19 +210,22 @@ class MainActivity : BaseActivity<ActivityMainBinding>(),
|
|||||||
else -> return false
|
else -> return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding.drawer.closeDrawers()
|
drawer?.closeDrawers()
|
||||||
|
appBar.setExpanded(true)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onWindowInsetsChanged(insets: Insets) {
|
override fun onWindowInsetsChanged(insets: Insets) {
|
||||||
binding.toolbarCard.updateLayoutParams<MarginLayoutParams> {
|
|
||||||
topMargin = insets.top + resources.resolveDp(8)
|
|
||||||
}
|
|
||||||
binding.fab.updateLayoutParams<MarginLayoutParams> {
|
binding.fab.updateLayoutParams<MarginLayoutParams> {
|
||||||
bottomMargin = insets.bottom + topMargin
|
bottomMargin = insets.bottom + topMargin
|
||||||
leftMargin = insets.left + topMargin
|
|
||||||
rightMargin = insets.right + topMargin
|
|
||||||
}
|
}
|
||||||
|
binding.toolbarCard.updateLayoutParams<MarginLayoutParams> {
|
||||||
|
topMargin = insets.top + bottomMargin
|
||||||
|
}
|
||||||
|
binding.root.updatePadding(
|
||||||
|
left = insets.left,
|
||||||
|
right = insets.right,
|
||||||
|
)
|
||||||
binding.container.updateLayoutParams<MarginLayoutParams> {
|
binding.container.updateLayoutParams<MarginLayoutParams> {
|
||||||
topMargin = -(binding.appbar.measureHeight())
|
topMargin = -(binding.appbar.measureHeight())
|
||||||
}
|
}
|
||||||
@@ -360,14 +363,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun onSearchOpened() {
|
private fun onSearchOpened() {
|
||||||
binding.drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
drawer?.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
||||||
drawerToggle.isDrawerIndicatorEnabled = false
|
drawerToggle?.isDrawerIndicatorEnabled = false
|
||||||
adjustFabVisibility(isSearchOpened = true)
|
adjustFabVisibility(isSearchOpened = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onSearchClosed() {
|
private fun onSearchClosed() {
|
||||||
binding.drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
drawer?.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||||
drawerToggle.isDrawerIndicatorEnabled = true
|
drawerToggle?.isDrawerIndicatorEnabled = true
|
||||||
adjustFabVisibility(isSearchOpened = false)
|
adjustFabVisibility(isSearchOpened = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.koitharu.kotatsu.main.ui
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.core.view.OnApplyWindowInsetsListener
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.core.view.updatePadding
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
import com.google.android.material.R as materialR
|
||||||
|
|
||||||
|
class NavigationViewInsetsListener : OnApplyWindowInsetsListener {
|
||||||
|
|
||||||
|
private var menuViewRef: WeakReference<View>? = null
|
||||||
|
|
||||||
|
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
|
||||||
|
val menuView = menuViewRef?.get() ?: v.findViewById<View>(materialR.id.design_navigation_view).also {
|
||||||
|
menuViewRef = WeakReference(it)
|
||||||
|
}
|
||||||
|
val systemWindowInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.updatePadding(top = systemWindowInsets.top)
|
||||||
|
// NavigationView doesn't dispatch insets to the menu view, so pad the bottom here.
|
||||||
|
menuView.updatePadding(bottom = systemWindowInsets.bottom)
|
||||||
|
return WindowInsetsCompat.CONSUMED
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,6 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.android.material.divider.MaterialDividerItemDecoration
|
import com.google.android.material.divider.MaterialDividerItemDecoration
|
||||||
import org.koin.android.ext.android.get
|
import org.koin.android.ext.android.get
|
||||||
@@ -20,6 +19,7 @@ import org.koitharu.kotatsu.details.ui.model.ChapterListItem
|
|||||||
import org.koitharu.kotatsu.details.ui.model.toListItem
|
import org.koitharu.kotatsu.details.ui.model.toListItem
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||||
import org.koitharu.kotatsu.utils.BottomSheetToolbarController
|
import org.koitharu.kotatsu.utils.BottomSheetToolbarController
|
||||||
|
import org.koitharu.kotatsu.utils.RecyclerViewScrollCallback
|
||||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||||
|
|
||||||
class ChaptersBottomSheet : BaseBottomSheet<SheetChaptersBinding>(), OnListItemClickListener<ChapterListItem> {
|
class ChaptersBottomSheet : BaseBottomSheet<SheetChaptersBinding>(), OnListItemClickListener<ChapterListItem> {
|
||||||
@@ -59,7 +59,7 @@ class ChaptersBottomSheet : BaseBottomSheet<SheetChaptersBinding>(), OnListItemC
|
|||||||
binding.recyclerView.adapter = ChaptersAdapter(this).also { adapter ->
|
binding.recyclerView.adapter = ChaptersAdapter(this).also { adapter ->
|
||||||
if (currentPosition >= 0) {
|
if (currentPosition >= 0) {
|
||||||
val targetPosition = (currentPosition - 1).coerceAtLeast(0)
|
val targetPosition = (currentPosition - 1).coerceAtLeast(0)
|
||||||
adapter.setItems(items, Scroller(binding.recyclerView, targetPosition))
|
adapter.setItems(items, RecyclerViewScrollCallback(binding.recyclerView, targetPosition))
|
||||||
} else {
|
} else {
|
||||||
adapter.items = items
|
adapter.items = items
|
||||||
}
|
}
|
||||||
@@ -78,13 +78,6 @@ class ChaptersBottomSheet : BaseBottomSheet<SheetChaptersBinding>(), OnListItemC
|
|||||||
fun onChapterChanged(chapter: MangaChapter)
|
fun onChapterChanged(chapter: MangaChapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Scroller(private val recyclerView: RecyclerView, private val position: Int) : Runnable {
|
|
||||||
override fun run() {
|
|
||||||
val offset = recyclerView.resources.getDimensionPixelSize(R.dimen.chapter_list_item_height) / 2
|
|
||||||
(recyclerView.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(position, offset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private const val ARG_CHAPTERS = "chapters"
|
private const val ARG_CHAPTERS = "chapters"
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
|
|||||||
rawX >= binding.root.width - gestureInsets.right ||
|
rawX >= binding.root.width - gestureInsets.right ||
|
||||||
rawY >= binding.root.height - gestureInsets.bottom ||
|
rawY >= binding.root.height - gestureInsets.bottom ||
|
||||||
binding.appbarTop.hasGlobalPoint(rawX, rawY) ||
|
binding.appbarTop.hasGlobalPoint(rawX, rawY) ||
|
||||||
binding.appbarBottom.hasGlobalPoint(rawX, rawY)
|
binding.appbarBottom?.hasGlobalPoint(rawX, rawY) == true
|
||||||
) {
|
) {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
@@ -320,11 +320,13 @@ class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
|
|||||||
if (binding.appbarTop.isVisible != isUiVisible) {
|
if (binding.appbarTop.isVisible != isUiVisible) {
|
||||||
val transition = TransitionSet()
|
val transition = TransitionSet()
|
||||||
.setOrdering(TransitionSet.ORDERING_TOGETHER)
|
.setOrdering(TransitionSet.ORDERING_TOGETHER)
|
||||||
.addTransition(Slide(Gravity.BOTTOM).addTarget(binding.appbarBottom))
|
|
||||||
.addTransition(Slide(Gravity.TOP).addTarget(binding.appbarTop))
|
.addTransition(Slide(Gravity.TOP).addTarget(binding.appbarTop))
|
||||||
|
binding.appbarBottom?.let { botomBar ->
|
||||||
|
transition.addTransition(Slide(Gravity.BOTTOM).addTarget(botomBar))
|
||||||
|
}
|
||||||
TransitionManager.beginDelayedTransition(binding.root, transition)
|
TransitionManager.beginDelayedTransition(binding.root, transition)
|
||||||
binding.appbarTop.isVisible = isUiVisible
|
binding.appbarTop.isVisible = isUiVisible
|
||||||
binding.appbarBottom.isVisible = isUiVisible
|
binding.appbarBottom?.isVisible = isUiVisible
|
||||||
if (isUiVisible) {
|
if (isUiVisible) {
|
||||||
showSystemUI()
|
showSystemUI()
|
||||||
} else {
|
} else {
|
||||||
@@ -341,7 +343,7 @@ class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
|
|||||||
right = systemBars.right,
|
right = systemBars.right,
|
||||||
left = systemBars.left
|
left = systemBars.left
|
||||||
)
|
)
|
||||||
binding.appbarBottom.updatePadding(
|
binding.appbarBottom?.updatePadding(
|
||||||
bottom = systemBars.bottom,
|
bottom = systemBars.bottom,
|
||||||
right = systemBars.right,
|
right = systemBars.right,
|
||||||
left = systemBars.left
|
left = systemBars.left
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
import org.koin.android.ext.android.get
|
import org.koin.android.ext.android.get
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
@@ -29,6 +29,7 @@ class PagesThumbnailsSheet : BaseBottomSheet<SheetPagesBinding>(),
|
|||||||
|
|
||||||
private lateinit var thumbnails: List<PageThumbnail>
|
private lateinit var thumbnails: List<PageThumbnail>
|
||||||
private val spanResolver = MangaListSpanResolver()
|
private val spanResolver = MangaListSpanResolver()
|
||||||
|
private var currentPageIndex = -1
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -37,12 +38,12 @@ class PagesThumbnailsSheet : BaseBottomSheet<SheetPagesBinding>(),
|
|||||||
dismissAllowingStateLoss()
|
dismissAllowingStateLoss()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val current = arguments?.getInt(ARG_CURRENT, -1) ?: -1
|
currentPageIndex = requireArguments().getInt(ARG_CURRENT, currentPageIndex)
|
||||||
val repository = MangaRepository(pages.first().source)
|
val repository = MangaRepository(pages.first().source)
|
||||||
thumbnails = pages.mapIndexed { i, x ->
|
thumbnails = pages.mapIndexed { i, x ->
|
||||||
PageThumbnail(
|
PageThumbnail(
|
||||||
number = i + 1,
|
number = i + 1,
|
||||||
isCurrent = i == current,
|
isCurrent = i == currentPageIndex,
|
||||||
repository = repository,
|
repository = repository,
|
||||||
page = x
|
page = x
|
||||||
)
|
)
|
||||||
@@ -69,11 +70,9 @@ class PagesThumbnailsSheet : BaseBottomSheet<SheetPagesBinding>(),
|
|||||||
resources.getQuantityString(R.plurals.pages, thumbnails.size, thumbnails.size)
|
resources.getQuantityString(R.plurals.pages, thumbnails.size, thumbnails.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
val initialTopPosition = binding.recyclerView.top
|
|
||||||
|
|
||||||
with(binding.recyclerView) {
|
with(binding.recyclerView) {
|
||||||
addItemDecoration(
|
addItemDecoration(
|
||||||
SpacingItemDecoration(view.resources.getDimensionPixelOffset(R.dimen.grid_spacing))
|
SpacingItemDecoration(resources.getDimensionPixelOffset(R.dimen.grid_spacing))
|
||||||
)
|
)
|
||||||
adapter = PageThumbnailAdapter(
|
adapter = PageThumbnailAdapter(
|
||||||
thumbnails,
|
thumbnails,
|
||||||
@@ -82,16 +81,12 @@ class PagesThumbnailsSheet : BaseBottomSheet<SheetPagesBinding>(),
|
|||||||
get(),
|
get(),
|
||||||
this@PagesThumbnailsSheet
|
this@PagesThumbnailsSheet
|
||||||
)
|
)
|
||||||
addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
|
||||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) = Unit
|
|
||||||
|
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
|
||||||
binding.appbar.isLifted = getChildAt(0).top < initialTopPosition
|
|
||||||
}
|
|
||||||
})
|
|
||||||
addOnLayoutChangeListener(spanResolver)
|
addOnLayoutChangeListener(spanResolver)
|
||||||
spanResolver.setGridSize(get<AppSettings>().gridSize / 100f, this)
|
spanResolver.setGridSize(get<AppSettings>().gridSize / 100f, this)
|
||||||
|
if (currentPageIndex > 0) {
|
||||||
|
val offset = resources.getDimensionPixelOffset(R.dimen.preferred_grid_width)
|
||||||
|
(layoutManager as GridLayoutManager).scrollToPositionWithOffset(currentPageIndex, offset)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import org.koitharu.kotatsu.parsers.model.MangaPage
|
|||||||
import org.koitharu.kotatsu.reader.ui.thumbnails.PageThumbnail
|
import org.koitharu.kotatsu.reader.ui.thumbnails.PageThumbnail
|
||||||
import org.koitharu.kotatsu.utils.ext.IgnoreErrors
|
import org.koitharu.kotatsu.utils.ext.IgnoreErrors
|
||||||
import org.koitharu.kotatsu.utils.ext.referer
|
import org.koitharu.kotatsu.utils.ext.referer
|
||||||
|
import org.koitharu.kotatsu.utils.ext.setTextColorAttr
|
||||||
|
import com.google.android.material.R as materialR
|
||||||
|
|
||||||
fun pageThumbnailAD(
|
fun pageThumbnailAD(
|
||||||
coil: ImageLoader,
|
coil: ImageLoader,
|
||||||
@@ -31,7 +33,7 @@ fun pageThumbnailAD(
|
|||||||
height = (gridWidth * 13f / 18f).toInt()
|
height = (gridWidth * 13f / 18f).toInt()
|
||||||
)
|
)
|
||||||
|
|
||||||
binding.handle.setOnClickListener {
|
binding.root.setOnClickListener {
|
||||||
clickListener.onItemClick(item.page, itemView)
|
clickListener.onItemClick(item.page, itemView)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +41,8 @@ fun pageThumbnailAD(
|
|||||||
job?.cancel()
|
job?.cancel()
|
||||||
binding.imageViewThumb.setImageDrawable(null)
|
binding.imageViewThumb.setImageDrawable(null)
|
||||||
with(binding.textViewNumber) {
|
with(binding.textViewNumber) {
|
||||||
setBackgroundResource(if (item.isCurrent) R.drawable.bg_badge_accent else R.drawable.bg_badge_default)
|
setBackgroundResource(if (item.isCurrent) R.drawable.bg_badge_accent else R.drawable.bg_badge_empty)
|
||||||
|
setTextColorAttr(if (item.isCurrent) materialR.attr.colorOnTertiary else android.R.attr.textColorPrimary)
|
||||||
text = (item.number).toString()
|
text = (item.number).toString()
|
||||||
}
|
}
|
||||||
job = scope.launch(Dispatchers.Default + IgnoreErrors) {
|
job = scope.launch(Dispatchers.Default + IgnoreErrors) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import org.koitharu.kotatsu.databinding.ItemSearchSuggestionMangaGridBinding
|
|||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionListener
|
import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionListener
|
||||||
import org.koitharu.kotatsu.search.ui.suggestion.model.SearchSuggestionItem
|
import org.koitharu.kotatsu.search.ui.suggestion.model.SearchSuggestionItem
|
||||||
import org.koitharu.kotatsu.utils.ScrollResetCallback
|
import org.koitharu.kotatsu.utils.RecyclerViewScrollCallback
|
||||||
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
||||||
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ fun searchSuggestionMangaListAD(
|
|||||||
right = recyclerView.paddingRight - spacing,
|
right = recyclerView.paddingRight - spacing,
|
||||||
)
|
)
|
||||||
recyclerView.addItemDecoration(SpacingItemDecoration(spacing))
|
recyclerView.addItemDecoration(SpacingItemDecoration(spacing))
|
||||||
val scrollResetCallback = ScrollResetCallback(recyclerView)
|
val scrollResetCallback = RecyclerViewScrollCallback(recyclerView, 0)
|
||||||
|
|
||||||
bind {
|
bind {
|
||||||
adapter.setItems(item.items, scrollResetCallback)
|
adapter.setItems(item.items, scrollResetCallback)
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.koitharu.kotatsu.utils
|
||||||
|
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
|
class RecyclerViewScrollCallback(recyclerView: RecyclerView, private val position: Int) : Runnable {
|
||||||
|
|
||||||
|
private val recyclerViewRef = WeakReference(recyclerView)
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
val rv = recyclerViewRef.get() ?: return
|
||||||
|
val lm = rv.layoutManager ?: return
|
||||||
|
rv.stopScroll()
|
||||||
|
if (lm is LinearLayoutManager) {
|
||||||
|
lm.scrollToPositionWithOffset(position, 0)
|
||||||
|
} else {
|
||||||
|
lm.scrollToPosition(position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.utils
|
|
||||||
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import java.lang.ref.WeakReference
|
|
||||||
|
|
||||||
class ScrollResetCallback(recyclerView: RecyclerView) : Runnable {
|
|
||||||
|
|
||||||
private val recyclerViewRef = WeakReference(recyclerView)
|
|
||||||
|
|
||||||
override fun run() {
|
|
||||||
recyclerViewRef.get()?.scrollToPosition(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.koitharu.kotatsu.utils.ext
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.core.graphics.Insets
|
||||||
|
|
||||||
|
fun Insets.getStart(view: View): Int {
|
||||||
|
return if (view.layoutDirection == View.LAYOUT_DIRECTION_RTL) {
|
||||||
|
right
|
||||||
|
} else {
|
||||||
|
left
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Insets.getEnd(view: View): Int {
|
||||||
|
return if (view.layoutDirection == View.LAYOUT_DIRECTION_RTL) {
|
||||||
|
left
|
||||||
|
} else {
|
||||||
|
right
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,9 @@ package org.koitharu.kotatsu.utils.ext
|
|||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.core.content.res.use
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
|
|
||||||
var TextView.textAndVisible: CharSequence?
|
var TextView.textAndVisible: CharSequence?
|
||||||
@@ -36,3 +38,10 @@ fun TextView.setTextAndVisible(@StringRes textResId: Int) {
|
|||||||
isGone = text.isNullOrEmpty()
|
isGone = text.isNullOrEmpty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun TextView.setTextColorAttr(@AttrRes attrResId: Int) {
|
||||||
|
val colors = context.obtainStyledAttributes(intArrayOf(attrResId)).use {
|
||||||
|
it.getColorStateList(0)
|
||||||
|
}
|
||||||
|
setTextColor(colors)
|
||||||
|
}
|
||||||
15
app/src/main/res/drawable/bg_badge_empty.xml
Normal file
15
app/src/main/res/drawable/bg_badge_empty.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<corners android:radius="5dp" />
|
||||||
|
<solid android:color="?colorBackgroundFloating" />
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="?colorOutline" />
|
||||||
|
<padding
|
||||||
|
android:bottom="2dp"
|
||||||
|
android:left="2dp"
|
||||||
|
android:right="2dp"
|
||||||
|
android:top="2dp" />
|
||||||
|
</shape>
|
||||||
81
app/src/main/res/layout-land/dialog_list_mode.xml
Normal file
81
app/src/main/res/layout-land/dialog_list_mode.xml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
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:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:animateLayoutChanges="true"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<org.koitharu.kotatsu.base.ui.widgets.CheckableButtonGroup
|
||||||
|
android:id="@+id/checkableGroup"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:weightSum="3">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/button_list"
|
||||||
|
style="@style/Widget.Kotatsu.ToggleButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:text="@string/list"
|
||||||
|
app:icon="@drawable/ic_list" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/button_list_detailed"
|
||||||
|
style="@style/Widget.Kotatsu.ToggleButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="12dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:text="@string/detailed_list"
|
||||||
|
app:icon="@drawable/ic_list_detailed" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/button_grid"
|
||||||
|
style="@style/Widget.Kotatsu.ToggleButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:text="@string/grid"
|
||||||
|
app:icon="@drawable/ic_grid" />
|
||||||
|
|
||||||
|
</org.koitharu.kotatsu.base.ui.widgets.CheckableButtonGroup>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView_grid_title"
|
||||||
|
style="?materialAlertDialogTitleTextStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="?attr/dialogPreferredPadding"
|
||||||
|
android:paddingRight="?attr/dialogPreferredPadding"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text="@string/grid_size"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<com.google.android.material.slider.Slider
|
||||||
|
android:id="@+id/slider_grid"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:stepSize="5"
|
||||||
|
android:valueFrom="50"
|
||||||
|
android:valueTo="150"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:labelBehavior="floating"
|
||||||
|
app:tickVisible="false"
|
||||||
|
tools:value="100"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -1,198 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.core.widget.NestedScrollView
|
|
||||||
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:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:clipToPadding="false"
|
|
||||||
android:scrollbars="vertical"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<org.koitharu.kotatsu.base.ui.widgets.CoverImageView
|
|
||||||
android:id="@+id/imageView_cover"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:foreground="?selectableItemBackground"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
android:transitionName="cover"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintWidth_percent="0.3"
|
|
||||||
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Kotatsu.Cover"
|
|
||||||
tools:background="@tools:sample/backgrounds/scenic"
|
|
||||||
tools:ignore="ContentDescription,UnusedAttribute" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView_title"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:maxLines="4"
|
|
||||||
android:textAppearance="?attr/textAppearanceHeadlineSmall"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/imageView_cover"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
tools:text="@tools:sample/lorem[15]" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView_subtitle"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:maxLines="4"
|
|
||||||
android:textAppearance="?attr/textAppearanceBodyMedium"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/imageView_cover"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/textView_title"
|
|
||||||
tools:text="@tools:sample/lorem[12]" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView_author"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="12dp"
|
|
||||||
android:layout_marginTop="2dp"
|
|
||||||
android:layout_marginEnd="12dp"
|
|
||||||
android:background="@drawable/list_selector"
|
|
||||||
android:padding="4dp"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textColor="?attr/colorTertiary"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/imageView_cover"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/textView_subtitle"
|
|
||||||
app:layout_constraintWidth_default="wrap"
|
|
||||||
tools:text="@tools:sample/full_names" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView_state"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:drawablePadding="4dp"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textAppearance="?attr/textAppearanceBodySmall"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/imageView_cover"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/textView_author"
|
|
||||||
tools:drawableStart="@drawable/ic_state_finished"
|
|
||||||
tools:text="Finished" />
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/info_layout"
|
|
||||||
layout="@layout/layout_details_info"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/imageView_cover"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/textView_state" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/button_favorite"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:paddingStart="0dp"
|
|
||||||
android:paddingEnd="0dp"
|
|
||||||
app:icon="@drawable/ic_heart_outline"
|
|
||||||
app:iconGravity="textTop"
|
|
||||||
app:iconPadding="0dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/button_read"
|
|
||||||
app:layout_constraintDimensionRatio="1:1"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/imageView_cover"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/button_read" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/button_read"
|
|
||||||
style="@style/Widget.Material3.Button.TonalButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:enabled="false"
|
|
||||||
android:text="@string/read"
|
|
||||||
android:textAllCaps="false"
|
|
||||||
app:iconGravity="textStart"
|
|
||||||
app:iconPadding="8dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/button_favorite"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/info_layout"
|
|
||||||
tools:text="@string/_continue" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Barrier
|
|
||||||
android:id="@+id/barrier_header"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:barrierDirection="bottom"
|
|
||||||
app:barrierMargin="8dp"
|
|
||||||
app:constraint_referenced_ids="imageView_cover,button_read" />
|
|
||||||
|
|
||||||
<org.koitharu.kotatsu.base.ui.widgets.ChipsView
|
|
||||||
android:id="@+id/chips_tags"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:paddingStart="16dp"
|
|
||||||
android:paddingEnd="16dp"
|
|
||||||
app:chipSpacingHorizontal="6dp"
|
|
||||||
app:chipSpacingVertical="6dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/barrier_header" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView_description"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:lineSpacingMultiplier="1.2"
|
|
||||||
android:textAppearance="?attr/textAppearanceBodyMedium"
|
|
||||||
android:textIsSelectable="true"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/chips_tags"
|
|
||||||
tools:ignore="UnusedAttribute"
|
|
||||||
tools:text="@tools:sample/lorem/random[250]" />
|
|
||||||
|
|
||||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
|
||||||
android:id="@+id/progressBar"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:indeterminate="true"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:hideAnimationBehavior="outward"
|
|
||||||
app:layout_constraintBottom_toTopOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:showAnimationBehavior="inward"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
||||||
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:id="@+id/coordinator"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".details.ui.DetailsActivity">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
|
||||||
android:id="@+id/appbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
|
||||||
android:id="@id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_scrollFlags="scroll|enterAlways">
|
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
|
||||||
android:id="@+id/tabs"
|
|
||||||
style="@style/Widget.Kotatsu.Tabs"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="end"
|
|
||||||
android:background="@android:color/transparent"
|
|
||||||
app:tabGravity="center"
|
|
||||||
app:tabMode="fixed" />
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.MaterialToolbar>
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
|
||||||
|
|
||||||
<androidx.viewpager2.widget.ViewPager2
|
|
||||||
android:id="@+id/pager"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
|
||||||
|
|
||||||
<org.koitharu.kotatsu.base.ui.widgets.FadingSnackbar
|
|
||||||
android:id="@+id/snackbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="bottom"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
||||||
83
app/src/main/res/layout-w600dp/activity_reader.xml
Normal file
83
app/src/main/res/layout-w600dp/activity_reader.xml
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout
|
||||||
|
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:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:keepScreenOn="true">
|
||||||
|
|
||||||
|
<androidx.fragment.app.FragmentContainerView
|
||||||
|
android:id="@+id/container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<org.koitharu.kotatsu.reader.ui.ReaderToastView
|
||||||
|
android:id="@+id/toastView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|center_horizontal"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:background="@drawable/bg_reader_indicator"
|
||||||
|
android:drawablePadding="6dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?attr/textAppearanceBodySmall"
|
||||||
|
android:theme="@style/ThemeOverlay.Material3.Dark"
|
||||||
|
tools:text="@string/loading_" />
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/appbar_top"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/dim"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:theme="@style/ThemeOverlay.Material3.Dark"
|
||||||
|
app:elevation="0dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@id/toolbar"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
app:popupTheme="@style/ThemeOverlay.Kotatsu" />
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/toolbar_bottom"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:popupTheme="@style/ThemeOverlay.Kotatsu" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layout_loading"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||||
|
android:id="@+id/progressBar"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:indeterminate="true" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView_loading"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="@string/loading_"
|
||||||
|
android:textAppearance="?attr/textAppearanceBody2" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
android:id="@+id/imageView_cover"
|
android:id="@+id/imageView_cover"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="8dp"
|
||||||
android:foreground="?selectableItemBackground"
|
android:foreground="?selectableItemBackground"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
android:transitionName="cover"
|
android:transitionName="cover"
|
||||||
@@ -35,9 +35,9 @@
|
|||||||
android:id="@+id/textView_title"
|
android:id="@+id/textView_title"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="3"
|
android:maxLines="3"
|
||||||
android:textAppearance="?attr/textAppearanceHeadlineSmall"
|
android:textAppearance="?attr/textAppearanceHeadlineSmall"
|
||||||
@@ -50,9 +50,9 @@
|
|||||||
android:id="@+id/textView_subtitle"
|
android:id="@+id/textView_subtitle"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="6dp"
|
android:layout_marginTop="4dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="3"
|
android:maxLines="3"
|
||||||
android:textAppearance="?attr/textAppearanceBodyMedium"
|
android:textAppearance="?attr/textAppearanceBodyMedium"
|
||||||
@@ -65,11 +65,11 @@
|
|||||||
android:id="@+id/textView_author"
|
android:id="@+id/textView_author"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="6dp"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:layout_marginEnd="12dp"
|
android:layout_marginEnd="6dp"
|
||||||
android:background="@drawable/list_selector"
|
android:background="@drawable/list_selector"
|
||||||
android:padding="4dp"
|
android:padding="2dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textColor="?attr/colorTertiary"
|
android:textColor="?attr/colorTertiary"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
@@ -84,9 +84,9 @@
|
|||||||
android:id="@+id/textView_state"
|
android:id="@+id/textView_state"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:drawablePadding="4dp"
|
android:drawablePadding="4dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textAppearance="?attr/textAppearanceBodySmall"
|
android:textAppearance="?attr/textAppearanceBodySmall"
|
||||||
@@ -96,12 +96,19 @@
|
|||||||
tools:drawableStart="@drawable/ic_state_finished"
|
tools:drawableStart="@drawable/ic_state_finished"
|
||||||
tools:text="Finished" />
|
tools:text="Finished" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Barrier
|
||||||
|
android:id="@+id/barrier_header"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:barrierDirection="bottom"
|
||||||
|
app:barrierMargin="8dp"
|
||||||
|
app:constraint_referenced_ids="imageView_cover,button_read" />
|
||||||
|
|
||||||
<include
|
<include
|
||||||
android:id="@+id/info_layout"
|
android:id="@+id/info_layout"
|
||||||
layout="@layout/layout_details_info"
|
layout="@layout/layout_details_info"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/imageView_cover"
|
app:layout_constraintStart_toEndOf="@id/imageView_cover"
|
||||||
app:layout_constraintTop_toBottomOf="@id/textView_state" />
|
app:layout_constraintTop_toBottomOf="@id/textView_state" />
|
||||||
@@ -128,7 +135,6 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
android:text="@string/read"
|
android:text="@string/read"
|
||||||
@@ -140,14 +146,6 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@id/info_layout"
|
app:layout_constraintTop_toBottomOf="@id/info_layout"
|
||||||
tools:text="@string/_continue" />
|
tools:text="@string/_continue" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Barrier
|
|
||||||
android:id="@+id/barrier_header"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:barrierDirection="bottom"
|
|
||||||
app:barrierMargin="8dp"
|
|
||||||
app:constraint_referenced_ids="imageView_cover,button_read" />
|
|
||||||
|
|
||||||
<org.koitharu.kotatsu.base.ui.widgets.ChipsView
|
<org.koitharu.kotatsu.base.ui.widgets.ChipsView
|
||||||
android:id="@+id/chips_tags"
|
android:id="@+id/chips_tags"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
90
app/src/main/res/layout-w720dp-land/activity_main.xml
Normal file
90
app/src/main/res/layout-w720dp-land/activity_main.xml
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
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:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<com.google.android.material.navigation.NavigationView
|
||||||
|
android:id="@+id/navigationView"
|
||||||
|
android:layout_width="260dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:fitsSystemWindows="false"
|
||||||
|
app:drawerLayoutCornerSize="0dp"
|
||||||
|
app:elevation="0dp"
|
||||||
|
app:menu="@menu/nav_drawer" />
|
||||||
|
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.fragment.app.FragmentContainerView
|
||||||
|
android:id="@id/container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||||
|
tools:layout="@layout/fragment_list" />
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/appbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:elevation="0dp"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
|
app:liftOnScroll="false">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/toolbar_card"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="54dp"
|
||||||
|
android:layout_marginVertical="8dp"
|
||||||
|
android:background="@drawable/toolbar_background">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@null"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true">
|
||||||
|
|
||||||
|
<org.koitharu.kotatsu.search.ui.widget.SearchEditText
|
||||||
|
android:id="@+id/searchView"
|
||||||
|
style="@style/Widget.Kotatsu.SearchView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@null"
|
||||||
|
android:drawablePadding="16dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:hint="@string/search_manga"
|
||||||
|
android:imeOptions="actionSearch"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.MaterialToolbar>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/fab"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:contentDescription="@string/_continue"
|
||||||
|
android:src="@drawable/ic_read_fill"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:backgroundTint="?attr/colorContainer"
|
||||||
|
app:fabSize="normal"
|
||||||
|
app:layout_anchor="@id/container"
|
||||||
|
app:layout_anchorGravity="bottom|end"
|
||||||
|
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
|
||||||
|
app:layout_dodgeInsetEdges="bottom"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
</LinearLayout>
|
||||||
79
app/src/main/res/layout-w720dp/activity_details.xml
Normal file
79
app/src/main/res/layout-w720dp/activity_details.xml
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
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:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context=".details.ui.DetailsActivity">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/appbar"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:elevation="0dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:liftOnScroll="false">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:theme="?attr/actionBarTheme">
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/spinner_branches"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:listitem="@layout/item_branch"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.MaterialToolbar>
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<androidx.fragment.app.FragmentContainerView
|
||||||
|
android:id="@+id/container_details"
|
||||||
|
android:name="org.koitharu.kotatsu.details.ui.DetailsFragment"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/guideline"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/appbar"
|
||||||
|
tools:layout="@layout/fragment_details" />
|
||||||
|
|
||||||
|
<androidx.fragment.app.FragmentContainerView
|
||||||
|
android:id="@+id/container_chapters"
|
||||||
|
android:name="org.koitharu.kotatsu.details.ui.ChaptersFragment"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/guideline"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/appbar"
|
||||||
|
tools:layout="@layout/fragment_chapters" />
|
||||||
|
|
||||||
|
<org.koitharu.kotatsu.base.ui.widgets.FadingSnackbar
|
||||||
|
android:id="@+id/snackbar"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/guideline"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintGuide_percent="0.6" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
28
app/src/main/res/layout-w720dp/fragment_chapters.xml
Normal file
28
app/src/main/res/layout-w720dp/fragment_chapters.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout
|
||||||
|
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:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerView_chapters"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:fastScrollEnabled="true"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
tools:listitem="@layout/item_chapter" />
|
||||||
|
|
||||||
|
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||||
|
android:id="@+id/progressBar"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/coordinator"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".details.ui.DetailsActivity">
|
tools:context=".details.ui.DetailsActivity">
|
||||||
@@ -12,24 +11,28 @@
|
|||||||
android:id="@+id/appbar"
|
android:id="@+id/appbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:liftOnScroll="false"
|
app:elevation="0dp"
|
||||||
app:elevation="0dp">
|
app:liftOnScroll="false">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@id/toolbar"
|
android:id="@id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:background="@drawable/m3_tabs_background"
|
||||||
android:theme="?attr/actionBarTheme"
|
android:theme="?attr/actionBarTheme"
|
||||||
app:layout_scrollFlags="scroll|enterAlways"/>
|
app:layout_scrollFlags="scroll|enterAlways"
|
||||||
|
tools:ignore="PrivateResource">
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
<com.google.android.material.tabs.TabLayout
|
||||||
android:id="@+id/tabs"
|
android:id="@+id/tabs"
|
||||||
style="@style/Widget.Kotatsu.Tabs"
|
android:layout_width="wrap_content"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_gravity="center_horizontal"
|
||||||
app:tabGravity="fill"
|
android:background="@null"
|
||||||
app:tabMaxWidth="0dp"
|
app:tabGravity="center"
|
||||||
app:tabMode="fixed" />
|
app:tabMode="scrollable" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.MaterialToolbar>
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/drawer"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".main.ui.MainActivity">
|
tools:context=".main.ui.MainActivity">
|
||||||
@@ -16,12 +15,15 @@
|
|||||||
android:id="@id/container"
|
android:id="@id/container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
tools:layout="@layout/fragment_list"
|
||||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/appbar"
|
android:id="@+id/appbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:stateListAnimator="@null">
|
android:stateListAnimator="@null">
|
||||||
|
|
||||||
@@ -29,10 +31,7 @@
|
|||||||
android:id="@+id/toolbar_card"
|
android:id="@+id/toolbar_card"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginVertical="8dp"
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:background="@drawable/toolbar_background">
|
android:background="@drawable/toolbar_background">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
@@ -42,11 +41,7 @@
|
|||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:focusableInTouchMode="true"
|
android:focusableInTouchMode="true"
|
||||||
android:theme="@style/ThemeOverlay.Kotatsu.MainToolbar"
|
app:contentInsetStartWithNavigation="0dp">
|
||||||
app:contentInsetStartWithNavigation="0dp"
|
|
||||||
app:titleTextAppearance="@style/TextAppearance.Kotatsu.PersistentToolbarTitle"
|
|
||||||
app:titleTextColor="?android:colorControlNormal"
|
|
||||||
tools:title="@string/app_name">
|
|
||||||
|
|
||||||
<org.koitharu.kotatsu.search.ui.widget.SearchEditText
|
<org.koitharu.kotatsu.search.ui.widget.SearchEditText
|
||||||
android:id="@+id/searchView"
|
android:id="@+id/searchView"
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout
|
<com.google.android.material.card.MaterialCardView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?attr/scrimBackground">
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
style="@style/Widget.Material3.CardView.Outlined"
|
||||||
|
app:cardBackgroundColor="?scrimBackground">
|
||||||
|
|
||||||
<org.koitharu.kotatsu.base.ui.widgets.CoverImageView
|
<org.koitharu.kotatsu.base.ui.widgets.CoverImageView
|
||||||
android:id="@+id/imageView_thumb"
|
android:id="@+id/imageView_thumb"
|
||||||
@@ -13,18 +15,12 @@
|
|||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
tools:src="@drawable/ic_placeholder" />
|
tools:src="@drawable/ic_placeholder" />
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/handle"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="?selectableItemBackground" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textView_number"
|
android:id="@+id/textView_number"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom|end"
|
android:layout_gravity="bottom|end"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="4dp"
|
||||||
android:ellipsize="none"
|
android:ellipsize="none"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:minWidth="26dp"
|
android:minWidth="26dp"
|
||||||
@@ -34,4 +30,4 @@
|
|||||||
tools:background="@drawable/bg_badge_default"
|
tools:background="@drawable/bg_badge_default"
|
||||||
tools:text="2" />
|
tools:text="2" />
|
||||||
|
|
||||||
</FrameLayout>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
@@ -21,6 +21,4 @@
|
|||||||
|
|
||||||
<dimen name="search_suggestions_manga_height">124dp</dimen>
|
<dimen name="search_suggestions_manga_height">124dp</dimen>
|
||||||
<dimen name="search_suggestions_manga_spacing">4dp</dimen>
|
<dimen name="search_suggestions_manga_spacing">4dp</dimen>
|
||||||
<!--Text dimens-->
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -85,4 +85,12 @@
|
|||||||
|
|
||||||
<style name="ThemeOverlay.Kotatsu.AMOLED" parent="" />
|
<style name="ThemeOverlay.Kotatsu.AMOLED" parent="" />
|
||||||
|
|
||||||
|
<style name="Theme.Kotatsu.Dialog" parent="">
|
||||||
|
<item name="android:windowNoTitle">true</item>
|
||||||
|
<item name="android:windowIsFloating">true</item>
|
||||||
|
<item name="windowMinWidthMajor">@dimen/abc_dialog_min_width_major</item>
|
||||||
|
<item name="windowMinWidthMinor">@dimen/abc_dialog_min_width_minor</item>
|
||||||
|
<item name="toolbarNavigationButtonStyle">@style/Theme.Kotatsu.ActionMode.CloseButton</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user