diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index cfb1416928..ba8c6b4b8f 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -1135,7 +1135,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. if (viewType == AdapterMessage.ViewType.THREAD) { ViewModelMessages model = new ViewModelProvider(getActivity()).get(ViewModelMessages.class); - model.observePrevNext(getViewLifecycleOwner(), id, new ViewModelMessages.IPrevNext() { + model.observePrevNext(getContext(), getViewLifecycleOwner(), id, new ViewModelMessages.IPrevNext() { @Override public void onPrevious(boolean exists, Long id) { boolean reversed = prefs.getBoolean("reversed", false); @@ -3957,7 +3957,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. private void loadMessages(final boolean top) { if (viewType == AdapterMessage.ViewType.THREAD && onclose != null) { ViewModelMessages model = new ViewModelProvider(getActivity()).get(ViewModelMessages.class); - model.observePrevNext(getViewLifecycleOwner(), id, new ViewModelMessages.IPrevNext() { + model.observePrevNext(getContext(), getViewLifecycleOwner(), id, new ViewModelMessages.IPrevNext() { boolean once = false; @Override diff --git a/app/src/main/java/eu/faircode/email/ViewModelMessages.java b/app/src/main/java/eu/faircode/email/ViewModelMessages.java index 7534a83da1..5a8cf730ef 100644 --- a/app/src/main/java/eu/faircode/email/ViewModelMessages.java +++ b/app/src/main/java/eu/faircode/email/ViewModelMessages.java @@ -24,6 +24,7 @@ import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; import android.text.TextUtils; +import android.util.Pair; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -244,10 +245,10 @@ public class ViewModelMessages extends ViewModel { models.remove(viewType); } - void observePrevNext(LifecycleOwner owner, final long id, final IPrevNext intf) { + void observePrevNext(Context context, LifecycleOwner owner, final long id, final IPrevNext intf) { Log.d("Observe prev/next model=" + last); - Model model = models.get(last); + final Model model = models.get(last); if (model == null) { // When showing accounts or folders intf.onPrevious(false, null); @@ -258,6 +259,7 @@ public class ViewModelMessages extends ViewModel { Log.d("Observe previous/next id=" + id); model.list.observe(owner, new Observer>() { + @Override public void onChanged(PagedList messages) { Log.d("Observe previous/next id=" + id + " messages=" + messages.size()); @@ -284,6 +286,62 @@ public class ViewModelMessages extends ViewModel { } Log.w("Observe previous/next gone id=" + id); + + Bundle args = new Bundle(); + args.putLong("id", id); + + new SimpleTask>() { + @Override + protected Pair onExecute(Context context, Bundle args) { + long id = args.getLong("id"); + + PagedList plist = model.list.getValue(); + if (plist == null) + return null; + + LimitOffsetDataSource ds = (LimitOffsetDataSource) plist.getDataSource(); + int count = ds.countItems(); + for (int i = 0; i < count; i += 100) { + List messages = ds.loadRange(i, Math.min(100, count - i)); + for (int j = 0; j < messages.size(); j++) + if (messages.get(j).id == id) { + int pos = i + j; + model.list.getValue().loadAround(pos); + + List lprev = null; + if (pos - 1 >= 0) + lprev = ds.loadRange(pos - 1, 1); + + List lnext = null; + if (pos + 1 < count) + lnext = ds.loadRange(pos + 1, 1); + + TupleMessageEx prev = (lprev != null && lprev.size() > 0 ? lprev.get(0) : null); + TupleMessageEx next = (lnext != null && lnext.size() > 0 ? lnext.get(0) : null); + + Pair result = new Pair<>( + prev == null ? null : prev.id, + next == null ? null : next.id); + Log.i("Observe previous/next fallback=" + result); + return result; + } + } + + return null; + } + + @Override + protected void onExecuted(Bundle args, Pair data) { + intf.onPrevious(data != null && data.first != null, data == null ? null : data.first); + intf.onNext(data != null && data.second != null, data == null ? null : data.second); + intf.onFound(-1, messages.size()); + } + + @Override + protected void onException(Bundle args, Throwable ex) { + // No nothing + } + }.execute(context, owner, args, "model:fallback"); } }); }