Skip to content

Releases: jeiel85/flux-hourglass-android

v1.9.1

Choose a tag to compare

@github-actions github-actions released this 15 Jun 11:01

Flux Hourglass v1.9.1 Release Notes

Flux Hourglass v1.9.1 is a bug-fix release that hardens the Setup Screen layout so the time picker and START button can never be pushed off-screen and lost.

The Bug

The Setup Screen content was laid out in a fixed Column(Modifier.fillMaxSize()) with verticalArrangement = Arrangement.SpaceBetween and no scroll fallback. When the total content height exceeded the viewport — short/small screens, split-screen, a large accessibility font scale, tall system-bar insets, or any future growth of the object filmstrip — SpaceBetween placed the lower children (Quick Presets, the HR/MIN/SEC picker, and the START button) below the bottom edge with no way to scroll to them. The controls silently disappeared, leaving only the header and the object selector visible.

The Fix

  • Min-height scroll container. The content is now wrapped in a BoxWithConstraints whose Column uses Modifier.heightIn(min = viewportHeight).verticalScroll(rememberScrollState()).
    • When the content fits (the common case), the column is exactly the viewport height, so Arrangement.SpaceBetween spreads the children exactly as before — the layout is pixel-identical and never scrolls.
    • When the content overflows, the column grows past the viewport and becomes scrollable, so every control stays reachable instead of being clipped away.
  • No visual change on screens where the content already fit.

Technical Notes

  • Added imports: androidx.compose.foundation.verticalScroll, androidx.compose.foundation.rememberScrollState, androidx.compose.foundation.layout.heightIn.
  • statusBarsPadding() / navigationBarsPadding() / background(PureBlack) moved to the outer BoxWithConstraints, so maxHeight reflects the true content area used as the column's minimum height.
  • All testTags (mode_column, mode_scroller, preset_row, start_button, the mode_* object tags, picker tags) are unchanged.
  • No data-model, schema, or persistence changes; saved durations and object preferences carry over.
  • Verification. The golden setup.png Roborazzi test still passes in compare mode (verifyRoborazziDebug), proving no visual regression when content fits. A separate overflow-forcing render (tiny viewport + 1.8× font) confirms START can be scrolled into view (performScrollTo().assertIsDisplayed()), which was impossible before the fix.
  • versionCode 10 → 11, versionName 1.9.0 → 1.9.1.

v1.9.0

Choose a tag to compare

@github-actions github-actions released this 15 Jun 05:58

Flux Hourglass v1.9.0 Release Notes

Flux Hourglass v1.9.0 reworks the object selector on the Setup Screen from a fixed three-row grid into a single horizontally scrollable filmstrip, reclaiming the vertical space the time picker and START button need.

What's New

Object Selector — Single Swipe-Through Row

The 15 objects previously occupied three stacked rows of five, a fixed block that crowded the time picker and start control and grew taller with every new object added (v1.6 → v1.7 → v1.8).

  • One row instead of three. Objects now live in a single LazyRow you swipe left/right. The footprint is fixed regardless of how many objects exist, so future additions no longer push the picker down.
  • Auto-centering selection. Tapping (or restoring) an object glides it to the horizontal center via animateScrollBy, computed from the live layoutInfo viewport. Off-screen selections jump close first, then center.
  • Edge-fade affordance. Pure-black horizontal gradients on both ends signal that the strip continues. The overlays carry no pointer modifiers, so the partially-faded edge items stay tappable.
  • Concept-preserving. Keeps the hairline-underline / letter-spaced ModeTab styling untouched — only the container changed. No new chrome, no expand/collapse state.

Technical Notes

  • DisplayMode enum and per-object mode_* test tags are unchanged; the order is now driven by a single ModeOptions list (ModeOption(mode, label, tag)), the single place to append new objects.
  • Removed the mode_row_1/2/3 containers; the wrapping Box keeps the mode_column test tag and the new LazyRow carries mode_scroller.
  • No data-model, schema, or persistence changes — DisplayMode serialization is identical, so saved object preferences carry over.
  • versionCode 9 → 10, versionName 1.8.0 → 1.9.0.

