recloudstream / cloudstream

Android app for streaming and downloading media.
GNU General Public License v3.0
6.76k stars 538 forks source link

Refactoring of the home page #277

Open tuyafeng opened 1 year ago

tuyafeng commented 1 year ago

Describe your suggested feature

Sorry, I don't have a discord account yet, so I post it here.

I encountered some difficulties in modifying the code of the homepage, and you are also planning to modify the homepage. I think we can discuss the refactoring of the homepage.

I think the current homepage has the following problems:

Other details

Solution:

We can wrap some views into a view according to their functions, and add it dynamically in the code. E.g:

Before:

# layout:
<!-- We have to write twice for tv and phone, sigh -->
<LinearLayout
                android:id="@+id/home_bookmarked_holder"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:visibility="gone"
                tools:visibility="visible">
<FrameLayout>
                <!-- children here, btw two many lines -->
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView />
</LinearLayout>

# code:
// but we just use it once
home_bookmarked_holder.isVisible = isVisible
//...

After:

class BookmarkedContainer @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
    // just inflate from xml or hard code here
}

class HomeFragment : Fragment() {

    private val bookmarkedContainer: BookmarkedContainer by lazy {
        BookmarkedContainer(requireContext())
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val layout = LinearLayout(requireContext())
        if (isTV) {
            // do somethin...
        } else {
        }
        layout.addView(bookmarkedContainer)
        return layout
    }
}

Through the above changes, we can only write the interface code once. Using it in HomeFragment to dynamically match the interface of TV and mobile phone. Also we can get rid of kotlin-android-extensions (I think it would be better to replace it with viewbinding, but that requires too many changes for now).

Acknowledgements

Blatzar commented 1 year ago

As long as kotlin-android-extensions doesn't impact runtime performance I'd prefer to keep it a while since view binding has been quite funky before.

Having two layout files for TV and phone is way preferable, adding views to a generic layout is extremely tedious and prone to unintentional fuckups, especially with the TV layout diverging even more in the future.

If anything should the home layout for TV also be a separate fragment but same viewmodel.

tuyafeng commented 1 year ago

If this is the case, maybe we should implement the TV interface and the mobile interface separately, saving the need to deal with the bad glue logic. The pseudo code is as follows:

interface HomePageView { 
  // or base class if you want to put some common logic code here
  void updateSeries(String source, bool cached);
  void updateBookmarks();
}

class HomeTabletFragment implements HomePageView {
  // do something for tv interface
}

class HomeCompactFragment implements HomePageView {
  // do something for mobile phone interface
}
LagradOst commented 1 year ago

I am running on the dev branch testing non nestedscrollview, it is much better