-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from hotwired/router
Add the concept of a dedicated Router and custom Routes
- Loading branch information
Showing
24 changed files
with
432 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
core/src/main/kotlin/dev/hotwire/core/navigation/routing/AppNavigationRoute.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package dev.hotwire.core.navigation.routing | ||
|
||
import androidx.appcompat.app.AppCompatActivity | ||
import androidx.core.net.toUri | ||
|
||
class AppNavigationRoute : Router.Route { | ||
override val name = "app-navigation" | ||
|
||
override val result = Router.RouteResult.NAVIGATE | ||
|
||
override fun matches(location: String): Boolean { | ||
return appUrl.toUri().host == location.toUri().host | ||
} | ||
|
||
override fun perform(location: String, activity: AppCompatActivity) { | ||
// No-op | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
core/src/main/kotlin/dev/hotwire/core/navigation/routing/BrowserRoute.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package dev.hotwire.core.navigation.routing | ||
|
||
import android.content.ActivityNotFoundException | ||
import android.content.Intent | ||
import androidx.appcompat.app.AppCompatActivity | ||
import androidx.core.net.toUri | ||
import dev.hotwire.core.logging.logError | ||
|
||
class BrowserRoute : Router.Route { | ||
override val name = "browser" | ||
|
||
override val result = Router.RouteResult.STOP | ||
|
||
override fun matches(location: String): Boolean { | ||
return appUrl.toUri().host != location.toUri().host | ||
} | ||
|
||
override fun perform(location: String, activity: AppCompatActivity) { | ||
val intent = Intent(Intent.ACTION_VIEW, location.toUri()) | ||
|
||
try { | ||
activity.startActivity(intent) | ||
} catch (e: ActivityNotFoundException) { | ||
logError("BrowserRoute", e) | ||
} | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
core/src/main/kotlin/dev/hotwire/core/navigation/routing/BrowserTabRoute.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package dev.hotwire.core.navigation.routing | ||
|
||
import androidx.appcompat.app.AppCompatActivity | ||
import androidx.browser.customtabs.CustomTabColorSchemeParams | ||
import androidx.browser.customtabs.CustomTabsIntent | ||
import androidx.core.net.toUri | ||
import com.google.android.material.R | ||
import dev.hotwire.core.turbo.util.colorFromThemeAttr | ||
|
||
class BrowserTabRoute : Router.Route { | ||
override val name = "browser-tab" | ||
|
||
override val result = Router.RouteResult.STOP | ||
|
||
override fun matches(location: String): Boolean { | ||
return appUrl.toUri().host != location.toUri().host | ||
} | ||
|
||
override fun perform(location: String, activity: AppCompatActivity) { | ||
val color = activity.colorFromThemeAttr(R.attr.colorSurface) | ||
val colorParams = CustomTabColorSchemeParams.Builder() | ||
.setToolbarColor(color) | ||
.setNavigationBarColor(color) | ||
.build() | ||
|
||
CustomTabsIntent.Builder() | ||
.setShowTitle(true) | ||
.setShareState(CustomTabsIntent.SHARE_STATE_ON) | ||
.setUrlBarHidingEnabled(false) | ||
.setDefaultColorSchemeParams(colorParams) | ||
.build() | ||
.launchUrl(activity, location.toUri()) | ||
} | ||
} |
78 changes: 78 additions & 0 deletions
78
core/src/main/kotlin/dev/hotwire/core/navigation/routing/Router.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package dev.hotwire.core.navigation.routing | ||
|
||
import androidx.appcompat.app.AppCompatActivity | ||
import dev.hotwire.core.config.Hotwire | ||
import dev.hotwire.core.logging.logEvent | ||
import dev.hotwire.core.navigation.routing.Router.Route | ||
|
||
/** | ||
* Routes location urls within in-app navigation or with custom behaviors | ||
* provided in [Route] instances. | ||
*/ | ||
class Router(private val routes: List<Route>) { | ||
|
||
/** | ||
* An interface to implement to provide custom route behaviors in your app. | ||
*/ | ||
interface Route { | ||
/** | ||
* The configured app url. You can use this to determine if a location | ||
* exists on the same domain. | ||
*/ | ||
val appUrl get() = Hotwire.appUrl | ||
|
||
/** | ||
* The route name used in debug logging. | ||
*/ | ||
val name: String | ||
|
||
/** | ||
* To permit in-app navigation when the location matches this route, | ||
* return [RouteResult.NAVIGATE]. To prevent in-app navigation return | ||
* [RouteResult.STOP]. | ||
*/ | ||
val result: RouteResult | ||
|
||
/** | ||
* Determines whether the location matches this route. Use your own custom | ||
* rules based on the location's domain, protocol, path, or any other | ||
* factors. | ||
*/ | ||
fun matches(location: String): Boolean | ||
|
||
/** | ||
* Perform custom routing behavior when a match is found. For example, | ||
* open an external browser or app for external domain urls. | ||
*/ | ||
fun perform(location: String, activity: AppCompatActivity) | ||
} | ||
|
||
enum class RouteResult { | ||
/** | ||
* Permit in-app navigation with your app's domain urls. | ||
*/ | ||
NAVIGATE, | ||
|
||
/** | ||
* Prevent in-app navigation. Always use this for external domain urls. | ||
*/ | ||
STOP | ||
} | ||
|
||
internal fun route(location: String, activity: AppCompatActivity): RouteResult { | ||
routes.forEach { route -> | ||
if (route.matches(location)) { | ||
logEvent("routeMatch", listOf( | ||
"route" to route.name, | ||
"location" to location | ||
)) | ||
|
||
route.perform(location, activity) | ||
return route.result | ||
} | ||
} | ||
|
||
logEvent("noRouteForLocation", location) | ||
return RouteResult.STOP | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.