Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ALTAPPS-535: Android add swipeRefresh to Home, Track and Profile fragments #433

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion androidHyperskillApp/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import com.android.build.api.dsl.ApplicationBuildType
import org.jetbrains.kotlin.konan.properties.loadProperties
import org.jetbrains.kotlin.konan.properties.propertyString
import com.android.build.api.dsl.ApplicationBuildType

plugins {
id("com.android.application")
Expand All @@ -14,6 +14,7 @@ dependencies {
implementation(libs.android.ui.material)
implementation(libs.android.ui.appcompat)
implementation(libs.android.ui.constraintlayout)
implementation(libs.android.ui.swiperefreshlayout)
implementation(libs.android.ui.core.ktx)
implementation(libs.android.ui.fragment)
implementation(libs.android.ui.fragment.ktx)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.hyperskill.app.android.core.view.ui

import androidx.swiperefreshlayout.widget.SwipeRefreshLayout

fun SwipeRefreshLayout.updateIsRefreshing(isRefreshing: Boolean) {
if (this.isRefreshing && !isRefreshing) {
this.isRefreshing = false
}
}

fun SwipeRefreshLayout.setHyperskillColors() {
setProgressBackgroundColorSchemeResource(org.hyperskill.app.R.color.color_surface)
setColorSchemeResources(org.hyperskill.app.R.color.color_primary)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import org.hyperskill.app.android.core.view.ui.dialog.LoadingProgressDialogFragm
import org.hyperskill.app.android.core.view.ui.dialog.dismissDialogFragmentIfExists
import org.hyperskill.app.android.core.view.ui.fragment.setChildFragment
import org.hyperskill.app.android.core.view.ui.navigation.requireRouter
import org.hyperskill.app.android.core.view.ui.setHyperskillColors
import org.hyperskill.app.android.core.view.ui.updateIsRefreshing
import org.hyperskill.app.android.databinding.FragmentHomeBinding
import org.hyperskill.app.android.gamification_toolbar.view.ui.delegate.GamificationToolbarDelegate
import org.hyperskill.app.android.main.view.ui.navigation.MainScreenRouter
Expand Down Expand Up @@ -104,14 +106,18 @@ class HomeFragment :
viewBinding.homeTopicsToDiscoverNext.homeTopicsToDiscoverNextRecycler
)
with(viewBinding) {
root.setHyperskillColors()
root.setOnRefreshListener {
homeViewModel.onNewMessage(HomeFeature.Message.PullToRefresh)
}
homeScreenError.tryAgain.setOnClickListener {
homeViewModel.onNewMessage(HomeFeature.Message.Initialize(forceUpdate = true))
}
homeScreenKeepLearningInWebButton.setOnClickListener {
homeViewModel.onNewMessage(HomeFeature.Message.ClickedContinueLearningOnWeb)
}

viewBinding.homeScreenTopicsRepetitionCard.root.setOnClickListener {
homeScreenTopicsRepetitionCard.root.setOnClickListener {
homeViewModel.onNewMessage(HomeFeature.Message.ClickedTopicsRepetitionsCard)
}
}
Expand Down Expand Up @@ -209,6 +215,8 @@ class HomeFragment :
override fun render(state: HomeFeature.State) {
viewStateDelegate.switchState(state.homeState)

viewBinding.root.updateIsRefreshing(state.isRefreshing)

val homeState = state.homeState
if (homeState is HomeFeature.HomeState.Content) {
renderMagicLinkState(homeState.isLoadingMagicLink)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import org.hyperskill.app.android.core.extensions.isChannelNotificationsEnabled
import org.hyperskill.app.android.core.extensions.openUrl
import org.hyperskill.app.android.core.view.ui.dialog.LoadingProgressDialogFragment
import org.hyperskill.app.android.core.view.ui.dialog.dismissDialogFragmentIfExists
import org.hyperskill.app.android.core.view.ui.setHyperskillColors
import org.hyperskill.app.android.core.view.ui.updateIsRefreshing
import org.hyperskill.app.android.databinding.FragmentProfileBinding
import org.hyperskill.app.android.home.view.ui.screen.HomeScreen
import org.hyperskill.app.android.main.view.ui.navigation.MainScreenRouter
Expand Down Expand Up @@ -115,6 +117,18 @@ class ProfileFragment :
)
}

with(viewBinding.root) {
setHyperskillColors()
setOnRefreshListener {
profileViewModel.onNewMessage(
ProfileFeature.Message.PullToRefresh(
isRefreshCurrent = isInitCurrent,
profileId = profileId
)
)
}
}

profileViewModel.onNewMessage(
ProfileFeature.Message.Initialize(
profileId = profileId,
Expand Down Expand Up @@ -241,6 +255,7 @@ class ProfileFragment :

override fun render(state: ProfileFeature.State) {
viewStateDelegate.switchState(state)
renderSwipeRefresh(state)
when (state) {
is ProfileFeature.State.Content -> {
profileId = state.profile.id
Expand Down Expand Up @@ -271,6 +286,15 @@ class ProfileFragment :
}
}

private fun renderSwipeRefresh(content: ProfileFeature.State) {
with(viewBinding.root) {
isEnabled = content is ProfileFeature.State.Content
if (content is ProfileFeature.State.Content) {
updateIsRefreshing(content.isRefreshing)
}
}
}

private fun renderNameProfileBadge(profile: Profile) {
with(viewBinding.profileHeader) {
profileAvatarImageView.load(profile.avatar, imageLoader) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@ import by.kirich1409.viewbindingdelegate.viewBinding
import coil.ImageLoader
import coil.load
import coil.size.Scale
import kotlin.math.roundToInt
import org.hyperskill.app.SharedResources
import org.hyperskill.app.android.HyperskillApp
import org.hyperskill.app.android.R
import org.hyperskill.app.android.core.extensions.openUrl
import org.hyperskill.app.android.core.view.ui.dialog.LoadingProgressDialogFragment
import org.hyperskill.app.android.core.view.ui.dialog.dismissDialogFragmentIfExists
import org.hyperskill.app.android.core.view.ui.navigation.requireRouter
import org.hyperskill.app.android.core.view.ui.setHyperskillColors
import org.hyperskill.app.android.core.view.ui.updateIsRefreshing
import org.hyperskill.app.android.databinding.FragmentTrackBinding
import org.hyperskill.app.android.gamification_toolbar.view.ui.delegate.GamificationToolbarDelegate
import org.hyperskill.app.android.main.view.ui.navigation.MainScreenRouter
Expand All @@ -38,7 +41,6 @@ import ru.nobird.android.view.base.ui.delegate.ViewStateDelegate
import ru.nobird.android.view.base.ui.extension.showIfNotExists
import ru.nobird.android.view.redux.ui.extension.reduxViewModel
import ru.nobird.app.presentation.redux.container.ReduxView
import kotlin.math.roundToInt

class TrackFragment :
Fragment(R.layout.fragment_track),
Expand Down Expand Up @@ -82,6 +84,12 @@ class TrackFragment :
viewBinding.trackError.tryAgain.setOnClickListener {
trackViewModel.onNewMessage(TrackFeature.Message.Initialize(forceUpdate = true))
}
with(viewBinding.root) {
setHyperskillColors()
setOnRefreshListener {
trackViewModel.onNewMessage(TrackFeature.Message.PullToRefresh)
}
}
topicsDelegate.setup(requireContext(), viewBinding.trackNextTopicsRecyclerView)
trackViewModel.onNewMessage(TrackFeature.Message.Initialize())
trackViewModel.onNewMessage(TrackFeature.Message.ViewedEventMessage)
Expand Down Expand Up @@ -152,6 +160,7 @@ class TrackFragment :

override fun render(state: TrackFeature.State) {
viewStateDelegate.switchState(state.trackState)
viewBinding.root.updateIsRefreshing(state.isRefreshing)
TransitionManager.beginDelayedTransition(viewBinding.root, AutoTransition())
val trackState = state.trackState
if (trackState is TrackFeature.TrackState.Content) {
Expand Down
188 changes: 97 additions & 91 deletions androidHyperskillApp/src/main/res/layout/fragment_home.xml
Original file line number Diff line number Diff line change
@@ -1,117 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
android:layout_height="match_parent">

<include
android:id="@+id/homeScreenAppBar"
layout="@layout/layout_gamification_toolbar"/>

<androidx.core.widget.NestedScrollView
android:id="@+id/homeScreenContainer"
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
>

<LinearLayout
<include
android:id="@+id/homeScreenAppBar"
layout="@layout/layout_gamification_toolbar"/>

<androidx.core.widget.NestedScrollView
android:id="@+id/homeScreenContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="16dp"
android:paddingBottom="20dp">

<include
android:visibility="gone"
android:id="@+id/homeScreenSkeleton"
layout="@layout/layout_home_skeleton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginHorizontal="20dp"
/>

<TextView
android:id="@+id/homeScreenKeepPracticingTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/home_keep_practicing_text"
android:layout_marginHorizontal="20dp"
/>

<FrameLayout
android:id="@+id/homeProblemsLimit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginHorizontal="20dp"
/>

<include
android:id="@+id/homeScreenProblemOfDayCard"
layout="@layout/layout_problem_of_the_day_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginHorizontal="20dp"
/>

<include
android:id="@+id/homeScreenTopicsRepetitionCard"
layout="@layout/layout_topics_repetition_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginHorizontal="20dp"
/>
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
>

<include
android:id="@+id/homeTopicsToDiscoverNext"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="@layout/layout_home_topics_to_discover_next"
android:layout_marginTop="46dp"
/>
android:orientation="vertical"
android:paddingTop="16dp"
android:paddingBottom="20dp">

<include
android:visibility="gone"
android:id="@+id/homeScreenSkeleton"
layout="@layout/layout_home_skeleton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginHorizontal="20dp"
/>

<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:paddingHorizontal="20dp"
>
<TextView
android:id="@+id/homeScreenKeepPracticingTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/home_keep_practicing_text"
android:layout_marginHorizontal="20dp"
/>

<com.google.android.material.button.MaterialButton
android:id="@+id/homeScreenKeepLearningInWebButton"
<FrameLayout
android:id="@+id/homeProblemsLimit"
android:layout_width="match_parent"
android:layout_height="@dimen/auth_button_height"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
app:strokeColor="?colorPrimary"
android:insetTop="0dp"
android:insetBottom="0dp"
android:text="@string/track_continue_in_web_text"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginHorizontal="20dp"
/>

<org.hyperskill.app.android.ui.custom.LoadingView
android:id="@+id/homeKeepLearningInWebButtonSkeleton"
<include
android:id="@+id/homeScreenProblemOfDayCard"
layout="@layout/layout_problem_of_the_day_card"
android:layout_width="match_parent"
android:layout_height="@dimen/auth_button_height"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginHorizontal="20dp"
/>

</FrameLayout>
<include
android:id="@+id/homeScreenTopicsRepetitionCard"
layout="@layout/layout_topics_repetition_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginHorizontal="20dp"
/>

</LinearLayout>
<include
android:id="@+id/homeTopicsToDiscoverNext"
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="@layout/layout_home_topics_to_discover_next"
android:layout_marginTop="46dp"
/>

</androidx.core.widget.NestedScrollView>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:paddingHorizontal="20dp"
>

<com.google.android.material.button.MaterialButton
android:id="@+id/homeScreenKeepLearningInWebButton"
android:layout_width="match_parent"
android:layout_height="@dimen/auth_button_height"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
app:strokeColor="?colorPrimary"
android:insetTop="0dp"
android:insetBottom="0dp"
android:text="@string/track_continue_in_web_text"
/>

<org.hyperskill.app.android.ui.custom.LoadingView
android:id="@+id/homeKeepLearningInWebButtonSkeleton"
android:layout_width="match_parent"
android:layout_height="@dimen/auth_button_height"
/>

</FrameLayout>

</LinearLayout>

</androidx.core.widget.NestedScrollView>

<include
android:id="@+id/homeScreenError"
layout="@layout/error_no_connection_with_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
/>

<include
android:id="@+id/homeScreenError"
layout="@layout/error_no_connection_with_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
Loading