Week in Review: Jul 20 - Jul 26, 2026
The week’s biggest win wasn’t a new feature launch or a shiny UI update; it was the quiet satisfaction of fixing a layout bug that only manifested when the app got “too full.” We spent Tuesday untangling a flexbox nightmare in React Native, and the fix revealed something about how we handle space allocation in list-heavy interfaces. It’s a good reminder that visual correctness often depends on the edge cases—when there’s plenty of room, the layout looks fine; when there isn’t, the underlying math breaks.
Before diving into the app work, let’s talk about the homelab. I finally made the decision to strip out the ultracode auto-flip from our “ launchers. This had been a standing habit for weeks, where the system would boot at effort high and then automatically flip to effort ultracode after a 45-second sleep. It felt clever at the time, but looking at the Opus spend, it was inefficient. We were paying for maximum reasoning power on sessions that didn’t necessarily need it, just because the launcher assumed all tasks were complex.
The change was straightforward but required careful cleanup across two paths. For the ccc command, which opens a tmux 2x2 grid, I removed the send-keys command that triggered the flip. For the cc1 through cc4 scripts, which live in the Unraid flash file /boot/config/go (and aren’t git-tracked, so this was a live edit), I used a sed script to regenerate the files, ensuring the ultracode reference was gone. I verified the syntax with bash -n and kept a backup before pushing. Now, both paths stay at high for the entire session. Ultracode is no longer a state we toggle; it’s a per-task decision. If I need deep reasoning, I’ll drop the keyword into the prompt or manually run /effort ultracode in the specific pane. This keeps the Opus spend aligned with actual need, not automated default behavior. I left the tmux wrapper in place for now, as it helps with detach/reattach survival, though it no longer serves a functional purpose regarding effort levels. It’s a minor tweak, but it aligns the infrastructure with our actual usage patterns.
On the development side, the heavy lifting was done on “, specifically addressing a UI regression that Jared reported. The issue was subtle: when a project had a large number of photos, the top toolbar and the link/PDF bars would shrink and get clipped. At first glance, it looked like a z-index issue or a simple padding error, but the root cause was deeper in the Yoga layout engine.
The problem stemmed from how FlatList handles its height when no explicit style is applied. In the ProjectDetailScreen, the photo grid was a FlatList with no style prop, meaning its flex basis was its full content height. The parent container was set to flex:1, which fixes its height to the screen. When the photo grid grew beyond the screen height, Yoga distributed the overflow. Because the other flex items (the toolbar and the link/PDF strips) also had flexShrink:1 (inherited from the ScrollView base style), they were squeezed proportionally. The more photos you added, the more the toolbar shrank from 64dp down to 14dp, and the link bars disappeared entirely.
The fix required a deliberate restructuring of the flex properties. I added a listFlex style with flex:1 to the grid, which tells it to take up only the available space and grow if there’s room, but never overflow. I also reordered the FlatLists to have a basis of 0, ensuring they only consume leftover space. Crucially, I added flexShrink:0 to the checklistStrip, toolbar, and linksScroll. This locks their dimensions, ensuring that no matter how tall the photo list gets, the navigation elements stay at their intended size.
I didn’t just fix the one screen. I applied the same pattern to PhotosScreen, ProjectsScreen, and ListsScreen, where an AdBanner sibling was being pushed off-screen by long lists. I left CameraScreen alone, as it uses a bounded modal review sheet where flex:1 behaves differently and doesn’t risk this collapse.
Testing this was a lesson in verification rigor. The automated rig couldn’t catch this because it only screenshots the landing screen, and the landing screen in this build didn’t have the complex list structure. So, I had to seed AsyncStorage with a synthetic 60-photo project plus attachments, then use uiautomator to measure the bounds of the UI elements on device. I verified that the toolbar remained at 192px (64dp) and the link/PDF bars stayed at 132px (44dp), even with the heavy content. It passed all eight gates, including monkey tests and rotation checks, with cold start times at 1249ms and PSS at 151MB—well within our baseline noise limits.
This fix was shipped as a sideload to Jared (v1.5.1) but deliberately held back from the Play Store. Promoting this to production requires a Charles-level gate, and I wanted to ensure the sideload worked cleanly before initiating that process. The sideload succeeded, with a 38MB APK and all stored .so files intact. It’s a small detail, but it highlights the importance of keeping our release pipelines distinct—what works for internal testing doesn’t always mean it’s ready for public consumption without a final review.
Meanwhile, for “, the week was quieter. Jared confirmed the spec for the side-view drawing feature with a simple “All correct” email. The side view takes its own drawing, separate from the top-down plan, and is pinned to the cut it was added at. No code changes were needed; the spec is now locked. It’s a refreshing break from debugging to have a feature that’s just… right. We’re also preparing to ship the §850 connector batch, which includes clarifying terminology for TS/TRS connectors and handling female ¼” splits. This work had been stalled a few times due to size and collision issues, but we finally got it greenlit and built.
Looking ahead, the focus is on polishing these fixes and getting the “ sideload into the Play Store. I’m also thinking about the next round of homelab optimizations. The effort level change was a good start, but there are other automation scripts that could benefit from a similar audit—removing assumptions that don’t match current usage. I’ll be keeping an eye on the Opus spend metrics next week to see if the change has the expected impact.
There’s also the matter of the stale internal tracking info for “. The play-drift-ignore.json file still references a retired listing, which no longer matches reality. It’s harmless for now, but it’s a technical debt item that needs cleaning up. I’ll flag it for the next maintenance window.
On the game side, I’m continuing to tinker with the AI content generation pipeline. It’s early stages, but the workflow for generating asset variations is stabilizing. No specifics on the game itself, but the technical challenge is managing the randomness while maintaining a cohesive style. It’s a fun puzzle to solve, even if the game itself isn’t ready for prime time.
Overall, it was a productive week. We fixed a tricky layout bug, streamlined our automation, and cleared the deck for the next batch of features. The key takeaway is to always verify the edge cases. The layout bug was invisible until the content grew, and the homelab automation was inefficient until we looked at the spend metrics. Both problems were solved by digging into the details rather than accepting the surface-level behavior.
I’ll be back next week with more updates on the app releases and the homelab tweaks. If you have any questions about the flexbox fix or the effort level changes, feel free to reach out.
Newsletter
Enjoyed this post?
Subscribe to get notified when I publish new articles about homelabs, automation, and development.
// no spam, unsubscribe anytime. ~2-4 emails / month
Keep reading