v1.8.0

Choose a tag to compare

@github-actions github-actions released this 15 Jun 00:42

Flux Hourglass v1.8.0 Release Notes

We are thrilled to present Flux Hourglass v1.8.0, introducing a sandbox physics settings panel, live procedural soundscapes, and interactive gesture-drawn collision barriers.

What's New

1. Sandbox Physics Settings

Customize the core simulation engine using three adjustable parameters in the Setup Screen (S E T T button):

  • Gravity Sensitivity ($0.3\times$ to $2.5\times$): Tweak how aggressively particles slump and react to accelerometer tilting.
  • Particle Size ($0.6\times$ to $2.2\times$): Modify grain size, splash radius, and droplet scale.
  • Particle Density ($0.5\times$ to $2.0\times$): Control the spawn rate/amount of simultaneous simulation elements.

2. Procedural Soundscapes

Listen to math-modeled, real-time PCM audio synthesis dynamically generated using mathematical noise models:

  • Rain Mode: Immersive low-pass filtered white noise rumbling.
  • Fire Mode: Organic crackling logs using random sparse amplitude pops over a low rumble.
  • Water Mode: Rolling amplitude-modulated wave rumble mimicking ocean waves.
  • Uses zero resource files, keeping the APK lightweight! Toggle sound with the middle overlay button.

3. Interactive Obstacle Drawing

Draw transient, fading lines on the screen using drag gestures. Grains (Sand), splashes (Water), and droplets (Rain) will deflect off your barriers in real time using elastic 2D collision vector calculations.

v1.7.0

Choose a tag to compare

@github-actions github-actions released this 14 Jun 14:43

Flux Hourglass 1.7.0

A major feature release introducing 5 premium interactive, accelerometer-driven particle-physics and fluid simulation modes: MAGNETIC, AURORA, RAIN, BLACKHOLE, and ELECTRIC. This release elevates the minimalist timer experience with satisfying physics and multi-touch gestures.

Highlights

  • Magnetic Ferrofluid Mode (MAGNETIC).
    • Features spiky black ferrofluid fluid dynamics that accumulate and stretch towards a virtual magnet.
    • Spikes bristle and wiggle organically with time-based sine wave micro-vibrations.
    • Interactive dragging moves the virtual magnet attraction center on touch.
  • Aurora Flow Field Mode (AURORA).
    • Sweeps glowing teal, green, and purple particles through a dynamic trigonometry flow field.
    • Particles drift with device tilt and slowly settle into a calm, glowing sediment layer at the bottom.
    • Touching the screen creates a powerful swirling vortex that redirects the particle winds.
  • Rain & Ripples Mode (RAIN).
    • Simulates rain condensation sliding down a glass pane, merging with other drops upon collision.
    • Drops slide at an angle determined by the device accelerometer (gravity vector).
    • Touching the screen sweeps drops away like a finger wiping the condensation.
  • Accretion black hole Mode (BLACKHOLE).
    • Features star particles orbiting a growing gravitational singularity.
    • Star orbits are perturbed by device tilt and experience friction, spiraling inward until they cross the event horizon.
    • Touching the screen spawns a secondary mini-singularity, splitting orbital streams.
  • Tesla Plasma Globe Mode (ELECTRIC).
    • Generates electric discharge arcs using recursive midpoint displacement fractal algorithms.
    • Arcs bend upward to simulate hot gas rising against the accelerometer's gravity vector.
    • Touching the screen focuses all main plasma arcs directly to the finger coordinate with rapid haptic micro-pulses.

Implementation Notes

  • Interactivity is managed through a unified pointerInput system using Compose's custom awaitPointerEventScope to cleanly capture tap, hold, drag, and release events in one thread-safe pass.
  • Accelerometer low-pass filtering feeds into all physics loops, adjusting drag directions, gravitational pull, and convective heat rise in real-time.

v1.6.0

