made a few callbacks save to activity being detached

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java          | 30 
src/main/java/eu/siacs/conversations/ui/ConversationsOverviewFragment.java | 40 
src/main/java/eu/siacs/conversations/ui/XmppFragment.java                  |  8 
3 files changed, 68 insertions(+), 10 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java 🔗

@@ -210,7 +210,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
 								conversation.messagesLoaded.set(true);
 								return;
 							}
-							getActivity().runOnUiThread(() -> {
+							runOnUiThread(() -> {
 								final int oldPosition = binding.messagesView.getFirstVisiblePosition();
 								Message message = null;
 								int childPos;
@@ -242,7 +242,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
 						@Override
 						public void informUser(final int resId) {
 
-							getActivity().runOnUiThread(() -> {
+							runOnUiThread(() -> {
 								if (messageLoaderToast != null) {
 									messageLoaderToast.cancel();
 								}
@@ -519,12 +519,12 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
 			@Override
 			public void inform(final String text) {
 				hidePrepareFileToast(prepareFileToast);
-				getActivity().runOnUiThread(() -> activity.replaceToast(text));
+				runOnUiThread(() -> activity.replaceToast(text));
 			}
 
 			@Override
 			public void success(Message message) {
-				getActivity().runOnUiThread(() -> activity.hideToast());
+				runOnUiThread(() -> activity.hideToast());
 				hidePrepareFileToast(prepareFileToast);
 				activity.xmppConnectionService.sendMessage(message);
 			}
@@ -532,7 +532,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
 			@Override
 			public void error(final int errorCode, Message message) {
 				hidePrepareFileToast(prepareFileToast);
-				getActivity().runOnUiThread(() -> activity.replaceToast(getString(errorCode)));
+				runOnUiThread(() -> activity.replaceToast(getString(errorCode)));
 
 			}
 
@@ -775,7 +775,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
 	@Override
 	public void onDetach() {
 		super.onDetach();
-		this.activity = null;
+		this.activity = null; //TODO maybe not a good idea since some callbacks really need it
 	}
 
 	@Override
@@ -2238,26 +2238,38 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
 
 	@Override
 	public void onTypingStarted() {
+		final XmppConnectionService service = activity == null ? null : activity.xmppConnectionService;
+		if (service == null) {
+			return;
+		}
 		Account.State status = conversation.getAccount().getStatus();
 		if (status == Account.State.ONLINE && conversation.setOutgoingChatState(ChatState.COMPOSING)) {
-			activity.xmppConnectionService.sendChatState(conversation);
+			service.sendChatState(conversation);
 		}
 		updateSendButton();
 	}
 
 	@Override
 	public void onTypingStopped() {
+		final XmppConnectionService service = activity == null ? null : activity.xmppConnectionService;
+		if (service == null) {
+			return;
+		}
 		Account.State status = conversation.getAccount().getStatus();
 		if (status == Account.State.ONLINE && conversation.setOutgoingChatState(ChatState.PAUSED)) {
-			activity.xmppConnectionService.sendChatState(conversation);
+			service.sendChatState(conversation);
 		}
 	}
 
 	@Override
 	public void onTextDeleted() {
+		final XmppConnectionService service = activity == null ? null : activity.xmppConnectionService;
+		if (service == null) {
+			return;
+		}
 		Account.State status = conversation.getAccount().getStatus();
 		if (status == Account.State.ONLINE && conversation.setOutgoingChatState(Config.DEFAULT_CHATSTATE)) {
-			activity.xmppConnectionService.sendChatState(conversation);
+			service.sendChatState(conversation);
 		}
 		updateSendButton();
 	}

src/main/java/eu/siacs/conversations/ui/ConversationsOverviewFragment.java 🔗

@@ -50,11 +50,15 @@ import eu.siacs.conversations.ui.adapter.ConversationAdapter;
 import eu.siacs.conversations.ui.interfaces.OnConversationArchived;
 import eu.siacs.conversations.ui.interfaces.OnConversationSelected;
 import eu.siacs.conversations.ui.util.PendingItem;
+import eu.siacs.conversations.ui.util.ScrollState;
 
 public class ConversationsOverviewFragment extends XmppFragment implements EnhancedListView.OnDismissCallback {
 
+	private static final String STATE_SCROLL_POSITION = ConversationsOverviewFragment.class.getName()+".scroll_state";
+
 	private final List<Conversation> conversations = new ArrayList<>();
 	private final PendingItem<Conversation> swipedConversation = new PendingItem<>();
+	private final PendingItem<ScrollState> pendingScrollState = new PendingItem<>();
 	private FragmentConversationsOverviewBinding binding;
 	private ConversationAdapter conversationsAdapter;
 	private XmppActivity activity;
@@ -89,6 +93,15 @@ public class ConversationsOverviewFragment extends XmppFragment implements Enhan
 
 	}
 
+	@Override
+	public void onActivityCreated(Bundle savedInstanceState) {
+		super.onActivityCreated(savedInstanceState);
+		if (savedInstanceState == null) {
+			return;
+		}
+		pendingScrollState.push(savedInstanceState.getParcelable(STATE_SCROLL_POSITION));
+	}
+
 	@Override
 	public void onAttach(Activity activity) {
 		super.onAttach(activity);
@@ -133,10 +146,25 @@ public class ConversationsOverviewFragment extends XmppFragment implements Enhan
 
 	@Override
 	void onBackendConnected() {
-		Log.d(Config.LOGTAG, "nice!");
 		refresh();
 	}
 
+	@Override
+	public void onSaveInstanceState(Bundle bundle) {
+		super.onSaveInstanceState(bundle);
+		bundle.putParcelable(STATE_SCROLL_POSITION,getScrollState());
+	}
+
+	private ScrollState getScrollState() {
+		int position = this.binding.list.getFirstVisiblePosition();
+		final View view = this.binding.list.getChildAt(0);
+		if (view != null) {
+			return new ScrollState(position,view.getTop());
+		} else {
+			return new ScrollState(position, 0);
+		}
+	}
+
 	@Override
 	public void onStart() {
 		super.onStart();
@@ -168,6 +196,16 @@ public class ConversationsOverviewFragment extends XmppFragment implements Enhan
 			}
 		}
 		this.conversationsAdapter.notifyDataSetChanged();
+		ScrollState scrollState = pendingScrollState.pop();
+		if (scrollState != null) {
+			setScrollPosition(scrollState);
+		}
+	}
+
+	private void setScrollPosition(ScrollState scrollPosition) {
+		if (scrollPosition != null) {
+			this.binding.list.setSelectionFromTop(scrollPosition.position, scrollPosition.offset);
+		}
 	}
 
 	@Override

src/main/java/eu/siacs/conversations/ui/XmppFragment.java 🔗

@@ -29,6 +29,7 @@
 
 package eu.siacs.conversations.ui;
 
+import android.app.Activity;
 import android.app.Fragment;
 
 public abstract class XmppFragment extends Fragment {
@@ -36,4 +37,11 @@ public abstract class XmppFragment extends Fragment {
 	abstract void onBackendConnected();
 
 	abstract void refresh();
+
+	protected void runOnUiThread(Runnable runnable) {
+		final Activity activity = getActivity();
+		if (activity != null) {
+			activity.runOnUiThread(runnable);
+		}
+	}
 }