Fix sageclient startup URL direct rendering
This commit is contained in:
parent
f642667bab
commit
51b207626a
@ -44,7 +44,8 @@ cd /path/to/bricks-mp/test/sageclient
|
|||||||
-Dsage.centerUi=/center.ui
|
-Dsage.centerUi=/center.ui
|
||||||
```
|
```
|
||||||
|
|
||||||
Run with a startup URL to enter that UI directly:
|
Run with a startup URL to enter that UI directly without showing the sample
|
||||||
|
base URL / login input shell:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /path/to/bricks-mp/test/sageclient
|
cd /path/to/bricks-mp/test/sageclient
|
||||||
@ -57,7 +58,7 @@ The packaged macOS app also accepts the URL as its first argument:
|
|||||||
open build/compose/binaries/main/app/sageclient.app --args https://ai.atvoe.com/center.ui
|
open build/compose/binaries/main/app/sageclient.app --args https://ai.atvoe.com/center.ui
|
||||||
```
|
```
|
||||||
|
|
||||||
If the argument is an absolute `http://` or `https://` URL, `sageclient` uses the URL origin as `baseUrl` and loads the path/query part as the initial Bricks UI. If the argument is a relative path such as `/center.ui`, it uses `sage.baseUrl` and loads that path. The actual HTTP request is still issued through `BricksHttp`, so startup URLs ending in `.ui` / `.dspy` are requested with `_webbricks_=1`, `_width`, `_height`, `_is_mobile` and `_lang`; they must not be fetched as raw HTML/template pages.
|
If the argument is an absolute `http://` or `https://` URL, `sageclient` uses the URL origin as `baseUrl` and dispatches that same absolute URL through the Bricks `urlwidget` loading path. If the argument is a relative path such as `/center.ui`, it uses `sage.baseUrl` and loads that path. The actual HTTP request is still issued through `BricksHttp`, so startup URLs ending in `.ui` / `.dspy` are requested with `_webbricks_=1`, `_width`, `_height`, `_is_mobile` and `_lang`; they must not be fetched as raw HTML/template pages.
|
||||||
|
|
||||||
Optional properties:
|
Optional properties:
|
||||||
|
|
||||||
|
|||||||
@ -123,45 +123,55 @@ fun main(args: Array<String>) = application {
|
|||||||
|
|
||||||
val currentWidget by context.currentWidget.collectAsState()
|
val currentWidget by context.currentWidget.collectAsState()
|
||||||
|
|
||||||
LaunchedEffect(actionDispatcher, startupUrl) {
|
val startupTarget = remember(startupUrl) { startupUrl?.let(::toWidgetUrl) }
|
||||||
startupUrl?.let { url ->
|
|
||||||
|
LaunchedEffect(actionDispatcher, startupTarget) {
|
||||||
|
startupTarget?.let { url ->
|
||||||
|
configureContextFromStartupUrl(context, url)
|
||||||
actionDispatcher.dispatch(
|
actionDispatcher.dispatch(
|
||||||
BricksBind(
|
BricksBind(
|
||||||
event = "startup",
|
event = "startup",
|
||||||
actiontype = "urlwidget",
|
actiontype = "urlwidget",
|
||||||
url = toWidgetPath(url)
|
url = url
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SageClientScreen(
|
if (startupTarget != null) {
|
||||||
baseUrl = context.baseUrl,
|
BricksStartupScreen(
|
||||||
widget = currentWidget,
|
widget = currentWidget,
|
||||||
actionDispatcher = actionDispatcher,
|
actionDispatcher = actionDispatcher
|
||||||
onBaseUrlChange = { context.baseUrl = it.trimEnd('/') },
|
)
|
||||||
onLoadCenter = {
|
} else {
|
||||||
actionDispatcher.dispatch(
|
SageClientScreen(
|
||||||
BricksBind(
|
baseUrl = context.baseUrl,
|
||||||
event = "click",
|
widget = currentWidget,
|
||||||
actiontype = "urlwidget",
|
actionDispatcher = actionDispatcher,
|
||||||
url = System.getProperty("sage.centerUi", DEFAULT_CENTER_UI)
|
onBaseUrlChange = { context.baseUrl = it.trimEnd('/') },
|
||||||
)
|
onLoadCenter = {
|
||||||
)
|
actionDispatcher.dispatch(
|
||||||
},
|
BricksBind(
|
||||||
onLogin = { username, password ->
|
event = "click",
|
||||||
scope.launch {
|
actiontype = "urlwidget",
|
||||||
loginAndLoadCenter(
|
url = System.getProperty("sage.centerUi", DEFAULT_CENTER_UI)
|
||||||
context = context,
|
)
|
||||||
http = http,
|
|
||||||
actionDispatcher = actionDispatcher,
|
|
||||||
username = username,
|
|
||||||
password = password,
|
|
||||||
onMessage = { title, body, isError -> message = Triple(title, body, isError) }
|
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
onLogin = { username, password ->
|
||||||
|
scope.launch {
|
||||||
|
loginAndLoadCenter(
|
||||||
|
context = context,
|
||||||
|
http = http,
|
||||||
|
actionDispatcher = actionDispatcher,
|
||||||
|
username = username,
|
||||||
|
password = password,
|
||||||
|
onMessage = { title, body, isError -> message = Triple(title, body, isError) }
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
)
|
}
|
||||||
|
|
||||||
dialogWidget?.let { widget ->
|
dialogWidget?.let { widget ->
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
@ -188,6 +198,27 @@ fun main(args: Array<String>) = application {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
private fun BricksStartupScreen(
|
||||||
|
widget: BricksWidget?,
|
||||||
|
actionDispatcher: ActionDispatcher
|
||||||
|
) {
|
||||||
|
Scaffold { padding ->
|
||||||
|
Box(modifier = Modifier.padding(padding).fillMaxSize()) {
|
||||||
|
if (widget == null) {
|
||||||
|
Text("Loading...")
|
||||||
|
} else {
|
||||||
|
RenderWidget(
|
||||||
|
widget = widget,
|
||||||
|
actionDispatcher = actionDispatcher,
|
||||||
|
modifier = Modifier.fillMaxSize()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun SageClientScreen(
|
private fun SageClientScreen(
|
||||||
@ -274,11 +305,7 @@ private fun configureContextFromStartupUrl(context: BricksContext, startupUrl: S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toWidgetPath(startupUrl: String): String {
|
private fun toWidgetUrl(startupUrl: String): String = startupUrl.ifBlank { "/" }
|
||||||
if (!startupUrl.startsWith("http://") && !startupUrl.startsWith("https://")) return startupUrl
|
|
||||||
val pathWithQuery = startupUrl.pathAndQueryPart()
|
|
||||||
return pathWithQuery.ifBlank { "/" }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun String.originPart(): String {
|
private fun String.originPart(): String {
|
||||||
val schemeEnd = indexOf("://")
|
val schemeEnd = indexOf("://")
|
||||||
@ -288,16 +315,6 @@ private fun String.originPart(): String {
|
|||||||
return substring(0, authorityEnd)
|
return substring(0, authorityEnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun String.pathAndQueryPart(): String {
|
|
||||||
val schemeEnd = indexOf("://")
|
|
||||||
val pathStart = if (schemeEnd >= 0) {
|
|
||||||
indexOf('/', startIndex = schemeEnd + 3).let { if (it < 0) return "" else it }
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
return substring(pathStart).substringBefore('#')
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun loginAndLoadCenter(
|
private suspend fun loginAndLoadCenter(
|
||||||
context: BricksContext,
|
context: BricksContext,
|
||||||
http: BricksHttp,
|
http: BricksHttp,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user