ConversationsMainActivity.java

  1/*
  2 * Copyright (c) 2018, Daniel Gultsch All rights reserved.
  3 *
  4 * Redistribution and use in source and binary forms, with or without modification,
  5 * are permitted provided that the following conditions are met:
  6 *
  7 * 1. Redistributions of source code must retain the above copyright notice, this
  8 * list of conditions and the following disclaimer.
  9 *
 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
 11 * this list of conditions and the following disclaimer in the documentation and/or
 12 * other materials provided with the distribution.
 13 *
 14 * 3. Neither the name of the copyright holder nor the names of its contributors
 15 * may be used to endorse or promote products derived from this software without
 16 * specific prior written permission.
 17 *
 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28 */
 29
 30package eu.siacs.conversations.ui;
 31
 32
 33import android.app.Fragment;
 34import android.app.FragmentManager;
 35import android.app.FragmentTransaction;
 36import android.databinding.DataBindingUtil;
 37import android.os.Bundle;
 38import android.support.annotation.IdRes;
 39import android.support.v7.app.ActionBar;
 40import android.util.Log;
 41import android.view.Menu;
 42import android.view.MenuItem;
 43
 44import eu.siacs.conversations.Config;
 45import eu.siacs.conversations.R;
 46import eu.siacs.conversations.databinding.ActivityConversationsBinding;
 47import eu.siacs.conversations.entities.Conversation;
 48import eu.siacs.conversations.ui.interfaces.OnConversationArchived;
 49import eu.siacs.conversations.ui.interfaces.OnConversationRead;
 50import eu.siacs.conversations.ui.interfaces.OnConversationSelected;
 51import eu.siacs.conversations.ui.interfaces.OnConversationsListItemUpdated;
 52import eu.siacs.conversations.ui.service.EmojiService;
 53
 54public class ConversationsMainActivity extends XmppActivity implements OnConversationSelected, OnConversationArchived, OnConversationsListItemUpdated, OnConversationRead {
 55
 56
 57	//secondary fragment (when holding the conversation, must be initialized before refreshing the overview fragment
 58	private static final @IdRes int[] FRAGMENT_ID_NOTIFICATION_ORDER = {R.id.secondary_fragment, R.id.main_fragment};
 59
 60	private ActivityConversationsBinding binding;
 61
 62	@Override
 63	protected void refreshUiReal() {
 64		for(@IdRes int id : FRAGMENT_ID_NOTIFICATION_ORDER) {
 65			refreshFragment(id);
 66		}
 67	}
 68
 69	@Override
 70	void onBackendConnected() {
 71		for(@IdRes int id : FRAGMENT_ID_NOTIFICATION_ORDER) {
 72			notifyFragmentOfBackendConnected(id);
 73		}
 74		invalidateActionBarTitle();
 75	}
 76
 77	private void notifyFragmentOfBackendConnected(@IdRes int id) {
 78		final Fragment fragment = getFragmentManager().findFragmentById(id);
 79		if (fragment != null && fragment instanceof XmppFragment) {
 80			((XmppFragment) fragment).onBackendConnected();
 81		}
 82	}
 83
 84	private void refreshFragment(@IdRes int id) {
 85		final Fragment fragment = getFragmentManager().findFragmentById(id);
 86		if (fragment != null && fragment instanceof XmppFragment) {
 87			((XmppFragment) fragment).refresh();
 88		}
 89	}
 90
 91	@Override
 92	protected void onCreate(final Bundle savedInstanceState) {
 93		super.onCreate(savedInstanceState);
 94		new EmojiService(this).init();
 95		this.binding = DataBindingUtil.setContentView(this, R.layout.activity_conversations);
 96		this.getFragmentManager().addOnBackStackChangedListener(this::invalidateActionBarTitle);
 97		this.initializeFragments();
 98		this.invalidateActionBarTitle();
 99	}
100
101	@Override
102	public boolean onCreateOptionsMenu(Menu menu) {
103		getMenuInflater().inflate(R.menu.activity_conversations, menu);
104		return super.onCreateOptionsMenu(menu);
105	}
106
107	@Override
108	public void onConversationSelected(Conversation conversation) {
109		Log.d(Config.LOGTAG, "selected " + conversation.getName());
110		ConversationFragment conversationFragment = (ConversationFragment) getFragmentManager().findFragmentById(R.id.secondary_fragment);
111		final boolean mainNeedsRefresh;
112		if (conversationFragment == null) {
113			mainNeedsRefresh = false;
114			conversationFragment = new ConversationFragment();
115			FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
116			fragmentTransaction.replace(R.id.main_fragment, conversationFragment);
117			fragmentTransaction.addToBackStack(null);
118			fragmentTransaction.commit();
119		} else {
120			mainNeedsRefresh = true;
121		}
122		conversationFragment.reInit(conversation);
123		if (mainNeedsRefresh) {
124			refreshFragment(R.id.main_fragment);
125		}
126	}
127
128	@Override
129	public boolean onOptionsItemSelected(MenuItem item) {
130		switch (item.getItemId()) {
131			case android.R.id.home:
132				FragmentManager fm = getFragmentManager();
133				if (fm.getBackStackEntryCount() > 0) {
134					fm.popBackStack();
135					return true;
136				}
137				break;
138		}
139		return super.onOptionsItemSelected(item);
140	}
141
142	private void initializeFragments() {
143		FragmentTransaction transaction = getFragmentManager().beginTransaction();
144		Fragment mainFragment = getFragmentManager().findFragmentById(R.id.main_fragment);
145		Fragment secondaryFragment = getFragmentManager().findFragmentById(R.id.secondary_fragment);
146		if (mainFragment != null) {
147			Log.d(Config.LOGTAG,"initializeFragment(). main fragment exists");
148			if (binding.secondaryFragment != null) {
149				if (mainFragment instanceof ConversationFragment) {
150					Log.d(Config.LOGTAG,"gained secondary fragment. moving...");
151					getFragmentManager().popBackStack();
152					transaction.remove(mainFragment);
153					transaction.commit();
154					getFragmentManager().executePendingTransactions();
155					transaction = getFragmentManager().beginTransaction();
156					transaction.replace(R.id.secondary_fragment, mainFragment);
157					transaction.replace(R.id.main_fragment, new ConversationsOverviewFragment());
158					transaction.commit();
159					return;
160				}
161			} else {
162				if (secondaryFragment != null && secondaryFragment instanceof ConversationFragment) {
163					Log.d(Config.LOGTAG,"lost secondary fragment. moving...");
164					transaction.remove(secondaryFragment);
165					transaction.commit();
166					getFragmentManager().executePendingTransactions();
167					transaction = getFragmentManager().beginTransaction();
168					transaction.replace(R.id.main_fragment, secondaryFragment);
169					transaction.addToBackStack(null);
170					transaction.commit();
171					return;
172				}
173			}
174		} else {
175			transaction.replace(R.id.main_fragment, new ConversationsOverviewFragment());
176		}
177
178		//TODO, do this in backendConnected so we can actually decide what to display
179		if (binding.secondaryFragment != null) {
180			transaction.replace(R.id.secondary_fragment, new ConversationFragment());
181		}
182		transaction.commit();
183	}
184
185	private void invalidateActionBarTitle() {
186		final ActionBar actionBar = getSupportActionBar();
187		if (actionBar != null) {
188			Fragment mainFragment = getFragmentManager().findFragmentById(R.id.main_fragment);
189			if (mainFragment != null && mainFragment instanceof ConversationFragment) {
190				final Conversation conversation = ((ConversationFragment) mainFragment).getConversation();
191				if (conversation != null) {
192					actionBar.setTitle(conversation.getName());
193					actionBar.setDisplayHomeAsUpEnabled(true);
194					return;
195				}
196			}
197			actionBar.setTitle(R.string.app_name);
198			actionBar.setDisplayHomeAsUpEnabled(false);
199		}
200	}
201
202	@Override
203	public void onConversationArchived(Conversation conversation) {
204
205	}
206
207	@Override
208	public void onConversationsListItemUpdated() {
209		Fragment fragment = getFragmentManager().findFragmentById(R.id.main_fragment);
210		if (fragment != null && fragment instanceof ConversationsOverviewFragment) {
211			((ConversationsOverviewFragment) fragment).refresh();
212		}
213	}
214
215	@Override
216	public void onConversationRead(Conversation conversation) {
217		Log.d(Config.LOGTAG, "read event for " + conversation.getName() + " received");
218	}
219}