Skip to content

Commit

Permalink
Bottom nav bar and screen transitions (#855)
Browse files Browse the repository at this point in the history
* Bottom nav bar fixes

* Drawer & back button

* Fix for when bottom nav bar isn't visible.

* Fix & rebase.

* Fix merge mistakes

---------

Co-authored-by: Kevin Phoenix <[email protected]>
  • Loading branch information
nahwneeth and twizmwazin authored Jun 24, 2023
1 parent 6e82b9a commit 54a2e01
Show file tree
Hide file tree
Showing 15 changed files with 465 additions and 400 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ dependencies {
implementation("com.google.accompanist:accompanist-pager-indicators:0.30.1")
implementation("com.google.accompanist:accompanist-flowlayout:0.30.1")
implementation("com.google.accompanist:accompanist-permissions: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
37 changes: 21 additions & 16 deletions app/src/main/java/com/jerboa/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,29 @@ package com.jerboa

import android.app.Application
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.util.Patterns
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import androidx.navigation.navDeepLink
import arrow.core.Either
import com.google.accompanist.navigation.animation.AnimatedNavHost
import com.google.accompanist.navigation.animation.composable
import com.google.accompanist.navigation.animation.rememberAnimatedNavController
import com.jerboa.api.ApiState
import com.jerboa.api.MINIMUM_API_VERSION
import com.jerboa.datatypes.types.GetCommunity
Expand Down Expand Up @@ -114,11 +115,10 @@ class MainActivity : ComponentActivity() {
AppSettingsViewModelFactory((application as JerboaApplication).appSettingsRepository)
}

@OptIn(ExperimentalAnimationApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))

val accountSync = getCurrentAccountSync(accountViewModel)
fetchInitialData(accountSync, siteViewModel, homeViewModel)

Expand All @@ -129,7 +129,7 @@ class MainActivity : ComponentActivity() {
JerboaTheme(
appSettings = appSettings,
) {
val navController = rememberNavController()
val navController = rememberAnimatedNavController()
val ctx = LocalContext.current
val serverVersionOutdatedViewed = remember { mutableStateOf(false) }

Expand All @@ -154,9 +154,13 @@ class MainActivity : ComponentActivity() {
else -> {}
}

NavHost(
AnimatedNavHost(
navController = navController,
startDestination = "home",
enterTransition = { slideInHorizontally { it } },
exitTransition = { slideOutHorizontally { -it } },
popEnterTransition = { slideInHorizontally { -it } },
popExitTransition = { slideOutHorizontally { it } },
) {
composable(
route = "login",
Expand All @@ -175,16 +179,20 @@ class MainActivity : ComponentActivity() {
composable(
route = "home",
) {
HomeActivity(
BottomNavActivity(
navController = navController,
homeViewModel = homeViewModel,
accountViewModel = accountViewModel,
siteViewModel = siteViewModel,
postEditViewModel = postEditViewModel,
appSettingsViewModel = appSettingsViewModel,
showVotingArrowsInListView = appSettings?.showVotingArrowsInListView ?: true,
useCustomTabs = appSettings?.useCustomTabs ?: true,
usePrivateTabs = appSettings?.usePrivateTabs ?: false,
appSettings = appSettings,
communityListViewModel = communityListViewModel,
inboxViewModel = inboxViewModel,
commentReplyViewModel = commentReplyViewModel,
commentEditViewModel = commentEditViewModel,
personProfileViewModel = personProfileViewModel,
privateMessageReplyViewModel = privateMessageReplyViewModel,
)
}
composable(
Expand Down Expand Up @@ -381,8 +389,6 @@ class MainActivity : ComponentActivity() {
CommunityListActivity(
navController = navController,
accountViewModel = accountViewModel,
siteViewModel = siteViewModel,
appSettingsViewModel = appSettingsViewModel,
communityListViewModel = communityListViewModel,
selectMode = it.arguments?.getBoolean("select")!!,
)
Expand Down Expand Up @@ -455,7 +461,6 @@ class MainActivity : ComponentActivity() {

InboxActivity(
navController = navController,
appSettingsViewModel = appSettingsViewModel,
inboxViewModel = inboxViewModel,
accountViewModel = accountViewModel,
commentReplyViewModel = commentReplyViewModel,
Expand Down
166 changes: 64 additions & 102 deletions app/src/main/java/com/jerboa/ui/components/common/AppBars.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Bookmarks
import androidx.compose.material.icons.filled.Email
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.KeyboardArrowDown
import androidx.compose.material.icons.filled.KeyboardArrowUp
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.outlined.*
import androidx.compose.material3.*
Expand All @@ -40,7 +43,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import com.google.accompanist.flowlayout.FlowCrossAxisAlignment
import com.google.accompanist.flowlayout.FlowMainAxisAlignment
import com.google.accompanist.flowlayout.FlowRow
Expand All @@ -53,6 +55,7 @@ import com.jerboa.loginFirstToast
import com.jerboa.scrollToNextParentComment
import com.jerboa.scrollToPreviousParentComment
import com.jerboa.siFormat
import com.jerboa.ui.components.home.BottomNavTab
import com.jerboa.ui.components.person.PersonProfileLink
import com.jerboa.ui.theme.*
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -84,13 +87,10 @@ fun SimpleTopAppBar(

@Composable
fun BottomAppBarAll(
navController: NavController = rememberNavController(),
screen: String,
unreadCount: Int,
selectedTab: BottomNavTab,
onSelect: (BottomNavTab) -> Unit,
unreadCounts: Int,
showBottomNav: Boolean? = true,
onClickSaved: () -> Unit,
onClickProfile: () -> Unit,
onClickInbox: () -> Unit,
) {
if (showBottomNav == true) {
// Check for preview mode
Expand All @@ -108,96 +108,60 @@ fun BottomAppBarAll(
}

NavigationBar {
NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Filled.Home,
contentDescription = stringResource(R.string.bottomBar_home),
)
},
label = {
Text(
text = stringResource(R.string.bottomBar_label_home),
color = MaterialTheme.colorScheme.onSurface,
)
},
selected = screen == "home",
onClick = {
navController.navigate("home")
},
)

NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Filled.Search,
contentDescription = stringResource(R.string.bottomBar_search),
)
},
label = {
Text(
text = stringResource(R.string.bottomBar_label_search),
color = MaterialTheme.colorScheme.onSurface,
)
},
selected = screen == "communityList",
onClick = {
navController.navigate("communityList")
},
)
NavigationBarItem(
icon = {
InboxIconAndBadge(
iconBadgeCount = unreadCount,
icon = Icons.Outlined.Email,
contentDescription = stringResource(R.string.bottomBar_inbox),
)
},
label = {
Text(
text = stringResource(R.string.bottomBar_label_inbox),
color = MaterialTheme.colorScheme.onSurface,
)
},
selected = screen == "inbox",
onClick = {
onClickInbox()
},
)
NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Outlined.Bookmarks,
contentDescription = stringResource(R.string.bottomBar_bookmarks),
)
},
label = {
Text(
text = stringResource(R.string.bottomBar_label_bookmarks),
color = MaterialTheme.colorScheme.onSurface,
)
},
selected = screen == "saved",
onClick = {
onClickSaved()
},
)
NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Outlined.Person,
contentDescription = stringResource(R.string.bottomBar_profile),
)
},
label = {
Text(
text = stringResource(R.string.bottomBar_label_profile),
color = MaterialTheme.colorScheme.onSurface,
)
},
selected = screen == "profile",
onClick = onClickProfile,
)
for (tab in BottomNavTab.values()) {
val selected = tab == selectedTab
NavigationBarItem(
icon = {
InboxIconAndBadge(
iconBadgeCount = if (tab == BottomNavTab.Inbox) unreadCounts else null,
icon = if (selected) {
when (tab) {
BottomNavTab.Home -> Icons.Filled.Home
BottomNavTab.Search -> Icons.Filled.Search
BottomNavTab.Inbox -> Icons.Filled.Email
BottomNavTab.Saved -> Icons.Filled.Bookmarks
BottomNavTab.Profile -> Icons.Filled.Person
}
} else {
when (tab) {
BottomNavTab.Home -> Icons.Outlined.Home
BottomNavTab.Search -> Icons.Outlined.Search
BottomNavTab.Inbox -> Icons.Outlined.Email
BottomNavTab.Saved -> Icons.Outlined.Bookmarks
BottomNavTab.Profile -> Icons.Outlined.Person
}
},
contentDescription = stringResource(
when (tab) {
BottomNavTab.Home -> R.string.bottomBar_home
BottomNavTab.Search -> R.string.bottomBar_search
BottomNavTab.Inbox -> R.string.bottomBar_inbox
BottomNavTab.Saved -> R.string.bottomBar_bookmarks
BottomNavTab.Profile -> R.string.bottomBar_profile
},
),
)
},
label = {
Text(
text = stringResource(
when (tab) {
BottomNavTab.Home -> R.string.bottomBar_label_home
BottomNavTab.Search -> R.string.bottomBar_label_search
BottomNavTab.Inbox -> R.string.bottomBar_label_inbox
BottomNavTab.Saved -> R.string.bottomBar_label_bookmarks
BottomNavTab.Profile -> R.string.bottomBar_label_profile
},
),
color = MaterialTheme.colorScheme.onSurface,
)
},
selected = selected,
onClick = {
onSelect(tab)
},
)
}
}
}
}
Expand All @@ -206,11 +170,9 @@ fun BottomAppBarAll(
@Composable
fun BottomAppBarAllPreview() {
BottomAppBarAll(
onClickInbox = {},
onClickProfile = {},
onClickSaved = {},
unreadCount = 0,
screen = "home",
selectedTab = BottomNavTab.Home,
onSelect = {},
unreadCounts = 30,
showBottomNav = true,
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.jerboa.ui.components.common

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowBack
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.res.stringResource
import androidx.navigation.NavController
import com.jerboa.R

@Composable
fun DefaultBackButton(navController: NavController) {
val canPop = remember { navController.previousBackStackEntry != null }

if (canPop) {
IconButton(onClick = navController::navigateUp) {
Icon(
Icons.Outlined.ArrowBack,
contentDescription = stringResource(R.string.community_back),
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.jerboa.datatypes.types.CommunityView
import com.jerboa.datatypes.types.SortType
import com.jerboa.datatypes.types.SubscribedType
import com.jerboa.getLocalizedSortingTypeName
import com.jerboa.ui.components.common.DefaultBackButton
import com.jerboa.ui.components.common.IconAndTextDrawerItem
import com.jerboa.ui.components.common.LargerCircularIcon
import com.jerboa.ui.components.common.PictrsBannerImage
Expand Down Expand Up @@ -180,14 +181,7 @@ fun CommunityHeader(
selectedSortType = selectedSortType,
)
},
navigationIcon = {
IconButton(onClick = { navController.popBackStack() }) {
Icon(
Icons.Outlined.ArrowBack,
contentDescription = stringResource(R.string.community_back),
)
}
},
navigationIcon = { DefaultBackButton(navController) },
actions = {
IconButton(onClick = {
showSortOptions = !showSortOptions
Expand Down
Loading

0 comments on commit 54a2e01

Please sign in to comment.