From fd26de76195716e741ad601a4a7872a9f6198403 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Wed, 1 Feb 2023 20:21:20 +0200 Subject: [PATCH] Improve scrobbling ui --- .gitignore | 1 + .idea/inspectionProfiles/Project_Default.xml | 17 ----- .../kotatsu/base/ui/BaseBottomSheet.kt | 5 +- .../kotatsu/details/ui/DetailsMenuProvider.kt | 14 +++- .../kotatsu/details/ui/DetailsViewModel.kt | 48 +++++++----- .../scrobbling/ScrobblingInfoBottomSheet.kt | 37 ++++++---- .../selector/ScrobblingSelectorBottomSheet.kt | 74 +++++++++++++------ .../selector/ScrobblingSelectorViewModel.kt | 11 ++- ...ikimoriMangaAD.kt => ScrobblingMangaAD.kt} | 2 +- .../adapter/ShikimoriSelectorAdapter.kt | 10 ++- .../settings/HistorySettingsFragment.kt | 3 +- app/src/main/res/drawable/ic_anilist.xml | 19 ++--- app/src/main/res/layout/sheet_scrobbling.xml | 11 +++ .../res/layout/sheet_scrobbling_selector.xml | 9 ++- app/src/main/res/menu/opt_details.xml | 2 +- 15 files changed, 166 insertions(+), 97 deletions(-) delete mode 100644 .idea/inspectionProfiles/Project_Default.xml rename app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/adapter/{ShikimoriMangaAD.kt => ScrobblingMangaAD.kt} (98%) diff --git a/.gitignore b/.gitignore index 84744a835..56cee6345 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ /.idea/deploymentTargetDropDown.xml /.idea/androidTestResultsUserPreferences.xml /.idea/render.experimental.xml +/.idea/inspectionProfiles/ .DS_Store /build /captures diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 38963f65d..000000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt index 1bba104b8..947b80e8c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt @@ -9,13 +9,13 @@ import android.view.ViewGroup import android.view.ViewGroup.LayoutParams import androidx.core.view.updateLayoutParams import androidx.viewbinding.ViewBinding -import com.google.android.material.R as materialR import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.dialog.AppBottomSheetDialog import org.koitharu.kotatsu.utils.ext.displayCompat +import com.google.android.material.R as materialR abstract class BaseBottomSheet : BottomSheetDialogFragment() { @@ -27,6 +27,9 @@ abstract class BaseBottomSheet : BottomSheetDialogFragment() { protected val behavior: BottomSheetBehavior<*>? get() = (dialog as? BottomSheetDialog)?.behavior + val isExpanded: Boolean + get() = behavior?.state == BottomSheetBehavior.STATE_EXPANDED + final override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsMenuProvider.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsMenuProvider.kt index 561ebbb36..65887cbc3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsMenuProvider.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsMenuProvider.kt @@ -42,7 +42,7 @@ class DetailsMenuProvider( menu.findItem(R.id.action_delete).isVisible = manga?.source == MangaSource.LOCAL menu.findItem(R.id.action_browser).isVisible = manga?.source != MangaSource.LOCAL menu.findItem(R.id.action_shortcut).isVisible = ShortcutManagerCompat.isRequestPinShortcutSupported(activity) - menu.findItem(R.id.action_shiki_track).isVisible = viewModel.isScrobblingAvailable + menu.findItem(R.id.action_scrobbling).isVisible = viewModel.isScrobblingAvailable menu.findItem(R.id.action_favourite).setIcon( if (viewModel.favouriteCategories.value == true) R.drawable.ic_heart else R.drawable.ic_heart_outline, ) @@ -60,11 +60,13 @@ class DetailsMenuProvider( } } } + R.id.action_favourite -> { viewModel.manga.value?.let { FavouriteCategoriesBottomSheet.show(activity.supportFragmentManager, it) } } + R.id.action_delete -> { val title = viewModel.manga.value?.title.orEmpty() MaterialAlertDialogBuilder(activity) @@ -76,6 +78,7 @@ class DetailsMenuProvider( .setNegativeButton(android.R.string.cancel, null) .show() } + R.id.action_save -> { viewModel.manga.value?.let { val chaptersCount = it.chapters?.size ?: 0 @@ -87,21 +90,25 @@ class DetailsMenuProvider( } } } + R.id.action_browser -> { viewModel.manga.value?.let { activity.startActivity(BrowserActivity.newIntent(activity, it.publicUrl, it.title)) } } + R.id.action_related -> { viewModel.manga.value?.let { activity.startActivity(MultiSearchActivity.newIntent(activity, it.title)) } } - R.id.action_shiki_track -> { + + R.id.action_scrobbling -> { viewModel.manga.value?.let { - ScrobblingSelectorBottomSheet.show(activity.supportFragmentManager, it) + ScrobblingSelectorBottomSheet.show(activity.supportFragmentManager, it, null) } } + R.id.action_shortcut -> { viewModel.manga.value?.let { activity.lifecycleScope.launch { @@ -112,6 +119,7 @@ class DetailsMenuProvider( } } } + else -> return false } return true diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt index d53e12f7a..e7c98d27e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt @@ -256,29 +256,24 @@ class DetailsViewModel @AssistedInject constructor( } } - fun updateScrobbling(rating: Float, status: ScrobblingStatus?) { - for (info in scrobblingInfo.value ?: return) { - val scrobbler = scrobblers.first { it.scrobblerService == info.scrobbler } - if (!scrobbler.isAvailable) continue - launchJob(Dispatchers.Default) { - scrobbler.updateScrobblingInfo( - mangaId = delegate.mangaId, - rating = rating, - status = status, - comment = null, - ) - } + fun updateScrobbling(index: Int, rating: Float, status: ScrobblingStatus?) { + val scrobbler = getScrobbler(index) ?: return + launchJob(Dispatchers.Default) { + scrobbler.updateScrobblingInfo( + mangaId = delegate.mangaId, + rating = rating, + status = status, + comment = null, + ) } } - fun unregisterScrobbling() { - for (scrobbler in scrobblers) { - if (!scrobbler.isAvailable) continue - launchJob(Dispatchers.Default) { - scrobbler.unregisterScrobbling( - mangaId = delegate.mangaId, - ) - } + fun unregisterScrobbling(index: Int) { + val scrobbler = getScrobbler(index) ?: return + launchJob(Dispatchers.Default) { + scrobbler.unregisterScrobbling( + mangaId = delegate.mangaId, + ) } } @@ -315,6 +310,19 @@ class DetailsViewModel @AssistedInject constructor( return spannable.trim() } + private fun getScrobbler(index: Int): Scrobbler? { + val info = scrobblingInfo.value?.getOrNull(index) + val scrobbler = if (info != null) { + scrobblers.find { it.scrobblerService == info.scrobbler && it.isAvailable } + } else { + null + } + if (scrobbler == null) { + errorEvent.call(IllegalStateException("Scrobbler [$index] is not available")) + } + return scrobbler + } + @AssistedFactory interface Factory { diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/scrobbling/ScrobblingInfoBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/scrobbling/ScrobblingInfoBottomSheet.kt index f5f8510e5..39fd5fd45 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/scrobbling/ScrobblingInfoBottomSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/scrobbling/ScrobblingInfoBottomSheet.kt @@ -15,9 +15,7 @@ import androidx.core.net.toUri import androidx.fragment.app.FragmentManager import androidx.fragment.app.activityViewModels import coil.ImageLoader -import coil.request.ImageRequest import dagger.hilt.android.AndroidEntryPoint -import javax.inject.Inject import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseBottomSheet import org.koitharu.kotatsu.databinding.SheetScrobblingBinding @@ -26,7 +24,12 @@ import org.koitharu.kotatsu.image.ui.ImageActivity import org.koitharu.kotatsu.scrobbling.domain.model.ScrobblingInfo import org.koitharu.kotatsu.scrobbling.domain.model.ScrobblingStatus import org.koitharu.kotatsu.scrobbling.ui.selector.ScrobblingSelectorBottomSheet -import org.koitharu.kotatsu.utils.ext.* +import org.koitharu.kotatsu.utils.ext.enqueueWith +import org.koitharu.kotatsu.utils.ext.getDisplayMessage +import org.koitharu.kotatsu.utils.ext.newImageRequest +import org.koitharu.kotatsu.utils.ext.scaleUpActivityOptionsOf +import org.koitharu.kotatsu.utils.ext.withArgs +import javax.inject.Inject @AndroidEntryPoint class ScrobblingInfoBottomSheet : @@ -41,6 +44,7 @@ class ScrobblingInfoBottomSheet : @Inject lateinit var coil: ImageLoader + private var menu: PopupMenu? = null override fun onCreate(savedInstanceState: Bundle?) { @@ -78,6 +82,7 @@ class ScrobblingInfoBottomSheet : override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { viewModel.updateScrobbling( + index = scrobblerIndex, rating = binding.ratingBar.rating / binding.ratingBar.numStars, status = enumValues().getOrNull(position), ) @@ -88,6 +93,7 @@ class ScrobblingInfoBottomSheet : override fun onRatingChanged(ratingBar: RatingBar, rating: Float, fromUser: Boolean) { if (fromUser) { viewModel.updateScrobbling( + index = scrobblerIndex, rating = rating / ratingBar.numStars, status = enumValues().getOrNull(binding.spinnerStatus.selectedItemPosition), ) @@ -115,15 +121,15 @@ class ScrobblingInfoBottomSheet : binding.ratingBar.rating = scrobbling.rating * binding.ratingBar.numStars binding.textViewDescription.text = scrobbling.description binding.spinnerStatus.setSelection(scrobbling.status?.ordinal ?: -1) - ImageRequest.Builder(context ?: return) - .target(binding.imageViewCover) - .data(scrobbling.coverUrl) - .crossfade(context) - .lifecycle(viewLifecycleOwner) - .placeholder(R.drawable.ic_placeholder) - .fallback(R.drawable.ic_placeholder) - .error(R.drawable.ic_error_placeholder) - .enqueueWith(coil) + binding.imageViewLogo.contentDescription = getString(scrobbling.scrobbler.titleResId) + binding.imageViewLogo.setImageResource(scrobbling.scrobbler.iconResId) + binding.imageViewCover.newImageRequest(scrobbling.coverUrl)?.apply { + lifecycle(viewLifecycleOwner) + placeholder(R.drawable.ic_placeholder) + fallback(R.drawable.ic_placeholder) + error(R.drawable.ic_error_placeholder) + enqueueWith(coil) + } } override fun onMenuItemClick(item: MenuItem): Boolean { @@ -135,13 +141,16 @@ class ScrobblingInfoBottomSheet : Intent.createChooser(intent, getString(R.string.open_in_browser)), ) } + R.id.action_unregister -> { - viewModel.unregisterScrobbling() + viewModel.unregisterScrobbling(scrobblerIndex) dismiss() } + R.id.action_edit -> { val manga = viewModel.manga.value ?: return false - ScrobblingSelectorBottomSheet.show(parentFragmentManager, manga) + val scrobblerService = viewModel.scrobblingInfo.value?.getOrNull(scrobblerIndex)?.scrobbler + ScrobblingSelectorBottomSheet.show(parentFragmentManager, manga, scrobblerService) dismiss() } } diff --git a/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorBottomSheet.kt index dcdfafcf8..a8eeb49e0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorBottomSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorBottomSheet.kt @@ -8,13 +8,12 @@ import android.view.LayoutInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup -import android.widget.AdapterView -import android.widget.ArrayAdapter import android.widget.Toast import androidx.appcompat.widget.SearchView import androidx.core.view.isVisible import androidx.fragment.app.FragmentManager import coil.ImageLoader +import com.google.android.material.tabs.TabLayout import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.domain.MangaIntent @@ -23,11 +22,14 @@ import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.base.ui.list.PaginationScrollListener import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga import org.koitharu.kotatsu.databinding.SheetScrobblingSelectorBinding +import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.scrobbling.domain.model.ScrobblerManga +import org.koitharu.kotatsu.scrobbling.domain.model.ScrobblerService import org.koitharu.kotatsu.scrobbling.ui.selector.adapter.ShikiMangaSelectionDecoration import org.koitharu.kotatsu.scrobbling.ui.selector.adapter.ShikimoriSelectorAdapter import org.koitharu.kotatsu.utils.ext.assistedViewModels +import org.koitharu.kotatsu.utils.ext.firstVisibleItemPosition import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.requireParcelable import org.koitharu.kotatsu.utils.ext.withArgs @@ -42,7 +44,8 @@ class ScrobblingSelectorBottomSheet : MenuItem.OnActionExpandListener, SearchView.OnQueryTextListener, DialogInterface.OnKeyListener, - AdapterView.OnItemSelectedListener { + TabLayout.OnTabSelectedListener, + ListStateHolderListener { @Inject lateinit var viewModelFactory: ScrobblingSelectorViewModel.Factory @@ -68,7 +71,7 @@ class ScrobblingSelectorBottomSheet : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val listAdapter = ShikimoriSelectorAdapter(viewLifecycleOwner, coil, this) + val listAdapter = ShikimoriSelectorAdapter(viewLifecycleOwner, coil, this, this) val decoration = ShikiMangaSelectionDecoration(view.context) with(binding.recyclerView) { adapter = listAdapter @@ -77,7 +80,7 @@ class ScrobblingSelectorBottomSheet : } binding.buttonDone.setOnClickListener(this) initOptionsMenu() - initSpinner() + initTabs() viewModel.content.observe(viewLifecycleOwner) { listAdapter.items = it } viewModel.selectedItemId.observe(viewLifecycleOwner) { @@ -103,6 +106,12 @@ class ScrobblingSelectorBottomSheet : viewModel.selectedItemId.value = item.id } + override fun onRetryClick(error: Throwable) = Unit + + override fun onEmptyActionClick() { + openSearch() + } + override fun onScrolledToEnd() { viewModel.loadList(append = true) } @@ -143,11 +152,23 @@ class ScrobblingSelectorBottomSheet : return false } - override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { - viewModel.setScrobblerIndex(position) + override fun onTabSelected(tab: TabLayout.Tab) { + viewModel.setScrobblerIndex(tab.position) } - override fun onNothingSelected(parent: AdapterView<*>?) = Unit + override fun onTabUnselected(tab: TabLayout.Tab?) = Unit + + override fun onTabReselected(tab: TabLayout.Tab?) { + if (!isExpanded) { + setExpanded(isExpanded = true, isLocked = behavior?.isDraggable == false) + } + binding.recyclerView.firstVisibleItemPosition = 0 + } + + private fun openSearch() { + val menuItem = binding.headerBar.menu.findItem(R.id.action_search) ?: return + menuItem.expandActionView() + } private fun onError(e: Throwable) { Toast.makeText(requireContext(), e.getDisplayMessage(resources), Toast.LENGTH_LONG).show() @@ -166,32 +187,41 @@ class ScrobblingSelectorBottomSheet : searchView.queryHint = searchMenuItem.title } - private fun initSpinner() { + private fun initTabs() { val entries = viewModel.availableScrobblers + val tabs = binding.tabs if (entries.size <= 1) { - binding.spinnerScrobblers.isVisible = false + tabs.isVisible = false return } - val adapter = ArrayAdapter( - requireContext(), - android.R.layout.simple_spinner_item, - entries.map { getString(it.scrobblerService.titleResId) }, - ) - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) - binding.spinnerScrobblers.adapter = adapter - viewModel.selectedScrobblerIndex.observe(viewLifecycleOwner) { - binding.spinnerScrobblers.setSelection(it) + val selectedId = arguments?.getInt(ARG_SCROBBLER, -1) ?: -1 + tabs.removeAllTabs() + tabs.clearOnTabSelectedListeners() + tabs.addOnTabSelectedListener(this) + for (entry in entries) { + val tab = tabs.newTab() + tab.tag = entry.scrobblerService + tab.setIcon(entry.scrobblerService.iconResId) + tab.setText(entry.scrobblerService.titleResId) + tabs.addTab(tab) + if (entry.scrobblerService.id == selectedId) { + tab.select() + } } - binding.spinnerScrobblers.onItemSelectedListener = this + tabs.isVisible = true } companion object { private const val TAG = "ScrobblingSelectorBottomSheet" + private const val ARG_SCROBBLER = "scrobbler" - fun show(fm: FragmentManager, manga: Manga) = - ScrobblingSelectorBottomSheet().withArgs(1) { + fun show(fm: FragmentManager, manga: Manga, scrobblerService: ScrobblerService?) = + ScrobblingSelectorBottomSheet().withArgs(2) { putParcelable(MangaIntent.KEY_MANGA, ParcelableManga(manga, withChapters = false)) + if (scrobblerService != null) { + putInt(ARG_SCROBBLER, scrobblerService.id) + } }.show(fm, TAG) } } diff --git a/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorViewModel.kt index a9509e2b7..cb926248f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorViewModel.kt @@ -12,7 +12,9 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filterNotNull +import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseViewModel +import org.koitharu.kotatsu.list.ui.model.EmptyHint import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.list.ui.model.LoadingFooter import org.koitharu.kotatsu.list.ui.model.LoadingState @@ -46,7 +48,7 @@ class ScrobblingSelectorViewModel @AssistedInject constructor( hasNextPage, ) { list, isHasNextPage -> when { - list.isEmpty() -> listOf() + list.isEmpty() -> listOf(emptyResultsHint()) isHasNextPage -> list + LoadingFooter else -> list } @@ -125,6 +127,13 @@ class ScrobblingSelectorViewModel @AssistedInject constructor( } } + private fun emptyResultsHint() = EmptyHint( + icon = R.drawable.ic_empty_history, + textPrimary = R.string.nothing_found, + textSecondary = R.string.text_search_holder_secondary, + actionStringRes = R.string.search, + ) + @AssistedFactory interface Factory { diff --git a/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/adapter/ShikimoriMangaAD.kt b/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/adapter/ScrobblingMangaAD.kt similarity index 98% rename from app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/adapter/ShikimoriMangaAD.kt rename to app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/adapter/ScrobblingMangaAD.kt index 8ce317320..73723229a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/adapter/ShikimoriMangaAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/adapter/ScrobblingMangaAD.kt @@ -13,7 +13,7 @@ import org.koitharu.kotatsu.utils.ext.enqueueWith import org.koitharu.kotatsu.utils.ext.newImageRequest import org.koitharu.kotatsu.utils.ext.textAndVisible -fun shikimoriMangaAD( +fun scrobblingMangaAD( lifecycleOwner: LifecycleOwner, coil: ImageLoader, clickListener: OnListItemClickListener, diff --git a/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/adapter/ShikimoriSelectorAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/adapter/ShikimoriSelectorAdapter.kt index 90c6af56b..656ae82de 100644 --- a/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/adapter/ShikimoriSelectorAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/adapter/ShikimoriSelectorAdapter.kt @@ -4,23 +4,27 @@ import androidx.lifecycle.LifecycleOwner import androidx.recyclerview.widget.DiffUtil import coil.ImageLoader import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter -import kotlin.jvm.internal.Intrinsics import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener +import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener +import org.koitharu.kotatsu.list.ui.adapter.emptyHintAD import org.koitharu.kotatsu.list.ui.adapter.loadingFooterAD import org.koitharu.kotatsu.list.ui.adapter.loadingStateAD import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.scrobbling.domain.model.ScrobblerManga +import kotlin.jvm.internal.Intrinsics class ShikimoriSelectorAdapter( lifecycleOwner: LifecycleOwner, coil: ImageLoader, clickListener: OnListItemClickListener, + stateHolderListener: ListStateHolderListener, ) : AsyncListDifferDelegationAdapter(DiffCallback()) { init { delegatesManager.addDelegate(loadingStateAD()) - .addDelegate(shikimoriMangaAD(lifecycleOwner, coil, clickListener)) + .addDelegate(scrobblingMangaAD(lifecycleOwner, coil, clickListener)) .addDelegate(loadingFooterAD()) + .addDelegate(emptyHintAD(stateHolderListener)) } private class DiffCallback : DiffUtil.ItemCallback() { @@ -37,4 +41,4 @@ class ShikimoriSelectorAdapter( return Intrinsics.areEqual(oldItem, newItem) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/HistorySettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/HistorySettingsFragment.kt index 53371ec18..6237b5cbd 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/HistorySettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/HistorySettingsFragment.kt @@ -217,7 +217,8 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach viewLifecycleScope.launch { pref.summary = withContext(Dispatchers.Default) { runCatching { - repository.loadUser().nickname + val user = repository.loadUser() + getString(R.string.logged_in_as, user.nickname) }.getOrElse { it.printStackTraceDebug() it.getDisplayMessage(resources) diff --git a/app/src/main/res/drawable/ic_anilist.xml b/app/src/main/res/drawable/ic_anilist.xml index e9fa65813..13cecb8a2 100644 --- a/app/src/main/res/drawable/ic_anilist.xml +++ b/app/src/main/res/drawable/ic_anilist.xml @@ -1,10 +1,11 @@ - - + + diff --git a/app/src/main/res/layout/sheet_scrobbling.xml b/app/src/main/res/layout/sheet_scrobbling.xml index ecb30f7c8..3cfaaf4fd 100644 --- a/app/src/main/res/layout/sheet_scrobbling.xml +++ b/app/src/main/res/layout/sheet_scrobbling.xml @@ -36,6 +36,17 @@ tools:background="@sample/covers[9]" tools:ignore="ContentDescription,UnusedAttribute" /> + + - + android:visibility="gone" + app:tabGravity="start" + tools:visibility="visible" /> diff --git a/app/src/main/res/menu/opt_details.xml b/app/src/main/res/menu/opt_details.xml index 7f5d3445f..5aa52c579 100644 --- a/app/src/main/res/menu/opt_details.xml +++ b/app/src/main/res/menu/opt_details.xml @@ -32,7 +32,7 @@ app:showAsAction="never" />