wip

Daniel Gultsch created

Change summary

src/main/AndroidManifest.xml                                                           |   2 
src/main/java/eu/siacs/conversations/ui/ConversationActivity.java                      |  36 
src/main/java/eu/siacs/conversations/ui/ConversationFragment.java                      |  89 
src/main/java/eu/siacs/conversations/ui/ConversationsMainActivity.java                 | 116 
src/main/java/eu/siacs/conversations/ui/ConversationsOverviewFragment.java             |  96 
src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java                 |   5 
src/main/java/eu/siacs/conversations/ui/XmppFragment.java                              |  37 
src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java                    |  13 
src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationArchived.java         |  36 
src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationRead.java             |  36 
src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationSelected.java         |  37 
src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationsListItemUpdated.java |  34 
src/main/res/layout-w945dp/activity_conversations.xml                                  |  22 
src/main/res/layout-w945dp/fragment_conversations_overview.xml                         |  32 
src/main/res/layout/activity_conversations.xml                                         |  35 
src/main/res/layout/fragment_conversations_overview.xml                                |  35 
16 files changed, 539 insertions(+), 122 deletions(-)

Detailed changes

src/main/AndroidManifest.xml 🔗

@@ -44,7 +44,7 @@
         </receiver>
 
         <activity
-            android:name=".ui.ConversationActivity"
+            android:name=".ui.ConversationsMainActivity"
             android:label="@string/app_name"
             android:launchMode="singleTask"
             android:minWidth="300dp"

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

@@ -162,7 +162,7 @@ public class ConversationActivity extends XmppActivity
 
 		this.mConversationFragment = new ConversationFragment();
 		FragmentTransaction transaction = getFragmentManager().beginTransaction();
-		transaction.replace(R.id.selected_conversation, this.mConversationFragment, "conversation");
+		//transaction.replace(R.id.selected_conversation, this.mConversationFragment, "conversation");
 		transaction.commit();
 
 		this.listView = findViewById(R.id.list);
@@ -260,9 +260,9 @@ public class ConversationActivity extends XmppActivity
 		listView.setUndoHideDelay(5000);
 		listView.setRequireTouchBeforeDismiss(false);
 
-		mContentView = findViewById(R.id.content_view_spl);
+		//mContentView = findViewById(R.id.content_view_spl);
 		if (mContentView == null) {
-			mContentView = findViewById(R.id.content_view_ll);
+			//mContentView = findViewById(R.id.content_view_ll);
 		}
 		if (mContentView instanceof SlidingPaneLayout) {
 			SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView;
@@ -767,11 +767,6 @@ public class ConversationActivity extends XmppActivity
 		}
 	}
 
-	public long getMaxHttpUploadSize(Conversation conversation) {
-		final XmppConnection connection = conversation.getAccount().getXmppConnection();
-		return connection == null ? -1 : connection.getFeatures().getMaxHttpUploadSize();
-	}
-
 	private String getBatteryOptimizationPreferenceKey() {
 		@SuppressLint("HardwareIds") String device = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
 		return "show_battery_optimization" + (device == null ? "" : device);
@@ -831,26 +826,6 @@ public class ConversationActivity extends XmppActivity
 		listAdapter.notifyDataSetChanged();
 	}
 
-	public void runIntent(PendingIntent pi, int requestCode) {
-		try {
-			this.startIntentSenderForResult(pi.getIntentSender(), requestCode,
-					null, 0, 0, 0);
-		} catch (final SendIntentException ignored) {
-		}
-	}
-
-	public boolean useSendButtonToIndicateStatus() {
-		return getPreferences().getBoolean("send_button_status", getResources().getBoolean(R.bool.send_button_status));
-	}
-
-	public boolean indicateReceived() {
-		return getPreferences().getBoolean("indicate_received", getResources().getBoolean(R.bool.indicate_received));
-	}
-
-	public boolean useGreenBackground() {
-		return getPreferences().getBoolean("use_green_background", getResources().getBoolean(R.bool.use_green_background));
-	}
-
 	@Override
 	protected void refreshUiReal() {
 		updateConversationList();
@@ -893,11 +868,6 @@ public class ConversationActivity extends XmppActivity
 		this.refreshUi();
 	}
 
