package com.github.libretube.fragments import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import com.github.libretube.R import com.github.libretube.adapters.ChannelAdapter import com.github.libretube.databinding.FragmentChannelBinding import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.SubscriptionHelper import com.github.libretube.util.formatShort import com.github.libretube.util.toID import retrofit2.HttpException import java.io.IOException class ChannelFragment : Fragment() { private val TAG = "ChannelFragment" private lateinit var binding: FragmentChannelBinding private var channelId: String? = null private var channelName: String? = null var nextPage: String? = null private var channelAdapter: ChannelAdapter? = null private var isLoading = true private var isSubscribed: Boolean? = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) arguments?.let { channelId = it.getString("channel_id").toID() channelName = it.getString("channel_name") ?.replace("/c/", "") ?.replace("/user/", "") } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentChannelBinding.inflate(layoutInflater, container, false) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.channelName.text = channelId binding.channelRecView.layoutManager = LinearLayoutManager(context) val refreshChannel = { binding.channelRefresh.isRefreshing = true fetchChannel() isSubscribed() } refreshChannel() binding.channelRefresh.setOnRefreshListener { refreshChannel() } binding.channelScrollView.viewTreeObserver .addOnScrollChangedListener { if (binding.channelScrollView.getChildAt(0).bottom == (binding.channelScrollView.height + binding.channelScrollView.scrollY) ) { // scroll view is at bottom if (nextPage != null && !isLoading) { isLoading = true binding.channelRefresh.isRefreshing = true fetchChannelNextPage() } } } } private fun isSubscribed() { lifecycleScope.launchWhenCreated { isSubscribed = SubscriptionHelper.isSubscribed(channelId!!) if (isSubscribed == null) return@launchWhenCreated runOnUiThread { if (isSubscribed == true) { binding.channelSubscribe.text = getString(R.string.unsubscribe) } binding.channelSubscribe.setOnClickListener { binding.channelSubscribe.text = if (isSubscribed == true) { SubscriptionHelper.unsubscribe(channelId!!) isSubscribed = false getString(R.string.subscribe) } else { SubscriptionHelper.subscribe(channelId!!) isSubscribed = true getString(R.string.unsubscribe) } } } } } private fun fetchChannel() { fun run() { lifecycleScope.launchWhenCreated { val response = try { if (channelId != null) RetrofitInstance.api.getChannel(channelId!!) else RetrofitInstance.api.getChannelByName(channelName!!) } catch (e: IOException) { binding.channelRefresh.isRefreshing = false println(e) Log.e(TAG, "IOException, you might not have internet connection") return@launchWhenCreated } catch (e: HttpException) { binding.channelRefresh.isRefreshing = false Log.e(TAG, "HttpException, unexpected response") return@launchWhenCreated } nextPage = response.nextpage isLoading = false binding.channelRefresh.isRefreshing = false runOnUiThread { binding.channelScrollView.visibility = View.VISIBLE binding.channelName.text = response.name if (response.verified) { binding.channelName.setCompoundDrawablesWithIntrinsicBounds( 0, 0, R.drawable.ic_verified, 0 ) } binding.channelSubs.text = resources.getString( R.string.subscribers, response.subscriberCount.formatShort() ) if (response.description?.trim() == "") { binding.channelDescription.visibility = View.GONE } else { binding.channelDescription.text = response.description?.trim() } ConnectionHelper.loadImage(response.bannerUrl, binding.channelBanner) ConnectionHelper.loadImage(response.avatarUrl, binding.channelImage) // recyclerview of the videos by the channel channelAdapter = ChannelAdapter( response.relatedStreams!!.toMutableList(), childFragmentManager ) binding.channelRecView.adapter = channelAdapter } } } run() } private fun fetchChannelNextPage() { fun run() { lifecycleScope.launchWhenCreated { val response = try { RetrofitInstance.api.getChannelNextPage(channelId!!, nextPage!!) } catch (e: IOException) { binding.channelRefresh.isRefreshing = false println(e) Log.e(TAG, "IOException, you might not have internet connection") return@launchWhenCreated } catch (e: HttpException) { binding.channelRefresh.isRefreshing = false Log.e(TAG, "HttpException, unexpected response," + e.response()) return@launchWhenCreated } nextPage = response.nextpage channelAdapter?.updateItems(response.relatedStreams!!) isLoading = false binding.channelRefresh.isRefreshing = false } } run() } private fun Fragment?.runOnUiThread(action: () -> Unit) { this ?: return if (!isAdded) return // Fragment not attached to an Activity activity?.runOnUiThread(action) } }