Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,22 @@ on:
push:
branches: [ main, develop ]
pull_request:
types: [opened, synchronize, reopened]
branches: [ main, develop ]
workflow_dispatch:

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}

- name: Set up JDK 17
uses: actions/setup-java@v4
Expand All @@ -30,6 +38,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}

- name: Set up JDK 17
uses: actions/setup-java@v4
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
android:supportsRtl="true"
android:theme="@style/Theme.Wisp">
<activity
android:name=".MainActivity"
android:name=".ui.main.MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.Wisp">
Expand Down
59 changes: 0 additions & 59 deletions app/src/main/java/com/angrypodo/wisp/MainActivity.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.angrypodo.wisp
package com.angrypodo.wisp.navigation

import com.angrypodo.wisp.annotations.Wisp
import kotlinx.serialization.Serializable
Expand All @@ -14,3 +14,7 @@ data class ProductDetail(val productId: String)
@Serializable
@Wisp("settings")
data object Settings

@Serializable
@Wisp("splash")
data object Splash
77 changes: 77 additions & 0 deletions app/src/main/java/com/angrypodo/wisp/ui/main/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.angrypodo.wisp.ui.main

import android.net.Uri
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.core.net.toUri
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.toRoute
import com.angrypodo.wisp.navigation.Home
import com.angrypodo.wisp.navigation.ProductDetail
import com.angrypodo.wisp.navigation.Settings
import com.angrypodo.wisp.navigation.Splash
import com.angrypodo.wisp.runtime.navigateTo
import com.angrypodo.wisp.ui.screens.HomeScreen
import com.angrypodo.wisp.ui.screens.ProductDetailScreen
import com.angrypodo.wisp.ui.screens.SettingsScreen
import com.angrypodo.wisp.ui.screens.SplashScreen
import com.angrypodo.wisp.ui.theme.WispTheme

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val deepLinkUri: Uri? = intent?.data
setContent {
WispTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
WispNavHost(deepLinkUri = deepLinkUri)
}
}
}
}
}

@Composable
private fun WispNavHost(deepLinkUri: Uri?) {
val navController = rememberNavController()

NavHost(navController = navController, startDestination = Splash) {
composable<Splash> {
SplashScreen(
navController = navController,
uri = deepLinkUri
)
}

composable<Home> {
HomeScreen(
onNavigateToProduct = {
val uri = "app://wisp?stack=product/123|settings".toUri()
navController.navigateTo(uri)
},
onNavigateToSettings = {
val uri = "app://wisp?stack=settings".toUri()
navController.navigateTo(uri)
}
)
}
composable<ProductDetail> { backStackEntry ->
val productDetail: ProductDetail = backStackEntry.toRoute()
ProductDetailScreen(productId = productDetail.productId)
}
composable<Settings> {
SettingsScreen()
}
}
}
45 changes: 45 additions & 0 deletions app/src/main/java/com/angrypodo/wisp/ui/screens/SampleScreens.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.angrypodo.wisp.ui.screens

import android.net.Uri
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
Expand All @@ -8,10 +9,15 @@ import androidx.compose.foundation.layout.height
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import com.angrypodo.wisp.navigation.Home
import com.angrypodo.wisp.runtime.Wisp
import kotlinx.coroutines.delay

@Composable
fun HomeScreen(onNavigateToProduct: () -> Unit, onNavigateToSettings: () -> Unit) {
Expand Down Expand Up @@ -55,3 +61,42 @@ fun SettingsScreen() {
Text(text = "Settings Screen", fontSize = 24.sp)
}
}

@Composable
fun SplashScreen(
navController: NavController,
uri: Uri?
) {
val wisp = Wisp.getDefaultInstance()

// A real app would check login status, fetch initial data, etc.
// Here we just simulate a delay.
LaunchedEffect(Unit) {
delay(1500)

val routes = uri?.let { wisp.resolveRoutes(it) }

if (routes.isNullOrEmpty()) {
// No deep link, navigate to home as usual.
navController.navigate(Home) {
popUpTo(navController.graph.id) { inclusive = true }
}
} else {
// Deep link found.
// The first route is "splash", which we are already on.
// We navigate to the rest of the stack.
val routesToNavigate = routes.drop(1)
wisp.navigateTo(navController, routesToNavigate)
}
}

Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Wisp", fontSize = 48.sp)
Spacer(modifier = Modifier.height(16.dp))
Text(text = "Loading...", fontSize = 24.sp)
}
}
11 changes: 0 additions & 11 deletions wisp-processor/src/main/java/com/angrypodo/wisp/ProcessorsUtils.kt

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.angrypodo.wisp.generator

