package com.knight.arch.ui;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.TextView;
import com.alibaba.fastjson.JSON;
import com.knight.arch.R;
import com.knight.arch.api.ApiService;
import com.knight.arch.api.GitHubApiConstants;
import com.knight.arch.api.OAuthGitHubWebFlow;
import com.knight.arch.events.LoginUriMsg;
import com.knight.arch.model.AccessTokenResponse;
import com.knight.arch.model.User;
import com.knight.arch.ui.adapter.TrendingReposTimeSpanAdapter;
import com.knight.arch.events.TrendingReposTimeSpanTextMsg;
import com.knight.arch.module.HomeModule;
import com.knight.arch.ui.base.InjectableActivity;
import com.knight.arch.ui.fragment.HotReposMainFragment;
import com.knight.arch.ui.fragment.HotUsersMainFragment;
import com.knight.arch.ui.fragment.LoginDialogFragment;
import com.knight.arch.ui.fragment.TrendingReposMainFragment;
import com.knight.arch.utils.L;
import com.orhanobut.logger.Logger;
import com.squareup.picasso.Picasso;
import com.umeng.analytics.MobclickAgent;
import java.util.Arrays;
import java.util.List;
import javax.inject.Inject;
import de.greenrobot.event.EventBus;
import de.hdodenhof.circleimageview.CircleImageView;
import rx.Observer;
import rx.android.app.AppObservable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
/**
* @author andyiac
* @date 15-8-4
* @web http://blog.andyiac.com/
*/
public class MainActivity extends InjectableActivity {
private HotUsersMainFragment hotUsersFragment;
private HotReposMainFragment hotReposFragment;
private TrendingReposMainFragment trendingReposMainFragment;
private DrawerLayout mDrawerLayout;
private ActionBar ab;
private Spinner mTrendingSpinner;
private CircleImageView imageAvatar;
private TextView tvName;
private TextView tvHtmlUrl;
@Inject
OAuthGitHubWebFlow oAuthGitHubWebFlow;
@Inject
ApiService apiService;
@Inject
Picasso picasso;
private SharedPreferences sharedPreferences;
Observer<AccessTokenResponse> tokenObservable = new Observer<AccessTokenResponse>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(AccessTokenResponse accessTokenResponse) {
L.json(JSON.toJSONString(accessTokenResponse));
sharedPreferences.edit().putString("token", accessTokenResponse.getAccess_token()).apply();
//拿到token 后就去拿 userInfo
getUserInfo();
}
};
Observer<Object> userInfoObservable = new Observer<Object>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Object o) {
User user = (User) o;
L.i("MainActivity after oauth get user info ");
L.json(user);
sharedPreferences.edit().putString("username", user.getLogin()).apply();
sharedPreferences.edit().putString("avatar_url", user.getAvatar_url()).apply();
sharedPreferences.edit().putString("html_url", user.getHtml_url()).apply();
// 更新DrawerHeader user UI
picasso.load(user.getAvatar_url()).into(imageAvatar);
tvName.setText(user.getLogin());
tvHtmlUrl.setText(user.getHtml_url());
}
};
private void getUserInfo() {
String token = sharedPreferences.getString("token", "");
if (!TextUtils.isEmpty(token))
AppObservable.bindActivity(this, apiService.getUserInfoWithToken(token))
.map(new Func1<User, Object>() {
@Override
public Object call(User user) {
return user;
}
}).observeOn(AndroidSchedulers.mainThread())
.subscribe(userInfoObservable);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
initView();
sharedPreferences = MainActivity.this.getSharedPreferences("githot_sp", MODE_PRIVATE);
}
public void onResume() {
super.onResume();
MobclickAgent.onResume(this);
String avatar = sharedPreferences.getString("avatar_url", "");
String uname = sharedPreferences.getString("username", "");
String html_url = sharedPreferences.getString("html_url", "");
if (!TextUtils.isEmpty(avatar) && !TextUtils.isEmpty(uname) && !TextUtils.isEmpty(html_url)) {
picasso.load(avatar).into(imageAvatar);
tvName.setText(uname);
tvHtmlUrl.setText(html_url);
}
}
public void onPause() {
super.onPause();
MobclickAgent.onPause(this);
}
@Override
protected int provideContentViewId() {
return R.layout.activity_main;
}
private void initView() {
// setStatusColor(android.R.color.transparent);
Toolbar toolbar = (Toolbar) findViewById(R.id.id_main_toolbar);
setSupportActionBar(toolbar);
ab = getSupportActionBar();
if (ab != null) {
ab.setHomeAsUpIndicator(R.mipmap.ic_menu);
ab.setDisplayHomeAsUpEnabled(true);
}
View spinnerContainer = LayoutInflater.from(this).inflate(R.layout.trending_repos_time_span, toolbar, false);
ActionBar.LayoutParams lp = new ActionBar.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
toolbar.addView(spinnerContainer, lp);
//the spinner use below link solution
//https://blog.danielbetts.net/2015/01/02/material-design-spinner-toolbar-style-fix/
mTrendingSpinner = (Spinner) spinnerContainer.findViewById(R.id.trending_time_spinner);
mTrendingSpinner.setAdapter(new TrendingReposTimeSpanAdapter(this));
mTrendingSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String ts = "daily";
switch (position) {
case 0:
ts = "daily";
break;
case 1:
ts = "weekly";
break;
case 2:
ts = "monthly";
break;
}
TrendingReposTimeSpanTextMsg msg = new TrendingReposTimeSpanTextMsg();
msg.setTimeSpan(ts);
EventBus.getDefault().post(msg);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
if (navigationView != null) {
setupDrawerContent(navigationView);
navigationView.setCheckedItem(R.id.nav_user_china);
initLoginView(navigationView);
}
selectFragment(R.id.nav_user_china);
}
private void initLoginView(NavigationView navigationView) {
View headerView = navigationView.inflateHeaderView(R.layout.nav_header);
imageAvatar = (CircleImageView) headerView.findViewById(R.id.id_nav_header_avatar);
tvName = (TextView) headerView.findViewById(R.id.id_nav_header_uname);
tvHtmlUrl = (TextView) headerView.findViewById(R.id.id_nav_header_giturl);
tvName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openLoginInBrowser();
}
});
imageAvatar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openLoginInBrowser();
}
});
}
private void openLoginInBrowser() {
// todo to use HttpUrl.Builder
String initialScope = "user,public_repo,repo";
String url = "https://www.github.com/login/oauth/authorize?client_id=" +
GitHubApiConstants.GITHUB_APP_CLIENT_ID + "&" + "scope=" + initialScope;
LoginDialogFragment loginDialogFragment = new LoginDialogFragment(url);
loginDialogFragment.show(getSupportFragmentManager(), "loginDialog");
}
//EventBus
public void onEvent(LoginUriMsg msg) {
// GitHub OAuth
// https://developer.github.com/v3/oauth/#web-application-flow
Uri uri = msg.getUrl();
if (uri.getQueryParameter("code") != null) {
// first step
String code = uri.getQueryParameter("code");
// second step
getAccessToken(code);
}
}
private void getAccessToken(String code) {
String client_id = GitHubApiConstants.GITHUB_APP_CLIENT_ID;
String client_secret = GitHubApiConstants.GITHUB_APP_CLIENT_SECRET;
AppObservable.bindActivity(this, oAuthGitHubWebFlow.getOAuthToken(client_id, client_secret, code))
.map(new Func1<AccessTokenResponse, AccessTokenResponse>() {
@Override
public AccessTokenResponse call(AccessTokenResponse accessTokenResponse) {
return accessTokenResponse;
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(tokenObservable);
}
//=============================================================================
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == android.R.id.home) {
mDrawerLayout.openDrawer(GravityCompat.START);
return true;
}
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public List<Object> getModules() {
return Arrays.<Object>asList(new HomeModule(this));
}
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
mDrawerLayout.closeDrawers();
selectFragment(menuItem.getItemId());
return true;
}
});
}
private void selectFragment(int fragmentId) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
hideAllFragment(transaction);
switch (fragmentId) {
case R.id.nav_user_china:
if (hotUsersFragment == null) {
hotUsersFragment = new HotUsersMainFragment();
// todo diff with transaction.replace() ?
transaction.add(R.id.id_main_frame_container, hotUsersFragment, "hotUser");
} else {
transaction.show(hotUsersFragment);
}
ab.setTitle("Hot users");
break;
case R.id.nav_repositories:
if (hotReposFragment == null) {
hotReposFragment = new HotReposMainFragment();
transaction.add(R.id.id_main_frame_container, hotReposFragment, "hotRepos");
} else {
transaction.show(hotReposFragment);
}
ab.setTitle("Hot repos");
break;
case R.id.nav_trending_repos:
mTrendingSpinner.setVisibility(View.VISIBLE);
if (trendingReposMainFragment == null) {
trendingReposMainFragment = new TrendingReposMainFragment();
transaction.add(R.id.id_main_frame_container, trendingReposMainFragment, "TrendingRepos");
} else {
transaction.show(trendingReposMainFragment);
}
ab.setTitle("");
break;
}
transaction.commit();
}
private void hideAllFragment(FragmentTransaction transaction) {
if (mTrendingSpinner != null) {
mTrendingSpinner.setVisibility(View.GONE);
}
if (hotUsersFragment != null) {
transaction.hide(hotUsersFragment);
}
if (hotReposFragment != null) {
transaction.hide(hotReposFragment);
}
if (trendingReposMainFragment != null) {
transaction.hide(trendingReposMainFragment);
}
}
}