Choose a tag to compare

@github-actions github-actions released this 13 Jun 13:11

Flux Hourglass 1.6.0

A premium release introducing a beautiful, progressive Campfire-to-Embers (불멍) motion alongside critical build environment stability upgrades. The fire simulation transitions dynamically from roaring bonfire flames to crackling embers and breathing glowing charcoal.

Highlights

  • Campfire-to-Embers Mode (FIRE). Tap "FIRE" on the setup screen to toggle this premium bonfire simulation:
    • Dynamic Progressive States: The fire starts with high intensity, roaring yellow/orange/white flames. As time runs out, the flames gradually die down.
    • Campfire Logs: The background features beautifully rendered crossed firewood logs at the bottom center of the screen.
    • Breathing Charcoal Glow: In the final phase (progress > 80%), the logs transition to a burning coal state, breathing with an organic pulsing red-orange glow using double sine/cosine waves.
    • Crackling Ember Sparks: Tiny, high-velocity golden spark particles crackle and float upwards from the coal bed during the embers phase, drifting sideways under device tilt.
    • Interactive Tilt Physics: The fire flames and floating sparks react dynamically to the device accelerometer, leaning realistically when the phone is tilted.
  • Gradle 9.5.1 Upgrade. Upgraded the project build system and Gradle wrapper to version 9.5.1 to resolve script compilation regressions on Windows environments.

Implementation Notes

  • Inside MainActivity.kt, the progressive state uses rememberUpdatedState(progress) inside the continuous LaunchedEffect simulation loop to correctly track real-time progression without resetting particle states.
  • The logs are rendered using Compose Canvas drawLine with a thick stroke and StrokeCap.Round. The glowing charcoal core is drawn as pulsing inner stroke layers:
    $$\text{glowColor} = \text{Color}(0xFFFF3D00).copy(\text{alpha} = \text{emberGlowAlpha} \cdot (0.85f + \sin(\text{tick} \cdot 0.05f) \cdot 0.15f))$$
  • Particle system caps max particles and adjusts spawn rates to decline linearly as the timer progress increases, transitioning flame spawning off at 80% progress and replacing them with a low-density spark emitter.

v1.5.0

Choose a tag to compare

@github-actions github-actions released this 28 May 14:08

Flux Hourglass 1.5.0

A premium release introducing a gorgeous Water Mode alongside complete Full-Screen Immersive Mode support. The liquid rendering utilizes accelerometer-driven fluid dynamics with beautiful wobbly bubbles and splash particles.

Highlights

  • Dynamic Water Mode. Tap "WATER" on the setup screen to toggle this premium liquid simulation. It features:
    • Double-Layer Waves: Undulating translucent waves (Cyan & Blue paths) flowing continuously in real-time.
    • Spring-Damper Tilt Physics: Highly-responsive fluid tilting that realistically sloshes back and forth when you tilt your device, settling naturally into equilibrium.
    • Ambient Gaseous Bubbles: Gentle bubbles spawning at the bottom pool, rising with a side-to-side wobble phase, and popping cleanly on the surface waves.
    • Gravity-Accelerated Splashes: Splashing water droplets erupting upwards under gravity from the exact point of the vertical stream's impact.
  • Full-Screen Immersive Mode. No more status or navigation bars breaking the minimalism. The entire display is dedicated to the visual timer experience, with bar visibility toggled via a transient swipe-to-reveal gesture.
  • Enhanced Physics & Aesthetics. Highly refined gravity formulas and scaled splash properties align the physical tilting response of the fluid perfectly with the device's actual angle, matching the premium look of the Sand simulation.

Implementation Notes

  • Inside MainActivity.onCreate, standard WindowInsetsControllerCompat handles the immersive configuration:
    val controller = WindowInsetsControllerCompat(window, window.decorView)
    controller.hide(WindowInsetsCompat.Type.systemBars())
    controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
  • Accelerometer values are continuously filtered using low-pass and spring-damper equations to prevent micro-jitter and achieve realistic fluid inertia:
    $$\text{acceleration} = (\text{targetSlosh} - \text{sloshAngle}) \cdot 35f - \text{sloshVelocity} \cdot 6f$$
  • Splash droplet horizontal velocity components scale linearly with tiltX * 36f to perfectly align the impact point with the falling water column on tilted screens.

