Skip to content

Commit

Permalink
Navigation enhancements: Bottom Navigation, screen transitions, back …
Browse files Browse the repository at this point in the history
…button (#670)

* Fixed bottom navigation on home screen. Default transitions. Hide back button if they do nothing.

* Resolve conflicts

* Fix formatting

* Added bottom padding.
  • Loading branch information
nahwneeth authored Jun 15, 2023
1 parent eb7a7c4 commit 36bde45
Show file tree
Hide file tree
Showing 50 changed files with 2,333 additions and 1,163 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ dependencies {
implementation 'com.google.accompanist:accompanist-pager:0.30.1'
implementation 'com.google.accompanist:accompanist-pager-indicators:0.30.1'
implementation 'com.google.accompanist:accompanist-flowlayout:0.30.1'
implementation "com.google.accompanist:accompanist-navigation-animation:0.30.1"

// LiveData
implementation 'androidx.compose.runtime:runtime-livedata:1.4.3'
Expand Down
799 changes: 252 additions & 547 deletions app/src/main/java/com/jerboa/MainActivity.kt

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions app/src/main/java/com/jerboa/nav/AboutNavigation.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.jerboa.nav

import androidx.compose.animation.ExperimentalAnimationApi
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import com.google.accompanist.navigation.animation.composable
import com.jerboa.db.AppSettings
import com.jerboa.ui.components.settings.about.AboutActivity

private const val aboutRoutePattern = "about"

@OptIn(ExperimentalAnimationApi::class)
fun NavGraphBuilder.aboutScreen(
navController: NavController,
appSettings: AppSettings?,
) {
composable(
route = aboutRoutePattern,
) {
AboutActivity(
navController = navController,
useCustomTabs = appSettings?.useCustomTabs ?: true,
usePrivateTabs = appSettings?.usePrivateTabs ?: false,
)
}
}
36 changes: 36 additions & 0 deletions app/src/main/java/com/jerboa/nav/AccountSettingsNavigation.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.jerboa.nav

import androidx.compose.animation.ExperimentalAnimationApi
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.navDeepLink
import com.google.accompanist.navigation.animation.composable
import com.jerboa.DEFAULT_LEMMY_INSTANCES
import com.jerboa.db.AccountViewModel
import com.jerboa.ui.components.home.SiteViewModel
import com.jerboa.ui.components.settings.account.AccountSettingsActivity
import com.jerboa.ui.components.settings.account.AccountSettingsViewModel

private const val accountSettingsRoutePattern = "accountSettings"

@OptIn(ExperimentalAnimationApi::class)
fun NavGraphBuilder.accountSettingsScreen(
navController: NavController,
accountSettingsViewModel: AccountSettingsViewModel,
accountViewModel: AccountViewModel,
siteViewModel: SiteViewModel,
) {
composable(
route = accountSettingsRoutePattern,
deepLinks = DEFAULT_LEMMY_INSTANCES.map { instance ->
navDeepLink { uriPattern = "$instance/settings" }
},
) {
AccountSettingsActivity(
navController = navController,
accountViewModel = accountViewModel,
siteViewModel = siteViewModel,
accountSettingsViewModel = accountSettingsViewModel,
)
}
}
34 changes: 34 additions & 0 deletions app/src/main/java/com/jerboa/nav/CommentEditNavigation.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.jerboa.nav

import androidx.compose.animation.ExperimentalAnimationApi
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import com.google.accompanist.navigation.animation.composable
import com.jerboa.db.AccountViewModel
import com.jerboa.ui.components.comment.edit.CommentEditActivity
import com.jerboa.ui.components.comment.edit.CommentEditViewModel
import com.jerboa.ui.components.person.PersonProfileViewModel
import com.jerboa.ui.components.post.PostViewModel

private const val commentEditRoutePattern = "commentEdit"

@OptIn(ExperimentalAnimationApi::class)
fun NavGraphBuilder.commentEditScreen(
accountViewModel: AccountViewModel,
navController: NavController,
commentEditViewModel: CommentEditViewModel,
personProfileViewModel: PersonProfileViewModel,
postViewModel: PostViewModel,
) {
composable(
route = commentEditRoutePattern,
) {
CommentEditActivity(
commentEditViewModel = commentEditViewModel,
accountViewModel = accountViewModel,
navController = navController,
personProfileViewModel = personProfileViewModel,
postViewModel = postViewModel,
)
}
}
99 changes: 99 additions & 0 deletions app/src/main/java/com/jerboa/nav/CommentNavigation.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package com.jerboa.nav

import android.content.Context
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.runtime.LaunchedEffect
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavType
import androidx.navigation.navArgument
import androidx.navigation.navDeepLink
import arrow.core.Either
import com.google.accompanist.navigation.animation.composable
import com.jerboa.DEFAULT_LEMMY_INSTANCES
import com.jerboa.db.Account
import com.jerboa.db.AccountViewModel
import com.jerboa.db.AppSettings
import com.jerboa.db.AppSettingsViewModel
import com.jerboa.ui.components.comment.edit.CommentEditViewModel
import com.jerboa.ui.components.comment.reply.CommentReplyViewModel
import com.jerboa.ui.components.home.SiteViewModel
import com.jerboa.ui.components.post.PostActivity
import com.jerboa.ui.components.post.PostViewModel
import com.jerboa.ui.components.post.edit.PostEditViewModel

private class CommentArgs(val id: Int) {
constructor(navBackStackEntry: NavBackStackEntry) :
this(navBackStackEntry.arguments?.getInt(ID)!!)

companion object {
const val ID = "id"
}
}

private const val commentRoutePattern = "comment/{${CommentArgs.ID}}"

@OptIn(ExperimentalAnimationApi::class)
fun NavGraphBuilder.commentScreen(
postViewModel: PostViewModel,
siteViewModel: SiteViewModel,
accountViewModel: AccountViewModel,
commentEditViewModel: CommentEditViewModel,
commentReplyViewModel: CommentReplyViewModel,
postEditViewModel: PostEditViewModel,
navController: NavController,
appSettingsViewModel: AppSettingsViewModel,
account: Account?,
appSettings: AppSettings?,
ctx: Context,
) {
composable(
route = commentRoutePattern,
deepLinks = DEFAULT_LEMMY_INSTANCES.map { instance ->
navDeepLink { uriPattern = "$instance/$commentRoutePattern" }
},
arguments = listOf(
navArgument(CommentArgs.ID) {
type = NavType.IntType
},
),
) {
val args = CommentArgs(it)

LaunchedEffect(Unit) {
val commentId = args.id
postViewModel.fetchPost(
id = Either.Right(commentId),
account = account,
clearPost = true,
clearComments = true,
ctx = ctx,
)
}
PostActivity(
postViewModel = postViewModel,
accountViewModel = accountViewModel,
commentEditViewModel = commentEditViewModel,
commentReplyViewModel = commentReplyViewModel,
postEditViewModel = postEditViewModel,
navController = navController,
showCollapsedCommentContent = appSettings?.showCollapsedCommentContent ?: false,
showActionBarByDefault = appSettings?.showCommentActionBarByDefault ?: true,
showVotingArrowsInListView = appSettings?.showVotingArrowsInListView ?: true,
onClickSortType = { commentSortType ->
val commentId = args.id
postViewModel.fetchPost(
id = Either.Right(commentId),
account = account,
clearPost = false,
clearComments = true,
ctx = ctx,
changeSortType = commentSortType,
)
},
selectedSortType = postViewModel.sortType.value,
siteViewModel = siteViewModel,
)
}
}
37 changes: 37 additions & 0 deletions app/src/main/java/com/jerboa/nav/CommentReplyNavigation.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.jerboa.nav

import androidx.compose.animation.ExperimentalAnimationApi
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import com.google.accompanist.navigation.animation.composable
import com.jerboa.db.AccountViewModel
import com.jerboa.ui.components.comment.reply.CommentReplyActivity
import com.jerboa.ui.components.comment.reply.CommentReplyViewModel
import com.jerboa.ui.components.home.SiteViewModel
import com.jerboa.ui.components.person.PersonProfileViewModel
import com.jerboa.ui.components.post.PostViewModel

private const val commentReplyRoutePattern = "commentReply"

@OptIn(ExperimentalAnimationApi::class)
fun NavGraphBuilder.commentReplyScreen(
commentReplyViewModel: CommentReplyViewModel,
accountViewModel: AccountViewModel,
personProfileViewModel: PersonProfileViewModel,
postViewModel: PostViewModel,
navController: NavController,
siteViewModel: SiteViewModel,
) {
composable(
route = commentReplyRoutePattern,
) {
CommentReplyActivity(
commentReplyViewModel = commentReplyViewModel,
postViewModel = postViewModel,
accountViewModel = accountViewModel,
personProfileViewModel = personProfileViewModel,
navController = navController,
siteViewModel = siteViewModel,
)
}
}
47 changes: 47 additions & 0 deletions app/src/main/java/com/jerboa/nav/CommentReportNavigation.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.jerboa.nav

import androidx.compose.animation.ExperimentalAnimationApi
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavType
import androidx.navigation.navArgument
import com.google.accompanist.navigation.animation.composable
import com.jerboa.db.AccountViewModel
import com.jerboa.ui.components.report.CreateReportViewModel
import com.jerboa.ui.components.report.comment.CreateCommentReportActivity

private class CommentReportArgs(val id: Int) {
constructor(navBackStackEntry: NavBackStackEntry) :
this(navBackStackEntry.arguments?.getInt(ID)!!)

companion object {
const val ID = "id"
}
}

private const val commentReportRoutePattern = "commentReport/{${CommentReportArgs.ID}}"

@OptIn(ExperimentalAnimationApi::class)
fun NavGraphBuilder.commentReportScreen(
accountViewModel: AccountViewModel,
navController: NavController,
createReportViewModel: CreateReportViewModel,
) {
composable(
route = commentReportRoutePattern,
arguments = listOf(
navArgument(CommentReportArgs.ID) {
type = NavType.IntType
},
),
) {
val args = CommentReportArgs(it)
createReportViewModel.setCommentId(args.id)
CreateCommentReportActivity(
createReportViewModel = createReportViewModel,
accountViewModel = accountViewModel,
navController = navController,
)
}
}
63 changes: 63 additions & 0 deletions app/src/main/java/com/jerboa/nav/CommunityListNavigation.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.jerboa.nav

import androidx.compose.animation.ExperimentalAnimationApi
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavType
import androidx.navigation.navArgument
import com.google.accompanist.navigation.animation.composable
import com.jerboa.db.AccountViewModel
import com.jerboa.ui.components.community.list.CommunityListActivity
import com.jerboa.ui.components.community.list.CommunityListViewModel
import com.jerboa.ui.components.home.SiteViewModel

private class CommunityListArgs(val select: Boolean) {
constructor(navBackStackEntry: NavBackStackEntry) :
this(navBackStackEntry.arguments?.getBoolean(SELECT)!!)

companion object {
const val SELECT = "select"
}
}

private const val communityListRoutePattern = "communityList?select={${CommunityListArgs.SELECT}}"

fun NavBackStackEntry.bottomNavIsSearch() = destination.route == communityListRoutePattern

@OptIn(ExperimentalAnimationApi::class)
fun NavGraphBuilder.communityListScreen(
navController: NavController,
communityListViewModel: CommunityListViewModel,
accountViewModel: AccountViewModel,
siteViewModel: SiteViewModel,
) {
composable(
route = communityListRoutePattern,
arguments = listOf(
navArgument(CommunityListArgs.SELECT) {
defaultValue = false
type = NavType.BoolType
},
),
) {
val args = CommunityListArgs(it)

// Whenever navigating here, reset the list with your followed communities
communityListViewModel.setCommunityListFromFollowed(siteViewModel)

CommunityListActivity(
navController = navController,
accountViewModel = accountViewModel,
communityListViewModel = communityListViewModel,
selectMode = args.select,
)
}
}

fun NavController.bottomNavSelectSearch() {
navigate(communityListRoutePattern) {
launchSingleTop = true
popUpTo(0)
}
}
Loading

0 comments on commit 36bde45

Please sign in to comment.