import com.angrypodo.wisp.WispClassName.INVALID_PARAMETER_ERROR
import com.angrypodo.wisp.WispClassName.MISSING_PARAMETER_ERROR
import com.angrypodo.wisp.WispClassName.ROUTE_FACTORY
import com.angrypodo.wisp.model.ClassRouteInfo
import com.angrypodo.wisp.model.ObjectRouteInfo
import com.angrypodo.wisp.model.ParameterInfo
import com.angrypodo.wisp.model.RouteInfo
import com.angrypodo.wisp.util.WispClassName.INVALID_PARAMETER_ERROR
import com.angrypodo.wisp.util.WispClassName.MISSING_PARAMETER_ERROR
import com.angrypodo.wisp.util.WispClassName.ROUTE_FACTORY
import com.google.devtools.ksp.processing.KSPLogger
import com.squareup.kotlinpoet.ANY
import com.squareup.kotlinpoet.BOOLEAN
Expand Down Expand Up @@ -105,8 +105,8 @@ internal class RouteFactoryGenerator(
nonNullableType == DOUBLE -> CodeBlock.of("%L?.toDoubleOrNull()", rawAccess)
else -> {
logger.error(
"Wisp Error: Unsupported type " +
"'${param.typeName}' for parameter '${param.name}'."
"Wisp Error: Unsupported type '${param.typeName}'" +
" for parameter '${param.name}'."
)
CodeBlock.of("null")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.angrypodo.wisp.generator

import com.angrypodo.wisp.WispClassName
import com.angrypodo.wisp.model.RouteInfo
import com.angrypodo.wisp.util.WispClassName
import com.squareup.kotlinpoet.ANY
import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.FileSpec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,8 @@ private fun KSClassDeclaration.extractParameters(): List<ParameterInfo> {
return primaryConstructor?.parameters?.mapNotNull { parameter ->
val parameterName = parameter.name?.asString() ?: return@mapNotNull null
val resolvedType = parameter.type.resolve()
val declaration = resolvedType.declaration
val isEnum =
declaration is KSClassDeclaration && declaration.classKind == ClassKind.ENUM_CLASS
(resolvedType.declaration as? KSClassDeclaration)?.classKind == ClassKind.ENUM_CLASS
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏼


ParameterInfo(
name = parameterName,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.angrypodo.wisp
package com.angrypodo.wisp.processor

import com.angrypodo.wisp.WispValidator.validateDuplicatePaths
import com.angrypodo.wisp.annotations.Wisp
import com.angrypodo.wisp.generator.RouteFactoryGenerator
import com.angrypodo.wisp.generator.WispRegistryGenerator
import com.angrypodo.wisp.mapper.toRouteInfo
import com.angrypodo.wisp.model.RouteInfo
import com.angrypodo.wisp.validation.WispValidator
import com.google.devtools.ksp.processing.CodeGenerator
import com.google.devtools.ksp.processing.Dependencies
import com.google.devtools.ksp.processing.KSPLogger
Expand Down Expand Up @@ -43,7 +43,7 @@ internal class WispProcessor(

val routeInfos = routesWithSymbols.map { it.first }

val duplicateValidationResult = validateDuplicatePaths(routeInfos)
val duplicateValidationResult = WispValidator.validateDuplicatePaths(routeInfos)

if (duplicateValidationResult is WispValidator.ValidationResult.Failure) {
duplicateValidationResult.errors.forEach { logger.error(it) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.angrypodo.wisp
package com.angrypodo.wisp.processor

import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.angrypodo.wisp
package com.angrypodo.wisp.util

import com.squareup.kotlinpoet.ClassName

internal object WispClassName {
private const val RUNTIME_PACKAGE = "com.angrypodo.wisp.runtime"
const val GENERATED_PACKAGE = "com.angrypodo.wisp.generated"

val ROUTE_FACTORY = ClassName(RUNTIME_PACKAGE, "RouteFactory")
val WISP_REGISTRY_SPEC = ClassName(RUNTIME_PACKAGE, "WispRegistrySpec")
val WISP_URI_MATCHER = ClassName(RUNTIME_PACKAGE, "WispUriMatcher")
val ROUTE_FACTORY = ClassName("com.angrypodo.wisp.runtime.spi", "RouteFactory")
val WISP_REGISTRY_SPEC = ClassName("com.angrypodo.wisp.runtime.spi", "WispRegistrySpec")
val WISP_URI_MATCHER = ClassName("com.angrypodo.wisp.runtime.matcher", "WispUriMatcher")

val UNKNOWN_PATH_ERROR = ClassName(RUNTIME_PACKAGE, "WispError", "UnknownPath")
val MISSING_PARAMETER_ERROR = ClassName(RUNTIME_PACKAGE, "WispError", "MissingParameter")
Expand Down
Loading
Loading