Skip to content

Commit

Permalink
Rename HotwireCore -> Hotwire and use extension functions in the navi…
Browse files Browse the repository at this point in the history
…gation module to extend the Hotwire.* configuration options
  • Loading branch information
jayohms committed Jun 11, 2024
1 parent 34b58c5 commit af59673
Show file tree
Hide file tree
Showing 22 changed files with 127 additions and 113 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package dev.hotwire.core.bridge

import dev.hotwire.core.config.HotwireCore
import dev.hotwire.core.config.Hotwire
import dev.hotwire.core.logging.logError
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
Expand All @@ -15,7 +15,7 @@ abstract class StradaJsonConverter {
"or use the provided KotlinXJsonConverter."

inline fun <reified T> toObject(jsonData: String): T? {
val converter = requireNotNull(HotwireCore.config.jsonConverter) { NO_CONVERTER }
val converter = requireNotNull(Hotwire.config.jsonConverter) { NO_CONVERTER }

return when (converter) {
is KotlinXJsonConverter -> converter.toObject<T>(jsonData)
Expand All @@ -25,7 +25,7 @@ abstract class StradaJsonConverter {
}

inline fun <reified T> toJson(data: T): String {
val converter = requireNotNull(HotwireCore.config.jsonConverter) { NO_CONVERTER }
val converter = requireNotNull(Hotwire.config.jsonConverter) { NO_CONVERTER }

return when (converter) {
is KotlinXJsonConverter -> converter.toJson(data)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package dev.hotwire.core.config

object HotwireCore {
object Hotwire {
val config: HotwireConfig = HotwireConfig()
}
4 changes: 2 additions & 2 deletions core/src/main/kotlin/dev/hotwire/core/logging/CoreLog.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package dev.hotwire.core.logging

import android.util.Log
import dev.hotwire.core.config.HotwireCore
import dev.hotwire.core.config.Hotwire

internal object CoreLog {
private const val DEFAULT_TAG = "Hotwire-Core"

private val debugEnabled get() = HotwireCore.config.debugLoggingEnabled
private val debugEnabled get() = Hotwire.config.debugLoggingEnabled

internal fun d(msg: String) = log(Log.DEBUG, msg)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package dev.hotwire.core.turbo.http

import android.content.Context
import dev.hotwire.core.config.HotwireCore
import dev.hotwire.core.config.Hotwire
import dev.hotwire.core.logging.logError
import okhttp3.Cache
import okhttp3.OkHttpClient
Expand Down Expand Up @@ -60,7 +60,7 @@ object TurboHttpClient {
builder.cache(it)
}

if (HotwireCore.config.debugLoggingEnabled) {
if (Hotwire.config.debugLoggingEnabled) {
builder.addInterceptor(loggingInterceptor)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package dev.hotwire.core.turbo.http

import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import dev.hotwire.core.config.HotwireCore
import dev.hotwire.core.config.Hotwire
import dev.hotwire.core.logging.logEvent
import dev.hotwire.core.turbo.session.Session
import dev.hotwire.core.turbo.util.isHttpGetRequest

internal class TurboWebViewRequestInterceptor(val session: Session) {
private val offlineRequestHandler get() = HotwireCore.config.offlineRequestHandler
private val offlineRequestHandler get() = Hotwire.config.offlineRequestHandler
private val httpRepository get() = session.httpRepository
private val currentVisit get() = session.currentVisit

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import androidx.webkit.WebViewClientCompat
import androidx.webkit.WebViewCompat
import androidx.webkit.WebViewFeature.VISUAL_STATE_CALLBACK
import androidx.webkit.WebViewFeature.isFeatureSupported
import dev.hotwire.core.config.HotwireCore
import dev.hotwire.core.config.Hotwire
import dev.hotwire.core.logging.logEvent
import dev.hotwire.core.turbo.delegates.TurboFileChooserDelegate
import dev.hotwire.core.turbo.errors.HttpError
Expand Down Expand Up @@ -92,7 +92,7 @@ class Session(
* @param location Location to cache.
*/
fun preCacheLocation(location: String) {
val requestHandler = checkNotNull(HotwireCore.config.offlineRequestHandler) {
val requestHandler = checkNotNull(Hotwire.config.offlineRequestHandler) {
"An offline request handler must be provided to pre-cache $location"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewCompat
import androidx.webkit.WebViewFeature
import com.google.gson.GsonBuilder
import dev.hotwire.core.config.HotwireCore
import dev.hotwire.core.config.Hotwire
import dev.hotwire.core.turbo.util.contentFromAsset
import dev.hotwire.core.turbo.util.runOnUiThread
import dev.hotwire.core.turbo.util.toJson
Expand All @@ -39,7 +39,7 @@ open class TurboWebView @JvmOverloads constructor(
id = View.generateViewId()
settings.javaScriptEnabled = true
settings.domStorageEnabled = true
settings.userAgentString = "${HotwireCore.config.userAgent} ${settings.userAgentString}"
settings.userAgentString = "${Hotwire.config.userAgent} ${settings.userAgentString}"
settings.setSupportMultipleWindows(true)
layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
initDayNightTheming()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package dev.hotwire.core.bridge

import com.nhaarman.mockito_kotlin.*
import dev.hotwire.core.config.HotwireCore
import dev.hotwire.core.config.Hotwire
import kotlinx.serialization.Serializable
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Assert.assertEquals
Expand All @@ -23,7 +23,7 @@ class BridgeComponentTest {

@Before
fun setup() {
HotwireCore.config.jsonConverter = KotlinXJsonConverter()
Hotwire.config.jsonConverter = KotlinXJsonConverter()
component = TestData.OneBridgeComponent("one", delegate)
}

Expand Down Expand Up @@ -104,7 +104,7 @@ class BridgeComponentTest {

@Test
fun replyToReplacingDataWithNoConverter() {
HotwireCore.config.jsonConverter = null
Hotwire.config.jsonConverter = null

component.didReceive(message)

Expand Down
8 changes: 4 additions & 4 deletions core/src/test/kotlin/dev/hotwire/core/bridge/MessageTest.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package dev.hotwire.core.bridge

import dev.hotwire.core.config.HotwireCore
import dev.hotwire.core.config.Hotwire
import kotlinx.serialization.Serializable
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Assert.assertEquals
Expand All @@ -12,7 +12,7 @@ class MessageTest {

@Before
fun setup() {
HotwireCore.config.jsonConverter = KotlinXJsonConverter()
Hotwire.config.jsonConverter = KotlinXJsonConverter()
}

@Test
Expand Down Expand Up @@ -98,7 +98,7 @@ class MessageTest {

@Test
fun replacingDataWithNoConverter() {
HotwireCore.config.jsonConverter = null
Hotwire.config.jsonConverter = null

val message = Message(
id = "1",
Expand All @@ -117,7 +117,7 @@ class MessageTest {

@Test
fun replacingDataWithInvalidConverter() {
HotwireCore.config.jsonConverter = InvalidJsonConverter()
Hotwire.config.jsonConverter = InvalidJsonConverter()

val message = Message(
id = "1",
Expand Down
12 changes: 6 additions & 6 deletions core/src/test/kotlin/dev/hotwire/core/bridge/UserAgentTest.kt
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
package dev.hotwire.core.bridge

import dev.hotwire.core.config.HotwireCore
import dev.hotwire.core.config.Hotwire
import org.junit.Assert.assertEquals
import org.junit.Test

class UserAgentTest {
@Test
fun userAgentSubstring() {
HotwireCore.config.registeredBridgeComponentFactories = TestData.componentFactories
Hotwire.config.registeredBridgeComponentFactories = TestData.componentFactories

val userAgentSubstring = HotwireCore.config.userAgentSubstring()
val userAgentSubstring = Hotwire.config.userAgentSubstring()
assertEquals(userAgentSubstring, "Turbo Native Android; bridge-components: [one two];")
}

@Test
fun userAgent() {
HotwireCore.config.registeredBridgeComponentFactories = TestData.componentFactories
HotwireCore.config.userAgent = "Test; ${HotwireCore.config.userAgentSubstring()}"
Hotwire.config.registeredBridgeComponentFactories = TestData.componentFactories
Hotwire.config.userAgent = "Test; ${Hotwire.config.userAgentSubstring()}"

val userAgent = HotwireCore.config.userAgent
val userAgent = Hotwire.config.userAgent
assertEquals(userAgent, "Test; Turbo Native Android; bridge-components: [one two];")
}
}
6 changes: 5 additions & 1 deletion demo/src/main/kotlin/dev/hotwire/demo/DemoApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Application
import dev.hotwire.core.BuildConfig
import dev.hotwire.core.bridge.BridgeComponentFactory
import dev.hotwire.core.bridge.KotlinXJsonConverter
import dev.hotwire.core.config.Hotwire
import dev.hotwire.core.turbo.config.PathConfiguration
import dev.hotwire.demo.bridge.FormComponent
import dev.hotwire.demo.bridge.MenuComponent
Expand All @@ -15,7 +16,10 @@ import dev.hotwire.demo.features.web.WebBottomSheetFragment
import dev.hotwire.demo.features.web.WebFragment
import dev.hotwire.demo.features.web.WebHomeFragment
import dev.hotwire.demo.features.web.WebModalFragment
import dev.hotwire.navigation.config.Hotwire
import dev.hotwire.navigation.config.defaultFragmentDestination
import dev.hotwire.navigation.config.registerBridgeComponents
import dev.hotwire.navigation.config.registerFragmentDestinations
import dev.hotwire.navigation.config.registerRouteDecisionHandlers
import dev.hotwire.navigation.routing.AppNavigationRouteDecisionHandler
import dev.hotwire.navigation.routing.BrowserTabRouteDecisionHandler

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package dev.hotwire.navigation.config

import androidx.fragment.app.Fragment
import dev.hotwire.core.bridge.BridgeComponent
import dev.hotwire.core.bridge.BridgeComponentFactory
import dev.hotwire.core.config.Hotwire
import dev.hotwire.navigation.destinations.HotwireNavDestination
import dev.hotwire.navigation.fragments.HotwireWebBottomSheetFragment
import dev.hotwire.navigation.fragments.HotwireWebFragment
import dev.hotwire.navigation.routing.AppNavigationRouteDecisionHandler
import dev.hotwire.navigation.routing.BrowserRouteDecisionHandler
import dev.hotwire.navigation.routing.Router
import kotlin.reflect.KClass

internal object HotwireNavigation {
var router = Router(listOf(
AppNavigationRouteDecisionHandler(),
BrowserRouteDecisionHandler()
))

var defaultFragmentDestination: KClass<out Fragment> = HotwireWebFragment::class

var registeredFragmentDestinations: List<KClass<out Fragment>> = listOf(
HotwireWebFragment::class,
HotwireWebBottomSheetFragment::class
)

@Suppress("UNCHECKED_CAST")
var registeredBridgeComponentFactories: List<BridgeComponentFactory<HotwireNavDestination, BridgeComponent<HotwireNavDestination>>>
get() = Hotwire.config.registeredBridgeComponentFactories as List<BridgeComponentFactory<HotwireNavDestination, BridgeComponent<HotwireNavDestination>>>
set(value) { Hotwire.config.registeredBridgeComponentFactories = value }
}

/**
* Registers the [Router.RouteDecisionHandler] instances that determine whether to route location
* urls within in-app navigation or with alternative custom behaviors.
*/
fun Hotwire.registerRouteDecisionHandlers(decisionHandlers: List<Router.RouteDecisionHandler>) {
HotwireNavigation.router = Router(decisionHandlers)
}

/**
* Register bridge components that the app supports. Every possible bridge
* component, wrapped in a [BridgeComponentFactory], must be provided here.
*/
fun Hotwire.registerBridgeComponents(factories: List<BridgeComponentFactory<HotwireNavDestination, BridgeComponent<HotwireNavDestination>>>) {
config.registeredBridgeComponentFactories = factories
}

/**
* The default fragment destination for web requests. If you have not
* loaded a path configuration with a matching rule and a `uri` available
* for all possible paths, this destination will be used as the default.
*/
var Hotwire.defaultFragmentDestination: KClass<out Fragment>
get() = HotwireNavigation.defaultFragmentDestination
set(value) { HotwireNavigation.defaultFragmentDestination = value }

/**
* Register fragment destinations that can be navigated to. Every possible
* destination must be provided here.
*/
fun Hotwire.registerFragmentDestinations(destinations: List<KClass<out Fragment>>) {
HotwireNavigation.registeredFragmentDestinations = destinations
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import androidx.fragment.app.Fragment
import androidx.navigation.NavOptions
import androidx.navigation.navOptions
import dev.hotwire.core.bridge.BridgeDestination
import dev.hotwire.core.config.Hotwire
import dev.hotwire.core.turbo.config.PathConfigurationProperties
import dev.hotwire.core.turbo.config.context
import dev.hotwire.core.turbo.nav.TurboNavPresentationContext
import dev.hotwire.core.turbo.visit.VisitAction
import dev.hotwire.navigation.R
import dev.hotwire.navigation.config.Hotwire
import dev.hotwire.navigation.config.HotwireNavigation
import dev.hotwire.navigation.fragments.HotwireFragmentDelegate
import dev.hotwire.navigation.fragments.HotwireFragmentViewModel
import dev.hotwire.navigation.navigator.Navigator
Expand Down Expand Up @@ -115,7 +116,7 @@ interface HotwireNavDestination : BridgeDestination {
* but it's recommend to use dedicated [Router.RouteDecisionHandler] instances for routing logic.
*/
fun decideRoute(newLocation: String): Router.Decision {
return Hotwire.router.decideRoute(
return HotwireNavigation.router.decideRoute(
location = newLocation,
configuration = navigator.configuration,
activity = fragment.requireActivity() as dev.hotwire.navigation.activities.HotwireActivity
Expand Down
Loading

0 comments on commit af59673

Please sign in to comment.