Skip to content

Instantly share code, notes, and snippets.

View cjbrooks12's full-sized avatar

Casey Brooks cjbrooks12

View GitHub Profile
@cjbrooks12
cjbrooks12 / ktorBallastSchedules.kt
Created November 2, 2024 14:47
Ktor integration for Ballast Scheduler
@file:OptIn(ExperimentalBallastApi::class)
@file:Suppress("UNCHECKED_CAST")
package com.copperleaf.ballast.ktor
import com.copperleaf.ballast.BallastViewModel
import com.copperleaf.ballast.BallastViewModelConfiguration
import com.copperleaf.ballast.EventHandler
import com.copperleaf.ballast.ExperimentalBallastApi
import com.copperleaf.ballast.InputHandler
enum class AppScreen(
routeFormat: String,
override val annotations: Set<RouteAnnotation> = emptySet(),
) : Route {
Home("/app/home"),
PostList("/app/posts?sort={?}"),
PostDetails("/app/posts/{postId}"),
;
override val matcher: RouteMatcher = RouteMatcher.create(routeFormat)
@cjbrooks12
cjbrooks12 / diagram.md
Last active March 11, 2023 18:54
A sample master-detail view with Ballast and Compose

Data flow diagram

graph TD
    AppVM
    ListVM
    EditorVM
    
    AppVM -->|AppContract.State| ListVM
 ListVM --&gt;|AppContract.Inputs| AppVM
@cjbrooks12
cjbrooks12 / ballastClicker.kt
Created March 1, 2023 15:41
Ballast Clicker
package com.copperleaf.ballast.clicker
import com.copperleaf.ballast.InputHandler
import com.copperleaf.ballast.InputHandlerScope
import kotlinx.coroutines.delay
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
@cjbrooks12
cjbrooks12 / injector.kt
Created February 7, 2023 17:49
Ballast Repository Pattern
object Injector {
private val singletonCoroutineScope = CoroutineScope(Dispatchers.Default + SupervisorJob())
private val repository = Repository(
coroutineScope = singletonCoroutineScope,
config = BallastViewModelConfiguration.Builder()
.withViewModel(
inputHandler = RepositoryInputHandler(),
initialState = RepositoryContract.State(),
name = "Repository",
)
@cjbrooks12
cjbrooks12 / ImmutableRandom.kt
Created August 16, 2022 18:26
Kotlin Immutable Random
import kotlin.random.Random
/**
* Denotes an instance of [Random] that does not mutate its own internal state. Unlike standard [Random],
* [ImmutableRandom] will always return the same value for subsequent calls to [nextBits], [nextInt], etc. One must
* call [nextRandom] to get a new instance of [ImmutableRandom] with a state that would typically have been updated
* internally.
*
* For the same seed, any sequence of `next*(), nextRandom()` should yield the same result as a normal [Random] calling
@cjbrooks12
cjbrooks12 / ExampleViewModel.kt
Last active May 10, 2022 15:03
Android KMM Strategies
public class ExampleViewModel : ViewModel() {
private val state = mutableStateFlowOf(ExampleFragmentState())
public fun observeStates(): StateFlow<ExampleFragmentState> = state.asStateFlow()
public fun button1Clicked() = viewModelScope.launch {
// ...
}
public fun button2Clicked() = viewModelScope.launch {
@cjbrooks12
cjbrooks12 / RouterWithCallbacks.kt
Created April 30, 2022 20:34
Ballast Simple Router
fun main() = singleWindowApplication {
MaterialTheme {
val applicationCoroutineScope = rememberCoroutineScope()
val router = remember(applicationCoroutineScope) { RouterViewModel(applicationCoroutineScope) }
val routerState by router.observeStates().collectAsState()
val handleNavigation = { input: RouterContract.Inputs -> router.trySend(input) }
when(routerState.currentPage) {
"/app/screen1" -> { Screen1(handleNavigation) }
@cjbrooks12
cjbrooks12 / LoginActivity.kt
Last active February 3, 2020 20:19
Lasagna Screens
class LoginActivity : AppCompatActivity(), LoginView {
val vm: LoginViewModel by lazy {
LoginViewModel(this, LoginService.getInstance(BuildConfig.DEBUG))
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
@cjbrooks12
cjbrooks12 / SpaghettiActivity.kt
Last active February 3, 2020 20:16
Spaghetti Screens
class MainActivity : AppCompatActivity() {
var username: String? = null
var passwordValue: String? = null
var passwordField: EditText? = null
val listener = object : TextWatcher {
override fun afterTextChanged(s: Editable?) {}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
username = s.toString()