package pro.dbro.ble.ui.activities;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.graphics.Palette;
import android.support.v7.widget.Toolbar;
import android.transition.Slide;
import android.transition.TransitionSet;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import com.nispok.snackbar.Snackbar;
import java.util.ArrayList;
import java.util.Arrays;
import butterknife.ButterKnife;
import butterknife.InjectView;
import hugo.weaving.DebugLog;
import im.delight.android.identicons.SymmetricIdenticon;
import pro.dbro.airshare.app.AirShareService;
import pro.dbro.airshare.app.ui.AirShareFragment;
import pro.dbro.ble.ChatClient;
import pro.dbro.ble.ChatPeerFlow;
import pro.dbro.ble.PrefsManager;
import pro.dbro.ble.R;
import pro.dbro.ble.data.model.Peer;
import pro.dbro.ble.protocol.OwnedIdentityPacket;
import pro.dbro.ble.ui.Notification;
import pro.dbro.ble.ui.adapter.StatusArrayAdapter;
import pro.dbro.ble.ui.fragment.MessagingFragment;
import pro.dbro.ble.ui.fragment.ProfileFragment;
import pro.dbro.ble.ui.fragment.WelcomeFragment;
import timber.log.Timber;
public class MainActivity extends AppCompatActivity implements LogConsumer,
WelcomeFragment.WelcomeFragmentCallback,
AirShareFragment.Callback,
MessagingFragment.ChatFragmentCallback, ChatClient.Callback {
public static final String TAG = "MainActivity";
private ActionBarDrawerToggle mDrawerToggle;
private MessagingFragment mMessagingFragment;
private OwnedIdentityPacket mUserIdentity;
private ChatClient mClient;
private AirShareFragment mAirShareFragment;
private Palette mPalette;
// private PeerAdapter mPeerAdapter;
@InjectView(R.id.status_spinner)
Spinner mStatusSpinner;
@InjectView(R.id.log)
TextView mLogView;
// @InjectView(R.id.peer_recyclerview)
// RecyclerView mPeerRecyclerView;
@InjectView(R.id.toolbar)
Toolbar mToolbar;
@InjectView(R.id.my_drawer_layout)
DrawerLayout mDrawer;
@InjectView(R.id.msg_pass_count)
TextView mMessagesPassedCount;
@InjectView(R.id.peers_met_count)
TextView mPeersMetCount;
@InjectView(R.id.profile_identicon)
SymmetricIdenticon mProfileIdenticon;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
mClient = new ChatClient(this);
// mLogView.setOnLongClickListener(new View.OnLongClickListener() {
// @Override
// public boolean onLongClick(View view) {
// mLogView.setText("");
// return false;
// }
// });
mStatusSpinner.setAdapter(new StatusArrayAdapter(this, new ArrayList<>(Arrays.asList(getResources().getStringArray(R.array.status_options)))));
mStatusSpinner.setEnabled(false);
mStatusSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (position) {
case 0: // Always online
mClient.makeAvailable();
mAirShareFragment.setShouldServiceContinueInBackground(true);
break;
case 1: // Online when using app
mClient.makeAvailable();
mAirShareFragment.setShouldServiceContinueInBackground(false);
break;
case 2: // Offline
mClient.makeUnavailable();
// mPeerAdapter.clearPeers();
break;
}
PrefsManager.setStatus(MainActivity.this, position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// do nothing
}
});
setSupportActionBar(mToolbar);
setTitle(getString(R.string.public_feed));
mToolbar.setTitleTextColor(getResources().getColor(android.R.color.white));
// mToolbar.setNavigationIcon(R.drawable.ic_drawer);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawer,
mToolbar, R.string.drawer_open, R.string.drawer_close) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
refreshProfileStats();
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
// Override ActionB
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (getSupportFragmentManager().getBackStackEntryCount() == 0)
mDrawer.openDrawer(Gravity.START);
else
getSupportFragmentManager().popBackStack();
}
});
mDrawer.setDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
checkUserRegistered();
// mPeerAdapter = new PeerAdapter(this, new ArrayList<Peer>());
// mPeerRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
// mPeerRecyclerView.setAdapter(mPeerAdapter);
getSupportFragmentManager().addOnBackStackChangedListener(new android.support.v4.app.FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
int numEntries = getSupportFragmentManager().getBackStackEntryCount();
if (numEntries == 0) {
mMessagingFragment.animateIn();
tintSystemBars(mPalette.getVibrantColor(R.color.primary), mPalette.getDarkVibrantColor(R.color.primaryDark),
getResources().getColor(R.color.primary), getResources().getColor(R.color.primaryDark));
// Hack animate the drawer icon
ValueAnimator drawerAnimator = ValueAnimator.ofFloat(1f, 0f);
drawerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mDrawerToggle.onDrawerSlide(null, (Float) animation.getAnimatedValue());
}
});
drawerAnimator.start();
setTitle(getString(R.string.public_feed));
}
}
});
}
/**
* Adds the message list fragment and populates
* the profile navigation drawer with the user profile
*/
private void revealChatViews() {
mMessagingFragment = new MessagingFragment();
mMessagingFragment.setDataStore(mClient.getDataStore());
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, mMessagingFragment, "messaging")
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit();
mProfileIdenticon.show(new String(mUserIdentity.publicKey));
((TextView) findViewById(R.id.profile_name)).setText(mUserIdentity.alias);
}
private void refreshProfileStats() {
mPeersMetCount.setText(String.valueOf(Math.max(0, mClient.getDataStore().countPeers() - 1))); //ignore self
mMessagesPassedCount.setText(String.valueOf(mClient.getDataStore().countMessagesPassed()));
}
/**
* LogConsumer interface
*/
@Override
public void onLogEvent(final String event) {
/*
mLogView.post(new Runnable() {
@Override
public void run() {
mLogView.append(event + "\n");
}
});
*/
}
/**
* Check if a username has been registered and take appropriate action.
*
* If a username has not yet been selected, show WelcomeFragment
* If a username has been selected, initialize AirShare
*/
private void checkUserRegistered() {
Peer localPeer = mClient.getPrimaryLocalPeer();
if (localPeer != null) {
// Register ourselves with the AirShare Service, using our own user model's alias
if (mAirShareFragment == null) {
mAirShareFragment = AirShareFragment.newInstance(localPeer.getAlias(), ChatClient.AIRSHARE_SERVICE_NAME, this);
Timber.d("Adding airshare frag");
getSupportFragmentManager().beginTransaction()
.add(mAirShareFragment, "airshare")
.commit();
}
} else {
// Show WelcomeFragment to collect the user's desired username
// will be notified of result via #onNameChosen
mToolbar.setVisibility(View.GONE);
getWindow().setStatusBarColor(getResources().getColor(R.color.welcome_status_bar));
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new WelcomeFragment())
.commit();
}
}
@Override
public void onServiceReady(AirShareService.ServiceBinder serviceBinder) {
mUserIdentity = (OwnedIdentityPacket) mClient.getPrimaryLocalPeer().getIdentity();
mClient.setAirShareServiceBinder(serviceBinder);
mClient.setCallback(this);
mClient.makeAvailable();
mStatusSpinner.setEnabled(true);
mStatusSpinner.setSelection(PrefsManager.getStatus(this));
revealChatViews();
refreshProfileStats();
}
@Override
public void onFinished(Exception exception) {
}
@Override
public void onMessageSendRequested(String message) {
mClient.sendPublicMessageFromPrimaryIdentity(message);
}
@Override
public void onMessageSelected(View identictionView, View usernameView, int messageId, int peerId) {
// Create new fragment to add (Fragment B)
Peer peer = mClient.getDataStore().getPeerById(peerId);
if (peer == null) {
Log.w(TAG, "Could not lookup peer. Cannot show profile");
return;
}
setTitle(peer.getAlias());
// identictionView.setTransitionName(getString(R.string.identicon_transition_name));
// usernameView.setTransitionName(getString(R.string.username_transition_name));
Fragment profileFragment = ProfileFragment.createForPeer(mClient.getDataStore(), peer);
// final TransitionSet sharedElementTransition = new TransitionSet();
// sharedElementTransition.addTransition(new ChangeBounds());
// sharedElementTransition.addTransition(new ChangeTransform());
// sharedElementTransition.setInterpolator(new AccelerateDecelerateInterpolator());
// sharedElementTransition.setDuration(200);
final TransitionSet slideTransition = new TransitionSet();
slideTransition.addTransition(new Slide());
slideTransition.setInterpolator(new AccelerateDecelerateInterpolator());
slideTransition.setDuration(300);
profileFragment.setEnterTransition(slideTransition);
profileFragment.setReturnTransition(slideTransition);
// profileFragment.setSharedElementEnterTransition(sharedElementTransition);
profileFragment.setAllowEnterTransitionOverlap(false);
profileFragment.setAllowReturnTransitionOverlap(false);
// Message fragment performs an exit when Profile is added, and an enter when profile is popped
// getFragmentManager().findFragmentByTag("messaging").setReenterTransition(slideTransition);
// getFragmentManager().findFragmentByTag("messaging").setExitTransition(slideTransition);
// getFragmentManager().findFragmentByTag("messaging").setSharedElementEnterTransition(sharedElementTransition);
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, profileFragment)
.addToBackStack("profile")
// .addSharedElement(identictionView, getString(R.string.identicon_transition_name))
// .addSharedElement(usernameView, getString(R.string.username_transition_name))
.commit();
Bitmap bitmap = Notification.loadBitmapFromView(identictionView, 100, 100);
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
public void onGenerated(Palette p) {
mPalette = p;
tintSystemBars(getResources().getColor(R.color.primary), getResources().getColor(R.color.primaryDark),
p.getVibrantColor(R.color.primary), p.getDarkVibrantColor(R.color.primaryDark));
}
});
// Hack animate the drawer icon
ValueAnimator drawerAnimator = ValueAnimator.ofFloat(0, 1f);
drawerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mDrawerToggle.onDrawerSlide(null, (Float) animation.getAnimatedValue());
}
});
drawerAnimator.start();
}
@Override
public void onAppPeerStatusUpdated(@NonNull Peer remotePeer, @NonNull ChatPeerFlow.Callback.ConnectionStatus status) {
Snackbar.with(getApplicationContext())
.position(Snackbar.SnackbarPosition.TOP)
.text(String.format("%s %s",
remotePeer.getAlias(),
status == ChatPeerFlow.Callback.ConnectionStatus.CONNECTED ? "connected" : "disconnected"))
.show((ViewGroup) findViewById(R.id.container));
// switch (status) {
// case CONNECTED:
// mPeerAdapter.notifyPeerAdded(remotePeer);
// break;
//
// case DISCONNECTED:
// mPeerAdapter.notifyPeerRemoved(remotePeer);
// break;
// }
}
private void tintSystemBars(final int toolbarFromColor, final int statusbarFromColor,
final int toolbarToColor, final int statusbarToColor) {
ValueAnimator toolbarAnim = ValueAnimator.ofArgb(toolbarFromColor, toolbarToColor);
ValueAnimator statusbarAnim = ValueAnimator.ofArgb(statusbarFromColor, statusbarToColor);
statusbarAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
getWindow().setStatusBarColor((Integer) animation.getAnimatedValue());
}
});
toolbarAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
getSupportActionBar().setBackgroundDrawable(new ColorDrawable((Integer) animation.getAnimatedValue()));
}
});
toolbarAnim.setDuration(500).start();
statusbarAnim.setDuration(500).start();
}
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
@Override
public void onNameChosen(String name) {
mToolbar.setVisibility(View.VISIBLE);
getWindow().setStatusBarColor(getResources().getColor(R.color.primaryDark));
mClient.createPrimaryIdentity(name);
checkUserRegistered();
}
}