diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index e6ae5fbc4b..094299a8ec 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -21,9 +21,11 @@ package eu.faircode.email; import android.app.Activity; import android.app.Dialog; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.IntentFilter; import android.content.SharedPreferences; import android.graphics.Canvas; import android.graphics.Color; @@ -59,6 +61,7 @@ import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.ImageButton; +import android.widget.ImageView; import android.widget.SeekBar; import android.widget.TextView; @@ -120,6 +123,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. private ImageButton ibHintSwipe; private ImageButton ibHintSelect; private TextView tvNoEmail; + private ImageView ivBusy; private FixedRecyclerView rvMessage; private SeekBar seekBar; private ImageButton ibDown; @@ -168,6 +172,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. private boolean manual = false; private Integer lastUnseen = null; private boolean swiping = false; + private int busy = 0; private AdapterMessage adapter; @@ -265,6 +270,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. ibHintSwipe = view.findViewById(R.id.ibHintSwipe); ibHintSelect = view.findViewById(R.id.ibHintSelect); tvNoEmail = view.findViewById(R.id.tvNoEmail); + ivBusy = view.findViewById(R.id.ivBusy); rvMessage = view.findViewById(R.id.rvMessage); seekBar = view.findViewById(R.id.seekBar); ibDown = view.findViewById(R.id.ibDown); @@ -749,9 +755,40 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. updateSwipeRefresh(); + ivBusy.setVisibility(View.GONE); + LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); + IntentFilter iff = new IntentFilter(); + iff.addAction(SimpleTask.ACTION_TASK_COUNT); + lbm.registerReceiver(receiver, iff); + return view; } + @Override + public void onDestroyView() { + LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); + lbm.unregisterReceiver(receiver); + + super.onDestroyView(); + } + + private BroadcastReceiver receiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + busy = intent.getIntExtra("count", 0); + if (busy == 0) + ivBusy.setVisibility(View.GONE); + else + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + if (busy > 0) + ivBusy.setVisibility(View.VISIBLE); + } + }, 1500); + } + }; + @Override public void onDestroy() { super.onDestroy(); diff --git a/app/src/main/java/eu/faircode/email/SimpleTask.java b/app/src/main/java/eu/faircode/email/SimpleTask.java index 83e97e0c6b..9e457da492 100644 --- a/app/src/main/java/eu/faircode/email/SimpleTask.java +++ b/app/src/main/java/eu/faircode/email/SimpleTask.java @@ -20,6 +20,7 @@ package eu.faircode.email; */ import android.content.Context; +import android.content.Intent; import android.os.Bundle; import android.os.Handler; @@ -31,6 +32,7 @@ import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleService; import androidx.lifecycle.OnLifecycleEvent; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; import java.util.ArrayList; import java.util.List; @@ -47,6 +49,8 @@ public abstract class SimpleTask implements LifecycleObserver { private static final ExecutorService executor = Executors.newFixedThreadPool( Runtime.getRuntime().availableProcessors(), Helper.backgroundThreadFactory); + static final String ACTION_TASK_COUNT = BuildConfig.APPLICATION_ID + ".ACTION_TASK_COUNT"; + public void execute(Context context, LifecycleOwner owner, @NonNull Bundle args, @NonNull String name) { run(context, owner, args, name); } @@ -71,10 +75,15 @@ public abstract class SimpleTask implements LifecycleObserver { final Handler handler = new Handler(); // prevent garbage collection + int count; synchronized (tasks) { tasks.add(this); + count = tasks.size(); } + LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); + lbm.sendBroadcast(new Intent(ACTION_TASK_COUNT).putExtra("count", count)); + try { onPreExecute(args); } catch (Throwable ex) { @@ -104,12 +113,12 @@ public abstract class SimpleTask implements LifecycleObserver { Lifecycle.State state = owner.getLifecycle().getCurrentState(); if (state.equals(Lifecycle.State.DESTROYED)) { // No delivery - cleanup(); + cleanup(context); } else if (state.isAtLeast(Lifecycle.State.RESUMED)) { // Inline delivery Log.i("Deliver task " + name); deliver(); - cleanup(); + cleanup(context); } else owner.getLifecycle().addObserver(new LifecycleObserver() { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) @@ -118,7 +127,7 @@ public abstract class SimpleTask implements LifecycleObserver { Log.i("Resume task " + name); owner.getLifecycle().removeObserver(this); deliver(); - cleanup(); + cleanup(context); } @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) @@ -126,7 +135,7 @@ public abstract class SimpleTask implements LifecycleObserver { // No delivery Log.i("Destroy task " + name); owner.getLifecycle().removeObserver(this); - cleanup(); + cleanup(context); } }); } @@ -154,11 +163,16 @@ public abstract class SimpleTask implements LifecycleObserver { }); } - private void cleanup() { + private void cleanup(Context context) { + int count; synchronized (tasks) { tasks.remove(this); - Log.i("Remaining tasks=" + tasks.size()); + count = tasks.size(); } + + LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); + lbm.sendBroadcast(new Intent(ACTION_TASK_COUNT).putExtra("count", count)); + Log.i("Remaining tasks=" + count); } protected void onPreExecute(Bundle args) { diff --git a/app/src/main/res/drawable/baseline_hourglass_full_24.xml b/app/src/main/res/drawable/baseline_hourglass_full_24.xml new file mode 100644 index 0000000000..a8af620cca --- /dev/null +++ b/app/src/main/res/drawable/baseline_hourglass_full_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/fragment_messages.xml b/app/src/main/res/layout/fragment_messages.xml index 940b9c70db..0c56cc64ac 100644 --- a/app/src/main/res/layout/fragment_messages.xml +++ b/app/src/main/res/layout/fragment_messages.xml @@ -143,6 +143,16 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/vSeparatorHintSelect" /> + +