v1.4.0

Choose a tag to compare

@github-actions github-actions released this 28 May 08:34

Flux Hourglass 1.4.0

A small but very physical release. Rotate the phone and the sand and
LEDs now actually obey gravity, and the bottom controls finally stay
readable when they sit on top of a white pile.

Highlights

  • Gravity-aware orientation. The accelerometer is sampled every
    frame and snapped to one of four 90° orientations (portrait,
    upside-down, landscape-left, landscape-right). The running screen
    rotates its content so the sand always falls from the physical
    12 o'clock toward the physical 6 o'clock, and the pile always lives
    on the gravity-down edge of the device. Hold the phone sideways and
    the sand falls sideways — the way you would expect.
  • LED grid follows gravity too. The 16 × 32 LED grid fills from
    the physical bottom regardless of how you hold the device, matching
    the sand mode's behaviour.
  • Readable PAUSE / RESET pills. The bottom controls now sit on a
    semi-transparent black rounded pill so they stay legible when the
    white sand pile (or a fully lit LED grid) reaches them. The label
    alpha also went up from 0.65 to 0.95 — they read clearly without
    having to stand out against the background alone.

Implementation notes

  • A GravityOrient enum classifies device-frame gravity into the
    four 90° orientations with hysteresis: the dominant axis has to
    beat the other by 1.5× and exceed 5 m/s² before we snap, so a
    phone held near the diagonal does not flip-flop every frame.
  • The running screen wraps its Canvas + overlay in a
    BoxWithConstraints that picks logical dimensions (swapped for
    landscape) and applies graphicsLayer(rotationZ = …) to the
    inner box. The physics never sees device coordinates — it always
    runs in a logical frame where +y is gravity-down. Tilt input
    is projected through GravityOrient.logicalGravity before being
    passed to ParticleSystem.update.
  • ParticleSystem.initDimensions now rescales heights[]
    proportionally when the logical height changes, so an in-flight
    pile keeps the same fill ratio across a rotation instead of
    appearing empty or overflowing.
  • Tap detection lives on the unrotated outer container, so taps
    resolve in device coordinates regardless of rotation while the
    visual content rotates underneath.

v1.3.0

Choose a tag to compare

@github-actions github-actions released this 28 May 05:01

Flux Hourglass 1.3.0

A focused upgrade to the visual core of the timer — the sand pile now
behaves like sand instead of plateauing two-thirds of the way, the
display reacts to physical gravity, and a brand-new LED grid mode
sits alongside the original hourglass.

Highlights

  • Pile fills the full screen. Previously the heap topped out at
    roughly two thirds of the height regardless of duration. The pile
    now tracks elapsed time 1:1, so when the timer ends the screen is
    fully covered. A baseline catch-up keeps the pile honest even on
    long durations where per-grain deposition would otherwise lag.
  • Softer, finer texture. Grains shrank from 3.0 dp to 1.4 dp and
    the column count nearly doubled (50 → 90), giving the pile a much
    smoother silhouette and a more powdery surface.
  • Real gyro response. The accelerometer is no longer cosmetic. The
    falling stream bends with the gravity vector, and the heap on the
    floor immediately slumps toward the lower side when you tilt the
    device — strong tilts trigger an extra pour pass for a more decisive
    reaction.
  • New LED mode. A "전광판" alternative renders the screen as a
    16 × 32 grid of LED-style cells that light up bottom-to-top in
    proportion to elapsed time. When every cell is lit, time is up.
    Toggle between S A N D and L E D from a new tab row at the top
    of the setup screen; the choice is persisted alongside the last
    duration.
  • Bolder typography. Secondary labels were close to invisible at
    the old 0.25–0.4 alpha range. They have been lifted to 0.55–0.8 and
    bumped from Thin / ExtraLight to Light (with Medium on the
    selected mode tab), so the chrome reads clearly without losing the
    minimalist character.

