diff --git a/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java index 151667cf..4fae3f5f 100644 --- a/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java +++ b/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java @@ -58,6 +58,7 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter differ; + private List items; private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() { @Override @@ -97,8 +98,10 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter(new AdapterListUpdateCallback(this), new AsyncDifferConfig.Builder<>(diffCallback).build()); // this.onClickListener = onClickListener; @@ -118,9 +121,10 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter list) { @@ -240,6 +245,7 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter list, @Nullable final Runnable commitCallback) { @@ -248,6 +254,7 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter sectionAndSort(final List list) { @@ -289,6 +296,10 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter getItems() { + return items; + } + @Override public void onViewRecycled(@NonNull final RecyclerView.ViewHolder holder) { if (holder instanceof DirectItemViewHolder) { @@ -303,6 +314,10 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter { - binding.input.requestFocus(); - binding.input.post(this::showKeyboard); - }); + binding.input.requestFocus(); + binding.input.post(this::showKeyboard); wasKbShowing = false; } setObservers(); @@ -332,12 +333,6 @@ public class DirectMessageThreadFragment extends Fragment { cleanup(); } - @Override - public void onDestroy() { - super.onDestroy(); - cleanup(); - } - private void cleanup() { if (prevTitleRunnable != null) { appExecutors.mainThread().cancel(prevTitleRunnable); @@ -363,13 +358,14 @@ public class DirectMessageThreadFragment extends Fragment { if (context == null) return; if (getArguments() == null) return; actionBar = fragmentActivity.getSupportActionBar(); - setObservers(); final DirectMessageThreadFragmentArgs fragmentArgs = DirectMessageThreadFragmentArgs.fromBundle(getArguments()); viewModel.getThreadTitle().postValue(fragmentArgs.getTitle()); final String threadId = fragmentArgs.getThreadId(); viewModel.setThreadId(threadId); setupList(); root.post(this::setupInput); + root.post(this::getInitialData); + setObservers(); } private void getInitialData() { @@ -386,9 +382,6 @@ public class DirectMessageThreadFragment extends Fragment { // setTitle(UPDATING_TITLE); final DirectThread thread = first.get(); viewModel.setThread(thread); - if (itemsAdapter != null) { - itemsAdapter.setThread(thread); - } return; } viewModel.fetchChats(); @@ -554,29 +547,12 @@ public class DirectMessageThreadFragment extends Fragment { } setTitle(viewModel.getThreadTitle().getValue()); }); - viewModel.getThread().observe(getViewLifecycleOwner(), thread -> { - if (thread != null && itemsAdapter != null) itemsAdapter.setThread(thread); - }); - appStateViewModel.getCurrentUser().observe(getViewLifecycleOwner(), currentUser -> { - viewModel.setCurrentUser(currentUser); - setupItemsAdapter(currentUser); - viewModel.getItems().observe( - getViewLifecycleOwner(), - list -> itemsAdapter.submitList(list, () -> { - itemOrHeaders = itemsAdapter.getList(); - binding.chats.post(() -> { - final RecyclerView.LayoutManager layoutManager = binding.chats.getLayoutManager(); - if (layoutManager instanceof LinearLayoutManager) { - final int position = ((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition(); - if (position < 0) return; - if (position == itemsAdapter.getItemCount() - 1) { - viewModel.fetchChats(); - } - } - }); - }) - ); + final ItemsAdapterDataMerger itemsAdapterDataMerger = new ItemsAdapterDataMerger(appStateViewModel.getCurrentUser(), viewModel.getThread()); + itemsAdapterDataMerger.observe(getViewLifecycleOwner(), userThreadPair -> { + viewModel.setCurrentUser(userThreadPair.first); + setupItemsAdapter(userThreadPair.first, userThreadPair.second); }); + viewModel.getItems().observe(getViewLifecycleOwner(), this::submitItemsToAdapter); final NavController navController = NavHostFragment.findNavController(this); final NavBackStackEntry backStackEntry = navController.getCurrentBackStackEntry(); if (backStackEntry != null) { @@ -585,15 +561,47 @@ public class DirectMessageThreadFragment extends Fragment { if (!(result instanceof Uri)) return; final Uri uri = (Uri) result; viewModel.sendUri(uri); + // clear result + resultLiveData.postValue(null); }); } } - private void setupItemsAdapter(final ProfileModel currentUser) { - if (itemsAdapter != null) return; - itemsAdapter = new DirectItemsAdapter(currentUser); + private void submitItemsToAdapter(final List items) { + if (itemsAdapter == null) return; + itemsAdapter.submitList(items, () -> { + itemOrHeaders = itemsAdapter.getList(); + binding.chats.post(() -> { + final RecyclerView.LayoutManager layoutManager = binding.chats.getLayoutManager(); + if (layoutManager instanceof LinearLayoutManager) { + final int position = ((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition(); + if (position < 0) return; + if (position == itemsAdapter.getItemCount() - 1) { + viewModel.fetchChats(); + } + } + }); + }); + } + + private void setupItemsAdapter(final ProfileModel currentUser, final DirectThread thread) { + if (itemsAdapter != null) { + if (itemsAdapter.getThread() == thread) return; + itemsAdapter.setThread(thread); + return; + } + itemsAdapter = new DirectItemsAdapter(currentUser, thread); itemsAdapter.setHasStableIds(true); + itemsAdapter.setStateRestorationPolicy(RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY); binding.chats.setAdapter(itemsAdapter); + registerDataObserver(); + final List items = viewModel.getItems().getValue(); + if (items != null && itemsAdapter.getItems() != items) { + submitItemsToAdapter(items); + } + } + + private void registerDataObserver() { itemsAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { @Override @@ -607,7 +615,6 @@ public class DirectMessageThreadFragment extends Fragment { } } }); - root.post(this::getInitialData); } private void setupInput() { @@ -1097,4 +1104,26 @@ public class DirectMessageThreadFragment extends Fragment { }); animatorSet.start(); } + + public static class ItemsAdapterDataMerger extends MediatorLiveData> { + private ProfileModel user; + private DirectThread thread; + + public ItemsAdapterDataMerger(final LiveData userLiveData, + final LiveData threadLiveData) { + addSource(userLiveData, user -> { + this.user = user; + combine(); + }); + addSource(threadLiveData, thread -> { + this.thread = thread; + combine(); + }); + } + + private void combine() { + if (user == null || thread == null) return; + setValue(new Pair<>(user, thread)); + } + } }