also looking at this
fix(mobile): preserve native editing, navigation, and durable media requests
#369
36 files
+864
-185
Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.
| @@ -34,3 +34,28 @@ fun main() { | ||
| 34 | 34 | } |
| 35 | 35 | `) |
| 36 | 36 | }, 180_000) |
| 37 | ||
| 38 | ||
| 39 | test('encodes shared grid counts as the unsigned integer fields in the native ABI', async () => { | |
| 40 | const template = await Bun.file(new URL('../templates/MainActivityNative.kt.template', import.meta.url)).text() | |
| 41 | const columns = template.match(/^[^\n]*put(?:Enum)?\(base, 29, node\.gridColumns[^\n]*$/m)?.[0] | |
| 42 | const rows = template.match(/^[^\n]*if \(explicitRowsAware\) put(?:Enum)?\(base, 34, [^\n]*$/m)?.[0] | |
| 43 | if (!columns || !rows) throw new Error('Shared grid count serialization is missing') | |
| 44 | await runKotlinFixture(` | |
| 45 | data class GridNode(val gridColumns: Int, val gridRows: Int?) | |
| 46 | ||
| 47 | fun main() { | |
| 48 | val base = 0 | |
| 49 | val node = GridNode(2, 3) | |
| 50 | val explicitRowsAware = true | |
| 51 | val nodeData = FloatArray(35) { Float.NaN } | |
| 52 | fun put(base: Int, index: Int, value: Float) { nodeData[base + index] = value } | |
| 53 | fun putEnum(base: Int, index: Int, value: Int) { put(base, index, Float.fromBits(value)) } | |
| 54 | ${columns} | |
| 55 | ${rows} | |
| 56 | check(nodeData[29].toRawBits() == 2) { "grid_columns is not encoded as u32" } | |
| 57 | check(nodeData[34].toRawBits() == 3) { "grid_rows is not encoded as u32" } | |
| 58 | println("PASS native grid counts retain the integer bit patterns consumed by Zig") | |
| 59 | } | |
| 60 | `) | |
| 61 | }, 180_000) | |
| @@ -1432,12 +1432,12 @@ internal class CraftNativeFlexLayout(context: Context) : LinearLayout(context) { | ||
| 1432 | 1432 | put(base, 26, node.padding[3].toFloat()) |
| 1433 | 1433 | put(base, 27, node.padding[0].toFloat()) |
| 1434 | 1434 | putEnum(base, 28, if (node.grid) 1 else 0) |
| 1435 | put(base, 29, node.gridColumns.toFloat()) | |
| 1435 | putEnum(base, 29, node.gridColumns) | |
| 1436 | 1436 | put(base, 30, node.rowGap) |
| 1437 | 1437 | put(base, 31, node.columnGap) |
| 1438 | 1438 | if (fields >= 33) putEnum(base, 32, (if (node.reverse) 1 else 0) or (if (node.wrapReverse) 2 else 0)) |
| 1439 | 1439 | if (autoRowsAware) put(base, 33, sharedLength(node.gridAutoRows, contentHeight)) |
| 1440 | if (explicitRowsAware) put(base, 34, (node.gridRows ?: 0).toFloat()) | |
| 1440 | if (explicitRowsAware) putEnum(base, 34, node.gridRows ?: 0) | |
| 1441 | 1441 | val firstChild = cursor |
| 1442 | 1442 | node.children.forEach { child -> write(child, contentWidth, contentHeight, false, node.direction) } |
| 1443 | 1443 | treeMeta[index * 2] = firstChild.toFloat() |
| @@ -2070,7 +2070,8 @@ describe('native renderer component contract', () => { | ||
| 2070 | 2070 | expect(android).toContain('private data class SharedTreeResult(') |
| 2071 | 2071 | expect(android).toContain('grid = nested?.grid ?: false') |
| 2072 | 2072 | expect(android).toContain('putEnum(base, 28, if (node.grid) 1 else 0)') |
| 2073 | expect(android).toContain('put(base, 29, node.gridColumns.toFloat())') | |
| 2073 | expect(android).toContain('putEnum(base, 29, node.gridColumns)') | |
| 2074 | expect(android).toContain('if (explicitRowsAware) putEnum(base, 34, node.gridRows ?: 0)') | |
| 2074 | 2075 | expect(android).toContain('CraftNative.layoutTree(width.toFloat(), height.toFloat(), nodeData, treeMeta)') |
| 2075 | 2076 | expect(android).toContain('CraftNative.layoutTreeV2(width.toFloat(), height.toFloat(), nodeData, treeMeta)') |
| 2076 | 2077 | expect(android).toContain('CraftNative.layoutTreeV3(width.toFloat(), height.toFloat(), nodeData, treeMeta)') |