mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	Get Started on new Grid, only layout left
This commit is contained in:
		| @@ -73,7 +73,7 @@ object PreferenceKeys { | ||||
|  | ||||
|     const val lastUsedCategory = "last_used_category" | ||||
|  | ||||
|     const val catalogueAsList = "pref_display_catalogue_as_list" | ||||
|     const val catalogueViewSetting = "pref_display_catalogue_view_setting" | ||||
|  | ||||
|     const val enabledLanguages = "source_languages" | ||||
|  | ||||
| @@ -137,7 +137,7 @@ object PreferenceKeys { | ||||
|  | ||||
|     const val downloadNewCategories = "download_new_categories" | ||||
|  | ||||
|     const val libraryAsList = "pref_display_library_as_list" | ||||
|     const val libraryViewSetting = "pref_display_library_view_setting" | ||||
|  | ||||
|     const val lang = "app_language" | ||||
|  | ||||
|   | ||||
| @@ -143,7 +143,7 @@ class PreferencesHelper(val context: Context) { | ||||
|  | ||||
|     fun lastVersionCode() = flowPrefs.getInt("last_version_code", 0) | ||||
|  | ||||
|     fun catalogueAsList() = rxPrefs.getBoolean(Keys.catalogueAsList, false) | ||||
|     fun catalogueViewSetting() = flowPrefs.getInt(Keys.catalogueViewSetting, 0) | ||||
|  | ||||
|     fun enabledLanguages() = flowPrefs.getStringSet(Keys.enabledLanguages, setOf("all", "en", Locale.getDefault().language)) | ||||
|  | ||||
| @@ -191,7 +191,7 @@ class PreferencesHelper(val context: Context) { | ||||
|  | ||||
|     fun libraryUpdatePrioritization() = flowPrefs.getInt(Keys.libraryUpdatePrioritization, 0) | ||||
|  | ||||
|     fun libraryAsList() = flowPrefs.getBoolean(Keys.libraryAsList, false) | ||||
|     fun libraryViewSetting() = flowPrefs.getInt(Keys.libraryViewSetting, 0) | ||||
|  | ||||
|     fun downloadBadge() = flowPrefs.getBoolean(Keys.downloadBadge, false) | ||||
|  | ||||
|   | ||||
| @@ -314,7 +314,7 @@ open class BrowseSourceController(bundle: Bundle) : | ||||
|             binding.catalogueView.removeView(oldRecycler) | ||||
|         } | ||||
|  | ||||
|         val recycler = if (presenter.isListMode) { | ||||
|         val recycler = if (presenter.mode == 1) { | ||||
|             RecyclerView(view.context).apply { | ||||
|                 id = R.id.recycler | ||||
|                 layoutManager = LinearLayoutManager(context) | ||||
| @@ -332,7 +332,7 @@ open class BrowseSourceController(bundle: Bundle) : | ||||
|                 (layoutManager as GridLayoutManager).spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { | ||||
|                     override fun getSpanSize(position: Int): Int { | ||||
|                         return when (adapter?.getItemViewType(position)) { | ||||
|                             R.layout.source_grid_item, null -> 1 | ||||
|                             R.layout.source_grid_item, R.layout.source_comfortable_grid_item, null -> 1 | ||||
|                             else -> spanCount | ||||
|                         } | ||||
|                     } | ||||
| @@ -399,10 +399,10 @@ open class BrowseSourceController(bundle: Bundle) : | ||||
|  | ||||
|         // Show next display mode | ||||
|         menu.findItem(R.id.action_display_mode).apply { | ||||
|             val icon = if (presenter.isListMode) { | ||||
|                 R.drawable.ic_view_module_24dp | ||||
|             } else { | ||||
|             val icon = if (presenter.mode == 0) { | ||||
|                 R.drawable.ic_view_list_24dp | ||||
|             } else { | ||||
|                 R.drawable.ic_view_module_24dp | ||||
|             } | ||||
|             setIcon(icon) | ||||
|         } | ||||
| @@ -583,7 +583,7 @@ open class BrowseSourceController(bundle: Bundle) : | ||||
|         val adapter = adapter ?: return | ||||
|  | ||||
|         presenter.swapDisplayMode() | ||||
|         val isListMode = presenter.isListMode | ||||
|         val isListMode = presenter.mode == 1 | ||||
|         activity?.invalidateOptionsMenu() | ||||
|         setupRecycler(view) | ||||
|         if (!isListMode || !view.context.connectivityManager.isActiveNetworkMetered) { | ||||
|   | ||||
| @@ -37,6 +37,12 @@ import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateSectionItem | ||||
| import eu.kanade.tachiyomi.util.removeCovers | ||||
| import exh.EXHSavedSearch | ||||
| import java.lang.RuntimeException | ||||
| import kotlinx.coroutines.CoroutineScope | ||||
| import kotlinx.coroutines.Dispatchers | ||||
| import kotlinx.coroutines.Job | ||||
| import kotlinx.coroutines.flow.launchIn | ||||
| import kotlinx.coroutines.flow.onEach | ||||
| import kotlinx.coroutines.flow.subscribe | ||||
| import rx.Observable | ||||
| import rx.Subscription | ||||
| import rx.android.schedulers.AndroidSchedulers | ||||
| @@ -100,7 +106,7 @@ open class BrowseSourcePresenter( | ||||
|     /** | ||||
|      * Whether the view is in list mode or not. | ||||
|      */ | ||||
|     var isListMode: Boolean = false | ||||
|     var mode: Int = 0 | ||||
|         private set | ||||
|  | ||||
|     /** | ||||
| @@ -118,6 +124,11 @@ open class BrowseSourcePresenter( | ||||
|      */ | ||||
|     private var initializerSubscription: Subscription? = null | ||||
|  | ||||
|     /** | ||||
|      * Scope to watch the view setting | ||||
|      */ | ||||
|     private val scope = CoroutineScope(Job() + Dispatchers.Default) | ||||
|  | ||||
|     override fun onCreate(savedState: Bundle?) { | ||||
|         super.onCreate(savedState) | ||||
|  | ||||
| @@ -129,10 +140,9 @@ open class BrowseSourcePresenter( | ||||
|             query = savedState.getString(::query.name, "") | ||||
|         } | ||||
|  | ||||
|         add( | ||||
|             prefs.catalogueAsList().asObservable() | ||||
|                 .subscribe { setDisplayMode(it) } | ||||
|         ) | ||||
|         prefs.catalogueViewSetting().asFlow() | ||||
|             .onEach { setDisplayMode(it) } | ||||
|             .launchIn(scope) | ||||
|  | ||||
|         restartPager() | ||||
|     } | ||||
| @@ -161,7 +171,7 @@ open class BrowseSourcePresenter( | ||||
|  | ||||
|         val sourceId = source.id | ||||
|  | ||||
|         val catalogueAsList = prefs.catalogueAsList() | ||||
|         val catalogueAsList = prefs.catalogueViewSetting() | ||||
|  | ||||
|         // Prepare the pager. | ||||
|         pagerSubscription?.let { remove(it) } | ||||
| @@ -210,10 +220,10 @@ open class BrowseSourcePresenter( | ||||
|     /** | ||||
|      * Sets the display mode. | ||||
|      * | ||||
|      * @param asList whether the current mode is in list or not. | ||||
|      * @param mode whether the current mode is in list or not. | ||||
|      */ | ||||
|     private fun setDisplayMode(asList: Boolean) { | ||||
|         isListMode = asList | ||||
|     private fun setDisplayMode(mode: Int) { | ||||
|         this.mode = mode | ||||
|         subscribeToMangaInitializer() | ||||
|     } | ||||
|  | ||||
| @@ -302,7 +312,13 @@ open class BrowseSourcePresenter( | ||||
|      * Changes the active display mode. | ||||
|      */ | ||||
|     fun swapDisplayMode() { | ||||
|         prefs.catalogueAsList().set(!isListMode) | ||||
|         prefs.catalogueViewSetting().set( | ||||
|             when (mode) { | ||||
|                 0 -> 1 | ||||
|                 1 -> 2 | ||||
|                 else -> 0 | ||||
|             } | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -0,0 +1,56 @@ | ||||
| package eu.kanade.tachiyomi.ui.browse.source.browse | ||||
|  | ||||
| import android.view.View | ||||
| import com.bumptech.glide.load.engine.DiskCacheStrategy | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.kanade.tachiyomi.data.database.models.Manga | ||||
| import eu.kanade.tachiyomi.data.glide.GlideApp | ||||
| import eu.kanade.tachiyomi.data.glide.toMangaThumbnail | ||||
| import eu.kanade.tachiyomi.widget.StateImageViewTarget | ||||
| import kotlinx.android.synthetic.main.source_comfortable_grid_item.card | ||||
| import kotlinx.android.synthetic.main.source_comfortable_grid_item.progress | ||||
| import kotlinx.android.synthetic.main.source_comfortable_grid_item.thumbnail | ||||
| import kotlinx.android.synthetic.main.source_comfortable_grid_item.title | ||||
|  | ||||
| /** | ||||
|  * Class used to hold the displayed data of a manga in the catalogue, like the cover or the title. | ||||
|  * All the elements from the layout file "item_source_grid" are available in this class. | ||||
|  * | ||||
|  * @param view the inflated view for this holder. | ||||
|  * @param adapter the adapter handling this holder. | ||||
|  * @constructor creates a new catalogue holder. | ||||
|  */ | ||||
| class SourceComfortableGridHolder(private val view: View, private val adapter: FlexibleAdapter<*>) : | ||||
|     SourceHolder(view, adapter) { | ||||
|  | ||||
|     /** | ||||
|      * Method called from [CatalogueAdapter.onBindViewHolder]. It updates the data for this | ||||
|      * holder with the given manga. | ||||
|      * | ||||
|      * @param manga the manga to bind. | ||||
|      */ | ||||
|     override fun onSetValues(manga: Manga) { | ||||
|         // Set manga title | ||||
|         title.text = manga.title | ||||
|  | ||||
|         // Set alpha of thumbnail. | ||||
|         thumbnail.alpha = if (manga.favorite) 0.3f else 1.0f | ||||
|  | ||||
|         setImage(manga) | ||||
|     } | ||||
|  | ||||
|     override fun setImage(manga: Manga) { | ||||
|         // Setting this via XML doesn't work | ||||
|         card.clipToOutline = true | ||||
|  | ||||
|         GlideApp.with(view.context).clear(thumbnail) | ||||
|         if (!manga.thumbnail_url.isNullOrEmpty()) { | ||||
|             GlideApp.with(view.context) | ||||
|                 .load(manga.toMangaThumbnail()) | ||||
|                 .diskCacheStrategy(DiskCacheStrategy.DATA) | ||||
|                 .centerCrop() | ||||
|                 .placeholder(android.R.color.transparent) | ||||
|                 .into(StateImageViewTarget(thumbnail, progress)) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -5,25 +5,24 @@ import android.view.View | ||||
| import android.view.ViewGroup.LayoutParams.MATCH_PARENT | ||||
| import android.widget.FrameLayout | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import com.f2prateek.rx.preferences.Preference | ||||
| import com.tfcporciuncula.flow.Preference | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.AbstractFlexibleItem | ||||
| import eu.davidea.flexibleadapter.items.IFlexible | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.database.models.Manga | ||||
| import eu.kanade.tachiyomi.data.preference.getOrDefault | ||||
| import eu.kanade.tachiyomi.widget.AutofitRecyclerView | ||||
| import kotlinx.android.synthetic.main.source_grid_item.view.card | ||||
| import kotlinx.android.synthetic.main.source_grid_item.view.gradient | ||||
|  | ||||
| class SourceItem(val manga: Manga, private val catalogueAsList: Preference<Boolean>) : | ||||
| class SourceItem(val manga: Manga, private val catalogueAsList: Preference<Int>) : | ||||
|     AbstractFlexibleItem<SourceHolder>() { | ||||
|  | ||||
|     override fun getLayoutRes(): Int { | ||||
|         return if (catalogueAsList.getOrDefault()) { | ||||
|             R.layout.source_list_item | ||||
|         } else { | ||||
|             R.layout.source_grid_item | ||||
|         return when (catalogueAsList.get()) { | ||||
|             0 -> R.layout.source_grid_item | ||||
|             1 -> R.layout.source_list_item | ||||
|             else -> R.layout.source_comfortable_grid_item | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -33,15 +32,28 @@ class SourceItem(val manga: Manga, private val catalogueAsList: Preference<Boole | ||||
|     ): SourceHolder { | ||||
|         val parent = adapter.recyclerView | ||||
|         return if (parent is AutofitRecyclerView) { | ||||
|             view.apply { | ||||
|                 card.layoutParams = FrameLayout.LayoutParams( | ||||
|                     MATCH_PARENT, parent.itemWidth / 3 * 4 | ||||
|                 ) | ||||
|                 gradient.layoutParams = FrameLayout.LayoutParams( | ||||
|                     MATCH_PARENT, parent.itemWidth / 3 * 4 / 2, Gravity.BOTTOM | ||||
|                 ) | ||||
|             if (catalogueAsList.get() == 0) { | ||||
|                 view.apply { | ||||
|                     card.layoutParams = FrameLayout.LayoutParams( | ||||
|                         MATCH_PARENT, parent.itemWidth / 3 * 4 | ||||
|                     ) | ||||
|                     gradient.layoutParams = FrameLayout.LayoutParams( | ||||
|                         MATCH_PARENT, parent.itemWidth / 3 * 4 / 2, Gravity.BOTTOM | ||||
|                     ) | ||||
|                 } | ||||
|                 SourceGridHolder(view, adapter) | ||||
|             } else { | ||||
|                 view.apply { | ||||
|                     card.layoutParams = FrameLayout.LayoutParams( | ||||
|                         MATCH_PARENT, parent.itemWidth / 3 * 5 | ||||
|                     ) | ||||
|                     // inside.layoutParams = FrameLayout.LayoutParams(parent.height / 3 * 4, MATCH_PARENT) | ||||
|                     gradient.layoutParams = FrameLayout.LayoutParams( | ||||
|                         MATCH_PARENT, parent.itemWidth / 3 * 4 / 2, Gravity.BOTTOM | ||||
|                     ) | ||||
|                 } | ||||
|                 SourceComfortableGridHolder(view, adapter) | ||||
|             } | ||||
|             SourceGridHolder(view, adapter) | ||||
|         } else { | ||||
|             SourceListHolder(view, adapter) | ||||
|         } | ||||
|   | ||||
| @@ -93,7 +93,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att | ||||
|     fun onCreate(controller: LibraryController) { | ||||
|         this.controller = controller | ||||
|  | ||||
|         recycler = if (preferences.libraryAsList().get()) { | ||||
|         recycler = if (preferences.libraryViewSetting().get() == 1) { | ||||
|             (swipe_refresh.inflate(R.layout.library_list_recycler) as RecyclerView).apply { | ||||
|                 layoutManager = LinearLayoutManager(context) | ||||
|             } | ||||
|   | ||||
| @@ -0,0 +1,68 @@ | ||||
| package eu.kanade.tachiyomi.ui.library | ||||
|  | ||||
| import android.view.View | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import com.bumptech.glide.load.engine.DiskCacheStrategy | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.IFlexible | ||||
| import eu.kanade.tachiyomi.data.glide.GlideApp | ||||
| import eu.kanade.tachiyomi.data.glide.toMangaThumbnail | ||||
| import eu.kanade.tachiyomi.util.isLocal | ||||
| import eu.kanade.tachiyomi.util.view.visibleIf | ||||
| import kotlinx.android.synthetic.main.source_comfortable_grid_item.card | ||||
| import kotlinx.android.synthetic.main.source_comfortable_grid_item.download_text | ||||
| import kotlinx.android.synthetic.main.source_comfortable_grid_item.local_text | ||||
| import kotlinx.android.synthetic.main.source_comfortable_grid_item.thumbnail | ||||
| import kotlinx.android.synthetic.main.source_comfortable_grid_item.title | ||||
| import kotlinx.android.synthetic.main.source_comfortable_grid_item.unread_text | ||||
|  | ||||
| /** | ||||
|  * Class used to hold the displayed data of a manga in the library, like the cover or the title. | ||||
|  * All the elements from the layout file "item_source_grid" are available in this class. | ||||
|  * | ||||
|  * @param view the inflated view for this holder. | ||||
|  * @param adapter the adapter handling this holder. | ||||
|  * @param listener a listener to react to single tap and long tap events. | ||||
|  * @constructor creates a new library holder. | ||||
|  */ | ||||
| class LibraryComfortableGridHolder( | ||||
|     private val view: View, | ||||
|     adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>> | ||||
| ) : LibraryHolder(view, adapter) { | ||||
|  | ||||
|     /** | ||||
|      * Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this | ||||
|      * holder with the given manga. | ||||
|      * | ||||
|      * @param item the manga item to bind. | ||||
|      */ | ||||
|     override fun onSetValues(item: LibraryItem) { | ||||
|         // Update the title of the manga. | ||||
|         title.text = item.manga.title | ||||
|  | ||||
|         // Update the unread count and its visibility. | ||||
|         with(unread_text) { | ||||
|             visibleIf { item.unreadCount > 0 } | ||||
|             text = item.unreadCount.toString() | ||||
|         } | ||||
|         // Update the download count and its visibility. | ||||
|         with(download_text) { | ||||
|             visibleIf { item.downloadCount > 0 } | ||||
|             text = item.downloadCount.toString() | ||||
|         } | ||||
|         // set local visibility if its local manga | ||||
|         local_text.visibleIf { item.manga.isLocal() } | ||||
|  | ||||
|         // Setting this via XML doesn't work | ||||
|         card.clipToOutline = true | ||||
|  | ||||
|         // Update the cover. | ||||
|         GlideApp.with(view.context).clear(thumbnail) | ||||
|         GlideApp.with(view.context) | ||||
|             .load(item.manga.toMangaThumbnail()) | ||||
|             .diskCacheStrategy(DiskCacheStrategy.RESOURCE) | ||||
|             .centerCrop() | ||||
|             .dontAnimate() | ||||
|             .into(thumbnail) | ||||
|     } | ||||
| } | ||||
| @@ -3,7 +3,10 @@ package eu.kanade.tachiyomi.ui.library | ||||
| import android.view.Gravity | ||||
| import android.view.View | ||||
| import android.view.ViewGroup.LayoutParams.MATCH_PARENT | ||||
| import android.view.ViewGroup.LayoutParams.WRAP_CONTENT | ||||
| import android.widget.FrameLayout | ||||
| import android.widget.ImageView | ||||
| import androidx.constraintlayout.widget.ConstraintLayout | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import com.tfcporciuncula.flow.Preference | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| @@ -16,13 +19,17 @@ import eu.kanade.tachiyomi.data.database.models.LibraryManga | ||||
| import eu.kanade.tachiyomi.data.database.models.Track | ||||
| import eu.kanade.tachiyomi.data.track.TrackManager | ||||
| import eu.kanade.tachiyomi.source.SourceManager | ||||
| import eu.kanade.tachiyomi.util.system.dpToPx | ||||
| import eu.kanade.tachiyomi.widget.AutofitRecyclerView | ||||
| import exh.util.updateLayoutParams | ||||
| import kotlinx.android.synthetic.main.source_comfortable_grid_item.view.constraint_layout | ||||
| import kotlinx.android.synthetic.main.source_grid_item.view.card | ||||
| import kotlinx.android.synthetic.main.source_grid_item.view.gradient | ||||
| import kotlinx.android.synthetic.main.source_grid_item.view.thumbnail | ||||
| import uy.kohesive.injekt.Injekt | ||||
| import uy.kohesive.injekt.api.get | ||||
|  | ||||
| class LibraryItem(val manga: LibraryManga, private val libraryAsList: Preference<Boolean>) : | ||||
| class LibraryItem(val manga: LibraryManga, private val libraryViewSetting: Preference<Int>) : | ||||
|     AbstractFlexibleItem<LibraryHolder>(), IFilterable<String> { | ||||
|  | ||||
|     private val sourceManager: SourceManager = Injekt.get() | ||||
| @@ -33,24 +40,58 @@ class LibraryItem(val manga: LibraryManga, private val libraryAsList: Preference | ||||
|     var unreadCount = -1 | ||||
|  | ||||
|     override fun getLayoutRes(): Int { | ||||
|         return if (libraryAsList.get()) { | ||||
|             R.layout.source_list_item | ||||
|         } else { | ||||
|             R.layout.source_grid_item | ||||
|         return when (libraryViewSetting.get()) { | ||||
|             0 -> R.layout.source_grid_item | ||||
|             1 -> R.layout.source_list_item | ||||
|             else -> R.layout.source_comfortable_grid_item | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder { | ||||
|         val parent = adapter.recyclerView | ||||
|         return if (parent is AutofitRecyclerView) { | ||||
|             view.apply { | ||||
|                 val coverHeight = parent.itemWidth / 3 * 4 | ||||
|                 card.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, coverHeight) | ||||
|                 gradient.layoutParams = FrameLayout.LayoutParams( | ||||
|                     MATCH_PARENT, coverHeight / 2, Gravity.BOTTOM | ||||
|                 ) | ||||
|             if (libraryViewSetting.get() == 0) { | ||||
|                 view.apply { | ||||
|                     val coverHeight = parent.itemWidth / 3 * 4 | ||||
|                     card.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, coverHeight) | ||||
|                     gradient.layoutParams = FrameLayout.LayoutParams( | ||||
|                         MATCH_PARENT, coverHeight / 2, Gravity.BOTTOM | ||||
|                     ) | ||||
|                 } | ||||
|                 LibraryGridHolder(view, adapter) | ||||
|             } else { | ||||
|                 view.apply { | ||||
|                     val coverHeight = parent.itemWidth / 3 * 4 | ||||
|  | ||||
|                     gradient.layoutParams = FrameLayout.LayoutParams( | ||||
|                         MATCH_PARENT, | ||||
|                         coverHeight * (66 / 100), | ||||
|                         Gravity.BOTTOM | ||||
|                     ) | ||||
|                     card.updateLayoutParams<ConstraintLayout.LayoutParams> { | ||||
|                         bottomMargin = 6.dpToPx | ||||
|                     } | ||||
|  | ||||
|                     constraint_layout.layoutParams = FrameLayout.LayoutParams( | ||||
|                         MATCH_PARENT, WRAP_CONTENT | ||||
|                     ) | ||||
|                     thumbnail.maxHeight = Int.MAX_VALUE | ||||
|                     thumbnail.minimumHeight = 0 | ||||
|                     constraint_layout.minHeight = 0 | ||||
|                     thumbnail.scaleType = ImageView.ScaleType.CENTER_CROP | ||||
|                     thumbnail.adjustViewBounds = false | ||||
|                     thumbnail.layoutParams = FrameLayout.LayoutParams( | ||||
|                         MATCH_PARENT, | ||||
|                         (parent.itemWidth / 3f * 3.7f).toInt() | ||||
|                     ) | ||||
|                     // .layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, coverHeight) | ||||
|  | ||||
|                     // gradient.layoutParams = FrameLayout.LayoutParams( | ||||
|                     // MATCH_PARENT, coverHeight / 2, Gravity.BOTTOM | ||||
|                     // ) | ||||
|                 } | ||||
|                 LibraryComfortableGridHolder(view, adapter) | ||||
|             } | ||||
|             LibraryGridHolder(view, adapter) | ||||
|         } else { | ||||
|             LibraryListHolder(view, adapter) | ||||
|         } | ||||
|   | ||||
| @@ -301,7 +301,7 @@ class LibraryPresenter( | ||||
|      * value. | ||||
|      */ | ||||
|     private fun getLibraryMangasObservable(): Observable<LibraryMap> { | ||||
|         val libraryAsList = preferences.libraryAsList() | ||||
|         val libraryAsList = preferences.libraryViewSetting() | ||||
|         return db.getLibraryMangas().asRxObservable() | ||||
|             .map { list -> | ||||
|                 list.map { LibraryItem(it, libraryAsList) }.groupBy { it.manga.category } | ||||
|   | ||||
| @@ -220,16 +220,18 @@ class LibrarySettingsSheet( | ||||
|         inner class DisplayGroup : Group { | ||||
|  | ||||
|             private val grid = Item.Radio(R.string.action_display_grid, this) | ||||
|             private val comfortableGrid = Item.Radio(R.string.action_display_comfortable_grid, this) | ||||
|             private val list = Item.Radio(R.string.action_display_list, this) | ||||
|  | ||||
|             override val header = null | ||||
|             override val items = listOf(grid, list) | ||||
|             override val items = listOf(grid, comfortableGrid, list) | ||||
|             override val footer = null | ||||
|  | ||||
|             override fun initModels() { | ||||
|                 val asList = preferences.libraryAsList().get() | ||||
|                 grid.checked = !asList | ||||
|                 list.checked = asList | ||||
|                 val mode = preferences.libraryViewSetting().get() | ||||
|                 grid.checked = mode == 0 | ||||
|                 list.checked = mode == 1 | ||||
|                 comfortableGrid.checked = mode == 2 | ||||
|             } | ||||
|  | ||||
|             override fun onItemClicked(item: Item) { | ||||
| @@ -239,7 +241,13 @@ class LibrarySettingsSheet( | ||||
|                 item.group.items.forEach { (it as Item.Radio).checked = false } | ||||
|                 item.checked = true | ||||
|  | ||||
|                 preferences.libraryAsList().set(item == list) | ||||
|                 preferences.libraryViewSetting().set( | ||||
|                     when (item) { | ||||
|                         grid -> 0 | ||||
|                         list -> 1 | ||||
|                         else -> 2 | ||||
|                     } | ||||
|                 ) | ||||
|  | ||||
|                 item.group.items.forEach { adapter.notifyItemChanged(it) } | ||||
|             } | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import android.animation.AnimatorListenerAdapter | ||||
| import android.app.Activity | ||||
| import android.content.Intent | ||||
| import android.os.Bundle | ||||
| import android.util.Log | ||||
| import android.view.LayoutInflater | ||||
| import android.view.Menu | ||||
| import android.view.MenuInflater | ||||
| @@ -178,9 +179,11 @@ class MangaAllInOneController : | ||||
|     } | ||||
|  | ||||
|     override fun createPresenter(): MangaAllInOnePresenter { | ||||
|         Log.d("Adapter", "Tester8") | ||||
|         return MangaAllInOnePresenter( | ||||
|             this, manga!!, source!!, smartSearchConfig | ||||
|         ) | ||||
|         Log.d("Adapter", "Tester9") | ||||
|     } | ||||
|  | ||||
|     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { | ||||
| @@ -198,6 +201,8 @@ class MangaAllInOneController : | ||||
|             .onEach { fetchMangaFromSource(manualFetch = true) } | ||||
|             .launchIn(scope) | ||||
|  | ||||
|         Log.d("Controller", "Tester1") | ||||
|  | ||||
|         // Init RecyclerView and adapter | ||||
|         adapter = MangaAllInOneAdapter(this, view.context) | ||||
|  | ||||
| @@ -206,6 +211,7 @@ class MangaAllInOneController : | ||||
|         binding.recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL)) | ||||
|         binding.recycler.setHasFixedSize(true) | ||||
|         adapter?.fastScroller = binding.fastScroller | ||||
|         Log.d("Adapter", "Tester2") | ||||
|  | ||||
|         binding.fab.clicks() | ||||
|             .onEach { | ||||
| @@ -233,22 +239,27 @@ class MangaAllInOneController : | ||||
|  | ||||
|         binding.actionToolbar.offsetAppbarHeight(activity!!) | ||||
|         binding.fab.offsetAppbarHeight(activity!!) | ||||
|         Log.d("Adapter", "Tester3") | ||||
|     } | ||||
|  | ||||
|     private fun getHeader(): MangaAllInOneHolder? { | ||||
|         Log.d("Adapter", "Tester4") | ||||
|         return binding.recycler.findViewHolderForAdapterPosition(0) as? MangaAllInOneHolder | ||||
|         Log.d("Adapter", "Tester5") | ||||
|     } | ||||
|  | ||||
|     private fun addMangaHeader() { | ||||
|         Log.d("Adapter", "Tester6") | ||||
|         if (adapter?.scrollableHeaders?.isEmpty() == true) { | ||||
|             adapter?.removeAllScrollableHeaders() | ||||
|             adapter?.addScrollableHeader(presenter.headerItem) | ||||
|         } | ||||
|         Log.d("Adapter", "Tester7") | ||||
|     } | ||||
|  | ||||
|     // EXH --> | ||||
|     override fun openSmartSearch() { | ||||
|         val smartSearchConfig = SourceController.SmartSearchConfig(presenter.manga.title, presenter.manga.id!!) | ||||
|         val smartSearchConfig = SourceController.SmartSearchConfig(presenter.manga.title, presenter.manga.id) | ||||
|  | ||||
|         router?.pushController( | ||||
|             SourceController( | ||||
| @@ -329,12 +340,16 @@ class MangaAllInOneController : | ||||
|     override fun onNextManga(manga: Manga, source: Source, chapters: List<MangaAllInOneChapterItem>, lastUpdateDate: Date, chapterCount: Float) { | ||||
|         if (manga.initialized) { | ||||
|             // Update view. | ||||
|             Log.d("Controller", "Tester1") | ||||
|             setMangaInfo(manga, source, chapters, lastUpdateDate, chapterCount) | ||||
|             Log.d("Controller", "Tester2") | ||||
|             if (fromSource && !presenter.hasRequested && chapters.isNullOrEmpty()) { | ||||
|                 Log.d("Controller", "Tester3") | ||||
|                 fetchMangaFromSource(fetchManga = false) | ||||
|             } | ||||
|         } else { | ||||
|             // Initialize manga. | ||||
|             Log.d("Controller", "Tester4") | ||||
|             fetchMangaFromSource() | ||||
|         } | ||||
|     } | ||||
|   | ||||
							
								
								
									
										145
									
								
								app/src/main/res/layout/source_comfortable_grid_item.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								app/src/main/res/layout/source_comfortable_grid_item.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| <?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="wrap_content" | ||||
|     android:background="@drawable/library_item_selector" | ||||
|     android:padding="4dp"> | ||||
|  | ||||
|     <androidx.constraintlayout.widget.ConstraintLayout | ||||
|         android:id="@+id/constraint_layout" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:orientation="vertical"> | ||||
|  | ||||
|         <FrameLayout | ||||
|             android:id="@+id/card" | ||||
|             android:layout_width="wrap_content" | ||||
|             android:layout_height="220dp" | ||||
|             android:layout_gravity="top" | ||||
|             android:background="@drawable/rounded_rectangle" | ||||
|             android:layout_marginStart="10dp" | ||||
|             android:layout_marginTop="10dp" | ||||
|             android:layout_marginEnd="10dp" | ||||
|             app:layout_constraintEnd_toEndOf="parent" | ||||
|             app:layout_constraintStart_toStartOf="parent" | ||||
|             app:layout_constraintTop_toTopOf="parent" | ||||
|             app:layout_constraintVertical_bias="1.0"> | ||||
|  | ||||
|             <ImageView | ||||
|                 android:id="@+id/thumbnail" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="match_parent" | ||||
|                 android:background="?attr/colorSurface" | ||||
|                 tools:ignore="ContentDescription" | ||||
|                 android:scaleType="centerCrop" | ||||
|                 tools:src="@mipmap/ic_launcher" /> | ||||
|  | ||||
|             <View | ||||
|                 android:id="@+id/gradient" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_gravity="bottom" | ||||
|                 android:background="@drawable/gradient_shape" /> | ||||
|  | ||||
|             <androidx.constraintlayout.widget.ConstraintLayout | ||||
|                 android:layout_width="wrap_content" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 tools:layout_editor_absoluteX="7dp" | ||||
|                 tools:layout_editor_absoluteY="7dp"> | ||||
|  | ||||
|                 <TextView | ||||
|                     android:id="@+id/unread_text" | ||||
|                     style="@style/TextAppearance.Regular.Caption" | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:layout_marginStart="4dp" | ||||
|                     android:layout_marginTop="4dp" | ||||
|                     android:background="@color/colorAccentDark" | ||||
|                     android:paddingStart="3dp" | ||||
|                     android:paddingTop="1dp" | ||||
|                     android:paddingEnd="3dp" | ||||
|                     android:paddingBottom="1dp" | ||||
|                     android:textColor="@color/md_white_1000" | ||||
|                     android:visibility="gone" | ||||
|                     app:layout_constraintStart_toEndOf="@+id/download_text" | ||||
|                     app:layout_constraintTop_toTopOf="parent" | ||||
|                     tools:text="120" | ||||
|                     tools:visibility="visible" /> | ||||
|  | ||||
|                 <TextView | ||||
|                     android:id="@+id/download_text" | ||||
|                     style="@style/TextAppearance.Regular.Caption" | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:layout_marginStart="4dp" | ||||
|                     android:layout_marginTop="4dp" | ||||
|                     android:background="@color/md_red_500" | ||||
|                     android:paddingStart="3dp" | ||||
|                     android:paddingTop="1dp" | ||||
|                     android:paddingEnd="3dp" | ||||
|                     android:paddingBottom="1dp" | ||||
|                     android:textColor="@color/md_white_1000" | ||||
|                     android:visibility="gone" | ||||
|                     app:layout_constraintStart_toEndOf="@+id/local_text" | ||||
|                     app:layout_constraintTop_toTopOf="parent" | ||||
|                     tools:text="120" | ||||
|                     tools:visibility="visible" /> | ||||
|  | ||||
|                 <TextView | ||||
|                     android:id="@+id/local_text" | ||||
|                     style="@style/TextAppearance.Regular.Caption" | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:layout_marginStart="4dp" | ||||
|                     android:layout_marginTop="4dp" | ||||
|                     android:background="@color/md_teal_500" | ||||
|                     android:paddingStart="3dp" | ||||
|                     android:paddingTop="1dp" | ||||
|                     android:paddingEnd="3dp" | ||||
|                     android:paddingBottom="1dp" | ||||
|                     android:text="@string/local_source_badge" | ||||
|                     android:textColor="@color/md_white_1000" | ||||
|                     android:visibility="gone" | ||||
|                     app:layout_constraintStart_toStartOf="parent" | ||||
|                     app:layout_constraintTop_toTopOf="parent" | ||||
|                     tools:visibility="visible" /> | ||||
|  | ||||
|             </androidx.constraintlayout.widget.ConstraintLayout> | ||||
|  | ||||
|         </FrameLayout> | ||||
|  | ||||
|         <ProgressBar | ||||
|             android:id="@+id/progress" | ||||
|             style="?android:attr/progressBarStyleSmall" | ||||
|             android:layout_width="wrap_content" | ||||
|             android:layout_height="wrap_content" | ||||
|             android:layout_gravity="center" | ||||
|             android:visibility="gone" | ||||
|             app:layout_constraintBottom_toBottomOf="parent" | ||||
|             app:layout_constraintEnd_toEndOf="parent" | ||||
|             app:layout_constraintStart_toStartOf="parent" | ||||
|             app:layout_constraintTop_toTopOf="parent" /> | ||||
|  | ||||
|         <TextView | ||||
|             android:id="@+id/title" | ||||
|             style="@style/TextAppearance.Regular.Body1" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content" | ||||
|             android:layout_gravity="bottom" | ||||
|             android:ellipsize="end" | ||||
|             android:fontFamily="@font/ptsans_narrow_bold" | ||||
|             android:lineSpacingExtra="-4dp" | ||||
|             android:maxLines="2" | ||||
|             android:padding="8dp" | ||||
|             android:shadowColor="@color/textColorPrimaryLight" | ||||
|             app:layout_constraintEnd_toEndOf="parent" | ||||
|             app:layout_constraintStart_toStartOf="parent" | ||||
|             app:layout_constraintBottom_toBottomOf="parent" | ||||
|             tools:text="Sample name" | ||||
|             android:orientation="vertical" /> | ||||
|  | ||||
|     </androidx.constraintlayout.widget.ConstraintLayout> | ||||
|  | ||||
| </FrameLayout> | ||||
| @@ -15,6 +15,7 @@ | ||||
|     <string name="action_search_manually">Search manually</string> | ||||
|     <string name="action_migrate_now">Migrate now</string> | ||||
|     <string name="action_copy_now">Copy now</string> | ||||
|     <string name="action_display_comfortable_grid">Comfortable grid</string> | ||||
|  | ||||
|     <!-- Preferences --> | ||||
|     <!-- Filter --> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user