Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.airbnb.lottie.LottieAnimationView;
import com.google.android.material.progressindicator.LinearProgressIndicator;

import org.appdevforall.k2go.R;
import org.appdevforall.k2go.contentexchange.domain.DeleteJob;
import org.appdevforall.k2go.util.ByteFormatter;
import org.appdevforall.k2go.util.Motion;

public class ContentDeleteProgressFragment extends Fragment {

Expand All @@ -39,6 +41,9 @@ public class ContentDeleteProgressFragment extends Fragment {
private Button cancel;
private Button retry;
private Button finish;
private View animBox;
private LottieAnimationView anim;
private boolean reduceMotion;

private final DeleteSession session = ContentDeleteService.session();

Expand All @@ -59,6 +64,17 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c
retry = root.findViewById(R.id.k2go_cxd_retry);
finish = root.findViewById(R.id.k2go_cxd_finish);

// Content -> shredder loop (K2GO-376). Reduce motion holds a single frame instead of looping.
animBox = root.findViewById(R.id.k2go_cxd_anim_box);
anim = root.findViewById(R.id.k2go_cxd_anim);
reduceMotion = Motion.reduced(getContext());
anim.setAnimation(R.raw.k2go_delete_shred_loop);
if (reduceMotion) {
anim.setProgress(0.5f);
} else {
anim.setRepeatCount(com.airbnb.lottie.LottieDrawable.INFINITE);
}

cancel.setOnClickListener(v -> ContentDeleteService.cancel(requireContext()));
retry.setOnClickListener(v -> ContentDeleteService.retry(requireContext()));
finish.setOnClickListener(v -> {
Expand All @@ -83,6 +99,9 @@ public void onResume() {
public void onPause() {
super.onPause();
session.setListener(null);
if (anim.isAnimating()) {
anim.pauseAnimation();
}
}

private void render() {
Expand All @@ -106,6 +125,19 @@ private void render() {
boolean settled = !running;
retry.setVisibility(settled && session.canRetry() ? View.VISIBLE : View.GONE);
finish.setVisibility(settled ? View.VISIBLE : View.GONE);
renderAnim(running);
}

/** Show the delete animation only while deleting; play it unless motion is off. */
private void renderAnim(boolean active) {
animBox.setVisibility(active ? View.VISIBLE : View.GONE);
if (active && !reduceMotion) {
if (!anim.isAnimating()) {
anim.playAnimation();
}
} else if (anim.isAnimating()) {
anim.pauseAnimation();
}
}

private void renderCurrentItem(boolean running) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ public class ImportProgressFragment extends Fragment {
private View animBox;
private LottieAnimationView anim;
private boolean reduceMotion;
private View animLogoLeft;
private View animGap;
private View animEdge;
private int loopRes; // the loop currently loaded, 0 = none yet

private final ImportSession session = ContentImportService.session();

Expand Down Expand Up @@ -85,19 +89,16 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c
render();
});

// Two-phones transfer animation, shared with Clone (R.raw.k2go_clone_loop). Reduce motion holds
// a single frame instead of looping; the screen never depends on movement to be understood.
// Transfer animation. Wi-Fi receive is phone to phone, so it shares the Clone loop (two logos); a
// drive import plays the microSD loop, which draws the card on the left, so the left logo is hidden.
// Reduce motion holds a single frame instead of looping; the screen never depends on movement.
// The loop is picked in render(): the service may begin the session after this view exists.
animBox = root.findViewById(R.id.k2go_cxi_anim_box);
anim = root.findViewById(R.id.k2go_cxi_anim);
animLogoLeft = root.findViewById(R.id.k2go_cxi_anim_logo_left);
animGap = root.findViewById(R.id.k2go_cxi_anim_gap);
animEdge = root.findViewById(R.id.k2go_cxi_anim_edge);
reduceMotion = Motion.reduced(getContext());
if (anim != null) {
anim.setAnimation(R.raw.k2go_clone_loop);
if (reduceMotion) {
anim.setProgress(0.5f);
} else {
anim.setRepeatCount(com.airbnb.lottie.LottieDrawable.INFINITE);
}
}

cancel.setOnClickListener(v -> ContentImportService.cancel(requireContext()));
retry.setOnClickListener(v -> ContentImportService.retry(requireContext()));
Expand Down Expand Up @@ -158,8 +159,35 @@ private void render() {
renderAnim(running);
}

/** Load the loop for this run's source once: Clone loop for Wi-Fi, microSD loop for a drive. */
private void bindLoop() {
boolean network = session.isNetwork();
int res = network ? R.raw.k2go_clone_loop : R.raw.k2go_import_sd_loop;
if (anim == null || res == loopRes) {
return;
}
loopRes = res;
animLogoLeft.setVisibility(network ? View.VISIBLE : View.INVISIBLE); // INVISIBLE keeps the weight grid
// The receiver logo sits where its loop puts the glow: 0.82 W (Clone loop) or 0.80 W (microSD loop).
setWeight(animGap, network ? 280 : 260);
setWeight(animEdge, network ? 0 : 20);
anim.setAnimation(res);
if (reduceMotion) {
anim.setProgress(0.5f);
} else {
anim.setRepeatCount(com.airbnb.lottie.LottieDrawable.INFINITE);
}
}

private static void setWeight(View v, float weight) {
android.widget.LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) v.getLayoutParams();
lp.weight = weight;
v.setLayoutParams(lp);
}

/** Show the transfer animation only while the transfer is in flight; play it unless motion is off. */
private void renderAnim(boolean active) {
bindLoop();
if (animBox != null) {
animBox.setVisibility(active ? View.VISIBLE : View.GONE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,43 @@
android:textColor="@color/k2go_ink"
android:text="@string/k2go_cx_delete_title" />

<!-- K2GO-376: delete animation (content -> shredder loop). The loop draws the shredder on the
right; this overlay composites the K2Go logo (the library, the source) on the left, on the
same grid as the import overlay. Shown only while deleting; reduce-motion holds a frame. -->
<FrameLayout
android:id="@+id/k2go_cxd_anim_box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:visibility="gone">

<com.airbnb.lottie.LottieAnimationView
android:id="@+id/k2go_cxd_anim"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<Space android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="60" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="940"
android:orientation="horizontal">
<ImageView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="360"
android:src="@drawable/ic_launcher_foreground" android:scaleType="centerCrop" android:contentDescription="@null" />
<Space android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="640" />
</LinearLayout>

</LinearLayout>
</FrameLayout>

<!-- Overall -->
<TextView
android:id="@+id/k2go_cxd_overall_label"
Expand Down
28 changes: 15 additions & 13 deletions controller/app/src/main/res/layout/fragment_k2go_content_import.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="@color/k2go_muted" />

<!-- K2GO-427: two-phones transfer animation (the same Lottie loop as Clone, ADFA-5143). The
loop ships without icons; the two K2Go logos are composited by this overlay. The fragment
shows this box only while the transfer runs and honours reduce-motion (a held frame). -->
<!-- K2GO-427: transfer animation. Wi-Fi receive plays the two-phones Clone loop (ADFA-5143) with
both logos; a drive import plays the microSD loop, which draws the card on the left, so the
fragment hides the left logo (K2GO-376). The loops ship without the K2Go logo: this overlay
composites it. Shown only while the transfer runs; reduce-motion holds a frame. -->
<FrameLayout
android:id="@+id/k2go_cxi_anim_box"
android:layout_width="match_parent"
Expand All @@ -60,23 +61,24 @@
android:layout_height="match_parent"
android:orientation="vertical">

<Space android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="300" />
<Space android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="60" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="480"
android:layout_weight="940"
android:orientation="horizontal">
<Space android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="25" />
<ImageView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="295"
android:src="@drawable/ic_launcher_foreground" android:scaleType="fitCenter" android:contentDescription="@null" />
<Space android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="360" />
<ImageView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="295"
android:src="@drawable/ic_launcher_foreground" android:scaleType="fitCenter" android:contentDescription="@null" />
<Space android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="25" />
<ImageView android:id="@+id/k2go_cxi_anim_logo_left"
android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="360"
android:src="@drawable/ic_launcher_foreground" android:scaleType="centerCrop" android:contentDescription="@null" />
<Space android:id="@+id/k2go_cxi_anim_gap"
android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="280" />
<ImageView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="360"
android:src="@drawable/ic_launcher_foreground" android:scaleType="centerCrop" android:contentDescription="@null" />
<Space android:id="@+id/k2go_cxi_anim_edge"
android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="0" />
</LinearLayout>

<Space android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="220" />
</LinearLayout>
</FrameLayout>

Expand Down

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions controller/app/src/main/res/raw/k2go_import_sd_loop.json

Large diffs are not rendered by default.

Loading