/**
* Wire
* Copyright (C) 2016 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.waz.zclient.pages.main.connect;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import com.waz.api.ConversationsList;
import com.waz.api.ErrorsList;
import com.waz.api.IConversation;
import com.waz.api.Message;
import com.waz.api.SyncState;
import com.waz.api.User;
import com.waz.zclient.R;
import com.waz.zclient.controllers.accentcolor.AccentColorObserver;
import com.waz.zclient.core.stores.connect.InboxLinkConversation;
import com.waz.zclient.core.stores.conversation.ConversationChangeRequester;
import com.waz.zclient.core.stores.conversation.ConversationStoreObserver;
import com.waz.zclient.core.stores.conversation.InboxLoadRequester;
import com.waz.zclient.core.stores.conversation.OnInboxLoadedListener;
import com.waz.zclient.core.stores.inappnotification.InAppNotificationStoreObserver;
import com.waz.zclient.core.stores.inappnotification.KnockingEvent;
import com.waz.zclient.pages.BaseFragment;
import com.waz.zclient.pages.main.connect.views.ConnectRequestInboxListView;
import com.waz.zclient.utils.LayoutSpec;
import com.waz.zclient.utils.ViewUtils;
import java.util.List;
public class ConnectRequestInboxFragment extends BaseFragment<ConnectRequestInboxFragment.Container> implements ConversationStoreObserver,
OnInboxLoadedListener,
AccentColorObserver,
InAppNotificationStoreObserver {
public static final String TAG = ConnectRequestInboxFragment.class.getName();
public static final String ARGUMENT_CONVERSATION_ID = "ARGUMENT_CONVERSATION_ID";
public static final String NO_ARGUMENT_PROVIDED_CONVERSATION_ID = "";
private ConnectRequestInboxAdapter inboxAdapter;
private String visibleConversationId = NO_ARGUMENT_PROVIDED_CONVERSATION_ID;
private ConnectRequestInboxListView inboxListView;
private Handler mainHandler;
public static ConnectRequestInboxFragment newInstance(String conversationId) {
ConnectRequestInboxFragment newFragment = new ConnectRequestInboxFragment();
Bundle args = new Bundle();
args.putString(ARGUMENT_CONVERSATION_ID, conversationId);
newFragment.setArguments(args);
return newFragment;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// Lifecycle
//
//////////////////////////////////////////////////////////////////////////////////////////
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainHandler = new Handler();
}
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup viewContainer, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_connect_request_inbox, viewContainer, false);
ConnectActionsCallback connectActionsCallback = new ConnectActionsCallback() {
@Override
public void onAccepted(IConversation conversation) {
onAcceptedUser(conversation);
}
@Override
public void onIgnored(User user) {
onIgnoredUser(user);
}
};
inboxAdapter = new ConnectRequestInboxAdapter(getActivity(), connectActionsCallback);
inboxListView = ViewUtils.getView(rootView, R.id.crlv_connect_request_inbox__list);
if (LayoutSpec.isTablet(getActivity())) {
inboxListView.setStackFromBottom(true);
inboxListView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
}
inboxListView.setAdapter(inboxAdapter);
if (savedInstanceState != null) {
visibleConversationId = savedInstanceState.getString(ARGUMENT_CONVERSATION_ID);
} else if (visibleConversationId.equals(NO_ARGUMENT_PROVIDED_CONVERSATION_ID)) {
visibleConversationId = getArguments().getString(ARGUMENT_CONVERSATION_ID);
}
return rootView;
}
@Override
public void onStart() {
super.onStart();
getStoreFactory().getConversationStore().addConversationStoreObserverAndUpdate(this);
getStoreFactory().getInAppNotificationStore().addInAppNotificationObserver(this);
getControllerFactory().getAccentColorController().addAccentColorObserver(this);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(ARGUMENT_CONVERSATION_ID, visibleConversationId);
}
@Override
public void onStop() {
getStoreFactory().getInAppNotificationStore().removeInAppNotificationObserver(this);
getControllerFactory().getAccentColorController().removeAccentColorObserver(this);
getStoreFactory().getConversationStore().removeConversationStoreObserver(this);
inboxAdapter.reset();
super.onStop();
}
@Override
public void onDestroyView() {
inboxListView = null;
super.onDestroyView();
}
public void setVisibleConnectRequest(Bundle arguments) {
String newConversationId = arguments.getString(ARGUMENT_CONVERSATION_ID);
if (newConversationId != null &&
!newConversationId.equals(InboxLinkConversation.TAG)) {
visibleConversationId = newConversationId;
getStoreFactory().getConversationStore().loadConnectRequestInboxConversations(this, InboxLoadRequester.INBOX_SHOW_SPECIFIC);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// Connect action callbacks
//
//////////////////////////////////////////////////////////////////////////////////////////
private void onIgnoredUser(User user) {
if (inboxAdapter.getCount() <= 1) {
getContainer().dismissInboxFragment();
} else {
visibleConversationId = getNextConversationId();
getStoreFactory().getConversationStore().loadConnectRequestInboxConversations(this,
InboxLoadRequester.INBOX_DISMISS);
}
}
private void onAcceptedUser(IConversation conversation) {
if (inboxAdapter.getCount() <= 1) {
getContainer().onAcceptedUser(conversation);
} else {
visibleConversationId = getNextConversationId();
getStoreFactory().getConversationStore().loadConnectRequestInboxConversations(this,
InboxLoadRequester.INBOX_DISMISS);
}
}
private String getNextConversationId() {
int currentPosition = inboxAdapter.getMainConnectRequestPosition();
int nextPosition;
if (currentPosition == 0) {
if (inboxAdapter.getCount() > 1) {
nextPosition = currentPosition + 1;
} else {
nextPosition = 0;
}
} else if (currentPosition == inboxAdapter.getCount() - 1) {
nextPosition = currentPosition - 1;
} else {
nextPosition = currentPosition + 1;
}
return inboxAdapter.getItem(nextPosition).getId();
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// ConversationStoreObserver
//
//////////////////////////////////////////////////////////////////////////////////////////
@Override
public void onConversationListUpdated(@NonNull ConversationsList conversationsList) {
getStoreFactory().getConversationStore().loadConnectRequestInboxConversations(this, InboxLoadRequester.INBOX_LOAD);
}
@Override
public void onConversationListStateHasChanged(ConversationsList.ConversationsListState state) {
}
@Override
public void onCurrentConversationHasChanged(IConversation fromConversation,
IConversation toConversation,
ConversationChangeRequester conversationChangerSender) {
}
@Override
public void onConversationSyncingStateHasChanged(SyncState syncState) {
}
@Override
public void onMenuConversationHasChanged(IConversation fromConversation) {
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// OnInboxLoadedListener
//
//////////////////////////////////////////////////////////////////////////////////////////
@Override
public void onConnectRequestInboxConversationsLoaded(List<IConversation> conversations, InboxLoadRequester inboxLoadRequester) {
if (conversations.size() == 0) {
return;
}
// Reset inbox, show first item
if (inboxLoadRequester == InboxLoadRequester.CONNECT_REQUEST_NOTIFICATION ||
inboxLoadRequester == InboxLoadRequester.INBOX_LOAD) {
visibleConversationId = NO_ARGUMENT_PROVIDED_CONVERSATION_ID;
setInboxConversations(conversations, 0);
return;
}
if (LayoutSpec.isTablet(getActivity())) {
setInboxConversations(conversations, -1);
return;
}
// Set main connect request if value is initiated for first time or a new id value was provided as an argument
// -> swiping back & forth between conversation list and inbox does not change currently displayed connect request
int newVisiblePosition = 0;
for (int i = 0; i < conversations.size(); i++) {
IConversation conversation = conversations.get(i);
if (conversation.getId().equals(visibleConversationId)) {
newVisiblePosition = i;
break;
}
}
if (inboxAdapter.getMainConnectRequestPosition() != newVisiblePosition ||
inboxLoadRequester == InboxLoadRequester.INBOX_DISMISS) {
setInboxConversations(conversations, newVisiblePosition);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// IncomingMessages.MessageListener
//
//////////////////////////////////////////////////////////////////////////////////////////
@Override
public void onIncomingMessage(Message message) {
if (message.getMessageType() == Message.Type.CONNECT_REQUEST) {
getStoreFactory().getConversationStore().loadConnectRequestInboxConversations(this, InboxLoadRequester.CONNECT_REQUEST_NOTIFICATION);
}
}
@Override
public void onIncomingKnock(KnockingEvent knock) {
}
@Override
public void onSyncError(ErrorsList.ErrorDescription error) {
}
private void setInboxConversations(List<IConversation> conversations, final int visiblePosition) {
boolean shouldScroll = visiblePosition >= 0;
inboxListView.setStackFromBottom(conversations.size() == 1);
inboxAdapter.setMainConnectRequestPosition(shouldScroll ? visiblePosition : conversations.size() - 1);
inboxAdapter.setConnectRequests(conversations);
inboxAdapter.notifyDataSetChanged();
if (shouldScroll) {
// Scroll to a particular connect request
// Added a delay to ensure that scrolling is not ignored
mainHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (getView() != null) {
inboxListView.setSelection(visiblePosition);
}
}
}, 100);
}
}
@Override
public void onAccentColorHasChanged(Object sender, int color) {
inboxAdapter.setAccentColor(color);
inboxAdapter.notifyDataSetChanged();
}
public interface Container {
void dismissInboxFragment();
void onAcceptedUser(IConversation conversation);
}
}