-
-	public boolean enterIsSend() {
-		return getPreferences().getBoolean("enter_is_send", getResources().getBoolean(R.bool.enter_is_send));
-	}
-
 	@Override
 	public void onShowErrorToast(final int resId) {
 		runOnUiThread(() -> Toast.makeText(ConversationActivity.this, resId, Toast.LENGTH_SHORT).show());

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

@@ -2,10 +2,13 @@ package eu.siacs.conversations.ui;
 
 import android.annotation.SuppressLint;
 import android.app.Activity;
+import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.databinding.DataBindingUtil;
 import android.net.Uri;
 import android.os.Build;
+import android.preference.Preference;
+import android.preference.PreferenceManager;
 import android.provider.MediaStore;
 import android.support.v7.app.AlertDialog;
 import android.app.Fragment;
@@ -107,7 +110,7 @@ import static eu.siacs.conversations.ui.XmppActivity.REQUEST_ANNOUNCE_PGP;
 import static eu.siacs.conversations.ui.XmppActivity.REQUEST_CHOOSE_PGP_ID;
 
 
-public class ConversationFragment extends Fragment implements EditMessage.KeyboardListener {
+public class ConversationFragment extends XmppFragment implements EditMessage.KeyboardListener {
 
 
 	public static final int REQUEST_SEND_MESSAGE = 0x0201;
@@ -139,7 +142,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 	private ActivityResult postponedActivityResult = null;
 	public Uri mPendingEditorContent = null;
 
-	private ConversationActivity activity;
+	private ConversationsMainActivity activity;
 
 	private OnClickListener clickToMuc = new OnClickListener() {
 
@@ -155,7 +158,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 
 		@Override
 		public void onClick(View v) {
-			activity.endConversation(conversation);
+			activity.onConversationArchived(conversation);
 		}
 	};
 	private OnClickListener joinMuc = new OnClickListener() {
@@ -683,7 +686,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 						attachFileToConversation(conversation, i.next());
 					}
 				};
-				if (conversation == null || conversation.getMode() == Conversation.MODE_MULTI || FileBackend.allFilesUnderSize(getActivity(), fileUris, activity.getMaxHttpUploadSize(conversation))) {
+				if (conversation == null || conversation.getMode() == Conversation.MODE_MULTI || FileBackend.allFilesUnderSize(getActivity(), fileUris, getMaxHttpUploadSize(conversation))) {
 					callback.onPresenceSelected();
 				} else {
 					activity.selectPresence(conversation, callback);
@@ -724,8 +727,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 
 	@Override
 	public void onAttach(Context context) {
-		if (context instanceof ConversationActivity) {
-			this.activity = (ConversationActivity) context;
+		Log.d(Config.LOGTAG,"onAttach()");
+		if (context instanceof ConversationsMainActivity) {
+			this.activity = (ConversationsMainActivity) context;
 		} else {
 			throw new IllegalStateException("Trying to attach fragment to activity that is not the ConversationActivity");
 		}
@@ -784,7 +788,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 
 		binding.messagesView.setOnScrollListener(mOnScrollListener);
 		binding.messagesView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
-		messageListAdapter = new MessageAdapter((ConversationActivity) getActivity(), this.messageList);
+		messageListAdapter = new MessageAdapter((XmppActivity) getActivity(), this.messageList);
 		messageListAdapter.setOnContactPictureClicked(message -> {
 			final boolean received = message.getStatus() <= Message.STATUS_RECEIVED;
 			if (received) {
@@ -1031,7 +1035,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 				handleAttachmentSelection(item);
 				break;
 			case R.id.action_archive:
-				activity.endConversation(conversation);
+				activity.onConversationArchived(conversation);
 				break;
 			case R.id.action_contact_details:
 				activity.switchToContactDetails(conversation.getContact());
@@ -1094,7 +1098,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 		if (conversation == null) {
 			return;
 		}
-		final ConversationFragment fragment = (ConversationFragment) getFragmentManager().findFragmentByTag("conversation");
 		switch (item.getItemId()) {
 			case R.id.encryption_choice_none:
 				conversation.setNextEncryption(Message.ENCRYPTION_NONE);
@@ -1123,7 +1126,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 				break;
 		}
 		activity.xmppConnectionService.updateConversation(conversation);
-		fragment.updateChatMsgHint();
+		updateChatMsgHint();
 		getActivity().invalidateOptionsMenu();
 		activity.refreshUi();
 	}
@@ -1152,7 +1155,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 
 								@Override
 								public void userInputRequried(PendingIntent pi, Contact contact) {
-									activity.runIntent(pi, attachmentChoice);
+									startPendingIntent(pi, attachmentChoice);
 								}
 
 								@Override
@@ -1239,9 +1242,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 		builder.setPositiveButton(getString(R.string.delete_messages), (dialog, which) -> {
 			this.activity.xmppConnectionService.clearConversationHistory(conversation);
 			if (endConversationCheckBox.isChecked()) {
-				this.activity.endConversation(conversation);
+				this.activity.onConversationArchived(conversation);
 			} else {
-				activity.updateConversationList();
+				activity.onConversationsListItemUpdated();
 				updateMessages();
 			}
 		});
@@ -1261,7 +1264,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 			}
 			conversation.setMutedTill(till);
 			activity.xmppConnectionService.updateConversation(conversation);
-			activity.updateConversationList();
+			activity.onConversationsListItemUpdated();
 			updateMessages();
 			getActivity().invalidateOptionsMenu();
 		});
@@ -1271,7 +1274,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 	public void unmuteConversation(final Conversation conversation) {
 		conversation.setMutedTill(0);
 		this.activity.xmppConnectionService.updateConversation(conversation);
-		this.activity.updateConversationList();
+		this.activity.onConversationsListItemUpdated();
 		updateMessages();
 		getActivity().invalidateOptionsMenu();
 	}
@@ -1296,6 +1299,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 					break;
 				case ATTACHMENT_CHOICE_TAKE_PHOTO:
 					Uri uri = activity.xmppConnectionService.getFileBackend().getTakePhotoUri();
+					//TODO save photo uri
 					//mPendingImageUris.clear();
 					//mPendingImageUris.add(uri);
 					intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
@@ -1408,7 +1412,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 	private void deleteFile(Message message) {
 		if (activity.xmppConnectionService.getFileBackend().deleteFile(message)) {
 			message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED));
-			activity.updateConversationList();
+			activity.onConversationsListItemUpdated();
 			updateMessages();
 		}
 	}
@@ -1431,7 +1435,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 			} else {
 				Toast.makeText(activity, R.string.file_deleted, Toast.LENGTH_SHORT).show();
 				message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED));
-				activity.updateConversationList();
+				activity.onConversationsListItemUpdated();
 				updateMessages();
 				return;
 			}
