Skip to content

Commit

Permalink
Merge pull request #10 from BottleRocketStudios/main
Browse files Browse the repository at this point in the history
Deploy v0.5.0
  • Loading branch information
BottleRocket-Colin authored Jul 11, 2024
2 parents e82307b + 45623d2 commit db76fcc
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 96 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/gradle-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ on:
branches: [ "deploy" ]

jobs:
build:

build:
runs-on: macOS-latest
timeout-minutes: 30
permissions:
contents: read
packages: write
Expand Down
10 changes: 5 additions & 5 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
[versions]
# Publishing version
launchpad-compose = "0.1.0"
launchpad-compose = "0.5.0"

# Android SDK versions
compile-sdk = "34"
min-sdk = "24"

# Dependency versions
agp = "8.2.2"
androidx-window = "1.2.0"
androidx-window = "1.3.0"
compose-plugin = "1.5.12"
kotlin = "1.9.22"
kt-lint-gradle = "11.6.1"
kt-lint-gradle = "12.1.0"
navigation-compose = "2.7.7"
precompose = "1.5.11"
navigation-compose-version = "2.7.0-alpha07"


[libraries]
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigation-compose" }
androidx-window = { group = "androidx.window", name = "window", version.ref = "androidx-window" }
compose-material3-window-size = { group = "androidx.compose.material3", name = "material3-window-size-class" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
precompose = { group = "moe.tlaster", name = "precompose", version.ref = "precompose" }
navigation-compose = { module = "org.jetbrains.androidx.navigation:navigation-compose", version.ref = "navigation-compose-version" }

[plugins]
androidLibrary = { id = "com.android.library", version.ref = "agp" }
Expand Down
8 changes: 2 additions & 6 deletions kmp-launchpad-compose/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,8 @@ kotlin {

androidTarget {
publishAllLibraryVariants()
compilations.all {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
jvmToolchain(17)

jvm("desktop")
task("testClasses")
Expand All @@ -36,7 +32,6 @@ kotlin {
implementation(libs.compose.material3.window.size)
}
commonMain.dependencies {
api(libs.precompose)
implementation(compose.animation)
@OptIn(ExperimentalComposeLibrary::class)
implementation(compose.components.resources)
Expand All @@ -45,6 +40,7 @@ kotlin {
implementation(compose.materialIconsExtended)
implementation(compose.runtime)
implementation(compose.ui)
implementation(libs.navigation.compose)
}
commonTest.dependencies {
implementation(kotlin("test-common"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import androidx.compose.runtime.collectAsState
import com.bottlerocketstudios.launchpad.compose.navigation.NavigationWrapper
import com.bottlerocketstudios.launchpad.compose.navigation.util.createDevicePostureFlow
import com.bottlerocketstudios.launchpad.compose.navigation.util.getWindowWidthSize
import moe.tlaster.precompose.PreComposeApp

class MainActivityExample : ComponentActivity() {

Expand All @@ -20,20 +19,19 @@ class MainActivityExample : ComponentActivity() {
// Collects the device posture flow and stores it in a state variable.
val devicePosture = devicePostureFlow.collectAsState()

PreComposeApp {
// In this example, the NavWrapper for the Precompose Navigation library is being used.
// The app param will extend the wrappers navigation component and bottom bar allowing both to be used in App Composable.
NavigationWrapper(
widthSize = getWindowWidthSize(this),
devicePosture = devicePosture.value,
navigationItems = exampleNavigationItems
) { navigator, bottomBar ->
ExampleApp(
widthSize = getWindowWidthSize(this),
navigator = navigator,
bottomBar = bottomBar
)
}
// In this example, the NavWrapper for the Precompose Navigation library is being used.
// The app param will extend the wrappers navigation component and bottom bar allowing both to be used in App Composable.
NavigationWrapper(
widthSize = getWindowWidthSize(this),
devicePosture = devicePosture.value,
navigationItems = exampleNavigationItems
) { navigator ->

// FIXME - after testing
// ExampleApp(
// widthSize = getWindowWidthSize(this),
//// navigator = navigator,
// )
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,36 @@
package com.bottlerocketstudios.launchpad.compose.example.navigation

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import com.bottlerocketstudios.launchpad.compose.navigation.utils.WindowWidthSizeClass
import moe.tlaster.precompose.navigation.NavHost
import moe.tlaster.precompose.navigation.Navigator
import moe.tlaster.precompose.navigation.transition.NavTransition

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ExampleApp(
widthSize: WindowWidthSizeClass,
navigator: Navigator?,
bottomBar: @Composable () -> Unit
navigator: NavHostController,
// bottomBar: @Composable () -> Unit
) {
Scaffold(
topBar = { TopAppBar(title = { Text("Example App") }) },
bottomBar = bottomBar
) {
navigator?.let { navController ->
NavHost(
// Assign the navigator to the NavHost
navigator = navController,
// Navigation transition for the scenes in this NavHost, this is optional
navTransition = NavTransition(),
// The start destination
initialRoute = "/home",
modifier = Modifier.padding(it)
) {
// Navgraph goes here
}
}
}
// FIXME - after testing
// Column(
// topBar = { TopAppBar(title = { Text("Example App") }) },
// bottomBar = bottomBar
// ) {
// NavHost(
// navController = navigator,
// startDestination = "/home",
// modifier = Modifier.padding(it)
// ) {
// // Navgraph goes here
// }
// }
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,31 @@ import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.width
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.PermanentDrawerSheet
import androidx.compose.material3.PermanentNavigationDrawer
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.bottlerocketstudios.launchpad.compose.navigation.components.LaunchpadBottomAppBar
import com.bottlerocketstudios.launchpad.compose.navigation.components.LaunchpadDrawerContent
import com.bottlerocketstudios.launchpad.compose.navigation.components.LaunchpadNavigationRail
Expand All @@ -29,8 +39,20 @@ import com.bottlerocketstudios.launchpad.compose.navigation.utils.NavigationType
import com.bottlerocketstudios.launchpad.compose.navigation.utils.WindowWidthSizeClass
import com.bottlerocketstudios.launchpad.compose.navigation.utils.generateNavItems
import com.bottlerocketstudios.launchpad.compose.navigation.utils.toNavigationType
import moe.tlaster.precompose.navigation.Navigator
import moe.tlaster.precompose.navigation.rememberNavigator

@Suppress("MemberVisibilityCanBePrivate")
class NavWrapperState {
var showNavigation by mutableStateOf(true)
var showNavigationRail by mutableStateOf(true)
var showBottomBar by mutableStateOf(true)
var showPermanentDrawer by mutableStateOf(true)
var showModalDrawer by mutableStateOf(true)

val shouldShowNavigationRail @Composable get() = showNavigationRail && showNavigation
val shouldShowBottomBar @Composable get() = showBottomBar && showNavigation
val shouldShowPermanentDrawer @Composable get() = showPermanentDrawer && showNavigation
val shouldShowModalDrawer @Composable get() = showModalDrawer && showNavigation
}

/**
* A composable function that wraps the Precompose navigation component.
Expand All @@ -48,12 +70,16 @@ fun NavigationWrapper(
widthSize: WindowWidthSizeClass,
devicePosture: DevicePosture,
navigationItems: List<NavigationItem>,
app: @Composable (navigator: Navigator?, bottomBar: (@Composable () -> Unit)) -> Unit
navState: NavWrapperState = NavWrapperState(),
app: @Composable (navigator: NavHostController) -> Unit
) {
// Setup State
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val navigator = rememberNavigator()
val currentBackStackEntry by navigator.currentEntry.collectAsState(null)
val currentRoute = currentBackStackEntry?.route
val navigator = rememberNavController()

val currentBackStackEntry by navigator.currentBackStackEntryAsState()
val currentRoute = currentBackStackEntry?.destination?.route

val navItems = remember {
generateNavItems(navigationItems) {
navigator.navigate(it.route)
Expand All @@ -65,45 +91,48 @@ fun NavigationWrapper(
}
}

when (navigationType.value) {
NavigationType.PERMANENT_NAVIGATION_DRAWER ->
PermanentNavigationDrawer(
drawerContent = {
PermanentDrawerSheet() { LaunchpadDrawerContent(navItems) { it == currentRoute?.route } }
}
) { app(navigator) { } }

NavigationType.MODAL_NAVIGATION ->
when {
// Modal Drawer
navigationType.value == NavigationType.MODAL_NAVIGATION && navState.shouldShowModalDrawer ->
ModalNavigationDrawer(
drawerState = drawerState,
drawerContent = { ModalDrawerSheet { LaunchpadDrawerContent(navItems) { it == currentRoute?.route } } }
) { app(navigator) { } }
drawerContent = { ModalDrawerSheet { LaunchpadDrawerContent(navItems) { it == currentRoute } } }
) { app(navigator) }

else -> Row {
AnimatedVisibility(
visible = navigationType.value == NavigationType.NAVIGATION_RAIL,
enter = slideInVertically(animationSpec = spring(stiffness = Spring.StiffnessHigh)),
exit = slideOutHorizontally(animationSpec = spring(stiffness = Spring.StiffnessHigh))
) {
LaunchpadNavigationRail(navItems) {
it == currentRoute?.route
// Permanent Drawer
navigationType.value == NavigationType.PERMANENT_NAVIGATION_DRAWER && navState.shouldShowPermanentDrawer ->
PermanentNavigationDrawer(
drawerContent = { PermanentDrawerSheet { LaunchpadDrawerContent(navItems) { it == currentRoute } } }
) { app(navigator) }

// Remaining states are animated in out around one central instance of app.
else ->
Row {
// Nav Rail
AnimatedVisibility(
visible = navigationType.value == NavigationType.NAVIGATION_RAIL && navState.shouldShowNavigationRail,
enter = slideInVertically(animationSpec = spring(stiffness = Spring.StiffnessHigh)),
exit = slideOutHorizontally(animationSpec = spring(stiffness = Spring.StiffnessHigh))
) {
LaunchpadNavigationRail(navItems) { it == currentRoute }
}
}

Column(
modifier = Modifier
.fillMaxSize()
) {
app(navigator) {
Column(modifier = Modifier.fillMaxSize()) {
// App content
Box(modifier = Modifier.weight(1f)) {
app(navigator)
}

// Bottom Bar
AnimatedVisibility(
visible = navigationType.value == NavigationType.BOTTOM_NAVIGATION,
visible = navigationType.value == NavigationType.BOTTOM_NAVIGATION && navState.shouldShowBottomBar,
enter = slideInVertically(animationSpec = spring(stiffness = Spring.StiffnessHigh)),
exit = slideOutHorizontally(animationSpec = spring(stiffness = Spring.StiffnessHigh))
) {
LaunchpadBottomAppBar(navItems) { it == currentRoute?.route }
LaunchpadBottomAppBar(navItems) { it == currentRoute }
}
}
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ fun LaunchpadBottomAppBar(
NavigationBar(
Modifier
.fillMaxWidth()
.height(72.dp)
) {
ToNavigationBarItems(navItems, isSelected)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.bottlerocketstudios.launchpad.compose.util

import androidx.compose.ui.window.WindowState
import com.bottlerocketstudios.launchpad.compose.navigation.utils.WindowWidthSizeClass

fun WindowState.getWindowWidthSizeClass() =
when (size.width.value.toLong()) {
in 840..Int.MAX_VALUE -> WindowWidthSizeClass.Expanded
in 600..840 -> WindowWidthSizeClass.Medium
in Int.MIN_VALUE..600 -> WindowWidthSizeClass.Compact
else -> WindowWidthSizeClass.Medium
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.bottlerocketstudios.launchpad.compose.util

import com.bottlerocketstudios.launchpad.compose.navigation.utils.WindowWidthSizeClass
import kotlinx.cinterop.ExperimentalForeignApi
import platform.UIKit.UIWindow

@OptIn(ExperimentalForeignApi::class)
fun UIWindow.getWindowWidthSizeClass() =
when (bounds.size) {
in 840..Int.MAX_VALUE -> WindowWidthSizeClass.Expanded
in 600..840 -> WindowWidthSizeClass.Medium
in Int.MIN_VALUE..600 -> WindowWidthSizeClass.Compact
else -> WindowWidthSizeClass.Medium
}

This file was deleted.

0 comments on commit db76fcc

Please sign in to comment.