Detect if the subscription list should be shown as a grid

Also used proper string keys for the preferences, left a TODO to fix it
in other places later.
This commit is contained in:
Mauricio Colli 2020-03-05 21:26:00 -03:00
parent f01e40e671
commit b62142db82
No known key found for this signature in database
GPG Key ID: F200BFD6F29DDD85
5 changed files with 94 additions and 50 deletions

View File

@ -3,14 +3,16 @@ package org.schabi.newpipe.local.subscription
import android.app.Activity import android.app.Activity
import android.app.AlertDialog import android.app.AlertDialog
import android.content.* import android.content.*
import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
import android.os.Parcelable import android.os.Parcelable
import android.preference.PreferenceManager
import android.view.* import android.view.*
import android.widget.Toast import android.widget.Toast
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import com.nononsenseapps.filepicker.Utils import com.nononsenseapps.filepicker.Utils
import com.xwray.groupie.Group import com.xwray.groupie.Group
import com.xwray.groupie.GroupAdapter import com.xwray.groupie.GroupAdapter
@ -40,6 +42,8 @@ import org.schabi.newpipe.util.AnimationUtils.animateView
import java.io.File import java.io.File
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import kotlin.math.floor
import kotlin.math.max
class SubscriptionFragment : BaseStateFragment<SubscriptionState>() { class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
private lateinit var viewModel: SubscriptionViewModel private lateinit var viewModel: SubscriptionViewModel
@ -238,7 +242,11 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
override fun initViews(rootView: View, savedInstanceState: Bundle?) { override fun initViews(rootView: View, savedInstanceState: Bundle?) {
super.initViews(rootView, savedInstanceState) super.initViews(rootView, savedInstanceState)
items_list.layoutManager = LinearLayoutManager(requireContext()) val shouldUseGridLayout = shouldUseGridLayout()
groupAdapter.spanCount = if (shouldUseGridLayout) getGridSpanCount() else 1
items_list.layoutManager = GridLayoutManager(requireContext(), groupAdapter.spanCount).apply {
spanSizeLookup = groupAdapter.spanSizeLookup
}
items_list.adapter = groupAdapter items_list.adapter = groupAdapter
viewModel = ViewModelProviders.of(this).get(SubscriptionViewModel::class.java) viewModel = ViewModelProviders.of(this).get(SubscriptionViewModel::class.java)
@ -305,11 +313,16 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
override fun handleResult(result: SubscriptionState) { override fun handleResult(result: SubscriptionState) {
super.handleResult(result) super.handleResult(result)
val shouldUseGridLayout = shouldUseGridLayout()
when (result) { when (result) {
is SubscriptionState.LoadedState -> { is SubscriptionState.LoadedState -> {
result.subscriptions.forEach { result.subscriptions.forEach {
if (it is ChannelItem) { if (it is ChannelItem) {
it.gesturesListener = listenerChannelItem it.gesturesListener = listenerChannelItem
it.itemVersion = when {
shouldUseGridLayout -> ChannelItem.ItemVersion.GRID
else -> ChannelItem.ItemVersion.MINI
}
} }
} }
@ -377,7 +390,29 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Grid Mode // Grid Mode
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// TODO: Re-implement grid mode selection
// TODO: Move these out of this class, as it can be reused
private fun shouldUseGridLayout(): Boolean {
val listMode = PreferenceManager.getDefaultSharedPreferences(requireContext())
.getString(getString(R.string.list_view_mode_key), getString(R.string.list_view_mode_value))
return when (listMode) {
getString(R.string.list_view_mode_auto_key) -> {
val configuration = resources.configuration
(configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
&& configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE))
}
getString(R.string.list_view_mode_grid_key) -> true
else -> false
}
}
private fun getGridSpanCount(): Int {
val minWidth = resources.getDimensionPixelSize(R.dimen.channel_item_grid_min_width)
return max(1, floor(resources.displayMetrics.widthPixels / minWidth.toDouble()).toInt())
}
companion object { companion object {
private const val REQUEST_EXPORT_CODE = 666 private const val REQUEST_EXPORT_CODE = 666

View File

@ -15,7 +15,7 @@ import org.schabi.newpipe.util.OnClickGesture
class ChannelItem( class ChannelItem(
private val infoItem: ChannelInfoItem, private val infoItem: ChannelInfoItem,
private val subscriptionId: Long = -1L, private val subscriptionId: Long = -1L,
private var itemVersion: ItemVersion = ItemVersion.NORMAL, var itemVersion: ItemVersion = ItemVersion.NORMAL,
var gesturesListener: OnClickGesture<ChannelInfoItem>? = null var gesturesListener: OnClickGesture<ChannelInfoItem>? = null
) : Item() { ) : Item() {

View File

@ -1,48 +1,48 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <RelativeLayout 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:id="@+id/itemRoot"
android:id="@+id/itemRoot" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:background="?attr/selectableItemBackground"
android:background="?attr/selectableItemBackground" android:clickable="true"
android:clickable="true" android:focusable="true"
android:focusable="true" android:minWidth="@dimen/channel_item_grid_min_width"
android:padding="@dimen/video_item_search_padding"> android:padding="@dimen/channel_item_grid_padding">
<de.hdodenhof.circleimageview.CircleImageView <de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/itemThumbnailView" android:id="@+id/itemThumbnailView"
android:layout_width="@dimen/video_item_grid_thumbnail_image_height" android:layout_width="@dimen/channel_item_grid_thumbnail_image_size"
android:layout_height="@dimen/video_item_grid_thumbnail_image_height" android:layout_height="@dimen/channel_item_grid_thumbnail_image_size"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:padding="2dp" android:layout_margin="2dp"
android:contentDescription="@string/list_thumbnail_view_description" android:contentDescription="@string/detail_uploader_thumbnail_view_description"
android:src="@drawable/buddy_channel_item" android:src="@drawable/buddy_channel_item"
tools:ignore="RtlHardcoded"/> tools:ignore="RtlHardcoded" />
<TextView <TextView
android:id="@+id/itemTitleView" android:id="@+id/itemTitleView"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/itemThumbnailView" android:layout_below="@id/itemThumbnailView"
android:ellipsize="end" android:layout_centerHorizontal="true"
android:lines="1" android:ellipsize="end"
android:gravity="center_horizontal" android:lines="1"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_search_title_text_size" android:textSize="@dimen/video_item_search_title_text_size"
tools:ignore="RtlHardcoded" tools:ignore="RtlHardcoded"
tools:text="Channel Title, Lorem ipsum"/> tools:text="Channel Title, Lorem ipsum" />
<TextView <TextView
android:id="@+id/itemAdditionalDetails" android:id="@+id/itemAdditionalDetails"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/itemTitleView" android:layout_below="@+id/itemTitleView"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:lines="1" android:lines="1"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/video_item_search_upload_date_text_size" android:textSize="@dimen/video_item_search_upload_date_text_size"
tools:ignore="RtlHardcoded" tools:ignore="RtlHardcoded"
tools:text="10M subscribers"/> tools:text="10M subscribers" />
</RelativeLayout> </RelativeLayout>

View File

@ -14,6 +14,9 @@
<dimen name="video_item_search_thumbnail_image_height">70dp</dimen> <dimen name="video_item_search_thumbnail_image_height">70dp</dimen>
<dimen name="video_item_grid_thumbnail_image_width">164dp</dimen> <dimen name="video_item_grid_thumbnail_image_width">164dp</dimen>
<dimen name="video_item_grid_thumbnail_image_height">92dp</dimen> <dimen name="video_item_grid_thumbnail_image_height">92dp</dimen>
<dimen name="channel_item_grid_thumbnail_image_size">42dp</dimen>
<dimen name="channel_item_grid_min_width">128dp</dimen>
<!-- Calculated: 2*video_item_search_padding + video_item_search_thumbnail_image_height --> <!-- Calculated: 2*video_item_search_padding + video_item_search_thumbnail_image_height -->
<dimen name="video_item_search_height">96dp</dimen> <dimen name="video_item_search_height">96dp</dimen>
<!-- Paddings & Margins --> <!-- Paddings & Margins -->
@ -24,6 +27,7 @@
<dimen name="video_item_search_duration_margin">2dp</dimen> <dimen name="video_item_search_duration_margin">2dp</dimen>
<dimen name="video_item_detail_description_to_details_margin">4dp</dimen> <dimen name="video_item_detail_description_to_details_margin">4dp</dimen>
<dimen name="software_component_item_padding">8dp</dimen> <dimen name="software_component_item_padding">8dp</dimen>
<dimen name="channel_item_grid_padding">12dp</dimen>
<!-- Miscellaneous --> <!-- Miscellaneous -->
<dimen name="popup_default_width">180dp</dimen> <dimen name="popup_default_width">180dp</dimen>
<dimen name="popup_minimum_width">150dp</dimen> <dimen name="popup_minimum_width">150dp</dimen>

View File

@ -1106,12 +1106,17 @@
</string-array> </string-array>
<string name="list_view_mode_key" translatable="false">list_view_mode</string> <string name="list_view_mode_key" translatable="false">list_view_mode</string>
<string name="list_view_mode_value" translatable="false">auto</string> <string name="list_view_mode_value" translatable="false">@string/list_view_mode_auto_key</string>
<!-- TODO: Use these across the app instead of hardcoding it -->
<string name="list_view_mode_auto_key" translatable="false">auto</string>
<string name="list_view_mode_list_key" translatable="false">list</string>
<string name="list_view_mode_grid_key" translatable="false">grid</string>
<string-array name="list_view_mode_values" translatable="false"> <string-array name="list_view_mode_values" translatable="false">
<item>auto</item> <item>@string/list_view_mode_auto_key</item>
<item>list</item> <item>@string/list_view_mode_list_key</item>
<item>grid</item> <item>@string/list_view_mode_grid_key</item>
</string-array> </string-array>
<string-array name="list_view_mode_description" translatable="false"> <string-array name="list_view_mode_description" translatable="false">
<item>@string/auto</item> <item>@string/auto</item>