From dd21f5d072b972e4e173b65a4d00ab465d3eaa8f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 21 Feb 2018 15:46:56 +0100 Subject: [PATCH] wip --- src/main/AndroidManifest.xml | 2 +- .../ui/ConversationActivity.java | 36 +----- .../ui/ConversationFragment.java | 89 +++++++++----- .../ui/ConversationsMainActivity.java | 116 ++++++++++++++++++ .../ui/ConversationsOverviewFragment.java | 96 +++++++++++++++ .../ui/StartConversationActivity.java | 5 + .../siacs/conversations/ui/XmppFragment.java | 37 ++++++ .../ui/adapter/MessageAdapter.java | 13 +- .../ui/interfaces/OnConversationArchived.java | 36 ++++++ .../ui/interfaces/OnConversationRead.java | 36 ++++++ .../ui/interfaces/OnConversationSelected.java | 37 ++++++ .../OnConversationsListItemUpdated.java | 34 +++++ .../layout-w945dp/activity_conversations.xml | 22 ++++ .../fragment_conversations_overview.xml | 32 ----- .../res/layout/activity_conversations.xml | 35 ++++++ .../fragment_conversations_overview.xml | 35 +++--- 16 files changed, 539 insertions(+), 122 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/ui/ConversationsMainActivity.java create mode 100644 src/main/java/eu/siacs/conversations/ui/ConversationsOverviewFragment.java create mode 100644 src/main/java/eu/siacs/conversations/ui/XmppFragment.java create mode 100644 src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationArchived.java create mode 100644 src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationRead.java create mode 100644 src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationSelected.java create mode 100644 src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationsListItemUpdated.java create mode 100644 src/main/res/layout-w945dp/activity_conversations.xml delete mode 100644 src/main/res/layout-w945dp/fragment_conversations_overview.xml create mode 100644 src/main/res/layout/activity_conversations.xml diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index d98c7a489..f55380dd1 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -44,7 +44,7 @@ Toast.makeText(ConversationActivity.this, resId, Toast.LENGTH_SHORT).show()); diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 548a76b4e..48a3ee8b9 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/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); diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationsMainActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationsMainActivity.java new file mode 100644 index 000000000..c6caf8385 --- /dev/null +++ b/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"); + } +} diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationsOverviewFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationsOverviewFragment.java new file mode 100644 index 000000000..cee9710bd --- /dev/null +++ b/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 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(); + } +} diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java index 2d5809691..1be1ae019 100644 --- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/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(); diff --git a/src/main/java/eu/siacs/conversations/ui/XmppFragment.java b/src/main/java/eu/siacs/conversations/ui/XmppFragment.java new file mode 100644 index 000000000..dca18050c --- /dev/null +++ b/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(); +} diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index a01ef856b..ffe3b78b1 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/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 implements CopyTextVie } }; - private final ConversationActivity activity; + private final XmppActivity activity; private DisplayMetrics metrics; @@ -139,7 +143,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie private final AudioPlayer audioPlayer; - public MessageAdapter(ConversationActivity activity, List messages) { + public MessageAdapter(XmppActivity activity, List messages) { super(activity, 0, messages); this.audioPlayer = new AudioPlayer(this); this.activity = activity; @@ -1003,8 +1007,9 @@ public class MessageAdapter extends ArrayAdapter 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) { diff --git a/src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationArchived.java b/src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationArchived.java new file mode 100644 index 000000000..be7f66604 --- /dev/null +++ b/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); +} diff --git a/src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationRead.java b/src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationRead.java new file mode 100644 index 000000000..c82b4ca1d --- /dev/null +++ b/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); +} diff --git a/src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationSelected.java b/src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationSelected.java new file mode 100644 index 000000000..9a32d3eb6 --- /dev/null +++ b/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); +} diff --git a/src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationsListItemUpdated.java b/src/main/java/eu/siacs/conversations/ui/interfaces/OnConversationsListItemUpdated.java new file mode 100644 index 000000000..096a7d486 --- /dev/null +++ b/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(); +} diff --git a/src/main/res/layout-w945dp/activity_conversations.xml b/src/main/res/layout-w945dp/activity_conversations.xml new file mode 100644 index 000000000..8cf9d2d09 --- /dev/null +++ b/src/main/res/layout-w945dp/activity_conversations.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/res/layout-w945dp/fragment_conversations_overview.xml b/src/main/res/layout-w945dp/fragment_conversations_overview.xml deleted file mode 100644 index 63eb0e57c..000000000 --- a/src/main/res/layout-w945dp/fragment_conversations_overview.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/res/layout/activity_conversations.xml b/src/main/res/layout/activity_conversations.xml new file mode 100644 index 000000000..3a20e0ad2 --- /dev/null +++ b/src/main/res/layout/activity_conversations.xml @@ -0,0 +1,35 @@ + + + + + \ No newline at end of file diff --git a/src/main/res/layout/fragment_conversations_overview.xml b/src/main/res/layout/fragment_conversations_overview.xml index 5c5616630..d88eb8266 100644 --- a/src/main/res/layout/fragment_conversations_overview.xml +++ b/src/main/res/layout/fragment_conversations_overview.xml @@ -1,15 +1,9 @@ - + - + android:layout_height="match_parent"> + - + android:dividerHeight="1dp"/> - - - - \ No newline at end of file + + + \ No newline at end of file