2 Commits
Author SHA1 Message Date
bvandeusenandClaude Opus 5.5 d9f755b128 ci: the integration lane finds its own Postgres, not another job's
CI & Build / Python lint (push) Successful in 2s
Android / Build, or is the channel already serving this? (push) Successful in 2s
CI & Build / Build now, or wait for Android? (push) Successful in 2s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 2s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Skipped
Desktop (Tauri) / Update manifest (push) Skipped
CI & Build / Python tests (push) Successful in 11s
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Skipped
Desktop (Tauri) / Tauri desktop (Linux) (push) Skipped
CI & Build / Web typecheck and unit tests (push) Successful in 8s
CI & Build / integration (push) Successful in 1m6s
CI & Build / Build & push image (push) Skipped
Android / Kotlin + Rust (APK) (push) Failing after 3m27s
Run 8653 failed at 'alembic upgrade head' with a password error: two
integration jobs were on the runner at once, and the name=integration
filter took the other one's database (#5312). The lookup is now scoped to
this job's GITEA-ACTIONS-TASK-<id>- prefix, read from the job container's
own name, and requires exactly one match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:40:36 -04:00
bvandeusenandClaude Opus 5.5 d6757fc0fc android: the board takes three and four columns on a wide window, as the web does
The board was Fixed(2) at every width, so a tablet showed two wide columns
where the web shows three or four (#5311). The column count now follows the
web's NoteGrid breakpoints on the window's width: three from 1024dp, four
from 1280dp. A phone keeps two.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:36:41 -04:00
2 changed files with 20 additions and 6 deletions
+8 -2
View File
@@ -249,8 +249,14 @@ jobs:
set -eux
echo "=== container landscape (diagnostic for the name filter) ==="
docker ps -a --format '{{.ID}} {{.Image}} -> {{.Names}}'
PG=$(docker ps --filter "name=integration" --filter "ancestor=postgres:16-alpine" -q | head -n1)
test -n "$PG"
# Only THIS job's Postgres. Other repos' integration jobs share the runner, and
# `name=integration` alone once picked one of theirs (run 8653: a different
# password). act names a job's containers GITEA-ACTIONS-TASK-<task id>-..., and
# the job container's hostname is its own container id.
TASK=$(docker inspect -f '{{.Name}}' "$(cat /etc/hostname)" | sed -n 's|^/\(GITEA-ACTIONS-TASK-[0-9]*-\).*|\1|p')
test -n "$TASK"
PG=$(docker ps --filter "name=$TASK" --filter "ancestor=postgres:16-alpine" -q)
test "$(echo "$PG" | wc -w)" -eq 1
PG_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$PG")
test -n "$PG_IP"
export INKWELL_DATABASE_URL="postgresql+asyncpg://inkwell:ci_integration@${PG_IP}:5432/inkwell_test"
@@ -60,6 +60,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
@@ -454,7 +455,7 @@ private fun DrawerRow(
}
/**
* The board: a two-column masonry, matching the web and desktop.
* The board: a masonry of two to four columns, by window width, matching the web.
*
* Staggered rather than a uniform grid because notes are wildly different heights
* — a one-line thought beside a twelve-item checklist — and forcing them to a
@@ -469,8 +470,17 @@ private fun NoteBoard(
onNoteAction: (Note, EditorAction) -> Unit,
onConfirmDelete: (Note) -> Unit,
) {
// The web's breakpoints (NoteGrid.vue: three columns from `lg`, 1024px, four from
// `xl`, 1280px), on the window's width, so a tablet lays out like a browser of the
// same size. Below that it stays at two, where the web drops to one on a phone.
val windowWidth = LocalConfiguration.current.screenWidthDp
val columns = when {
windowWidth >= 1280 -> 4
windowWidth >= 1024 -> 3
else -> 2
}
LazyVerticalStaggeredGrid(
columns = StaggeredGridCells.Fixed(BOARD_COLUMNS),
columns = StaggeredGridCells.Fixed(columns),
modifier = Modifier.fillMaxSize(),
// Bottom padding clears the FAB, so the last note is never trapped under it.
contentPadding = PaddingValues(start = GUTTER, end = GUTTER, top = 4.dp, bottom = 88.dp),
@@ -577,8 +587,6 @@ fun StoreUnavailableScreen(reason: String?) {
}
}
private const val BOARD_COLUMNS = 2
// Not private: the reminder notice is board content and has to line up with the
// search bar and the cards, so it shares the board's gutter rather than guessing.
internal val GUTTER = 12.dp