Implementation notes

  • ParticleSystem now owns a baseline lift step that adds the deficit
    between the target average height (1 - remainingFraction) * h and
    the current average back into every column. The lift is capped at
    h * 0.004 per frame so it never produces a visible jolt.
  • pvx is no longer reset to zero each frame; particles integrate
    horizontal gravity and despawn when they leave the canvas. Spawn
    positions get mild jitter plus a small directional bias so the
    stream visibly leans when the device is tilted.
  • Slumping uses an asymmetric threshold (1.0 ± biasX) with four
    passes per frame, escalating to six passes when |gravityX| > 2.0.
  • LED mode reuses the same touch-reveal + pause/reset overlay as the
    sand mode through a shared RunningOverlay composable; the renderer
    itself is a single Canvas that lights cells in row-major order
    from the bottom.
  • TimerPreferences gained a mode field backed by a string
    preference (SAND / LED), defaulting to SAND for first runs and
    upgrading users.

v1.2.0

Choose a tag to compare

@github-actions github-actions released this 15 Jun 00:43

Flux Hourglass 1.2.0

Two ergonomic improvements that make the timer feel less like a one-shot
demo and more like a tool you reach for repeatedly.

Highlights

  • Completion chime. When the timer finishes, a soft three-note chime
    plays on the notification audio stream alongside the existing vibration
    pulse. Volume is intentionally subdued so it does not intrude on
    meditation or focus sessions; if the device is silent, only the
    vibration fires.
  • Remembers your last duration. A small DataStore Preferences file
    persists the most recent H R / M I N / S E C the user pressed
    S T A R T with. The next time the app launches, the pickers are
    pre-seeded with that value — no extra preset tap needed.

Implementation notes

  • TimerPreferences is a thin wrapper over a Preferences DataStore
    named timer_prefs. Reads are clamped to the same ranges as the picker
    (0..99 hours, 0..59 minutes/seconds) so corrupt or out-of-range
    storage cannot crash the UI.
  • The chime uses ToneGenerator(STREAM_NOTIFICATION, 70) so it respects
    the user's silent/DnD profile and does not require any new permission.
  • Seed reads happen with runBlocking { observe(context).first() }
    during composition. The first launch hits the disk once; everything
    after that is in the Compose state.

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 15 Jun 00:43

Flux Hourglass 1.1.0

The first meaningful upgrade after the initial 1.0.0 release. Focuses on the
real-world ergonomics of using the hourglass as an everyday timer without
breaking the minimalist surface.

Highlights

  • Quick presets. A row of 1m / 3m / 5m / 10m / 25m / 1h text chips sits
    just under the title on the setup screen and populates the H R / M I N / S E C
    pickers in one tap. They are deliberately rendered as thin labels — not
    buttons — so they read as suggestions, not chrome.
  • Pause / Resume. The running screen now exposes a faint P A U S E
    control opposite the existing R E S E T label. Pausing freezes the timer
    exactly where it is; the new Paused screen shows the remaining HH : MM : SS
    plus the percent of the duration still ahead, with a centered R E S U M E
    affordance that re-anchors the countdown from the moment you tap.
  • Screen stays on. While the timer is in the Running state the activity
    sets FLAG_KEEP_SCREEN_ON so the display does not dim mid-run; the flag is
    cleared the moment the timer reaches the Paused, Finished, or Setup state.

Implementation notes

  • TimerState.Paused(remainingMillis, totalMillis) is a new state. The view
    model snapshots the remaining time on pause and re-anchors endTime to
    System.currentTimeMillis() + remainingMillis on resume, so the existing
    monotonic-clock tick loop continues to be the single source of truth.
  • The KeepScreenOn() composable is scoped to the running screen only and
    cleans up via DisposableEffect, so it does not leak when the timer
    finishes, is reset, or the activity is torn down.