diff --git a/app/src/main/java/org/pixeldroid/app/posts/PostActivity.kt b/app/src/main/java/org/pixeldroid/app/posts/PostActivity.kt index 79c18222..266b71e0 100644 --- a/app/src/main/java/org/pixeldroid/app/posts/PostActivity.kt +++ b/app/src/main/java/org/pixeldroid/app/posts/PostActivity.kt @@ -6,6 +6,7 @@ import android.view.View import android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts +import androidx.constraintlayout.widget.ConstraintLayout import androidx.lifecycle.lifecycleScope import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.pixeldroid.app.R @@ -24,13 +25,16 @@ import org.pixeldroid.app.utils.displayDimensionsInPx class PostActivity : BaseActivity() { private lateinit var binding: ActivityPostBinding - private var commentFragment = CommentFragment() + private lateinit var commentFragment: CommentFragment private lateinit var status: Status override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityPostBinding.inflate(layoutInflater) + + commentFragment = CommentFragment(binding.swipeRefreshLayout) + setContentView(binding.root) setSupportActionBar(binding.topBar) supportActionBar?.setDisplayHomeAsUpEnabled(true) @@ -105,6 +109,11 @@ class PostActivity : BaseActivity() { supportFragmentManager.beginTransaction() .add(R.id.commentFragment, commentFragment).commit() + + binding.swipeRefreshLayout.setOnRefreshListener { + commentFragment.adapter.refresh() + commentFragment.adapter.notifyDataSetChanged() + } } private suspend fun postComment( diff --git a/app/src/main/java/org/pixeldroid/app/posts/feeds/uncachedFeeds/UncachedFeedFragment.kt b/app/src/main/java/org/pixeldroid/app/posts/feeds/uncachedFeeds/UncachedFeedFragment.kt index db58c98e..934055ca 100644 --- a/app/src/main/java/org/pixeldroid/app/posts/feeds/uncachedFeeds/UncachedFeedFragment.kt +++ b/app/src/main/java/org/pixeldroid/app/posts/feeds/uncachedFeeds/UncachedFeedFragment.kt @@ -11,6 +11,7 @@ import androidx.paging.ExperimentalPagingApi import androidx.paging.LoadState import androidx.paging.PagingDataAdapter import androidx.recyclerview.widget.RecyclerView +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import kotlinx.coroutines.Job import kotlinx.coroutines.flow.distinctUntilChangedBy import kotlinx.coroutines.flow.filter @@ -20,6 +21,7 @@ import org.pixeldroid.app.posts.feeds.initAdapter import org.pixeldroid.app.posts.feeds.launch import org.pixeldroid.app.utils.BaseFragment import org.pixeldroid.app.utils.api.objects.FeedContent +import org.pixeldroid.app.utils.limitedLengthSmoothScrollToPosition /** @@ -30,8 +32,7 @@ open class UncachedFeedFragment : BaseFragment() { internal lateinit var viewModel: FeedViewModel internal lateinit var adapter: PagingDataAdapter - lateinit var binding: FragmentFeedBinding - + var binding: FragmentFeedBinding? = null private var job: Job? = null @@ -48,25 +49,35 @@ open class UncachedFeedFragment : BaseFragment() { .distinctUntilChangedBy { it.refresh } // Only react to cases where Remote REFRESH completes i.e., NotLoading. .filter { it.refresh is LoadState.NotLoading } - .collect { binding.list.scrollToPosition(0) } + .collect { binding?.list?.scrollToPosition(0) } } } - override fun onCreateView( + fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - + savedInstanceState: Bundle?, swipeRefreshLayout: SwipeRefreshLayout? + ): View { super.onCreateView(inflater, container, savedInstanceState) binding = FragmentFeedBinding.inflate(layoutInflater) - initAdapter( - binding.progressBar, binding.swipeRefreshLayout, binding.list, - binding.motionLayout, binding.errorLayout, adapter - ) + binding!!.let { + initAdapter( + it.progressBar, swipeRefreshLayout ?: it.swipeRefreshLayout, it.list, + it.motionLayout, it.errorLayout, adapter + ) - return binding.root + } + return binding!!.root + } + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return onCreateView(inflater, container, savedInstanceState, null) + } + fun onTabReClicked() { + binding?.list?.limitedLengthSmoothScrollToPosition(0) } } diff --git a/app/src/main/java/org/pixeldroid/app/posts/feeds/uncachedFeeds/comments/CommentFragment.kt b/app/src/main/java/org/pixeldroid/app/posts/feeds/uncachedFeeds/comments/CommentFragment.kt index 486b66b2..def96386 100644 --- a/app/src/main/java/org/pixeldroid/app/posts/feeds/uncachedFeeds/comments/CommentFragment.kt +++ b/app/src/main/java/org/pixeldroid/app/posts/feeds/uncachedFeeds/comments/CommentFragment.kt @@ -5,12 +5,15 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.NestedScrollingChild +import androidx.core.view.NestedScrollingChildHelper import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import androidx.paging.ExperimentalPagingApi import androidx.paging.PagingDataAdapter import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import org.pixeldroid.app.R import org.pixeldroid.app.databinding.CommentBinding import org.pixeldroid.app.posts.PostActivity @@ -25,7 +28,7 @@ import org.pixeldroid.app.utils.setProfileImageFromURL /** * Fragment to show a list of [Status]s, in form of comments */ -class CommentFragment : UncachedFeedFragment() { +class CommentFragment(val swipeRefreshLayout: SwipeRefreshLayout): UncachedFeedFragment() { private lateinit var id: String private lateinit var domain: String @@ -42,11 +45,11 @@ class CommentFragment : UncachedFeedFragment() { @OptIn(ExperimentalPagingApi::class) override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? + savedInstanceState: Bundle?, ): View? { - val view = super.onCreateView(inflater, container, savedInstanceState) + val view = super.onCreateView(inflater, container, savedInstanceState, swipeRefreshLayout) // Get the view model @Suppress("UNCHECKED_CAST") @@ -62,6 +65,7 @@ class CommentFragment : UncachedFeedFragment() { launch() initSearch() + binding?.swipeRefreshLayout?.isEnabled = false return view } companion object { diff --git a/app/src/main/java/org/pixeldroid/app/profile/ProfileActivity.kt b/app/src/main/java/org/pixeldroid/app/profile/ProfileActivity.kt index ab33818a..cddd0c7d 100644 --- a/app/src/main/java/org/pixeldroid/app/profile/ProfileActivity.kt +++ b/app/src/main/java/org/pixeldroid/app/profile/ProfileActivity.kt @@ -7,16 +7,19 @@ import android.util.Log import android.view.View import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts +import androidx.constraintlayout.motion.widget.MotionLayout import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.viewpager2.adapter.FragmentStateAdapter import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.tabs.TabLayout +import com.google.android.material.tabs.TabLayout.OnTabSelectedListener import com.google.android.material.tabs.TabLayoutMediator import kotlinx.coroutines.launch import org.pixeldroid.app.R import org.pixeldroid.app.databinding.ActivityProfileBinding +import org.pixeldroid.app.posts.feeds.cachedFeeds.CachedFeedFragment import org.pixeldroid.app.posts.feeds.uncachedFeeds.UncachedFeedFragment import org.pixeldroid.app.posts.parseHTMLText import org.pixeldroid.app.utils.BaseActivity @@ -58,6 +61,29 @@ class ProfileActivity : BaseActivity() { val tabs = createProfileTabs(account) setupTabs(tabs) setContent(account) + + binding.profileMotion.setTransitionListener( + object : MotionLayout.TransitionListener { + override fun onTransitionStarted( + motionLayout: MotionLayout?, startId: Int, endId: Int, + ) {} + + override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {} + + override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) { + if (currentId == R.id.hideProfile && motionLayout?.startState == R.id.start) { + // If the 1st transition has been made go to the second one + motionLayout.setTransition(R.id.second) + } else if(currentId == R.id.hideProfile && motionLayout?.startState == R.id.hideProfile){ + motionLayout.setTransition(R.id.first) + } + } + + override fun onTransitionTrigger( + motionLayout: MotionLayout?, triggerId: Int, positive: Boolean, progress: Float, + ) {} + } + ) } private fun createProfileTabs(account: Account?): Array> { @@ -104,7 +130,7 @@ class ProfileActivity : BaseActivity() { } private fun setupTabs( - tabs: Array> + tabs: Array>, ){ binding.viewPager.adapter = object : FragmentStateAdapter(this) { override fun createFragment(position: Int): Fragment { @@ -136,6 +162,14 @@ class ProfileActivity : BaseActivity() { } } }.attach() + + binding.profileTabs.addOnTabSelectedListener(object : OnTabSelectedListener { + override fun onTabSelected(tab: TabLayout.Tab) {} + override fun onTabUnselected(tab: TabLayout.Tab) {} + override fun onTabReselected(tab: TabLayout.Tab) { + tabs[tab.position].onTabReClicked() + } + }) } private fun setContent(account: Account?) { diff --git a/app/src/main/java/org/pixeldroid/app/profile/ProfileFeedFragment.kt b/app/src/main/java/org/pixeldroid/app/profile/ProfileFeedFragment.kt index 558a95d4..3b96ddf7 100644 --- a/app/src/main/java/org/pixeldroid/app/profile/ProfileFeedFragment.kt +++ b/app/src/main/java/org/pixeldroid/app/profile/ProfileFeedFragment.kt @@ -101,7 +101,7 @@ class ProfileFeedFragment : UncachedFeedFragment() { val view = super.onCreateView(inflater, container, savedInstanceState) if(grid || bookmarks || collections || addCollection) { - binding.list.layoutManager = GridLayoutManager(context, 3) + binding?.list?.layoutManager = GridLayoutManager(context, 3) } // Get the view model @@ -191,8 +191,11 @@ class ProfileFeedFragment : UncachedFeedFragment() { val url = "$domain/i/collections/create" if(domain.isNullOrEmpty() || !requireContext().openUrl(url)) { - Snackbar.make(binding.root, getString(R.string.new_collection_link_failed), - Snackbar.LENGTH_LONG).show() + binding?.let { binding -> + Snackbar.make( + binding.root, getString(R.string.new_collection_link_failed), + Snackbar.LENGTH_LONG).show() + } } } diff --git a/app/src/main/res/layout/activity_post.xml b/app/src/main/res/layout/activity_post.xml index 9a98703d..743adceb 100644 --- a/app/src/main/res/layout/activity_post.xml +++ b/app/src/main/res/layout/activity_post.xml @@ -3,88 +3,104 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/scrollview" - android:fitsSystemWindows="true" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="?attr/colorSecondaryContainer" + android:fitsSystemWindows="true" tools:context=".posts.PostActivity"> - + android:layout_height="match_parent"> - + android:layout_height="match_parent" + android:background="?attr/colorSurface"> - - - - - + android:layout_height="match_parent" + android:fillViewport="true" + app:layout_constraintBottom_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent"> + android:layout_height="wrap_content"> - - - - - -