From fcef800cfe8d4eaba59bf345f5c0d8097ca5e1f7 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Thu, 22 Oct 2026 11:29:16 +0200 Subject: Fix viewer timer and lifecycle review findings - tick() refreshes lastTick on every tick, so a failed video no longer advances at once with its whole playback time. - Photo timer counts only once the photo is shown (or failed), so a slow load cannot advance before display. - Slides started while the activity is stopped stay paused and stopped; onStart re-prepares them. - toggleLike error UI guard no longer indexes a replaced playlist. Co-Authored-By: Claude Opus 5.5 --- app/src/main/java/mygram/droid/ViewerActivity.java | 26 +++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/mygram/droid/ViewerActivity.java b/app/src/main/java/mygram/droid/ViewerActivity.java index 098f817..59e6948 100644 --- a/app/src/main/java/mygram/droid/ViewerActivity.java +++ b/app/src/main/java/mygram/droid/ViewerActivity.java @@ -77,7 +77,7 @@ public final class ViewerActivity extends Activity { private int index, slide; /** Bumped on every slide change; late callbacks for older slides are dropped. */ private volatile int generation; - private boolean paused, failed, loadingMore, parkedAtEnd; + private boolean paused, failed, loadingMore, parkedAtEnd, shown, stopped; private long photoElapsed, lastTick; @Override @@ -171,6 +171,7 @@ public final class ViewerActivity extends Activity { int gen = ++generation; paused = false; failed = false; + shown = false; photoElapsed = 0; lastTick = SystemClock.uptimeMillis(); parkedAtEnd = false; @@ -199,13 +200,20 @@ public final class ViewerActivity extends Activity { @Override public boolean onResourceReady(Drawable d, Object model, Target target, DataSource source, boolean first) { - if (gen == generation) - photoElapsed = 0; // count from when the photo is on screen + if (gen == generation) { // count from when the photo is on screen + shown = true; + photoElapsed = 0; + lastTick = SystemClock.uptimeMillis(); + } return false; } }).into(photo); } tick(); + if (stopped) { // page arrived in the background: stay paused, onStart re-prepares + setPaused(true); + player.stop(); + } } // ponytail: a grab already blocked in setDataSource is not interrupted, so a slow one delays the next post's frame; upgrade: a timeout or per-post cancellation. @@ -234,14 +242,14 @@ public final class ViewerActivity extends Activity { /** Drives the progress bar and the photo timer. */ private void tick() { handler.removeCallbacks(ticker); + long now = SystemClock.uptimeMillis(), dt = now - lastTick; + lastTick = now; if (media().video && !failed) { long d = player.getDuration(); progress.setProgress(d > 0 ? (int) (1000 * player.getCurrentPosition() / d) : 0); } else { - long now = SystemClock.uptimeMillis(); - if (!paused) - photoElapsed += now - lastTick; - lastTick = now; + if (!paused && (shown || failed)) + photoElapsed += dt; long total = Prefs.photoSeconds() * 1000L; progress.setProgress((int) (1000 * Math.min(photoElapsed, total) / total)); if (photoElapsed >= total) { @@ -315,7 +323,7 @@ public final class ViewerActivity extends Activity { if (Likes.has(p.id) != on) return; // a newer toggle wins Likes.set(p.id, !on); - if (!Playlist.posts.isEmpty() && post() == p) + if (!isDestroyed() && post() == p) heart.setVisibility(on ? View.GONE : View.VISIBLE); String msg = e.getMessage(); Toast.makeText(this, "Like failed" + (msg != null ? ": " + msg : ""), Toast.LENGTH_SHORT).show(); @@ -397,6 +405,7 @@ public final class ViewerActivity extends Activity { @Override protected void onStart() { super.onStart(); + stopped = false; // The first show() already prepared (state is not IDLE), so this only revives a stopped decoder. if (!Playlist.posts.isEmpty() && media().video && !failed && player.getPlaybackState() == Player.STATE_IDLE) { player.setPlayWhenReady(!paused); @@ -407,6 +416,7 @@ public final class ViewerActivity extends Activity { @Override protected void onStop() { super.onStop(); + stopped = true; player.stop(); // free the video decoder while in the background } -- cgit v1.2.3