@@ -1472,7 +1476,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 
 	private void retryDecryption(Message message) {
 		message.setEncryption(Message.ENCRYPTION_PGP);
-		activity.updateConversationList();
+		activity.onConversationsListItemUpdated();
 		updateMessages();
 		conversation.getAccount().getPgpDecryptionService().decrypt(message, false);
 	}
@@ -1526,6 +1530,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 		}
 	}
 
+	@Override
+	public void onStart() {
+		super.onStart();
+		reInit(conversation);
+	}
+
 	@Override
 	public void onStop() {
 		super.onStop();
@@ -1551,9 +1561,17 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 	}
 
 	public boolean reInit(Conversation conversation) {
+		Log.d(Config.LOGTAG,"reInit()");
 		if (conversation == null) {
 			return false;
 		}
+
+		if (this.activity == null) {
+			Log.d(Config.LOGTAG,"activity was null");
+			this.conversation = conversation;
+			return false;
+		}
+
 		setupIme();
 		if (this.conversation != null) {
 			final String msg = this.binding.textinput.getText().toString();
@@ -1692,15 +1710,14 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 			if (getView() == null) {
 				return;
 			}
-			final ConversationActivity activity = (ConversationActivity) getActivity();
 			if (this.conversation != null) {
 				conversation.populateWithMessages(ConversationFragment.this.messageList);
 				updateSnackBar(conversation);
 				updateStatusMessages();
 				this.messageListAdapter.notifyDataSetChanged();
 				updateChatMsgHint();
-				if (!activity.isConversationsOverviewVisable() || !activity.isConversationsOverviewHideable()) {
-					activity.sendReadMarkerIfNecessary(conversation);
+				if (activity != null) {
+					activity.onConversationRead(this.conversation);
 				}
 				updateSendButton();
 				updateEditablity();
@@ -1733,6 +1750,10 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 		mSendingPgpMessage.set(false);
 	}
 
+	public long getMaxHttpUploadSize(Conversation conversation) {
+		final XmppConnection connection = conversation.getAccount().getXmppConnection();
+		return connection == null ? -1 : connection.getFeatures().getMaxHttpUploadSize();
+	}
 
 	private void updateEditablity() {
 		boolean canWrite = this.conversation.getMode() == Conversation.MODE_SINGLE || this.conversation.getMucOptions().participating() || this.conversation.getNextCounterpart() != null;
@@ -1743,11 +1764,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 	}
 
 	public void updateSendButton() {
+		boolean useSendButtonToIndicateStatus = PreferenceManager.getDefaultSharedPreferences(getActivity()).getBoolean("send_button_status", getResources().getBoolean(R.bool.send_button_status));
 		final Conversation c = this.conversation;
 		final Presence.Status status;
 		final String text = this.binding.textinput == null ? "" : this.binding.textinput.getText().toString();
 		final SendButtonAction action = SendButtonTool.getAction(getActivity(),c,text);
-		if (activity.useSendButtonToIndicateStatus() && c.getAccount().getStatus() == Account.State.ONLINE) {
+		if (useSendButtonToIndicateStatus && c.getAccount().getStatus() == Account.State.ONLINE) {
 			if (activity.xmppConnectionService != null && activity.xmppConnectionService.getMessageArchiveService().isCatchingUp(c)) {
 				status = Presence.Status.OFFLINE;
 			} else if (c.getMode() == Conversation.MODE_SINGLE) {
@@ -1913,13 +1935,11 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 	}
 
 	protected void sendPlainTextMessage(Message message) {
-		ConversationActivity activity = (ConversationActivity) getActivity();
 		activity.xmppConnectionService.sendMessage(message);
 		messageSent();
 	}
 
 	protected void sendPgpMessage(final Message message) {
-		final ConversationActivity activity = (ConversationActivity) getActivity();
 		final XmppConnectionService xmppService = activity.xmppConnectionService;
 		final Contact contact = message.getConversation().getContact();
 		if (!activity.hasPgp()) {
@@ -1940,7 +1960,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 
 							@Override
 							public void userInputRequried(PendingIntent pi,Contact contact) {
-								activity.runIntent(pi,REQUEST_ENCRYPT_MESSAGE);
+								startPendingIntent(pi,REQUEST_ENCRYPT_MESSAGE);
 							}
 
 							@Override
@@ -1996,7 +2016,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 
 					@Override
 					public void userInputRequried(PendingIntent pi, Message message) {
-						activity.runIntent(pi, REQUEST_SEND_MESSAGE);
+						startPendingIntent(pi, REQUEST_SEND_MESSAGE);
 					}
 
 					@Override
@@ -2033,9 +2053,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 	}
 
 	protected void sendAxolotlMessage(final Message message) {
-		final ConversationActivity activity = (ConversationActivity) getActivity();
-		final XmppConnectionService xmppService = activity.xmppConnectionService;
-		xmppService.sendMessage(message);
+		activity.xmppConnectionService.sendMessage(message);
 		messageSent();
 	}
 
@@ -2052,7 +2070,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 
 	@Override
 	public boolean onEnterPressed() {
-		if (activity.enterIsSend()) {
+		SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(getActivity());
+		final boolean enterIsSend = p.getBoolean("enter_is_send", getResources().getBoolean(R.bool.enter_is_send));
+		if (enterIsSend) {
 			sendMessage();
 			return true;
 		} else {
@@ -2066,7 +2086,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 		if (status == Account.State.ONLINE && conversation.setOutgoingChatState(ChatState.COMPOSING)) {
 			activity.xmppConnectionService.sendChatState(conversation);
 		}
-		activity.hideConversationsOverview();
 		updateSendButton();
 	}
 
@@ -2131,6 +2150,14 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 		return true;
 	}
 
+	private void startPendingIntent(PendingIntent pendingIntent, int requestCode) {
+		try {
+			getActivity().startIntentSenderForResult(pendingIntent.getIntentSender(), requestCode,null, 0, 0, 0);
+		} catch (final SendIntentException ignored) {
+		}
+	}
+
+	@Override
 	public void onBackendConnected() {
 		if (postponedActivityResult != null) {
 			handleActivityResult(postponedActivityResult);

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

@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2018, Daniel Gultsch All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package eu.siacs.conversations.ui;
+
+
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.databinding.DataBindingUtil;
+import android.os.Bundle;
+import android.support.annotation.IdRes;
+import android.util.Log;
+
+import eu.siacs.conversations.Config;
+import eu.siacs.conversations.R;
+import eu.siacs.conversations.databinding.ActivityConversationsBinding;
+import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.ui.interfaces.OnConversationArchived;
+import eu.siacs.conversations.ui.interfaces.OnConversationRead;
+import eu.siacs.conversations.ui.interfaces.OnConversationSelected;
+import eu.siacs.conversations.ui.interfaces.OnConversationsListItemUpdated;
+import eu.siacs.conversations.ui.service.EmojiService;
+
+public class ConversationsMainActivity extends XmppActivity implements OnConversationSelected, OnConversationArchived, OnConversationsListItemUpdated, OnConversationRead {
+
+	private ActivityConversationsBinding binding;
+
+	@Override
+	protected void refreshUiReal() {
+
+	}
+
+	@Override
+	void onBackendConnected() {
+		notifyFragment(R.id.main_fragment);
+		notifyFragment(R.id.secondary_fragment);
+	}
+
+	private void notifyFragment(@IdRes int id) {
+		Fragment mainFragment = getFragmentManager().findFragmentById(id);
+		if (mainFragment != null && mainFragment instanceof XmppFragment) {
+			((XmppFragment) mainFragment).onBackendConnected();
+		}
+	}
+
+	@Override
+	protected void onCreate(final Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		new EmojiService(this).init();
+		this.binding = DataBindingUtil.setContentView(this,R.layout.activity_conversations);
+		this.initializeFragments();
+	}
+
+	@Override
+	public void onConversationSelected(Conversation conversation) {
+		Log.d(Config.LOGTAG,"selected "+conversation.getName());
+		ConversationFragment conversationFragment = (ConversationFragment) getFragmentManager().findFragmentById(R.id.secondary_fragment);
+		if (conversationFragment == null) {
+			conversationFragment = new ConversationFragment();
+			FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
+			fragmentTransaction.replace(R.id.main_fragment,conversationFragment);
+			fragmentTransaction.commit();
+		}
+		conversationFragment.reInit(conversation);
+	}
+
+	private void initializeFragments() {
+		FragmentTransaction transaction = getFragmentManager().beginTransaction();
+		transaction.replace(R.id.main_fragment, new ConversationsOverviewFragment());
+		if (binding.secondaryFragment != null) {
+			transaction.replace(R.id.secondary_fragment, new ConversationFragment());
+		}
+		transaction.commit();
+	}
+
+	@Override
+	public void onConversationArchived(Conversation conversation) {
+
+	}
+
+	@Override
+	public void onConversationsListItemUpdated() {
+
+	}
+
+	@Override
+	public void onConversationRead(Conversation conversation) {
+		Log.d(Config.LOGTAG,"read event for "+conversation.getName()+" received");
+	}
+}

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

@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2018, Daniel Gultsch All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package eu.siacs.conversations.ui;
+
+import android.content.Context;
+import android.databinding.DataBindingUtil;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.timroes.android.listview.EnhancedListView;
+import eu.siacs.conversations.Config;
+import eu.siacs.conversations.R;
+import eu.siacs.conversations.databinding.FragmentConversationsOverviewBinding;
+import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.ui.adapter.ConversationAdapter;
+import eu.siacs.conversations.ui.interfaces.OnConversationSelected;
+
+public class ConversationsOverviewFragment extends XmppFragment {
+
+	private FragmentConversationsOverviewBinding binding;
+
+	private final List<Conversation> conversations = new ArrayList<>();
+	private ConversationAdapter conversationsAdapter;
+	private ConversationsMainActivity activity;
+
+	@Override
+	public void onAttach(Context context) {
+		if (context instanceof ConversationsMainActivity) {
+			this.activity = (ConversationsMainActivity) context;
+		} else {
+			throw new IllegalStateException("Trying to attach fragment to activity that is not the ConversationActivity");
+		}
+		super.onAttach(context);
+	}
+
+	@Override
+	public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+		this.binding = DataBindingUtil.inflate(inflater, R.layout.fragment_conversations_overview, container, false);
+		this.binding.fab.setOnClickListener((view)-> StartConversationActivity.launch(getActivity()));
+
+		this.conversationsAdapter = new ConversationAdapter(this.activity, this.conversations);
+		this.binding.list.setAdapter(this.conversationsAdapter);
+		this.binding.list.setSwipeDirection(EnhancedListView.SwipeDirection.BOTH);
+		this.binding.list.setOnItemClickListener((parent, view, position, id) -> {
+			Conversation conversation = this.conversations.get(position);
+			if (activity instanceof OnConversationSelected) {
+				((OnConversationSelected) activity).onConversationSelected(conversation);
+			} else {
+				Log.w(ConversationsOverviewFragment.class.getCanonicalName(),"Activity does not implement OnConversationSelected");
+			}
+		});
+
+		return binding.getRoot();
+	}
+
+	@Override
+	void onBackendConnected() {
+		Log.d(Config.LOGTAG,"nice!");
+		this.activity.xmppConnectionService.populateWithOrderedConversations(this.conversations);
+		this.conversationsAdapter.notifyDataSetChanged();
+	}
+}

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

@@ -943,6 +943,11 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
         invalidateOptionsMenu();
     }
 
+    public static void launch(Context context) {
+        final Intent intent = new Intent(context,StartConversationActivity.class);
+        context.startActivity(intent);
+    }
+
     @Override
     public void OnUpdateBlocklist(final Status status) {
         refreshUi();

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

@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, Daniel Gultsch All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package eu.siacs.conversations.ui;
+
+import android.app.Fragment;
+
+public abstract class XmppFragment extends Fragment {
+
+	abstract void onBackendConnected();
+}

src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java 🔗

@@ -2,6 +2,7 @@ package eu.siacs.conversations.ui.adapter;
 
 import android.content.ActivityNotFoundException;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
@@ -12,6 +13,7 @@ import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.AsyncTask;
+import android.preference.PreferenceManager;
 import android.support.annotation.ColorInt;
 import android.support.v4.content.ContextCompat;
 import android.text.Spannable;
@@ -62,6 +64,8 @@ import eu.siacs.conversations.persistance.FileBackend;
 import eu.siacs.conversations.services.MessageArchiveService;
 import eu.siacs.conversations.services.NotificationService;
 import eu.siacs.conversations.ui.ConversationActivity;
+import eu.siacs.conversations.ui.ConversationsMainActivity;
+import eu.siacs.conversations.ui.XmppActivity;
 import eu.siacs.conversations.ui.service.AudioPlayer;
 import eu.siacs.conversations.ui.text.DividerSpan;
 import eu.siacs.conversations.ui.text.FixedURLSpan;
@@ -123,7 +127,7 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 		}
 	};
 
-	private final ConversationActivity activity;
+	private final XmppActivity activity;
 
 	private DisplayMetrics metrics;
 
@@ -139,7 +143,7 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 
 	private final AudioPlayer audioPlayer;
 
-	public MessageAdapter(ConversationActivity activity, List<Message> messages) {
+	public MessageAdapter(XmppActivity activity, List<Message> messages) {
 		super(activity, 0, messages);
 		this.audioPlayer = new AudioPlayer(this);
 		this.activity = activity;
@@ -1003,8 +1007,9 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 	}
 
 	public void updatePreferences() {
-		this.mIndicateReceived = activity.indicateReceived();
-		this.mUseGreenBackground = activity.useGreenBackground();
+		SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(activity);
+		this.mIndicateReceived = p.getBoolean("indicate_received", activity.getResources().getBoolean(R.bool.indicate_received));
+		this.mUseGreenBackground = p.getBoolean("use_green_background", activity.getResources().getBoolean(R.bool.use_green_background));
 	}
 
 	public TextView getMessageBody(View view) {

src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationArchived.java 🔗

@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018, Daniel Gultsch All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package eu.siacs.conversations.ui.interfaces;
+
+import eu.siacs.conversations.entities.Conversation;
+
+public interface OnConversationArchived {
+	void onConversationArchived(Conversation conversation);
+}

src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationRead.java 🔗

@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018, Daniel Gultsch All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package eu.siacs.conversations.ui.interfaces;
+
+import eu.siacs.conversations.entities.Conversation;
+
+public interface OnConversationRead {
+	void onConversationRead(Conversation conversation);
+}

src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationSelected.java 🔗

@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, Daniel Gultsch All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package eu.siacs.conversations.ui.interfaces;
+
+
+import eu.siacs.conversations.entities.Conversation;
+
+public interface OnConversationSelected {
+	void onConversationSelected(Conversation conversation);
+}

src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationsListItemUpdated.java 🔗

@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018, Daniel Gultsch All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package eu.siacs.conversations.ui.interfaces;
+
+public interface OnConversationsListItemUpdated {
+	void onConversationsListItemUpdated();
+}

src/main/res/layout-w945dp/activity_conversations.xml 🔗

@@ -0,0 +1,22 @@
+<layout xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="horizontal">
+
+        <FrameLayout
+            android:id="@+id/main_fragment"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"/>
+
+        <FrameLayout
+            android:id="@+id/secondary_fragment"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="2"/>
+
+    </LinearLayout>
+
+</layout>

src/main/res/layout-w945dp/fragment_conversations_overview.xml 🔗

@@ -1,32 +0,0 @@
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/content_view_ll"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="horizontal"
-    android:baselineAligned="false">
-
-    <LinearLayout
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:background="?attr/color_background_primary"
-        android:orientation="vertical" >
-
-        <de.timroes.android.listview.EnhancedListView
-            android:id="@+id/list"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:background="?attr/color_background_primary"
-            android:divider="@color/black12"
-            android:dividerHeight="1dp" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:id="@+id/selected_conversation"
-        android:layout_width="0dp"
-        android:layout_weight="2"
-        android:layout_height="match_parent"
-        android:orientation="vertical" >
-    </LinearLayout>
-
-</LinearLayout>

src/main/res/layout/activity_conversations.xml 🔗

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (c) 2018, Daniel Gultsch All rights reserved.
+  ~
+  ~ Redistribution and use in source and binary forms, with or without modification,
+  ~ are permitted provided that the following conditions are met:
+  ~
+  ~ 1. Redistributions of source code must retain the above copyright notice, this
+  ~ list of conditions and the following disclaimer.
+  ~
+  ~ 2. Redistributions in binary form must reproduce the above copyright notice,
+  ~ this list of conditions and the following disclaimer in the documentation and/or
+  ~ other materials provided with the distribution.
+  ~
+  ~ 3. Neither the name of the copyright holder nor the names of its contributors
+  ~ may be used to endorse or promote products derived from this software without
+  ~ specific prior written permission.
+  ~
+  ~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ~ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  ~ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  ~ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+  ~ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+  ~ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  ~ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+  ~ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  ~ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  ~ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  -->
+<layout xmlns:android="http://schemas.android.com/apk/res/android">
+<FrameLayout
+    android:id="@+id/main_fragment"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"/>
+</layout>

src/main/res/layout/fragment_conversations_overview.xml 🔗

@@ -1,15 +1,9 @@
-<android.support.v4.widget.SlidingPaneLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/content_view_spl"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent" >
+<layout xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <LinearLayout
-        xmlns:android="http://schemas.android.com/apk/res/android"
+    <FrameLayout
         android:layout_width="match_parent"
-        android:layout_marginRight="@dimen/swipe_handle_size"
-        android:layout_height="match_parent"
-        android:background="?attr/color_background_primary"
-        android:orientation="vertical" >
+        android:layout_height="match_parent">
+
 
         <de.timroes.android.listview.EnhancedListView
             android:id="@+id/list"
@@ -17,15 +11,14 @@
             android:layout_height="wrap_content"
             android:background="?attr/color_background_primary"
             android:divider="@color/black12"
-            android:dividerHeight="1dp" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:id="@+id/selected_conversation"
-        android:layout_width="fill_parent"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:orientation="vertical" >
-    </LinearLayout>
+            android:dividerHeight="1dp"/>
 
-</android.support.v4.widget.SlidingPaneLayout>
+        <android.support.design.widget.FloatingActionButton
+            android:id="@+id/fab"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="end|bottom"
+            android:layout_margin="16dp"
+            android:src="?attr/icon_new"/>
+    </FrameLayout>
+</layout>